16258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper/* Find debugging and symbol information for a module in libdwfl. 2159ac52b061c60947a943c102298cd692223274fMark Wielaard Copyright (C) 2005-2013 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 46258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 5de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of either 76258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 216258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 226258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 236258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper General Public License for more details. 246258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 25de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard not, see <http://www.gnu.org/licenses/>. */ 286258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 296258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper#include "libdwflP.h" 306258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 31b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehstruct search_state 326258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper{ 33b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Dwfl_Module *mod; 34b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Addr addr; 356258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 36b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Sym *closest_sym; 37b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh bool adjust_st_value; 38b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Word addr_shndx; 39b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Elf *addr_symelf; 40159ac52b061c60947a943c102298cd692223274fMark Wielaard 41b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* Keep track of the closest symbol we have seen so far. 42b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Here we store only symbols with nonzero st_size. */ 43b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh const char *closest_name; 44b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Addr closest_value; 45b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Word closest_shndx; 46b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Elf *closest_elf; 47159ac52b061c60947a943c102298cd692223274fMark Wielaard 48b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* Keep track of an eligible symbol with st_size == 0 as a fallback. */ 49b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh const char *sizeless_name; 50b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Sym sizeless_sym; 51b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Addr sizeless_value; 52b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Word sizeless_shndx; 53b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Elf *sizeless_elf; 546258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 55b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* Keep track of the lowest address a relevant sizeless symbol could have. */ 56b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Addr min_label; 57b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh}; 586258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 59b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh/* Return true iff we consider ADDR to lie in the same section as SYM. */ 60b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehstatic inline bool 61b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehsame_section (struct search_state *state, 62b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Addr value, Elf *symelf, GElf_Word shndx) 63b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh{ 64b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* For absolute symbols and the like, only match exactly. */ 65b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (shndx >= SHN_LORESERVE) 66b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return value == state->addr; 67b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 68b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* If value might not be st_value, the shndx of the symbol might 69b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh not match the section of the value. Explicitly look both up. */ 70b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (! state->adjust_st_value) 71b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 72b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Dwarf_Addr v; 73b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (state->addr_shndx == SHN_UNDEF) 74b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 75b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh v = state->addr; 76b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->addr_shndx = __libdwfl_find_section_ndx (state->mod, &v); 77b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 78b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 79b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh v = value; 80b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return state->addr_shndx == __libdwfl_find_section_ndx (state->mod, &v); 816258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 826258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 83b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* Figure out what section ADDR lies in. */ 84b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (state->addr_shndx == SHN_UNDEF || state->addr_symelf != symelf) 85b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 86b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Addr mod_addr = dwfl_deadjust_st_value (state->mod, symelf, 87b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->addr); 88b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Elf_Scn *scn = NULL; 89b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->addr_shndx = SHN_ABS; 90b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->addr_symelf = symelf; 91b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh while ((scn = elf_nextscn (symelf, scn)) != NULL) 92b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 93b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Shdr shdr_mem; 94b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 95b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (likely (shdr != NULL) 96b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && mod_addr >= shdr->sh_addr 97b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && mod_addr < shdr->sh_addr + shdr->sh_size) 98b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 99b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->addr_shndx = elf_ndxscn (scn); 100b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh break; 101b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 102b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 103b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 10442f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath 105b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return shndx == state->addr_shndx && state->addr_symelf == symelf; 106b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh} 10742f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath 108b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh/* Return GELF_ST_BIND as higher-is-better integer. */ 109b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehstatic inline int 110b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehbinding_value (const GElf_Sym *symp) 111b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh{ 112b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh switch (GELF_ST_BIND (symp->st_info)) 113b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 114b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh case STB_GLOBAL: 115b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return 3; 116b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh case STB_WEAK: 117b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return 2; 118b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh case STB_LOCAL: 119b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return 1; 120b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh default: 121b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return 0; 122b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 123b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh} 12442f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath 125b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh/* Try one symbol and associated value from the search table. */ 126b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehstatic inline void 127b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehtry_sym_value (struct search_state *state, 128b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Addr value, GElf_Sym *sym, 129b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh const char *name, GElf_Word shndx, 130b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Elf *elf, bool resolved) 131b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh{ 132159ac52b061c60947a943c102298cd692223274fMark Wielaard /* Even if we don't choose this symbol, its existence excludes 133159ac52b061c60947a943c102298cd692223274fMark Wielaard any sizeless symbol (assembly label) that is below its upper 134159ac52b061c60947a943c102298cd692223274fMark Wielaard bound. */ 135b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (value + sym->st_size > state->min_label) 136b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->min_label = value + sym->st_size; 137159ac52b061c60947a943c102298cd692223274fMark Wielaard 138b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (sym->st_size == 0 || state->addr - value < sym->st_size) 139159ac52b061c60947a943c102298cd692223274fMark Wielaard { 140159ac52b061c60947a943c102298cd692223274fMark Wielaard /* This symbol is a better candidate than the current one 141159ac52b061c60947a943c102298cd692223274fMark Wielaard if it's closer to ADDR or is global when it was local. */ 142b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (state->closest_name == NULL 143b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || state->closest_value < value 144b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || binding_value (state->closest_sym) < binding_value (sym)) 145159ac52b061c60947a943c102298cd692223274fMark Wielaard { 146159ac52b061c60947a943c102298cd692223274fMark Wielaard if (sym->st_size != 0) 147159ac52b061c60947a943c102298cd692223274fMark Wielaard { 148b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh *state->closest_sym = *sym; 149b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->closest_value = value; 150b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->closest_shndx = shndx; 151b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->closest_elf = elf; 152b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->closest_name = name; 153159ac52b061c60947a943c102298cd692223274fMark Wielaard } 154b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh else if (state->closest_name == NULL 155b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && value >= state->min_label 156b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && same_section (state, value, 157b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh resolved ? state->mod->main.elf : elf, 158b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh shndx)) 159159ac52b061c60947a943c102298cd692223274fMark Wielaard { 160159ac52b061c60947a943c102298cd692223274fMark Wielaard /* Handwritten assembly symbols sometimes have no 161159ac52b061c60947a943c102298cd692223274fMark Wielaard st_size. If no symbol with proper size includes 162159ac52b061c60947a943c102298cd692223274fMark Wielaard the address, we'll use the closest one that is in 163159ac52b061c60947a943c102298cd692223274fMark Wielaard the same section as ADDR. */ 164b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->sizeless_sym = *sym; 165b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->sizeless_value = value; 166b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->sizeless_shndx = shndx; 167b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->sizeless_elf = elf; 168b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->sizeless_name = name; 169159ac52b061c60947a943c102298cd692223274fMark Wielaard } 170159ac52b061c60947a943c102298cd692223274fMark Wielaard } 171159ac52b061c60947a943c102298cd692223274fMark Wielaard /* When the beginning of its range is no closer, 172159ac52b061c60947a943c102298cd692223274fMark Wielaard the end of its range might be. Otherwise follow 173159ac52b061c60947a943c102298cd692223274fMark Wielaard GELF_ST_BIND preference. If all are equal prefer 174159ac52b061c60947a943c102298cd692223274fMark Wielaard the first symbol found. */ 175159ac52b061c60947a943c102298cd692223274fMark Wielaard else if (sym->st_size != 0 176b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && state->closest_value == value 177b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && ((state->closest_sym->st_size > sym->st_size 178b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && (binding_value (state->closest_sym) 179159ac52b061c60947a943c102298cd692223274fMark Wielaard <= binding_value (sym))) 180b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || (state->closest_sym->st_size >= sym->st_size 181b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && (binding_value (state->closest_sym) 182159ac52b061c60947a943c102298cd692223274fMark Wielaard < binding_value (sym))))) 183159ac52b061c60947a943c102298cd692223274fMark Wielaard { 184b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh *state->closest_sym = *sym; 185b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->closest_value = value; 186b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->closest_shndx = shndx; 187b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->closest_elf = elf; 188b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->closest_name = name; 189159ac52b061c60947a943c102298cd692223274fMark Wielaard } 190159ac52b061c60947a943c102298cd692223274fMark Wielaard } 191b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh} 192159ac52b061c60947a943c102298cd692223274fMark Wielaard 193b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh/* Look through the symbol table for a matching symbol. */ 194b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehstatic inline void 195b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehsearch_table (struct search_state *state, int start, int end) 196b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh{ 197ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard for (int i = start; i < end; ++i) 1986258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 199ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard GElf_Sym sym; 200159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Addr value; 201ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard GElf_Word shndx; 202819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaard Elf *elf; 203159ac52b061c60947a943c102298cd692223274fMark Wielaard bool resolved; 204b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh const char *name = __libdwfl_getsym (state->mod, i, &sym, &value, 205159ac52b061c60947a943c102298cd692223274fMark Wielaard &shndx, &elf, NULL, 206b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh &resolved, 207b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state->adjust_st_value); 208ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard if (name != NULL && name[0] != '\0' 209ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard && sym.st_shndx != SHN_UNDEF 210b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && value <= state->addr 211ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard && GELF_ST_TYPE (sym.st_info) != STT_SECTION 212ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard && GELF_ST_TYPE (sym.st_info) != STT_FILE 213ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard && GELF_ST_TYPE (sym.st_info) != STT_TLS) 214c76f0b05676f6207affbfd85e75063db3b6eeccfRoland McGrath { 215b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh try_sym_value (state, value, &sym, name, shndx, elf, resolved); 216ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard 217159ac52b061c60947a943c102298cd692223274fMark Wielaard /* If this is an addrinfo variant and the value could be 218159ac52b061c60947a943c102298cd692223274fMark Wielaard resolved then also try matching the (adjusted) st_value. */ 219b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (resolved && state->mod->e_type != ET_REL) 220c76f0b05676f6207affbfd85e75063db3b6eeccfRoland McGrath { 221159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Addr adjusted_st_value; 222b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh adjusted_st_value = dwfl_adjusted_st_value (state->mod, elf, 223159ac52b061c60947a943c102298cd692223274fMark Wielaard sym.st_value); 224b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (value != adjusted_st_value 225b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && adjusted_st_value <= state->addr) 226b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh try_sym_value (state, adjusted_st_value, &sym, name, shndx, 227159ac52b061c60947a943c102298cd692223274fMark Wielaard elf, false); 22842f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath } 2296258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 2306258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 231b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh} 232b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 233b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh/* Returns the name of the symbol "closest" to ADDR. 234b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Never returns symbols at addresses above ADDR. */ 235b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehconst char * 236b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehinternal_function 237b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh__libdwfl_addrsym (Dwfl_Module *_mod, GElf_Addr _addr, GElf_Off *off, 238b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh GElf_Sym *_closest_sym, GElf_Word *shndxp, 239b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Elf **elfp, Dwarf_Addr *biasp, bool _adjust_st_value) 240b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh{ 241b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh int syments = INTUSE(dwfl_module_getsymtab) (_mod); 242b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (syments < 0) 243b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return NULL; 244b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 245b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh struct search_state state = 246b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 247b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .addr = _addr, 248b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .mod = _mod, 249b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .closest_sym = _closest_sym, 250b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .adjust_st_value = _adjust_st_value, 251b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .addr_shndx = SHN_UNDEF, 252b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .addr_symelf = NULL, 253b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .closest_name = NULL, 254b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .closest_value = 0, 255b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .closest_shndx = SHN_UNDEF, 256b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .closest_elf = NULL, 257b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .sizeless_name = NULL, 258b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .sizeless_sym = { 0, 0, 0, 0, 0, SHN_UNDEF }, 259b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .sizeless_value = 0, 260b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .sizeless_shndx = SHN_UNDEF, 261b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .sizeless_elf = NULL, 262b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh .min_label = 0 263b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh }; 2646258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 2655083a70d3b64946fa47ea5766943a15a3ecc6891Mark Wielaard /* First go through global symbols. mod->first_global and 2665083a70d3b64946fa47ea5766943a15a3ecc6891Mark Wielaard mod->aux_first_global are setup by dwfl_module_getsymtab to the 267697bdca1d7d70ebdcae90759dd885258400e1951Mark Wielaard index of the first global symbol in those symbol tables. Both 268697bdca1d7d70ebdcae90759dd885258400e1951Mark Wielaard are non-zero when the table exist, except when there is only a 269697bdca1d7d70ebdcae90759dd885258400e1951Mark Wielaard dynsym table loaded through phdrs, then first_global is zero and 270697bdca1d7d70ebdcae90759dd885258400e1951Mark Wielaard there will be no auxiliary table. All symbols with local binding 271697bdca1d7d70ebdcae90759dd885258400e1951Mark Wielaard come first in the symbol table, then all globals. The zeroth, 272697bdca1d7d70ebdcae90759dd885258400e1951Mark Wielaard null entry, in the auxiliary table is skipped if there is a main 273697bdca1d7d70ebdcae90759dd885258400e1951Mark Wielaard table. */ 274b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh int first_global = INTUSE (dwfl_module_getsymtab_first_global) (state.mod); 27514c2d9e614cb0e3fd50ad757eaba686b37699580Mark Wielaard if (first_global < 0) 27614c2d9e614cb0e3fd50ad757eaba686b37699580Mark Wielaard return NULL; 277b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh search_table (&state, first_global == 0 ? 1 : first_global, syments); 278ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard 279ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard /* If we found nothing searching the global symbols, then try the locals. 280ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard Unless we have a global sizeless symbol that matches exactly. */ 281b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (state.closest_name == NULL && first_global > 1 282b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && (state.sizeless_name == NULL || state.sizeless_value != state.addr)) 283b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh search_table (&state, 1, first_global); 284ef431cd30b8a1a6b12a8783516fc95da88a9a636Mark Wielaard 28542f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath /* If we found no proper sized symbol to use, fall back to the best 28642f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath candidate sizeless symbol we found, if any. */ 287b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (state.closest_name == NULL 288b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && state.sizeless_name != NULL 289b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && state.sizeless_value >= state.min_label) 29042f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath { 291b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh *state.closest_sym = state.sizeless_sym; 292b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state.closest_value = state.sizeless_value; 293b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state.closest_shndx = state.sizeless_shndx; 294b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state.closest_elf = state.sizeless_elf; 295b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh state.closest_name = state.sizeless_name; 29642f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath } 29742f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath 298b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh *off = state.addr - state.closest_value; 299159ac52b061c60947a943c102298cd692223274fMark Wielaard 3006258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper if (shndxp != NULL) 301b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh *shndxp = state.closest_shndx; 302819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaard if (elfp != NULL) 303b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh *elfp = state.closest_elf; 304819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaard if (biasp != NULL) 305b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh *biasp = dwfl_adjusted_st_value (state.mod, state.closest_elf, 0); 306b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return state.closest_name; 3076258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper} 308819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaard 309819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaard 310819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaardconst char * 311819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaarddwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr, 312819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaard GElf_Sym *closest_sym, GElf_Word *shndxp) 313819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaard{ 314159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Off off; 315159ac52b061c60947a943c102298cd692223274fMark Wielaard return __libdwfl_addrsym (mod, addr, &off, closest_sym, shndxp, 316159ac52b061c60947a943c102298cd692223274fMark Wielaard NULL, NULL, true); 317819c349f6339512d6961a6172c539fdf2c2f1328Mark Wielaard} 3186258e7486eb3eed6e50005946795c5fbf73aa106Ulrich DrepperINTDEF (dwfl_module_addrsym) 319159ac52b061c60947a943c102298cd692223274fMark Wielaard 320159ac52b061c60947a943c102298cd692223274fMark Wielaardconst char 321159ac52b061c60947a943c102298cd692223274fMark Wielaard*dwfl_module_addrinfo (Dwfl_Module *mod, GElf_Addr address, 322159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Off *offset, GElf_Sym *sym, 323159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Word *shndxp, Elf **elfp, Dwarf_Addr *bias) 324159ac52b061c60947a943c102298cd692223274fMark Wielaard{ 325159ac52b061c60947a943c102298cd692223274fMark Wielaard return __libdwfl_addrsym (mod, address, offset, sym, shndxp, elfp, bias, 326159ac52b061c60947a943c102298cd692223274fMark Wielaard false); 327159ac52b061c60947a943c102298cd692223274fMark Wielaard} 328159ac52b061c60947a943c102298cd692223274fMark WielaardINTDEF (dwfl_module_addrinfo) 329