diff options
Diffstat (limited to 'libdwfl/dwfl_module_getsym.c')
-rw-r--r-- | libdwfl/dwfl_module_getsym.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c index 5f289ccb..f78e6ec0 100644 --- a/libdwfl/dwfl_module_getsym.c +++ b/libdwfl/dwfl_module_getsym.c @@ -1,5 +1,5 @@ /* Find debugging and symbol information for a module in libdwfl. - Copyright (C) 2006,2007 Red Hat, Inc. + Copyright (C) 2006,2007,2009 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -74,12 +74,25 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx, if (sym->st_shndx != SHN_XINDEX) shndx = sym->st_shndx; + /* Figure out whether this symbol points into an SHF_ALLOC section. */ + bool alloc = true; + if ((shndxp != NULL || mod->e_type != ET_REL) + && (sym->st_shndx == SHN_XINDEX + || (sym->st_shndx < SHN_LORESERVE && sym->st_shndx != SHN_UNDEF))) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (mod->symfile->elf, shndx), + &shdr_mem); + alloc = unlikely (shdr == NULL) || (shdr->sh_flags & SHF_ALLOC); + } + if (shndxp != NULL) - *shndxp = shndx; + /* Yield -1 in case of a non-SHF_ALLOC section. */ + *shndxp = alloc ? shndx : (GElf_Word) -1; - switch (shndx) + switch (sym->st_shndx) { - case SHN_ABS: + case SHN_ABS: /* XXX sometimes should use bias?? */ case SHN_UNDEF: case SHN_COMMON: break; @@ -99,8 +112,9 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx, return NULL; } } - /* Apply the bias to the symbol value. */ - sym->st_value += mod->symfile->bias; + else if (alloc) + /* Apply the bias to the symbol value. */ + sym->st_value += mod->symfile->bias; break; } |