diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2001-02-03 02:37:28 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2001-02-03 02:37:28 +0000 |
commit | 2bcaea073f1a3e2e85eedde34f1ebaccc582b065 (patch) | |
tree | 0aa7f734b72914e4a8f08e30071bebe6674c186c /lib | |
parent | 86410f02dc57247659a39215c295ce8a7f5b5f62 (diff) |
Fix the the elf nlist for cases where we can't mmap the headers.
This makes /dev/ksyms work (when that code is commited).
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/gen/nlist.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/lib/libc/gen/nlist.c b/lib/libc/gen/nlist.c index 809c4373d07..1efa698bff2 100644 --- a/lib/libc/gen/nlist.c +++ b/lib/libc/gen/nlist.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: nlist.c,v 1.35 2001/01/25 05:33:04 art Exp $"; +static char rcsid[] = "$OpenBSD: nlist.c,v 1.36 2001/02/03 02:37:27 art Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -318,6 +318,7 @@ __elf_fdnlist(fd, list) Elf_Shdr *shdr = NULL; Elf_Word shdr_size; struct stat st; + int usemalloc = 0; /* Make sure obj is OK */ if (lseek(fd, (off_t)0, SEEK_SET) == -1 || @@ -338,8 +339,15 @@ __elf_fdnlist(fd, list) /* mmap section header table */ shdr = (Elf_Shdr *)mmap(NULL, (size_t)shdr_size, PROT_READ, MAP_COPY|MAP_FILE, fd, (off_t) ehdr.e_shoff); - if (shdr == MAP_FAILED) - return (-1); + if (shdr == MAP_FAILED) { + usemalloc = 1; + if ((shdr = malloc(shdr_size)) == NULL) + return (-1); + if (pread(fd, shdr, shdr_size, ehdr.e_shoff) != shdr_size) { + free(shdr); + return (-1); + } + } /* * Find the symbol table entry and it's corresponding @@ -358,7 +366,10 @@ __elf_fdnlist(fd, list) } /* Flush the section header table */ - munmap((caddr_t)shdr, shdr_size); + if (usemalloc) + free(shdr); + else + munmap((caddr_t)shdr, shdr_size); /* Check for files too large to mmap. */ /* XXX is this really possible? */ @@ -372,10 +383,19 @@ __elf_fdnlist(fd, list) * making the memory allocation permanent as with malloc/free * (i.e., munmap will return it to the system). */ - strtab = mmap(NULL, (size_t)symstrsize, PROT_READ, MAP_COPY|MAP_FILE, - fd, (off_t) symstroff); - if (strtab == MAP_FAILED) - return (-1); + if (usemalloc) { + if ((strtab = malloc(symstrsize)) == NULL) + return (-1); + if (pread(fd, strtab, symstrsize, symstroff) != symstrsize) { + free(strtab); + return (-1); + } + } else { + strtab = mmap(NULL, (size_t)symstrsize, PROT_READ, + MAP_COPY|MAP_FILE, fd, (off_t) symstroff); + if (strtab == MAP_FAILED) + return (-1); + } /* * clean out any left-over information for all valid entries. * Type and value defined to be 0 if not found; historical @@ -465,7 +485,10 @@ __elf_fdnlist(fd, list) } } elf_done: - munmap(strtab, symstrsize); + if (usemalloc) + free(strtab); + else + munmap(strtab, symstrsize); return (nent); } #endif /* _NLIST_DO_ELF */ |