diff --git a/lib/libexecinfo/symtab.c b/lib/libexecinfo/symtab.c index ca23a1d375a3..23ce14846dd8 100644 --- a/lib/libexecinfo/symtab.c +++ b/lib/libexecinfo/symtab.c @@ -1,4 +1,4 @@ -/* $NetBSD: symtab.c,v 1.4 2016/04/11 15:30:18 christos Exp $ */ +/* $NetBSD: symtab.c,v 1.5 2016/04/20 14:00:16 christos Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -29,12 +29,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include -__RCSID("$NetBSD: symtab.c,v 1.4 2016/04/11 15:30:18 christos Exp $"); +__RCSID("$NetBSD: symtab.c,v 1.5 2016/04/20 14:00:16 christos Exp $"); #include #include #include #include +#include #include #include @@ -58,6 +59,7 @@ struct symbol { struct symtab { size_t nsymbols; struct symbol *symbols; + bool ispie; }; static int @@ -85,6 +87,7 @@ symtab_create(int fd, int bind, int type) Elf *elf; symtab_t *st; Elf_Scn *scn = NULL; + GElf_Ehdr ehdr; if (elf_version(EV_CURRENT) == EV_NONE) { warnx("Elf Library is out of date."); @@ -102,6 +105,13 @@ symtab_create(int fd, int bind, int type) elf_end(elf); return NULL; } + if (gelf_getehdr(elf, &ehdr) == NULL) { + warnx("Error getting ELF Ehdr"); + elf_end(elf); + return NULL; + } + + st->ispie = ehdr.e_type == ET_DYN; while ((scn = elf_nextscn(elf, scn)) != NULL) { GElf_Shdr shdr; @@ -176,12 +186,14 @@ symtab_find(const symtab_t *st, const void *p, Dl_info *dli) size_t hi = ns; size_t lo = 0; size_t mid = ns / 2; - uintptr_t dd, sd, me = (uintptr_t)p - (uintptr_t)dli->dli_fbase; - uintptr_t ad = (uintptr_t)dli->dli_saddr - (uintptr_t)dli->dli_fbase; + uintptr_t fbase = st->ispie ? (uintptr_t)dli->dli_fbase : 0; + uintptr_t dd, sd, me = (uintptr_t)p - fbase; + uintptr_t ad = (uintptr_t)dli->dli_saddr - fbase; #ifdef SYMTAB_DEBUG - fprintf(stderr, "%s: [fbase=%p, saddr=%p, me=%#jx]\n", __func__, - dli->dli_fbase, dli->dli_saddr, (uintmax_t)me); + fprintf(stderr, "%s: [fbase=%#jx, saddr=%p, me=%#jx ad=%#jx]\n", + __func__, (uintmax_t)fbase, dli->dli_saddr, (uintmax_t)me, + (uintmax_t)ad); #endif for (;;) { if (s[mid].st_value < me) @@ -202,14 +214,14 @@ symtab_find(const symtab_t *st, const void *p, Dl_info *dli) dli->dli_saddr = (void *)s[mid].st_value; dli->dli_sname = s[mid].st_name; #ifdef SYMTAB_DEBUG - fprintf(stderr, "%s: %p -> [%p, %s]\n", __func__, - p, dli->dli_saddr, dli->dli_sname); + fprintf(stderr, "%s: me=%#jx -> [%#jx, %s]\n", __func__, + (uintmax_t)me, (uintmax_t)sd, dli->dli_sname); #endif } #ifdef SYMTAB_DEBUG else - fprintf(stderr, "%s: %p -> [%p, ***]\n", __func__, - p, dli->dli_saddr); + fprintf(stderr, "%s: %#jx -> [%#jx, ***]\n", __func__, + (uintmax_t)me, (uintmax_t)sd); #endif return 1; }