21 #include <sys/types.h>
41 #include <elfutils/libebl.h>
42 #include <elfutils/libdw.h>
43 #include <elfutils/libdwfl.h>
50 if (!gelf_getehdr(elf,&ehdr)) {
51 verror(
"gelf_getehdr: %s\n",elf_errmsg(elf_errno()));
55 if (ehdr.e_type == ET_EXEC)
56 return DEBUGFILE_TYPE_MAIN;
57 else if (ehdr.e_type == ET_DYN)
58 return DEBUGFILE_TYPE_SHAREDLIB;
59 else if (ehdr.e_type == ET_REL)
60 return DEBUGFILE_TYPE_LIB;
62 verror(
"unrecognized ELF type %d!\n",ehdr.e_type);
68 ADDR *base_virt_addr_saveptr,
69 ADDR *base_phys_addr_saveptr) {
75 ADDR base_phys_addr = 0;
76 ADDR base_virt_addr = 0;
85 ehdr = gelf_getehdr(elf,&ehdr_mem);
86 if (ehdr && ehdr->e_phnum > 0) {
90 for (i = 0; i < ehdr->e_phnum; ++
i) {
91 if (!(phdr = gelf_getphdr(elf,i,&phdr_mem))) {
92 vwarn(
"could not read program header %d\n",(
int)i);
96 if (phdr->p_type != PT_LOAD)
99 if (phdr->p_vaddr < base_virt_addr) {
100 base_phys_addr = phdr->p_paddr;
101 base_virt_addr = phdr->p_vaddr;
110 base_phys_addr = base_virt_addr = 0;
112 if (base_phys_addr_saveptr)
113 *base_phys_addr_saveptr = base_phys_addr;
114 if (base_virt_addr_saveptr)
115 *base_virt_addr_saveptr = base_virt_addr;
121 int *has_debuginfo_saveptr,
122 char **buildid_saveptr,
123 char **gnu_debuglinkfile_saveptr,
124 uint32_t *gnu_debuglinkfile_crc_saveptr) {
136 int has_debuginfo = 0;
137 char *buildid = NULL;
138 char *debuglinkfile = NULL;
139 uint32_t debuglinkfilecrc = 0;
142 verror(
"elf_get_arch_info failed\n");
145 is64 = (is64 == 8) ? 1 : 0;
147 #if _INT_ELFUTILS_VERSION >= 152
148 if (elf_getshdrstrndx(elf,&shstrndx) < 0) {
150 if (elf_getshstrndx(elf,&shstrndx) < 0) {
152 verror(
"cannot get section header string table index\n");
157 while ((scn = elf_nextscn(elf,scn)) != NULL) {
158 shdr = gelf_getshdr(scn,&shdr_mem);
160 if (shdr && shdr->sh_size > 0) {
161 name = elf_strptr(elf,shstrndx,shdr->sh_name);
163 if (strcmp(name,
".debug_info") == 0) {
165 "found %s section (%d)\n",name,shdr->sh_size);
169 else if (!buildid && shdr->sh_type == SHT_NOTE) {
171 "found %s note section (%d)\n",name,shdr->sh_size);
172 edata = elf_rawdata(scn,NULL);
174 vwarn(
"cannot get data for valid section '%s': %s",
175 name,elf_errmsg(-1));
179 ndata = edata->d_buf;
180 nend = ndata + edata->d_size;
181 while (ndata < nend) {
183 nthdr64 = (Elf64_Nhdr *)ndata;
186 ndata +=
sizeof(Elf64_Nhdr);
188 ndata += nthdr64->n_namesz;
189 if (nthdr64->n_namesz % 4)
190 ndata += (4 - nthdr64->n_namesz % 4);
193 if (nthdr64->n_type == NT_GNU_BUILD_ID) {
194 buildid = strdup(ndata);
198 ndata += nthdr64->n_descsz;
199 if (nthdr64->n_namesz % 4)
200 ndata += (4 - nthdr64->n_namesz % 4);
203 nthdr32 = (Elf32_Nhdr *)ndata;
206 ndata +=
sizeof(Elf32_Nhdr);
207 ndata += nthdr32->n_namesz;
208 if (nthdr32->n_namesz % 4)
209 ndata += (4 - nthdr32->n_namesz % 4);
211 if (nthdr32->n_type == NT_GNU_BUILD_ID) {
212 buildid = strdup(ndata);
216 ndata += nthdr32->n_descsz;
217 if (nthdr32->n_namesz % 4)
218 ndata += (4 - nthdr32->n_namesz % 4);
222 else if (strcmp(name,
".gnu_debuglink") == 0) {
223 edata = elf_rawdata(scn,NULL);
225 vwarn(
"cannot get data for valid section '%s': %s",
226 name,elf_errmsg(-1));
229 debuglinkfile = strdup(edata->d_buf);
230 debuglinkfilecrc = *(uint32_t *)(edata->d_buf + edata->d_size - 4);
235 if (has_debuginfo_saveptr)
236 *has_debuginfo_saveptr = has_debuginfo;
238 *buildid_saveptr = buildid;
241 if (gnu_debuglinkfile_saveptr)
242 *gnu_debuglinkfile_saveptr = debuglinkfile;
243 else if (debuglinkfile)
245 if (gnu_debuglinkfile_crc_saveptr)
246 *gnu_debuglinkfile_crc_saveptr = debuglinkfilecrc;
255 if (!(eident = elf_getident(elf,NULL))) {
256 verror(
"elf_getident: %s\n",elf_errmsg(elf_errno()));
260 if ((uint8_t)eident[EI_CLASS] == ELFCLASS32) {
265 else if ((uint8_t)eident[EI_CLASS] == ELFCLASS64) {
271 verror(
"unknown elf class %d; not 32/64 bit!\n",
272 (uint8_t)eident[EI_CLASS]);
276 if ((uint8_t)eident[EI_DATA] == ELFDATA2LSB) {
278 *endian = DATA_LITTLE_ENDIAN;
281 else if ((uint8_t)eident[EI_DATA] == ELFDATA2MSB) {
283 *endian = DATA_BIG_ENDIAN;
287 verror(
"unknown elf data %d; not big/little endian!\n",
288 (uint8_t)eident[EI_DATA]);
302 #if _INT_ELFUTILS_VERSION >= 152
303 if (elf_getshdrstrndx(elf,&shstrndx) < 0) {
305 if (elf_getshstrndx(elf,&shstrndx) < 0) {
307 verror(
"cannot get section header string table index\n");
312 while ((scn = elf_nextscn(elf,scn)) != NULL) {
313 shdr = gelf_getshdr(scn,&shdr_mem);
315 if (shdr && shdr->sh_size > 0) {
316 name = elf_strptr(elf,shstrndx,shdr->sh_name);
318 if (strcmp(name,
".dynamic") == 0) {
320 "found %s section (%d); ELF file is dynamic\n",
332 char *elf_filename) {
341 Word_t nextstart = -1;
342 Word_t tmpstart = -1;
355 GElf_Shdr *sections = NULL;
360 struct symbol *tmp_symbol;
363 if (!(ehdr = gelf_getehdr(elf,&ehdr_mem))) {
364 verror(
"cannot read ELF header: %s",elf_errmsg(-1));
368 ebl = ebl_openbackend(elf);
370 verror(
"cannot create EBL handle: %s",strerror(errno));
374 class = gelf_getclass(elf);
376 #if _INT_ELFUTILS_VERSION >= 152
377 if (elf_getshdrstrndx(elf,&shstrndx) < 0) {
379 if (elf_getshstrndx(elf,&shstrndx) < 0) {
381 verror(
"cannot get section header string table index\n");
387 while ((scn = elf_nextscn(elf,scn)) != NULL) {
388 shdr = gelf_getshdr(scn,&shdr_mem);
390 if (shdr && shdr->sh_size > 0 && shdr->sh_type == SHT_STRTAB) {
391 name = elf_strptr(elf,shstrndx,shdr->sh_name);
393 if (strcmp(name,
".strtab") != 0)
397 "found .strtab section in ELF file %s\n",
400 edata = elf_rawdata(scn,NULL);
401 if (!edata || !edata->d_size || !edata->d_buf) {
402 verror(
"cannot get data for valid section %s in %s: %s",
403 name,elf_filename,elf_errmsg(-1));
407 debugfile->elf_strtablen = edata->d_size;
408 debugfile->elf_strtab =
malloc(edata->d_size);
409 memcpy(debugfile->elf_strtab,edata->d_buf,edata->d_size);
414 if (!debugfile->elf_strtab) {
415 vwarn(
"could not find .strtab for ELF file %s; cannot load .symtab!\n",
423 sections = (GElf_Shdr *)
calloc(ehdr->e_shnum,
sizeof(GElf_Shdr));
425 for (i = 0; i < ehdr->e_shnum; ++
i) {
426 scn = elf_getscn(elf,i);
427 gelf_getshdr(scn,§ions[i]);
432 while ((scn = elf_nextscn(elf,scn)) != NULL) {
433 shdr = gelf_getshdr(scn,&shdr_mem);
435 if (!shdr || shdr->sh_size <= 0 || shdr->sh_type != SHT_SYMTAB)
438 name = elf_strptr(elf,shstrndx,shdr->sh_name);
440 if (strcmp(name,
".symtab") != 0)
445 edata = elf_getdata(scn,NULL);
446 if (!edata || !edata->d_size || !edata->d_buf) {
447 verror(
"cannot get data for valid section %s in %s: %s",
448 name,elf_filename,elf_errmsg(-1));
452 nsyms = edata->d_size / (
class == ELFCLASS32 ? sizeof (Elf32_Sym) \
453 : sizeof (Elf64_Sym));
455 vdebug(2,LA_DEBUG,LF_DWARF,".symtab section in ELF file %s has %d symbols\n",
459 for (i = 0; i < nsyms; ++i) {
460 sym = gelf_getsym(edata,i,&sym_mem);
461 if (sym->st_name >= debugfile->elf_strtablen) {
462 vwarn(
"skipping ELF symbol with bad name strtab idx %d\n",
467 stt = GELF_ST_TYPE(sym->st_info);
477 if (stt == STT_NOTYPE && sym->st_shndx < ehdr->e_shnum) {
478 if (sections[sym->st_shndx].sh_flags & SHF_EXECINSTR)
480 else if (sections[sym->st_shndx].sh_flags & SHF_ALLOC)
484 if (!(stt == STT_OBJECT || stt == STT_COMMON || stt == STT_TLS
489 #ifdef DWDEBUG_USE_STRTAB
490 symname = &debugfile->elf_strtab[sym->st_name];
492 symname = strdup(&debugfile->elf_strtab[sym->st_name]);
496 (stt == STT_OBJECT || stt == STT_TLS
497 || stt == STT_COMMON) \
501 if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL
502 || GELF_ST_BIND(sym->st_info) == STB_WEAK)
508 symbol->base_addr = (
ADDR)sym->st_value;
509 symbol->has_base_addr = 1;
511 symtab_insert(debugfile->elf_symtab,symbol,0);
520 if (g_hash_table_size(debugfile->
addresses) == 0
521 || !g_hash_table_lookup(debugfile->
addresses,
522 (gpointer)symbol->base_addr))
523 g_hash_table_insert(debugfile->
addresses,
524 (gpointer)symbol->base_addr,
527 if (symbol->base_addr != 0)
528 clrange_add(&debugfile->elf_ranges,symbol->base_addr,
529 symbol->base_addr + symbol->
size.
bytes,symbol);
565 for (j = 0; j < array_list_len(ral); ++j) {
575 "checking end of ELF symbol %s (0x%"PRIxADDR","
591 if (SYMBOL_IS_FUNCTION(symbol) && symbol->
isexternal) {
600 for (k = 0; k < array_list_len(tmp_ral); ++k) {
602 array_list_item(tmp_ral,k);
618 vwarn(
"could not find next global symbol after %s;"
619 " not updating 0-length GLOBAL!\n",
625 "updating 0-length GLOBAL symbol %s to"
626 " 0x%"PRIxADDR
",0x%"PRIxADDR
"\n",
639 vwarn(
"could not find a next range after %s;"
640 " not updating 0-length symbol!\n",
649 "updating 0-length symbol %s to 0x%"PRIxADDR
","
667 #ifndef DWDEBUG_USE_STRTAB
671 if (debugfile->elf_strtab) {
672 free(debugfile->elf_strtab);
673 debugfile->elf_strtablen = 0;
674 debugfile->elf_strtab = NULL;
681 ebl_closebackend(ebl);
687 if (debugfile->elf_strtab)
688 free(debugfile->elf_strtab);
689 ebl_closebackend(ebl);
int elf_get_debuginfo_info(Elf *elf, int *has_debuginfo_saveptr, char **buildid_saveptr, char **gnu_debuglinkfile_saveptr, uint32_t *gnu_debuglinkfile_crc_saveptr)
struct symbol * symbol_create(symbol_type_t symtype, symbol_source_t source, char *name, int name_copy, SMOFFSET offset, load_type_t loadtype, struct scope *scope)
unsigned int guessed_size
static uint64_t unsigned int i
unsigned int size_is_bytes
int elf_is_dynamic_exe(Elf *elf)
#define verror(format,...)
#define vwarn(format,...)
struct array_list * clrange_find_next_inc(clrange_t *clf, Word_t index)
#define CLRANGE_DATA(crd)
int clrange_update_end(clrange_t *clf, Word_t start, Word_t end, void *data)
#define vdebug(devel, areas, flags, format,...)
#define CLRANGE_START(crd)
void * calloc(size_t nmemb, size_t size)
debugfile_type_t elf_get_debugfile_type_t(Elf *elf)
int debugfile_load_elfsymtab(struct debugfile *debugfile, Elf *elf, char *elf_filename)
char * symbol_get_name(struct symbol *symbol)
void * malloc(size_t size)
int elf_get_arch_info(Elf *elf, int *wordsize, int *endian)
int clrange_add(clrange_t *clf, Word_t start, Word_t end, void *data)
int elf_get_base_addrs(Elf *elf, ADDR *base_virt_addr_saveptr, ADDR *base_phys_addr_saveptr)
struct array_list * clrange_find_next_exc(clrange_t *clf, Word_t index)