aboutsummaryrefslogtreecommitdiff
path: root/lib/libstand
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2014-04-27 08:13:43 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2014-04-27 08:13:43 +0000
commit9d2ab4a62d6733c45958627ac113bdbd818d1e2a (patch)
treeb92e741b68057a24e381faa9809f32030d65574c /lib/libstand
parent1991e07af89dbccabfb71af86738da2a979b3d20 (diff)
parent8be1b6d975fae2513af1b0e5ad6923c3c2428ddd (diff)
Notes
Diffstat (limited to 'lib/libstand')
-rw-r--r--lib/libstand/Makefile29
-rw-r--r--lib/libstand/close.c4
-rw-r--r--lib/libstand/dosfs.c55
-rw-r--r--lib/libstand/dosfs.h3
-rw-r--r--lib/libstand/environment.c21
-rw-r--r--lib/libstand/powerpc/_setjmp.S133
-rw-r--r--lib/libstand/sbrk.c6
-rw-r--r--lib/libstand/zalloc.c9
-rw-r--r--lib/libstand/zalloc_defs.h16
-rw-r--r--lib/libstand/zalloc_mem.h2
10 files changed, 196 insertions, 82 deletions
diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile
index 33c155fc94766..5f645203597a6 100644
--- a/lib/libstand/Makefile
+++ b/lib/libstand/Makefile
@@ -6,11 +6,12 @@
# quite large.
#
-.include <bsd.own.mk>
+MK_PROFILE= no
MK_SSP= no
+.include <bsd.own.mk>
+
LIB= stand
-NO_PROFILE=
NO_PIC=
INCS= stand.h
MAN= libstand.3
@@ -21,18 +22,20 @@ CFLAGS+= -ffreestanding -Wformat
CFLAGS+= -I${.CURDIR}
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
-CFLAGS+= -mpreferred-stack-boundary=2
CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
.endif
+.if ${MACHINE_CPUARCH} == "i386"
+CFLAGS.gcc+= -mpreferred-stack-boundary=2
+.endif
+.if ${MACHINE_CPUARCH} == "amd64"
+CFLAGS+= -fPIC
+.endif
.if ${MACHINE} == "pc98"
CFLAGS+= -Os
.endif
.if ${MACHINE_CPUARCH} == "powerpc"
CFLAGS+= -msoft-float -D_STANDALONE -DNETIF_DEBUG
.endif
-.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64"
-CFLAGS+= -m32 -I.
-.endif
.if ${MACHINE_CPUARCH} == "arm"
CFLAGS+= -msoft-float -D_STANDALONE
.endif
@@ -103,9 +106,7 @@ SRCS+= syncicache.c
SRCS+= uuid_equal.c uuid_is_nil.c
# _setjmp/_longjmp
-.if ${MACHINE_CPUARCH} == "amd64"
-.PATH: ${.CURDIR}/i386
-.elif ${MACHINE_ARCH} == "powerpc64"
+.if ${MACHINE_ARCH} == "powerpc64"
.PATH: ${.CURDIR}/powerpc
.else
.PATH: ${.CURDIR}/${MACHINE_CPUARCH}
@@ -179,13 +180,3 @@ SRCS+= nandfs.c
.include <bsd.lib.mk>
-.if ${MACHINE_CPUARCH} == "amd64"
-beforedepend ${OBJS}: machine
-cleandepend: cleanmachine
-cleanmachine:
- rm -f machine
-
-machine:
- rm -f machine
- ln -s ${.CURDIR}/../../sys/i386/include machine
-.endif
diff --git a/lib/libstand/close.c b/lib/libstand/close.c
index 61b1b0d99ffe7..939f025b8fd0f 100644
--- a/lib/libstand/close.c
+++ b/lib/libstand/close.c
@@ -75,8 +75,10 @@ close(int fd)
errno = EBADF;
return (-1);
}
- if (f->f_rabuf != NULL)
+ if (f->f_rabuf != NULL) {
free(f->f_rabuf);
+ f->f_rabuf = NULL;
+ }
if (!(f->f_flags & F_RAW) && f->f_ops)
err1 = (f->f_ops->fo_close)(f);
if (!(f->f_flags & F_NODEV) && f->f_dev)
diff --git a/lib/libstand/dosfs.c b/lib/libstand/dosfs.c
index e15ecdcf6fb30..72205a2c648a5 100644
--- a/lib/libstand/dosfs.c
+++ b/lib/libstand/dosfs.c
@@ -162,6 +162,14 @@ dos_mount(DOS_FS *fs, struct open_file *fd)
(void)dosunmount(fs);
return(err);
}
+ fs->root = dot[0];
+ fs->root.name[0] = ' ';
+ if (fs->fatsz == 32) {
+ fs->root.clus[0] = fs->rdcl & 0xff;
+ fs->root.clus[1] = (fs->rdcl >> 8) & 0xff;
+ fs->root.dex.h_clus[0] = (fs->rdcl >> 16) & 0xff;
+ fs->root.dex.h_clus[1] = (fs->rdcl >> 24) & 0xff;
+ }
return 0;
}
@@ -381,21 +389,32 @@ dos_readdir(struct open_file *fd, struct dirent *d)
if (dd.de.name[0] == 0xe5)
continue;
- /* Skip volume labels */
- if (dd.de.attr & FA_LABEL)
- continue;
-
- if ((dd.de.attr & FA_MASK) == FA_XDE) {
- if (dd.xde.seq & 0x40)
- chk = dd.xde.chk;
- else if (dd.xde.seq != xdn - 1 || dd.xde.chk != chk)
- continue;
- x = dd.xde.seq & ~0x40;
- if (x < 1 || x > 20) {
- x = 0;
+ /* Check if directory entry is volume label */
+ if (dd.de.attr & FA_LABEL) {
+ /*
+ * If volume label set, check if the current entry is
+ * extended entry (FA_XDE) for long file names.
+ */
+ if ((dd.de.attr & FA_MASK) == FA_XDE) {
+ /*
+ * Read through all following extended entries
+ * to get the long file name. 0x40 marks the
+ * last entry containing part of long file name.
+ */
+ if (dd.xde.seq & 0x40)
+ chk = dd.xde.chk;
+ else if (dd.xde.seq != xdn - 1 || dd.xde.chk != chk)
+ continue;
+ x = dd.xde.seq & ~0x40;
+ if (x < 1 || x > 20) {
+ x = 0;
+ continue;
+ }
+ cp_xdnm(fn, &dd.xde);
+ } else {
+ /* skip only volume label entries */
continue;
}
- cp_xdnm(fn, &dd.xde);
} else {
if (xdn == 1) {
x = 0;
@@ -483,10 +502,12 @@ namede(DOS_FS *fs, const char *path, DOS_DE **dep)
int err;
err = 0;
- de = dot;
- if (*path == '/')
- path++;
+ de = &fs->root;
while (*path) {
+ while (*path == '/')
+ path++;
+ if (*path == '\0')
+ break;
if (!(s = strchr(path, '/')))
s = strchr(path, 0);
if ((n = s - path) > 255)
@@ -498,8 +519,6 @@ namede(DOS_FS *fs, const char *path, DOS_DE **dep)
return ENOTDIR;
if ((err = lookup(fs, stclus(fs->fatsz, de), name, &de)))
return err;
- if (*path == '/')
- path++;
}
*dep = de;
return 0;
diff --git a/lib/libstand/dosfs.h b/lib/libstand/dosfs.h
index e44b6b51f2889..9e5744de2e5c5 100644
--- a/lib/libstand/dosfs.h
+++ b/lib/libstand/dosfs.h
@@ -23,6 +23,8 @@
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
*/
#ifndef DOSIO_H
@@ -108,6 +110,7 @@ typedef struct {
u_int lsndta; /* start of data area */
u_int fatsz; /* FAT entry size */
u_int xclus; /* maximum cluster number */
+ DOS_DE root;
} DOS_FS;
typedef struct {
diff --git a/lib/libstand/environment.c b/lib/libstand/environment.c
index fde4cf9c38740..291e330044300 100644
--- a/lib/libstand/environment.c
+++ b/lib/libstand/environment.c
@@ -75,7 +75,14 @@ env_setenv(const char *name, int flags, const void *value,
* for one already.
*/
if ((ev->ev_sethook != NULL) && !(flags & EV_NOHOOK))
- return(ev->ev_sethook(ev, flags, value));
+ return (ev->ev_sethook(ev, flags, value));
+
+ /* If there is data in the variable, discard it. */
+ if (ev->ev_value != NULL && (ev->ev_flags & EV_DYNAMIC) != 0)
+ free(ev->ev_value);
+ ev->ev_value = NULL;
+ ev->ev_flags &= ~EV_DYNAMIC;
+
} else {
/*
@@ -84,6 +91,7 @@ env_setenv(const char *name, int flags, const void *value,
ev = malloc(sizeof(struct env_var));
ev->ev_name = strdup(name);
ev->ev_value = NULL;
+ ev->ev_flags = 0;
/* hooks can only be set when the variable is instantiated */
ev->ev_sethook = sethook;
ev->ev_unsethook = unsethook;
@@ -117,21 +125,16 @@ env_setenv(const char *name, int flags, const void *value,
}
}
}
-
- /* If there is data in the variable, discard it */
- if (ev->ev_value != NULL)
- free(ev->ev_value);
/* If we have a new value, use it */
if (flags & EV_VOLATILE) {
ev->ev_value = strdup(value);
+ ev->ev_flags |= EV_DYNAMIC;
} else {
ev->ev_value = (char *)value;
+ ev->ev_flags |= flags & EV_DYNAMIC;
}
- /* Keep the flag components that are relevant */
- ev->ev_flags = flags & (EV_DYNAMIC);
-
return(0);
}
@@ -201,7 +204,7 @@ env_discard(struct env_var *ev)
if (environ == ev)
environ = ev->ev_next;
free(ev->ev_name);
- if (ev->ev_flags & EV_DYNAMIC)
+ if (ev->ev_value != NULL && (ev->ev_flags & EV_DYNAMIC) != 0)
free(ev->ev_value);
free(ev);
}
diff --git a/lib/libstand/powerpc/_setjmp.S b/lib/libstand/powerpc/_setjmp.S
index 5a30810b54ffc..3884b114274c9 100644
--- a/lib/libstand/powerpc/_setjmp.S
+++ b/lib/libstand/powerpc/_setjmp.S
@@ -1,36 +1,115 @@
-/* $NetBSD: _setjmp.S,v 1.1 1997/03/29 20:55:53 thorpej Exp $ */
+/* $FreeBSD$ */
+/* from: NetBSD: setjmp.S,v 1.1 1998/01/27 15:13:12 sakamoto Exp $ */
+/* from: OpenBSD: setjmp.S,v 1.2 1996/12/28 06:22:18 rahnds Exp */
+/* kernel version of this file, does not have signal goop */
+/* int setjmp(jmp_buf env) */
#include <machine/asm.h>
-#if (defined(LIBC_SCCS) || defined(LIBC_RCS)) && !defined(lint)
- .text
- .asciz "$FreeBSD$"
+#ifdef __powerpc64__
+#define LD_REG ld
+#define ST_REG std
+#define REGWIDTH 8
+#else
+#define LD_REG lwz
+#define ST_REG stw
+#define REGWIDTH 4
#endif
-/*
- * C library -- _setjmp, _longjmp
- *
- * _longjmp(a,v)
- * will generate a "return(v?v:1)" from the last call to
- * _setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is NOT restored.
- */
+#define JMP_r1 1*REGWIDTH
+#define JMP_r2 2*REGWIDTH
+#define JMP_r14 3*REGWIDTH
+#define JMP_r15 4*REGWIDTH
+#define JMP_r16 5*REGWIDTH
+#define JMP_r17 6*REGWIDTH
+#define JMP_r18 7*REGWIDTH
+#define JMP_r19 8*REGWIDTH
+#define JMP_r20 9*REGWIDTH
+#define JMP_r21 10*REGWIDTH
+#define JMP_r22 11*REGWIDTH
+#define JMP_r23 12*REGWIDTH
+#define JMP_r24 13*REGWIDTH
+#define JMP_r25 14*REGWIDTH
+#define JMP_r26 15*REGWIDTH
+#define JMP_r27 16*REGWIDTH
+#define JMP_r28 17*REGWIDTH
+#define JMP_r29 18*REGWIDTH
+#define JMP_r30 19*REGWIDTH
+#define JMP_r31 20*REGWIDTH
+#define JMP_lr 21*REGWIDTH
+#define JMP_cr 22*REGWIDTH
+#define JMP_ctr 23*REGWIDTH
+#define JMP_xer 24*REGWIDTH
+#define JMP_sig 25*REGWIDTH
-ENTRY(_setjmp)
- mflr 11
- mfcr 12
- mr 10,1
- mr 9,2
- stmw 9,8(3)
- li 3,0
+ASENTRY_NOPROF(setjmp)
+ ST_REG 31, JMP_r31(3)
+ /* r1, r2, r14-r30 */
+ ST_REG 1, JMP_r1 (3)
+ ST_REG 2, JMP_r2 (3)
+ ST_REG 14, JMP_r14(3)
+ ST_REG 15, JMP_r15(3)
+ ST_REG 16, JMP_r16(3)
+ ST_REG 17, JMP_r17(3)
+ ST_REG 18, JMP_r18(3)
+ ST_REG 19, JMP_r19(3)
+ ST_REG 20, JMP_r20(3)
+ ST_REG 21, JMP_r21(3)
+ ST_REG 22, JMP_r22(3)
+ ST_REG 23, JMP_r23(3)
+ ST_REG 24, JMP_r24(3)
+ ST_REG 25, JMP_r25(3)
+ ST_REG 26, JMP_r26(3)
+ ST_REG 27, JMP_r27(3)
+ ST_REG 28, JMP_r28(3)
+ ST_REG 29, JMP_r29(3)
+ ST_REG 30, JMP_r30(3)
+ /* cr, lr, ctr, xer */
+ mfcr 0
+ ST_REG 0, JMP_cr(3)
+ mflr 0
+ ST_REG 0, JMP_lr(3)
+ mfctr 0
+ ST_REG 0, JMP_ctr(3)
+ mfxer 0
+ ST_REG 0, JMP_xer(3)
+ /* f14-f31, fpscr */
+ li 3, 0
blr
-ENTRY(_longjmp)
- lmw 9,8(3)
- mtlr 11
- mtcr 12
- mr 2,9
- mr 1,10
- mr 3,4
+
+.extern sigsetmask
+ASENTRY_NOPROF(longjmp)
+ LD_REG 31, JMP_r31(3)
+ /* r1, r2, r14-r30 */
+ LD_REG 1, JMP_r1 (3)
+ LD_REG 2, JMP_r2 (3)
+ LD_REG 14, JMP_r14(3)
+ LD_REG 15, JMP_r15(3)
+ LD_REG 16, JMP_r16(3)
+ LD_REG 17, JMP_r17(3)
+ LD_REG 18, JMP_r18(3)
+ LD_REG 19, JMP_r19(3)
+ LD_REG 20, JMP_r20(3)
+ LD_REG 21, JMP_r21(3)
+ LD_REG 22, JMP_r22(3)
+ LD_REG 23, JMP_r23(3)
+ LD_REG 24, JMP_r24(3)
+ LD_REG 25, JMP_r25(3)
+ LD_REG 26, JMP_r26(3)
+ LD_REG 27, JMP_r27(3)
+ LD_REG 28, JMP_r28(3)
+ LD_REG 29, JMP_r29(3)
+ LD_REG 30, JMP_r30(3)
+ /* cr, lr, ctr, xer */
+ LD_REG 0, JMP_cr(3)
+ mtcr 0
+ LD_REG 0, JMP_lr(3)
+ mtlr 0
+ LD_REG 0, JMP_ctr(3)
+ mtctr 0
+ LD_REG 0, JMP_xer(3)
+ mtxer 0
+ /* f14-f31, fpscr */
+ mr 3, 4
blr
diff --git a/lib/libstand/sbrk.c b/lib/libstand/sbrk.c
index 93d94e4824512..471e78ecf6dfe 100644
--- a/lib/libstand/sbrk.c
+++ b/lib/libstand/sbrk.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include "stand.h"
+#include "zalloc_defs.h"
static size_t maxheap, heapsize = 0;
static void *heapbase;
@@ -40,8 +41,9 @@ static void *heapbase;
void
setheap(void *base, void *top)
{
- /* Align start address to 16 bytes for the malloc code. Sigh. */
- heapbase = (void *)(((uintptr_t)base + 15) & ~15);
+ /* Align start address for the malloc code. Sigh. */
+ heapbase = (void *)(((uintptr_t)base + MALLOCALIGN_MASK) &
+ ~MALLOCALIGN_MASK);
maxheap = (char *)top - (char *)heapbase;
}
diff --git a/lib/libstand/zalloc.c b/lib/libstand/zalloc.c
index 41aef0d306947..4d1ec6291210c 100644
--- a/lib/libstand/zalloc.c
+++ b/lib/libstand/zalloc.c
@@ -71,6 +71,15 @@ __FBSDID("$FreeBSD$");
#include "zalloc_defs.h"
/*
+ * Objects in the pool must be aligned to at least the size of struct MemNode.
+ * They must also be aligned to MALLOCALIGN, which should normally be larger
+ * than the struct, so assert that to be so at compile time.
+ */
+typedef char assert_align[(sizeof(struct MemNode) <= MALLOCALIGN) ? 1 : -1];
+
+#define MEMNODE_SIZE_MASK MALLOCALIGN_MASK
+
+/*
* znalloc() - allocate memory (without zeroing) from pool. Call reclaim
* and retry if appropriate, return NULL if unable to allocate
* memory.
diff --git a/lib/libstand/zalloc_defs.h b/lib/libstand/zalloc_defs.h
index 5331ee068160d..7f2cc1202c9be 100644
--- a/lib/libstand/zalloc_defs.h
+++ b/lib/libstand/zalloc_defs.h
@@ -52,18 +52,26 @@
#define BLKEXTENDMASK (BLKEXTEND - 1)
/*
- * required malloc alignment. Just hardwire to 16.
+ * Required malloc alignment.
*
- * Note: if we implement a more sophisticated realloc, we should ensure that
- * MALLOCALIGN is at least as large as MemNode.
+ * Embedded platforms using the u-boot API drivers require that all I/O buffers
+ * be on a cache line sized boundary. The worst case size for that is 64 bytes.
+ * For other platforms, 16 bytes works fine. The alignment also must be at
+ * least sizeof(struct MemNode); this is asserted in zalloc.c.
*/
+#if defined(__arm__) || defined(__mips__) || defined(__powerpc__)
+#define MALLOCALIGN 64
+#else
+#define MALLOCALIGN 16
+#endif
+#define MALLOCALIGN_MASK (MALLOCALIGN - 1)
+
typedef struct Guard {
size_t ga_Bytes;
size_t ga_Magic; /* must be at least 32 bits */
} Guard;
-#define MALLOCALIGN 16
#define GAMAGIC 0x55FF44FD
#define GAFREE 0x5F54F4DF
diff --git a/lib/libstand/zalloc_mem.h b/lib/libstand/zalloc_mem.h
index f29c0d7c00395..26d388dfc75e1 100644
--- a/lib/libstand/zalloc_mem.h
+++ b/lib/libstand/zalloc_mem.h
@@ -48,8 +48,6 @@ typedef struct MemPool {
uintptr_t mp_Used;
} MemPool;
-#define MEMNODE_SIZE_MASK ((sizeof(MemNode) <= 8) ? 7 : 15)
-
#define ZNOTE_FREE 0
#define ZNOTE_REUSE 1