diff options
| author | Simon J. Gerraty <sjg@FreeBSD.org> | 2013-04-12 20:48:55 +0000 |
|---|---|---|
| committer | Simon J. Gerraty <sjg@FreeBSD.org> | 2013-04-12 20:48:55 +0000 |
| commit | 69e6d7b75e96c406d072cb83ffc9b26fbf1a86fb (patch) | |
| tree | 54038c9ac32a45f8741dcc23fb9a8ffc0e15ff89 /lib/libstand | |
| parent | 51048477bcc79bcc8753121ec91c150648df3d1b (diff) | |
| parent | 8818042ff2ecd155adb5c248a22de2dbe5d9c2a9 (diff) | |
Notes
Diffstat (limited to 'lib/libstand')
| -rw-r--r-- | lib/libstand/Makefile | 5 | ||||
| -rw-r--r-- | lib/libstand/nandfs.c | 57 | ||||
| -rw-r--r-- | lib/libstand/stand.h | 1 | ||||
| -rw-r--r-- | lib/libstand/strtoul.c | 121 |
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); +} |
