diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2004-01-14 02:52:05 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2004-01-14 02:52:05 +0000 |
commit | c3b2c717c3de68aacb1ccab66e9a0cc7bde40b91 (patch) | |
tree | b565f8a2700ca77277838cb9468ff7220591b808 /usr.bin/nm | |
parent | f7cc5b8655c9095d9f23aa77c1baec172c8b4598 (diff) |
Fallback to malloc + pread if mmap fails; fixes "nm /dev/ksyms". OK mickey@
Diffstat (limited to 'usr.bin/nm')
-rw-r--r-- | usr.bin/nm/nm.c | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/usr.bin/nm/nm.c b/usr.bin/nm/nm.c index 9b5644f8d39..7f1b37a6239 100644 --- a/usr.bin/nm/nm.c +++ b/usr.bin/nm/nm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nm.c,v 1.21 2004/01/13 17:32:32 mickey Exp $ */ +/* $OpenBSD: nm.c,v 1.22 2004/01/14 02:52:04 millert Exp $ */ /* $NetBSD: nm.c,v 1.7 1996/01/14 23:04:03 pk Exp $ */ /* @@ -42,7 +42,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)nm.c 8.1 (Berkeley) 6/6/93"; #endif -static const char rcsid[] = "$OpenBSD: nm.c,v 1.21 2004/01/13 17:32:32 mickey Exp $"; +static const char rcsid[] = "$OpenBSD: nm.c,v 1.22 2004/01/14 02:52:04 millert Exp $"; #include <sys/param.h> #include <sys/mman.h> @@ -344,6 +344,27 @@ mmbr_name(struct ar_hdr *arh, char **name, int baselen, int *namelen, FILE *fp) return (0); } +#define MMAP(ptr, len, prot, flags, fd, off) do { \ + didmmap = (ptr = mmap(NULL, len, prot, flags, fd, off)) != MAP_FAILED; \ + if (!didmmap) { \ + if ((ptr = malloc(len)) == NULL) { \ + ptr = MAP_FAILED; \ + warn("malloc"); \ + } else if (pread(fd, ptr, len, off) != len) { \ + free(ptr); \ + ptr = MAP_FAILED; \ + warn("pread"); \ + } \ + } \ +} while (0) + +#define MUNMAP(addr, len) do { \ + if (didmmap) \ + munmap(addr, len); \ + else \ + free(addr); \ +} while (0) + /* * show_symtab() * show archive ranlib index (fs5) @@ -355,19 +376,16 @@ show_symtab(off_t off, u_long len, const char *name, FILE *fp) int *symtab, *ps; char *strtab, *p; int num, rval = 0; - int namelen; + int namelen, didmmap; - if ((symtab = mmap(NULL, len, PROT_READ, - MAP_PRIVATE|MAP_FILE, fileno(fp), off)) == MAP_FAILED) { - warn("%s: mmap", name); + MMAP(symtab, len, PROT_READ, MAP_PRIVATE|MAP_FILE, fileno(fp), off); + if (symtab == MAP_FAILED) return (1); - } namelen = sizeof(ar_head.ar_name); if ((p = malloc(sizeof(ar_head.ar_name))) == NULL) { warn("%s: malloc", name); - munmap(symtab, len); - return (1); + MUNMAP(symtab, len); } printf("\nArchive index:\n"); @@ -397,7 +415,7 @@ show_symtab(off_t off, u_long len, const char *name, FILE *fp) } free(p); - munmap(symtab, len); + MUNMAP(symtab, len); return (rval); } @@ -413,24 +431,18 @@ show_symdef(off_t off, u_long len, const char *name, FILE *fp) void *symdef; char *strtab, *p; u_long size; - int namelen, rval = 0; - - if ((symdef = mmap(NULL, len, PROT_READ, - MAP_PRIVATE|MAP_FILE, fileno(fp), off)) == MAP_FAILED) { - warn("%s: mmap", name); - return (1); - } + int namelen, didmmap, rval = 0; - if (madvise(symdef, len, MADV_SEQUENTIAL)) { - warn("%s: madvise", name); - munmap(symdef, len); + MMAP(symdef, len, PROT_READ, MAP_PRIVATE|MAP_FILE, fileno(fp), off); + if (symdef == MAP_FAILED) return (1); - } + if (didmmap) + (void)madvise(symdef, len, MADV_SEQUENTIAL); namelen = sizeof(ar_head.ar_name); if ((p = malloc(sizeof(ar_head.ar_name))) == NULL) { warn("%s: malloc", name); - munmap(symdef, len); + MUNMAP(symdef, len); return (1); } @@ -464,7 +476,7 @@ show_symdef(off_t off, u_long len, const char *name, FILE *fp) } free(p); - munmap(symdef, len); + MUNMAP(symdef, len); return (rval); } @@ -621,7 +633,7 @@ show_file(int count, int warn_fmt, const char *name, FILE *fp, off_t foff, union struct nlist *np; Elf_Shdr *shdr; off_t staboff; - int i, aout; + int i, aout, didmmap; aout = 0; if (IS_ELF(head->elf) && @@ -731,10 +743,9 @@ show_file(int count, int warn_fmt, const char *name, FILE *fp, off_t foff, union free(names); return(1); } - stabsize = fix_long_order(stabsize, N_GETMID(head->aout)); - if ((stab = mmap(NULL, stabsize, PROT_READ, - MAP_PRIVATE|MAP_FILE, fileno(fp), staboff)) == MAP_FAILED) { - warn("%s: mmap", name); + MMAP(stab, stabsize, PROT_READ, MAP_PRIVATE|MAP_FILE, + fileno(fp), staboff); + if (stab == MAP_FAILED) { free(snames); free(names); return (1); @@ -775,7 +786,7 @@ show_file(int count, int warn_fmt, const char *name, FILE *fp, off_t foff, union warn("%s: madvise", name); free(snames); free(names); - munmap(stab, stabsize); + MUNMAP(stab, stabsize); return (1); } @@ -829,7 +840,7 @@ show_file(int count, int warn_fmt, const char *name, FILE *fp, off_t foff, union free(snames); free(names); - munmap(stab, stabsize); + MUNMAP(stab, stabsize); return(0); } @@ -840,7 +851,7 @@ elf_symload(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh, Elf_Shdr *shdr struct nlist *np; Elf_Sym sbuf; char *shstr; - int i; + int i, didmmap = 0; shstrsize = shdr[eh->e_shstrndx].sh_size; if ((shstr = malloc(shstrsize)) == NULL) { @@ -871,10 +882,9 @@ elf_symload(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh, Elf_Shdr *shdr return (1); } - if ((stab = mmap(NULL, stabsize, PROT_READ, - MAP_PRIVATE|MAP_FILE, fileno(fp), - foff + shdr[i].sh_offset)) == MAP_FAILED) { - warn("%s: mmap", name); + MMAP(stab, stabsize, PROT_READ, MAP_PRIVATE|MAP_FILE, + fileno(fp), foff + shdr[i].sh_offset); + if (stab == MAP_FAILED) { free(shstr); return (1); } @@ -886,7 +896,7 @@ elf_symload(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh, Elf_Shdr *shdr if (fseeko(fp, foff + shdr[i].sh_offset, SEEK_SET)) { warn("%s: fseeko", name); if (stab) - munmap(stab, stabsize); + MUNMAP(stab, stabsize); free(shstr); return (1); } @@ -895,7 +905,7 @@ elf_symload(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh, Elf_Shdr *shdr if ((names = calloc(nrawnames, sizeof(*np))) == NULL) { warn("%s: malloc names", name); if (stab) - munmap(stab, stabsize); + MUNMAP(stab, stabsize); free(names); free(shstr); return (1); @@ -903,7 +913,7 @@ elf_symload(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh, Elf_Shdr *shdr if ((snames = malloc(nrawnames * sizeof(np))) == NULL) { warn("%s: malloc snames", name); if (stab) - munmap(stab, stabsize); + MUNMAP(stab, stabsize); free(shstr); free(names); free(snames); @@ -915,7 +925,7 @@ elf_symload(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh, Elf_Shdr *shdr fp) != sizeof(sbuf)) { warn("%s: read symbol", name); if (stab) - munmap(stab, stabsize); + MUNMAP(stab, stabsize); free(shstr); free(names); free(snames); |