Page MenuHomeFreeBSD

D57034.id177945.diff
No OneTemporary

D57034.id177945.diff

diff --git a/lib/libc/gen/nlist.c b/lib/libc/gen/nlist.c
--- a/lib/libc/gen/nlist.c
+++ b/lib/libc/gen/nlist.c
@@ -85,6 +85,8 @@
#define ISLAST(p) (p->n_un.n_name == 0 || p->n_un.n_name[0] == 0)
+static int elf_scan_symtab(Elf_Shdr *, Elf_Ehdr *, int, char *, size_t,
+ struct nlist *, int);
static void elf_sym_to_nlist(struct nlist *, Elf_Sym *, Elf_Shdr *, int);
/*
@@ -123,14 +125,11 @@
struct nlist *p;
Elf_Off symoff = 0, symstroff = 0;
Elf_Size symsize = 0, symstrsize = 0;
- Elf_Ssize cc, i;
+ Elf_Ssize i;
int nent = -1;
int errsave;
- Elf_Sym sbuf[1024];
- Elf_Sym *s;
Elf_Ehdr ehdr;
- char *strtab = NULL;
- Elf_Shdr *shdr = NULL;
+ Elf_Shdr *shdr;
Elf_Size shdr_size;
void *base;
struct stat st;
@@ -158,39 +157,6 @@
return (-1);
shdr = (Elf_Shdr *)base;
- /*
- * Find the symbol table entry and it's corresponding
- * string table entry. Version 1.1 of the ABI states
- * that there is only one symbol table but that this
- * could change in the future.
- */
- for (i = 0; i < ehdr.e_shnum; i++) {
- if (shdr[i].sh_type == SHT_SYMTAB) {
- symoff = shdr[i].sh_offset;
- symsize = shdr[i].sh_size;
- symstroff = shdr[shdr[i].sh_link].sh_offset;
- symstrsize = shdr[shdr[i].sh_link].sh_size;
- break;
- }
- }
-
- /* Check for files too large to mmap. */
- if (symstrsize > SIZE_T_MAX) {
- errno = EFBIG;
- goto done;
- }
- /*
- * Map string table into our address space. This gives us
- * an easy way to randomly access all the strings, without
- * making the memory allocation permanent as with malloc/free
- * (i.e., munmap will return it to the system).
- */
- base = mmap(NULL, (size_t)symstrsize, PROT_READ, MAP_PRIVATE, fd,
- (off_t)symstroff);
- if (base == MAP_FAILED)
- goto done;
- strtab = (char *)base;
-
/*
* clean out any left-over information for all valid entries.
* Type and value defined to be 0 if not found; historical
@@ -210,14 +176,70 @@
++nent;
}
- /* Don't process any further if object is stripped. */
- if (symoff == 0)
- goto done;
-
- if (lseek(fd, (off_t) symoff, SEEK_SET) == -1) {
- nent = -1;
- goto done;
+ /*
+ * Find the symbol table entry and it's corresponding
+ * string table entry. Version 1.1 of the ABI states
+ * that there is only one symbol table but that this
+ * could change in the future.
+ */
+ for (i = 0; nent > 0 && i < ehdr.e_shnum; i++) {
+ if (shdr[i].sh_type != SHT_SYMTAB &&
+ shdr[i].sh_type != SHT_DYNSYM)
+ continue;
+ symoff = shdr[i].sh_offset;
+ symsize = shdr[i].sh_size;
+ symstroff = shdr[shdr[i].sh_link].sh_offset;
+ symstrsize = shdr[shdr[i].sh_link].sh_size;
+
+ /* Don't process any further if object is stripped. */
+ if (symoff == 0 || symsize == 0) {
+ errno = ENOENT;
+ continue;
+ }
+
+ /* Check for files too large to mmap. */
+ if (symstrsize > SIZE_T_MAX) {
+ errno = EFBIG;
+ continue;
+ }
+
+ /*
+ * Map string table into our address space. This gives us
+ * an easy way to randomly access all the strings, without
+ * making the memory allocation permanent as with
+ * malloc/free (i.e., munmap will return it to the
+ * system).
+ */
+ base = mmap(NULL, (size_t)symstrsize, PROT_READ,
+ MAP_PRIVATE, fd, (off_t)symstroff);
+ if (base == MAP_FAILED)
+ continue;
+
+ if (lseek(fd, (off_t)symoff, SEEK_SET) == -1)
+ nent = -1;
+ else
+ nent = elf_scan_symtab(shdr, &ehdr, fd, base,
+ symsize, list, nent);
+
+ errsave = errno;
+ munmap(base, symstrsize);
+ errno = errsave;
}
+ errsave = errno;
+ munmap(shdr, shdr_size);
+ errno = errsave;
+ return (nent);
+}
+
+static int
+elf_scan_symtab(Elf_Shdr *shdr, Elf_Ehdr *ehdr, int fd, char *strtab,
+ size_t symsize, struct nlist *list, int nent)
+{
+ Elf_Sym sbuf[1024];
+ Elf_Sym *s;
+ char *name;
+ struct nlist *p;
+ Elf_Ssize cc;
while (symsize > 0 && nent > 0) {
cc = MIN(symsize, sizeof(sbuf));
@@ -225,31 +247,18 @@
break;
symsize -= cc;
for (s = sbuf; cc > 0 && nent > 0; ++s, cc -= sizeof(*s)) {
- char *name;
- struct nlist *p;
-
name = strtab + s->st_name;
if (name[0] == '\0')
continue;
- for (p = list; !ISLAST(p); p++) {
+ for (p = list; nent > 0 && !ISLAST(p); p++) {
if ((p->n_un.n_name[0] == '_' &&
- strcmp(name, p->n_un.n_name+1) == 0)
- || strcmp(name, p->n_un.n_name) == 0) {
+ strcmp(name, p->n_un.n_name+1) == 0) ||
+ strcmp(name, p->n_un.n_name) == 0)
elf_sym_to_nlist(p, s, shdr,
- ehdr.e_shnum);
- if (--nent <= 0)
- break;
- }
+ ehdr->e_shnum);
}
}
}
- done:
- errsave = errno;
- if (strtab != NULL)
- munmap(strtab, symstrsize);
- if (shdr != NULL)
- munmap(shdr, shdr_size);
- errno = errsave;
return (nent);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 22, 5:40 PM (17 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33217057
Default Alt Text
D57034.id177945.diff (4 KB)

Event Timeline