diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-11-06 14:59:28 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-11-06 14:59:28 +0000 |
commit | f11e9bc166ef923a9251a7e2881c7caa8e9a608f (patch) | |
tree | 4c737de854ea4b6bfa6070f7d8e83a3034703475 /usr.bin | |
parent | 175df4e57707aa3ba3ab59bf0dbd3218718509fc (diff) |
Use the symtab's sh_link to get the string table section.
This is technically more correct than looking for ".strtab" and allows
us to get rid of unportable ELF_STRTAB.
We can also get rid of the hack for some incorrect ELF files since we
no longer try to apply relocations for the string table.
From Mark Johnston, markj@FreeBSD
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ctfconv/ctfconv.c | 14 | ||||
-rw-r--r-- | usr.bin/ctfconv/elf.c | 28 | ||||
-rw-r--r-- | usr.bin/ctfdump/ctfdump.c | 15 | ||||
-rw-r--r-- | usr.bin/ctfdump/elf.c | 30 |
4 files changed, 55 insertions, 32 deletions
diff --git a/usr.bin/ctfconv/ctfconv.c b/usr.bin/ctfconv/ctfconv.c index 31eb7bc7fb0..a7f65090a8c 100644 --- a/usr.bin/ctfconv/ctfconv.c +++ b/usr.bin/ctfconv/ctfconv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ctfconv.c,v 1.15 2017/11/03 12:55:43 mpi Exp $ */ +/* $OpenBSD: ctfconv.c,v 1.16 2017/11/06 14:59:27 mpi Exp $ */ /* * Copyright (c) 2016-2017 Martin Pieuchot @@ -60,7 +60,7 @@ void dump_obj(struct itype *, int *); int iself(const char *, size_t); int elf_getshstab(const char *, size_t, const char **, size_t *); ssize_t elf_getsymtab(const char *, size_t, const char *, size_t, - const Elf_Sym **, size_t *); + const Elf_Sym **, size_t *, const char **, size_t *); ssize_t elf_getsection(char *, size_t, const char *, const char *, size_t, const char **, size_t *); @@ -221,15 +221,11 @@ elf_convert(char *p, size_t filesize) if (elf_getshstab(p, filesize, &shstab, &shstabsz)) return 1; - /* Find symbol table location and number of symbols. */ - if (elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, &nsymb) == -1) + /* Find symbol table and associated string table. */ + if (elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, &nsymb, + &strtab, &strtabsz) == -1) warnx("symbol table not found"); - /* Find string table location and size. */ - if (elf_getsection(p, filesize, ELF_STRTAB, shstab, shstabsz, &strtab, - &strtabsz) == -1) - warnx("string table not found"); - /* Find abbreviation location and size. */ if (elf_getsection(p, filesize, DEBUG_ABBREV, shstab, shstabsz, &abbuf, &ablen) == -1) { diff --git a/usr.bin/ctfconv/elf.c b/usr.bin/ctfconv/elf.c index b7b2c542517..0bd026ebe86 100644 --- a/usr.bin/ctfconv/elf.c +++ b/usr.bin/ctfconv/elf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: elf.c,v 1.7 2017/10/27 08:33:46 mpi Exp $ */ +/* $OpenBSD: elf.c,v 1.8 2017/11/06 14:59:27 mpi Exp $ */ /* * Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org> @@ -104,14 +104,16 @@ elf_getshstab(const char *p, size_t filesize, const char **shstab, ssize_t elf_getsymtab(const char *p, size_t filesize, const char *shstab, - size_t shstabsz, const Elf_Sym **symtab, size_t *nsymb) + size_t shstabsz, const Elf_Sym **symtab, size_t *nsymb, const char **strtab, + size_t *strtabsz) { Elf_Ehdr *eh = (Elf_Ehdr *)p; - Elf_Shdr *sh; + Elf_Shdr *sh, *symsh; size_t snlen; ssize_t i; snlen = strlen(ELF_SYMTAB); + symsh = NULL; for (i = 0; i < eh->e_shnum; i++) { sh = (Elf_Shdr *)(p + eh->e_shoff + i * eh->e_shentsize); @@ -133,12 +135,26 @@ elf_getsymtab(const char *p, size_t filesize, const char *shstab, *symtab = (Elf_Sym *)(p + sh->sh_offset); if (nsymb != NULL) *nsymb = (sh->sh_size / sh->sh_entsize); + symsh = sh; - return i; + break; } } - return -1; + if (symsh == NULL || (symsh->sh_link >= eh->e_shnum)) + return -1; + + sh = (Elf_Shdr *)(p + eh->e_shoff + symsh->sh_link * eh->e_shentsize); + + if ((sh->sh_offset + sh->sh_size) > filesize) + return -1; + + if (strtab != NULL) + *strtab = p + sh->sh_offset; + if (strtabsz != NULL) + *strtabsz = sh->sh_size; + + return i; } ssize_t @@ -240,7 +256,7 @@ elf_reloc_apply(const char *p, size_t filesize, const char *shstab, /* Find symbol table location and number of symbols. */ symtabidx = elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, - &nsymb); + &nsymb, NULL, NULL); if (symtabidx == -1) { warnx("symbol table not found"); return; diff --git a/usr.bin/ctfdump/ctfdump.c b/usr.bin/ctfdump/ctfdump.c index ce9e8fd9700..adad8b76562 100644 --- a/usr.bin/ctfdump/ctfdump.c +++ b/usr.bin/ctfdump/ctfdump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ctfdump.c,v 1.18 2017/11/03 12:53:38 mpi Exp $ */ +/* $OpenBSD: ctfdump.c,v 1.19 2017/11/06 14:59:27 mpi Exp $ */ /* * Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org> @@ -67,7 +67,8 @@ const char *elf_idx2sym(size_t *, uint8_t); int iself(const char *, size_t); int elf_getshstab(const char *, size_t, const char **, size_t *); ssize_t elf_getsymtab(const char *, size_t filesize, const char *, - size_t, const Elf_Sym **, size_t *); + size_t, const Elf_Sym **, size_t *, const char **, + size_t *); ssize_t elf_getsection(char *, size_t, const char *, const char *, size_t, const char **, size_t *); @@ -206,15 +207,11 @@ elf_dump(char *p, size_t filesize, uint8_t flags) if (elf_getshstab(p, filesize, &shstab, &shstabsz)) return 1; - /* Find symbol table location and number of symbols. */ - if (elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, &nsymb) == -1) + /* Find symbol table and associated string table. */ + if (elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, &nsymb, + &strtab, &strtabsz) == -1) warnx("symbol table not found"); - /* Find string table location and size. */ - if (elf_getsection(p, filesize, ELF_STRTAB, shstab, shstabsz, &strtab, - &strtabsz) == -1) - warnx("string table not found"); - /* Find CTF section and dump it. */ for (i = 0; i < eh->e_shnum; i++) { sh = (Elf_Shdr *)(p + eh->e_shoff + i * eh->e_shentsize); diff --git a/usr.bin/ctfdump/elf.c b/usr.bin/ctfdump/elf.c index fbf653ac69e..2236a68ac2f 100644 --- a/usr.bin/ctfdump/elf.c +++ b/usr.bin/ctfdump/elf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: elf.c,v 1.6 2017/11/01 15:45:28 mpi Exp $ */ +/* $OpenBSD: elf.c,v 1.7 2017/11/06 14:59:27 mpi Exp $ */ /* * Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org> @@ -104,14 +104,16 @@ elf_getshstab(const char *p, size_t filesize, const char **shstab, ssize_t elf_getsymtab(const char *p, size_t filesize, const char *shstab, - size_t shstabsz, const Elf_Sym **symtab, size_t *nsymb) + size_t shstabsz, const Elf_Sym **symtab, size_t *nsymb, const char **strtab, + size_t *strtabsz) { Elf_Ehdr *eh = (Elf_Ehdr *)p; - Elf_Shdr *sh; + Elf_Shdr *sh, *symsh; size_t snlen; ssize_t i; snlen = strlen(ELF_SYMTAB); + symsh = NULL; for (i = 0; i < eh->e_shnum; i++) { sh = (Elf_Shdr *)(p + eh->e_shoff + i * eh->e_shentsize); @@ -133,12 +135,26 @@ elf_getsymtab(const char *p, size_t filesize, const char *shstab, *symtab = (Elf_Sym *)(p + sh->sh_offset); if (nsymb != NULL) *nsymb = (sh->sh_size / sh->sh_entsize); + symsh = sh; - return i; + break; } } - return -1; + if (symsh == NULL || (symsh->sh_link >= eh->e_shnum)) + return -1; + + sh = (Elf_Shdr *)(p + eh->e_shoff + symsh->sh_link * eh->e_shentsize); + + if ((sh->sh_offset + sh->sh_size) > filesize) + return -1; + + if (strtab != NULL) + *strtab = p + sh->sh_offset; + if (strtabsz != NULL) + *strtabsz = sh->sh_size; + + return i; } ssize_t @@ -172,10 +188,8 @@ elf_getsection(char *p, size_t filesize, const char *sname, const char *shstab, sidx = i; sdata = p + sh->sh_offset; ssz = sh->sh_size; -#ifdef needreloc elf_reloc_apply(p, filesize, shstab, shstabsz, sidx, sdata, ssz); -#endif break; } } @@ -242,7 +256,7 @@ elf_reloc_apply(const char *p, size_t filesize, const char *shstab, /* Find symbol table location and number of symbols. */ symtabidx = elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, - &nsymb); + &nsymb, NULL, NULL); if (symtabidx == -1) { warnx("symbol table not found"); return; |