summaryrefslogtreecommitdiff
path: root/lib/libstand
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
commit69e6d7b75e96c406d072cb83ffc9b26fbf1a86fb (patch)
tree54038c9ac32a45f8741dcc23fb9a8ffc0e15ff89 /lib/libstand
parent51048477bcc79bcc8753121ec91c150648df3d1b (diff)
parent8818042ff2ecd155adb5c248a22de2dbe5d9c2a9 (diff)
Notes
Diffstat (limited to 'lib/libstand')
-rw-r--r--lib/libstand/Makefile5
-rw-r--r--lib/libstand/nandfs.c57
-rw-r--r--lib/libstand/stand.h1
-rw-r--r--lib/libstand/strtoul.c121
4 files changed, 165 insertions, 19 deletions
diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile
index 807136d116dc..2886e927fab4 100644
--- a/lib/libstand/Makefile
+++ b/lib/libstand/Makefile
@@ -39,7 +39,7 @@ CFLAGS+= -msoft-float -D_STANDALONE
# standalone components and stuff we have modified locally
SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c gets.c \
- globals.c pager.c printf.c strdup.c strerror.c strtol.c random.c \
+ globals.c pager.c printf.c strdup.c strerror.c strtol.c strtoul.c random.c \
sbrk.c twiddle.c zalloc.c zalloc_malloc.c
# private (pruned) versions of libc string functions
@@ -67,6 +67,9 @@ SRCS+= divsi3.S
.else
# Compiler support functions
.PATH: ${.CURDIR}/../../contrib/compiler-rt/lib/
+# __clzsi2 and ctzsi2 for various builtin functions
+SRCS+= clzsi2.c ctzsi2.c
+# Divide and modulus functions called by the compiler
SRCS+= divmoddi4.c divmodsi4.c divdi3.c divsi3.c moddi3.c modsi3.c
SRCS+= udivmoddi4.c udivmodsi4.c udivdi3.c udivsi3.c umoddi3.c umodsi3.c
diff --git a/lib/libstand/nandfs.c b/lib/libstand/nandfs.c
index d5fcb9dde4f0..713dc125de7c 100644
--- a/lib/libstand/nandfs.c
+++ b/lib/libstand/nandfs.c
@@ -95,8 +95,7 @@ static off_t nandfs_seek(struct open_file *, off_t, int);
static int nandfs_stat(struct open_file *, struct stat *);
static int nandfs_readdir(struct open_file *, struct dirent *);
-static int nandfs_buf_read(struct nandfs *, char **, size_t *);
-static struct nandfs_node *nandfs_lookup_inode(struct nandfs *, nandfs_daddr_t);
+static int nandfs_buf_read(struct nandfs *, void **, size_t *);
static struct nandfs_node *nandfs_lookup_path(struct nandfs *, const char *);
static int nandfs_read_inode(struct nandfs *, struct nandfs_node *,
nandfs_lbn_t, u_int, void *, int);
@@ -125,6 +124,27 @@ struct fs_ops nandfs_fsops = {
#define NINDIR(fs) ((fs)->nf_blocksize / sizeof(nandfs_daddr_t))
+/* from NetBSD's src/sys/net/if_ethersubr.c */
+static uint32_t
+nandfs_crc32(uint32_t crc, const uint8_t *buf, size_t len)
+{
+ static const uint32_t crctab[] = {
+ 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
+ 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+ 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
+ 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
+ };
+ size_t i;
+
+ crc = crc ^ ~0U;
+ for (i = 0; i < len; i++) {
+ crc ^= buf[i];
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ }
+ return (crc ^ ~0U);
+}
+
static int
nandfs_check_fsdata_crc(struct nandfs_fsdata *fsdata)
{
@@ -138,7 +158,7 @@ nandfs_check_fsdata_crc(struct nandfs_fsdata *fsdata)
/* Calculate */
fsdata->f_sum = (0);
- comp_crc = crc32(0, (uint8_t *)fsdata, fsdata->f_bytes);
+ comp_crc = nandfs_crc32(0, (uint8_t *)fsdata, fsdata->f_bytes);
/* Restore */
fsdata->f_sum = fsdata_crc;
@@ -162,7 +182,7 @@ nandfs_check_superblock_crc(struct nandfs_fsdata *fsdata,
/* Calculate */
super->s_sum = (0);
- comp_crc = crc32(0, (uint8_t *)super, fsdata->f_sbbytes);
+ comp_crc = nandfs_crc32(0, (uint8_t *)super, fsdata->f_sbbytes);
/* Restore */
super->s_sum = super_crc;
@@ -397,7 +417,7 @@ nandfs_open(const char *path, struct open_file *f)
return (0);
}
-static int
+static void
nandfs_free_node(struct nandfs_node *node)
{
struct bmap_buf *bmap, *tmp;
@@ -424,6 +444,7 @@ nandfs_close(struct open_file *f)
nandfs_free_node(fs->nf_opened_node);
free(fs->nf_sb);
free(fs);
+ return (0);
}
static int
@@ -431,7 +452,7 @@ nandfs_read(struct open_file *f, void *addr, size_t size, size_t *resid)
{
struct nandfs *fs = (struct nandfs *)f->f_fsdata;
size_t csize, buf_size;
- uint8_t *buf;
+ void *buf;
int error = 0;
NANDFS_DEBUG("nandfs_read(file=%p, addr=%p, size=%d)\n", f, addr, size);
@@ -440,7 +461,7 @@ nandfs_read(struct open_file *f, void *addr, size_t size, size_t *resid)
if (fs->nf_offset >= fs->nf_opened_node->inode->i_size)
break;
- error = nandfs_buf_read(fs, (void *)&buf, &buf_size);
+ error = nandfs_buf_read(fs, &buf, &buf_size);
if (error)
break;
@@ -517,7 +538,7 @@ nandfs_readdir(struct open_file *f, struct dirent *d)
{
struct nandfs *fs = f->f_fsdata;
struct nandfs_dir_entry *dirent;
- uint8_t *buf;
+ void *buf;
size_t buf_size;
NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)\n", f, d);
@@ -528,7 +549,7 @@ nandfs_readdir(struct open_file *f, struct dirent *d)
return (ENOENT);
}
- if (nandfs_buf_read(fs, (void *)&buf, &buf_size)) {
+ if (nandfs_buf_read(fs, &buf, &buf_size)) {
NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)"
"buf_read failed\n", f, d);
return (EIO);
@@ -546,7 +567,7 @@ nandfs_readdir(struct open_file *f, struct dirent *d)
}
static int
-nandfs_buf_read(struct nandfs *fs, char **buf_p, size_t *size_p)
+nandfs_buf_read(struct nandfs *fs, void **buf_p, size_t *size_p)
{
nandfs_daddr_t blknr, blkoff;
@@ -612,8 +633,8 @@ nandfs_lookup_path(struct nandfs *fs, const char *path)
struct nandfs_node *node;
struct nandfs_dir_entry *dirent;
char *namebuf;
- uint64_t i, j, done, counter, pinode, inode;
- int nlinks = 0, len, link_len, nameidx;
+ uint64_t i, done, pinode, inode;
+ int nlinks = 0, counter, len, link_len, nameidx;
uint8_t *buffer, *orig;
char *strp, *lpath;
@@ -650,7 +671,8 @@ nandfs_lookup_path(struct nandfs *fs, const char *path)
buffer = orig;
done = counter = 0;
while (1) {
- dirent = (struct nandfs_dir_entry *)buffer;
+ dirent =
+ (struct nandfs_dir_entry *)(void *)buffer;
NANDFS_DEBUG("%s: dirent.name = %s\n",
__func__, dirent->name);
NANDFS_DEBUG("%s: dirent.rec_len = %d\n",
@@ -746,9 +768,9 @@ static int
nandfs_read_inode(struct nandfs *fs, struct nandfs_node *node,
nandfs_daddr_t blknr, u_int nblks, void *buf, int raw)
{
- int i;
uint64_t *pblks;
uint64_t *vblks;
+ u_int i;
int error;
pblks = malloc(nblks * sizeof(uint64_t));
@@ -777,7 +799,7 @@ nandfs_read_inode(struct nandfs *fs, struct nandfs_node *node,
return (EIO);
}
- buf += fs->nf_blocksize;
+ buf = (void *)((uintptr_t)buf + fs->nf_blocksize);
}
free(pblks);
@@ -859,8 +881,7 @@ nandfs_bmap_lookup(struct nandfs *fs, struct nandfs_node *node,
{
struct nandfs_inode *ino;
nandfs_daddr_t ind_block_num;
- uint64_t *map, *indir;
- uint64_t idx0, idx1, vblk, tmp;
+ uint64_t *map;
int idx;
int level;
@@ -1006,7 +1027,7 @@ ioread(struct open_file *f, off_t pos, void *buf, u_int length)
err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, pos,
nsec * bsize, buffer, NULL);
- memcpy(buf, buffer + off, length);
+ memcpy(buf, (void *)((uintptr_t)buffer + off), length);
free(buffer);
return (err);
diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h
index 10bb829c4ced..2a1e9a993276 100644
--- a/lib/libstand/stand.h
+++ b/lib/libstand/stand.h
@@ -261,6 +261,7 @@ extern u_long random(void);
/* imports from stdlib, locally modified */
extern long strtol(const char *, char **, int);
+extern unsigned long strtoul(const char *, char **, int);
extern char *optarg; /* getopt(3) external variables */
extern int optind, opterr, optopt, optreset;
extern int getopt(int, char * const [], const char *);
diff --git a/lib/libstand/strtoul.c b/lib/libstand/strtoul.c
new file mode 100644
index 000000000000..5735d20d25ed
--- /dev/null
+++ b/lib/libstand/strtoul.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "stand.h"
+#include <limits.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long
+strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+ const char *s;
+ unsigned long acc;
+ char c;
+ unsigned long cutoff;
+ int neg, any, cutlim;
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace((unsigned char)c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+ if (base < 2 || base > 36)
+ goto noconv;
+
+ cutoff = ULONG_MAX / base;
+ cutlim = ULONG_MAX % base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULONG_MAX;
+ errno = ERANGE;
+ } else if (!any) {
+noconv:
+ errno = EINVAL;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}