dwfl_module_addrsym.c revision 6258e7486eb3eed6e50005946795c5fbf73aa106
16258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper/* Find debugging and symbol information for a module in libdwfl. 26258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Copyright (C) 2005, 2006, 2007 Red Hat, Inc. 36258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper This file is part of Red Hat elfutils. 46258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 56258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Red Hat elfutils is free software; you can redistribute it and/or modify 66258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper it under the terms of the GNU General Public License as published by the 76258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Free Software Foundation; version 2 of the License. 86258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 96258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Red Hat elfutils is distributed in the hope that it will be useful, but 106258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 116258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 126258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper General Public License for more details. 136258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 146258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper You should have received a copy of the GNU General Public License along 156258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper with Red Hat elfutils; if not, write to the Free Software Foundation, 166258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 176258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 186258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper In addition, as a special exception, Red Hat, Inc. gives You the 196258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper additional right to link the code of Red Hat elfutils with code licensed 206258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper under any Open Source Initiative certified open source license 216258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper (http://www.opensource.org/licenses/index.php) which requires the 226258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper distribution of source code with any binary distribution and to 236258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper distribute linked combinations of the two. Non-GPL Code permitted under 246258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper this exception must only link to the code of Red Hat elfutils through 256258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper those well defined interfaces identified in the file named EXCEPTION 266258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper found in the source code files (the "Approved Interfaces"). The files 276258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper of Non-GPL Code may instantiate templates or use macros or inline 286258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper functions from the Approved Interfaces without causing the resulting 296258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper work to be covered by the GNU General Public License. Only Red Hat, 306258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Inc. may make changes or additions to the list of Approved Interfaces. 316258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Red Hat's grant of this exception is conditioned upon your not adding 326258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper any new exceptions. If you wish to add a new Approved Interface or 336258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper exception, please contact Red Hat. You must obey the GNU General Public 346258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper License in all respects for all of the Red Hat elfutils code and other 356258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper code used in conjunction with Red Hat elfutils except the Non-GPL Code 366258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper covered by this exception. If you modify this file, you may extend this 376258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper exception to your version of the file, but you are not obligated to do 386258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper so. If you do not wish to provide this exception without modification, 396258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper you must delete this exception statement from your version and license 406258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper this file solely under the GPL without exception. 416258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 426258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Red Hat elfutils is an included package of the Open Invention Network. 436258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper An included package of the Open Invention Network is a package for which 446258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Open Invention Network licensees cross-license their patents. No patent 456258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper license is granted, either expressly or impliedly, by designation as an 466258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper included package. Should you wish to participate in the Open Invention 476258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Network licensing program, please visit www.openinventionnetwork.com 486258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper <http://www.openinventionnetwork.com>. */ 496258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 506258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper#include "libdwflP.h" 516258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 526258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepperconst char * 536258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepperdwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr, 546258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper GElf_Sym *closest_sym, GElf_Word *shndxp) 556258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper{ 566258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper int syments = INTUSE(dwfl_module_getsymtab) (mod); 576258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper if (syments < 0) 586258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper return NULL; 596258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 606258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper /* Return true iff we consider ADDR to lie in the same section as SYM. */ 616258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper GElf_Word addr_shndx = SHN_UNDEF; 626258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper inline bool same_section (const GElf_Sym *sym, GElf_Word shndx) 636258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 646258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper /* For absolute symbols and the like, only match exactly. */ 656258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper if (shndx >= SHN_LORESERVE) 666258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper return sym->st_value == addr; 676258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 686258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper /* Ignore section and other special symbols. */ 696258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper switch (GELF_ST_TYPE (sym->st_info)) 706258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 716258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper case STT_SECTION: 726258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper case STT_FILE: 736258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper case STT_TLS: 746258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper return false; 756258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 766258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 776258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper /* Figure out what section ADDR lies in. */ 786258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper if (addr_shndx == SHN_UNDEF) 796258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 806258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper GElf_Addr mod_addr = addr - mod->symfile->bias; 816258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Elf_Scn *scn = NULL; 826258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper addr_shndx = SHN_ABS; 836258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper while ((scn = elf_nextscn (mod->symfile->elf, scn)) != NULL) 846258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 856258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper GElf_Shdr shdr_mem; 866258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 876258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper if (likely (shdr != NULL) 886258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper && mod_addr >= shdr->sh_addr 896258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper && mod_addr < shdr->sh_addr + shdr->sh_size) 906258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 916258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper addr_shndx = elf_ndxscn (scn); 926258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper break; 936258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 946258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 956258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 966258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 976258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper return shndx == addr_shndx; 986258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 996258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 1006258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper /* Look through the symbol table for a matching symbol. */ 1016258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper const char *closest_name = NULL; 1026258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper closest_sym->st_value = 0; 1036258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper GElf_Word closest_shndx = SHN_UNDEF; 1046258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper for (int i = 1; i < syments; ++i) 1056258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 1066258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper GElf_Sym sym; 1076258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper GElf_Word shndx; 1086258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx); 1096258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper if (name != NULL && sym.st_value <= addr) 1106258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 1116258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper inline void closest (void) 1126258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 1136258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper *closest_sym = sym; 1146258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper closest_shndx = shndx; 1156258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper closest_name = name; 1166258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 1176258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 1186258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper if (addr < sym.st_value + sym.st_size) 1196258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper { 1206258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper closest (); 1216258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper break; 1226258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 1236258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 1246258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper /* Handwritten assembly symbols sometimes have no st_size. 1256258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper If no symbol with proper size includes the address, we'll 1266258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper use the closest one that is in the same section as ADDR. */ 1276258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper if (sym.st_size == 0 && sym.st_value >= closest_sym->st_value 1286258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper && same_section (&sym, shndx)) 1296258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper closest (); 1306258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 1316258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper } 1326258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 1336258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper if (shndxp != NULL) 1346258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper *shndxp = closest_shndx; 1356258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper return closest_name; 1366258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper} 1376258e7486eb3eed6e50005946795c5fbf73aa106Ulrich DrepperINTDEF (dwfl_module_addrsym) 138