21 #include <sys/types.h>
47 #include <elfutils/libebl.h>
48 #include <elfutils/libdw.h>
49 #include <elfutils/libdwfl.h>
54 static const char *elf_binfile_get_backend_name(
void);
59 const char *DFPATH[]);
69 .open = elf_binfile_open,
70 .open_debuginfo = elf_binfile_open_debuginfo,
71 .infer_instance = elf_binfile_infer_instance,
72 .close = elf_binfile_close,
73 .free = elf_binfile_free,
74 .free_instance = elf_binfile_free_instance,
77 static struct arch *elf_get_arch(Elf *elf) {
82 if (!gelf_getehdr(elf,&ehdr)) {
83 verror(
"cannot read ELF header: %s",elf_errmsg(-1));
88 if (!(eident = elf_getident(elf,NULL))) {
89 verror(
"elf_getident: %s\n",elf_errmsg(elf_errno()));
93 if ((uint8_t)eident[EI_DATA] == ELFDATA2LSB) {
96 else if ((uint8_t)eident[EI_DATA] == ELFDATA2MSB) {
97 verror(
"big endian ELF files unsupported; no arch for them\n");
101 verror(
"unknown elf data %d; not big/little endian!\n",
102 (uint8_t)eident[EI_DATA]);
106 if (ehdr.e_machine == EM_386)
108 else if (ehdr.e_machine == EM_X86_64)
111 verror(
"unsupported elf machine type %d!\n",ehdr.e_machine);
118 static const char *elf_binfile_get_backend_name(
void) {
127 ebl_closebackend(bfelf->
ebl);
131 dwfl_end(bfelf->
dwfl);
136 if (binfile->
image && had_dwfl) {
143 else if (bfelf->
elf) {
148 if (binfile->
fd > -1) {
152 if (binfile->
image) {
154 binfile->
image = NULL;
160 static void elf_binfile_free(
struct binfile *binfile) {
165 elf_binfile_close(binfile);
211 bfielf->
shdrs = NULL;
226 struct binfile *elf_binfile_open_debuginfo(
struct binfile *binfile,
228 const char *DFPATH[]) {
232 char *finalfile = NULL;
260 for (
i = 0; DFPATH[
i]; ++
i) {
262 snprintf(pbuf,PATH_MAX,
"%s/%s/.build-id/%02hhx/%s.debug",
266 snprintf(pbuf,PATH_MAX,
"%s/.build-id/%02hhx/%s.debug",
268 if (stat(pbuf,&stbuf) == 0) {
289 filedir = strdup(binfile->
filename);
291 tmp = rindex(filedir,
'/');
294 for (
i = 0; DFPATH[
i]; ++
i) {
296 snprintf(pbuf,PATH_MAX,
"%s/%s/%s/%s",
300 snprintf(pbuf,PATH_MAX,
"%s/%s/%s",
302 if (stat(pbuf,&stbuf) == 0) {
312 "no debuginfo sources associated with %s\n",binfile->
filename);
323 static struct binfile_instance *elf_binfile_infer_instance(
struct binfile *binfile,
339 #define ARCH_SHF_X86 0
340 static unsigned long const shfm[][2] = {
356 uint8_t *done_sections;
359 int kallsyms_after_init = 0;
360 int set_module_ronx = 0;
361 int module_unload = 1;
362 int major = 0,minor = 0,patch = 0;
371 bfi =
calloc(1,
sizeof(*bfi));
372 bfielf =
calloc(1,
sizeof(*bfielf));
397 if ((tmp = (
char *)g_hash_table_lookup(config,
"__VERSION_MAJOR")))
399 if ((tmp = (
char *)g_hash_table_lookup(config,
"__VERSION_MINOR")))
401 if ((tmp = (
char *)g_hash_table_lookup(config,
"__VERSION_PATCH")))
404 config_str = g_hash_table_lookup(config,
"CONFIG_KALLSYMS");
405 if (config_str && (*config_str ==
'y' || *config_str ==
'Y'))
410 || (major == 2 && minor == 6 && patch >= 32)))
411 kallsyms_after_init = 1;
414 g_hash_table_lookup(config,
"CONFIG_DEBUG_SET_MODULE_RONX");
416 && (*config_str ==
'y' || *config_str ==
'Y'))
420 g_hash_table_lookup(config,
"CONFIG_MODULE_UNLOAD");
422 && (*config_str ==
'n' || *config_str ==
'N'))
442 #define __ALIGN(x,a) (((x) + (typeof(x))(a) - 1) & ~((typeof(x))(a) - 1))
443 #define __PAGE_SIZE 0x1000
444 #define __DEBUG_ALIGN (x) __ALIGN((x),__PAGE_SIZE)
446 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
448 secname = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
450 if (kallsyms && !kallsyms_after_init
451 && (strcmp(secname,
".symtab") == 0
452 || strcmp(secname,
".strtab") == 0))
453 bfielf->
shdrs[
i].sh_flags |= SHF_ALLOC;
458 if (strcmp(secname,
".data..percpu") == 0)
459 bfielf->
shdrs[
i].sh_flags &= ~(
unsigned long)SHF_ALLOC;
464 if (strcmp(secname,
"__versions") == 0)
465 bfielf->
shdrs[i].sh_flags &= ~(
unsigned long)SHF_ALLOC;
466 if (strcmp(secname,
".modinfo") == 0)
467 bfielf->
shdrs[i].sh_flags &= ~(
unsigned long)SHF_ALLOC;
472 if (!module_unload && strncmp(secname,
".exit",5) == 0)
473 bfielf->
shdrs[i].sh_flags &= ~(
unsigned long)SHF_ALLOC;
480 for (fm = 0; fm <
sizeof(shfm)/(2*
sizeof(
unsigned long)); ++
fm) {
481 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
483 secname = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
485 if ((shdr->sh_flags & shfm[fm][0]) != shfm[fm][0]
486 || (shdr->sh_flags & shfm[fm][1])
487 || done_sections[i] != 0
489 || strncmp(secname,
".init",5) == 0)
492 align = shdr->sh_addralign ? shdr->sh_addralign : 1;
502 done_sections[
i] = 1;
512 if (set_module_ronx) {
513 if (fm == 0 || fm == 1 || fm == 2)
518 for (fm = 0; fm <
sizeof(shfm)/(2*
sizeof(
unsigned long)); ++
fm) {
519 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
521 secname = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
523 if ((shdr->sh_flags & shfm[fm][0]) != shfm[fm][0]
524 || shdr->sh_flags & shfm[fm][1]
525 || done_sections[i] != 0
526 || !secname || strncmp(secname,
".init",5) != 0)
529 align = shdr->sh_addralign ? shdr->sh_addralign : 1;
539 done_sections[
i] = 1;
549 if (set_module_ronx) {
550 if (fm == 0 || fm == 1 || fm == 2)
559 if (kallsyms && kallsyms_after_init) {
560 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
562 secname = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
564 if (strcmp(secname,
".symtab") == 0
565 || strcmp(secname,
".strtab") == 0)
566 bfielf->
shdrs[
i].sh_flags |= SHF_ALLOC;
569 for (fm = 0; fm <
sizeof(shfm)/(2*
sizeof(
unsigned long)); ++
fm) {
570 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
572 secname = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
574 if ((shdr->sh_flags & shfm[fm][0]) != shfm[fm][0]
575 || (shdr->sh_flags & shfm[fm][1])
576 || done_sections[i] != 0
578 || strncmp(secname,
".init",5) == 0)
581 align = shdr->sh_addralign ? shdr->sh_addralign : 1;
591 done_sections[
i] = 1;
601 if (set_module_ronx) {
602 if (fm == 0 || fm == 1 || fm == 2)
615 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
618 if (!shdr || shdr->sh_size <= 0 || shdr->sh_type != SHT_SYMTAB)
621 secname = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
623 if (strcmp(secname,
".symtab") != 0)
629 scn = elf_getscn(bfelf->
elf,i);
630 edata = elf_getdata(scn,NULL);
631 if (!edata || !edata->d_size || !edata->d_buf) {
632 verror(
"cannot get data for valid section %s in %s: %s (skipping)\n",
633 secname,binfile->
filename,elf_errmsg(-1));
638 edata->d_size / (bfelf->
class == ELFCLASS32 ?
sizeof (Elf32_Sym) \
639 :
sizeof (Elf64_Sym));
644 ".symtab section in ELF file %s has %d symbols\n",
649 sym = gelf_getsym(edata,i,&sym_mem);
651 if (GELF_ST_TYPE(sym->st_info) == STT_SECTION) {
654 else if ((GELF_ST_TYPE(sym->st_info) == STT_OBJECT
655 || GELF_ST_TYPE(sym->st_info) == STT_FUNC)
656 && sym->st_shndx != SHN_UNDEF
657 && sym->st_shndx != SHN_ABS
658 && sym->st_shndx != SHN_COMMON) {
675 struct binfile *bf = NULL;
685 struct symbol *tmp_symbol;
694 Word_t tmpstart = -1;
715 GElf_Shdr shdr_new_mem;
719 Word_t plt_start = 0;
722 int plt_entry_size = 0;
724 char *pltsymbuf = NULL;
728 int dynsymtabsec = -1;
730 int dynstrtabsec = -1;
731 struct symbol *tsymbol;
732 struct scope *root_scope;
752 if (strstr(filename,root_prefix) != filename) {
753 vwarn(
"BUG: filename '%s' does not start with root_prefix '%s'!\n",
754 filename,root_prefix);
761 elf_version(EV_CURRENT);
769 if ((bf->
fd = open(bf->
filename,0,O_RDONLY)) < 0) {
773 else if (!(bfelf->
elf = elf_begin(bf->
fd,ELF_C_READ,NULL))) {
775 bf->
filename,elf_errmsg(elf_errno()));
778 else if (!gelf_getehdr(bfelf->
elf,&bfelf->
ehdr)) {
779 verror(
"cannot read ELF header: %s",elf_errmsg(-1));
783 else if (bfelf->
ehdr.e_type != ET_EXEC && bfelf->
ehdr.e_type != ET_REL
784 && bfelf->
ehdr.e_type != ET_DYN) {
785 verror(
"unreadable ELF type 0x%x\n",bfelf->
ehdr.e_type);
790 if (!(bf->
arch = elf_get_arch(bfelf->
elf))) {
795 if (bfelf->
ehdr.e_type == ET_EXEC)
797 else if (bfelf->
ehdr.e_type == ET_DYN)
799 else if (bfelf->
ehdr.e_type == ET_REL)
805 bfelf->
ebl = ebl_openbackend(bfelf->
elf);
806 if (bfelf->
ebl == NULL) {
807 verror(
"cannot create EBL handle: %s",strerror(errno));
811 bfelf->
class = gelf_getclass(bfelf->
elf);
813 #if _INT_ELFUTILS_VERSION >= 152
814 if (elf_getshdrstrndx(bfelf->
elf,&bfelf->
shstrndx) < 0) {
816 if (elf_getshstrndx(bfelf->
elf,&bfelf->
shstrndx) < 0) {
818 verror(
"cannot get section header string table index\n");
826 if (bfelf->
ehdr.e_type == ET_REL && bfinst) {
836 verror(
"stat %s (before relocation): %s\n",
843 lseek(fdi,0,SEEK_SET);
844 while (rci < stbuf.st_size) {
845 rc = read(fdi,bf->
image+rci,stbuf.st_size - rci);
847 if (errno == EAGAIN || errno == EINTR)
864 "relocating ELF file %s in memory...\n",bf->
filename);
869 bfelf->
shdrs = (GElf_Shdr *)
calloc(bfelf->
ehdr.e_shnum,
sizeof(GElf_Shdr));
870 if (bfelfinst->
shdrs) {
872 bfelf->
ehdr.e_shnum*
sizeof(GElf_Shdr));
875 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
876 scn = elf_getscn(bfelf->
elf,i);
877 if (!gelf_getshdr(scn,&bfelf->
shdrs[i])) {
878 verror(
"could not load section header for section %d!\n",i);
884 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
886 scn = elf_getscn(bfelf->
elf,i);
888 verror(
"could not find Elf section for section %d!\n",i);
891 else if (!shdr || shdr->sh_size <= 0)
893 else if (shdr->sh_type != SHT_REL)
896 edata = elf_getdata(scn,NULL);
897 if (!edata || !edata->d_size || !edata->d_buf) {
898 verror(
"cannot get data for relocation section %d during"
907 nrels = shdr->sh_size / shdr->sh_entsize;
909 rsec = shdr->sh_info;
910 rstsec = shdr->sh_link;
915 rstscn = elf_getscn(bfelf->
elf,rstsec);
917 verror(
"could not load symtab section %d during relocation!\n",
921 rstedata = elf_getdata(rstscn,NULL);
922 if (!rstedata || !rstedata->d_size || !rstedata->d_buf) {
923 verror(
"cannot get data for valid symtab section %d during"
930 "found %d relocations in %d in ELF file %s\n",
937 if (!(bfelf->
shdrs[rsec].sh_flags & SHF_ALLOC)) {
939 "skipping reloc section %d for non-alloc section %d\n",
944 for (j = 0; j < nrels; ++j) {
945 if (!gelf_getrel(edata,j,&rel)) {
946 verror(
"bad relocation %d in %d; skipping!\n",j,i);
949 rtype = GELF_R_TYPE(rel.r_info);
950 rsymidx = GELF_R_SYM(rel.r_info);
951 if (!gelf_getsym(rstedata,rsymidx,&rsym)) {
952 verror(
"could not load sym %d in %d (for %d/%d) during"
953 " relocation; skipping!\n",
959 verror(
"bad section %d for symbol %d (relocation %d/%d)!\n",
960 rsym.st_shndx,rsymidx,j,i);
969 rcoffset = bfelf->
shdrs[rsec].sh_offset + rel.r_offset;
971 if (GELF_ST_TYPE(rsym.st_info) == STT_SECTION) {
977 if (!(bfelf->
shdrs[rsym.st_shndx].sh_flags & SHF_ALLOC)) {
979 "skipping reloc for non-alloc section %d\n",
984 rvalue = (GElf_Addr)bfelfinst->
section_tab[rsym.st_shndx];
986 else if (GELF_ST_TYPE(rsym.st_info) == STT_OBJECT
987 || GELF_ST_TYPE(rsym.st_info) == STT_FUNC) {
988 rvalue = rsym.st_value \
989 + (GElf_Addr)bfelfinst->
section_tab[rsym.st_shndx];
991 else if (GELF_ST_TYPE(rsym.st_info) == STT_NOTYPE
992 && GELF_ST_BIND(rsym.st_info) == STB_GLOBAL) {
994 "skipping global symbol %d"
995 " (relocation %d/%d); skipping!\n",
999 verror(
"unknown symbol type %d for symbol %d"
1000 " (relocation %d/%d); skipping!\n",
1001 GELF_ST_TYPE(rsym.st_info),rsymidx,j,i);
1008 if (rcoffset >= stbuf.st_size) {
1010 "relocation offset exceeds file length by %d"
1011 " (symbol %d, relocation %d/%d); skipping\n!",
1012 rcoffset - stbuf.st_size,
1020 rvalue -= rel.r_offset;
1021 if (rcoffset >= stbuf.st_size) {
1023 "relocation offset exceeds file length by %d"
1024 " (symbol %d, relocation %d/%d); skipping\n!",
1025 rcoffset - stbuf.st_size,
1032 verror(
"cannot handle relocation type %d for symbol %d"
1033 " (relocation %d/%d); skipping\n!",
1046 elf_end(bfelf->
elf);
1049 bfelf->
elf = elf_memory(bf->
image,stbuf.st_size);
1055 if (bfelfinst->
shdrs) {
1056 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
1057 scn = elf_getscn(bfelf->
elf,i);
1058 if (!(shdr_new = gelf_getshdr(scn,&shdr_new_mem))) {
1059 verror(
"could not load section header for section %d!\n",i);
1063 if (shdr_new->sh_flags != bfelfinst->
shdrs[i].sh_flags) {
1064 shdr_new->sh_flags = bfelfinst->
shdrs[
i].sh_flags;
1066 if (gelf_update_shdr(scn,shdr_new)) {
1068 "could not update sh_flags for section %d;"
1069 " skipping; debuginfo reloc might be broken!\n",
1078 "opened relocated ELF file %s in memory\n",bf->
filename);
1080 else if (bfelf->
ehdr.e_type == ET_REL) {
1082 "relocatable file %s, but no program image; not relocating!\n",
1095 if (bfelf->
ehdr.e_phnum > 0) {
1096 bfelf->
phdrs = (GElf_Phdr *)
calloc(bfelf->
ehdr.e_phnum,
sizeof(GElf_Phdr));
1100 for (i = 0; i < bfelf->
ehdr.e_phnum; ++
i) {
1101 if (!(phdr = gelf_getphdr(bfelf->
elf,i,&bfelf->
phdrs[i]))) {
1102 vwarn(
"could not read program header %d\n",(
int)i);
1106 if (phdr->p_type != PT_LOAD)
1126 bfelf->
shdrs = (GElf_Shdr *)
calloc(bfelf->
ehdr.e_shnum,
sizeof(GElf_Shdr));
1127 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
1128 scn = elf_getscn(bfelf->
elf,i);
1129 if (!gelf_getshdr(scn,&bfelf->
shdrs[i])) {
1130 verror(
"could not load section header for section %d!\n",i);
1136 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
1138 scn = elf_getscn(bfelf->
elf,i);
1140 if (!shdr || shdr->sh_size <= 0)
1143 verror(
"could not find Elf section for section %d!\n",i);
1147 name = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
1149 if (shdr->sh_type == SHT_STRTAB && strcmp(name,
".strtab") == 0) {
1151 vwarn(
"multiple .strtab sections; ignoring after first!\n");
1156 "found .strtab section in ELF file %s\n",
1159 edata = elf_rawdata(scn,NULL);
1160 if (!edata || !edata->d_size || !edata->d_buf) {
1161 verror(
"cannot get data for valid section %s in %s: %s",
1169 memcpy(bf->
strtab,edata->d_buf,edata->d_size);
1171 else if (shdr->sh_type == SHT_SYMTAB) {
1172 if (symtabsec > -1) {
1173 vwarn(
"multiple .dynsym sections; ignoring after first!\n");
1178 "found %s section in ELF file %s\n",name,bf->
filename);
1182 else if (shdr->sh_type == SHT_DYNSYM) {
1183 if (dynsymtabsec > -1) {
1184 vwarn(
"multiple .dynsym sections; ignoring after first!\n");
1189 "found %s section in ELF file %s\n",name,bf->
filename);
1196 dynstrtabsec = shdr->sh_link;
1197 if (dynstrtabsec >= bfelf->
ehdr.e_shnum || dynstrtabsec < 1) {
1198 verror(
"bad sh_link (dynstr sec idx) %d; not using dynsym sec %d!\n",
1199 dynstrtabsec,dynsymtabsec);
1204 scn = elf_getscn(bfelf->
elf,dynstrtabsec);
1206 verror(
"could not find Elf section for section %d!\n",i);
1211 edata = elf_rawdata(scn,NULL);
1212 if (!edata || !edata->d_size || !edata->d_buf) {
1213 verror(
"cannot get data for valid section %s in %s: %s",
1220 memcpy(bf->
dynstrtab,edata->d_buf,edata->d_size);
1222 else if (strcmp(name,
".plt") == 0) {
1224 "found %s section (%d); recording\n",
1225 name,shdr->sh_size);
1228 plt_entry_size = shdr->sh_entsize;
1229 plt_start = shdr->sh_addr;
1230 plt_size = shdr->sh_size;
1232 else if (strcmp(name,
".dynamic") == 0) {
1234 "found %s section (%d); ELF file is dynamic\n",
1235 name,shdr->sh_size);
1238 else if (strcmp(name,
".debug_info") == 0) {
1240 "found %s section (%d)\n",name,shdr->sh_size);
1244 else if (!bfelf->
buildid && shdr->sh_type == SHT_NOTE) {
1246 "found %s note section (%d)\n",name,shdr->sh_size);
1247 edata = elf_rawdata(scn,NULL);
1249 vwarn(
"cannot get data for valid section '%s': %s",
1250 name,elf_errmsg(-1));
1254 ndata = edata->d_buf;
1255 nend = ndata + edata->d_size;
1256 while (ndata < nend) {
1258 nthdr64 = (Elf64_Nhdr *)ndata;
1261 ndata +=
sizeof(Elf64_Nhdr);
1263 ndata += nthdr64->n_namesz;
1264 if (nthdr64->n_namesz % 4)
1265 ndata += (4 - nthdr64->n_namesz % 4);
1268 if (nthdr64->n_type == NT_GNU_BUILD_ID) {
1269 bfelf->
buildid = strndup(ndata,nend - ndata);
1273 ndata += nthdr64->n_descsz;
1274 if (nthdr64->n_descsz % 4)
1275 ndata += (4 - nthdr64->n_descsz % 4);
1278 nthdr32 = (Elf32_Nhdr *)ndata;
1281 ndata +=
sizeof(Elf32_Nhdr);
1282 ndata += nthdr32->n_namesz;
1283 if (nthdr32->n_namesz % 4)
1284 ndata += (4 - nthdr32->n_namesz % 4);
1286 if (nthdr32->n_type == NT_GNU_BUILD_ID) {
1287 bfelf->
buildid = strndup(ndata,nend - ndata);
1291 ndata += nthdr32->n_descsz;
1292 if (nthdr32->n_descsz % 4)
1293 ndata += (4 - nthdr32->n_descsz % 4);
1297 else if (strcmp(name,
".gnu_debuglink") == 0) {
1298 edata = elf_rawdata(scn,NULL);
1300 vwarn(
"cannot get data for valid section '%s': %s",
1301 name,elf_errmsg(-1));
1306 *(uint32_t *)(edata->d_buf + edata->d_size - 4);
1320 pltsymbuf_len = 128;
1321 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
1323 scn = elf_getscn(bfelf->
elf,i);
1325 if (!shdr || shdr->sh_size <= 0)
1328 verror(
"could not find Elf section for section %d!\n",i);
1332 name = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
1334 if (shdr->sh_type != SHT_RELA || strcmp(name,
".rela.plt") != 0)
1338 verror(
"found .rela.plt section, but no .plt in ELF file %s!\n",
1344 "found .rela.plt section in ELF file %s;"
1345 " generating @plt symbol names\n",
1348 edata = elf_rawdata(scn,NULL);
1349 if (!edata || !edata->d_size || !edata->d_buf) {
1350 verror(
"cannot get data for valid section %s in %s: %s",
1358 nrels = shdr->sh_size / shdr->sh_entsize;
1360 rsec = shdr->sh_info;
1361 rstsec = shdr->sh_link;
1363 rstrsec = bfelf->
shdrs[rstsec].sh_link;
1368 rstscn = elf_getscn(bfelf->
elf,rstsec);
1370 verror(
"could not load symtab section %d during plt relocation!\n",
1374 rstedata = elf_getdata(rstscn,NULL);
1375 if (!rstedata || !rstedata->d_size || !rstedata->d_buf) {
1376 verror(
"cannot get data for valid symtab section %d during"
1377 " plt relocation!\n",
1383 "found %d plt relocations in %d in ELF file %s\n",
1389 for (j = 0; j < nrels; ++j) {
1390 if (!gelf_getrela(edata,j,&rela)) {
1392 "bad relocation %d in %d; skipping!\n",j,i);
1395 rtype = GELF_R_TYPE(rela.r_info);
1396 rsymidx = GELF_R_SYM(rela.r_info);
1397 if (!gelf_getsym(rstedata,rsymidx,&rsym)) {
1399 "could not load sym %d in %d (for %d/%d) during"
1400 " relocation; skipping!\n",
1401 rsymidx,rstsec,j,i);
1405 if (rtype != R_X86_64_JUMP_SLOT || rtype != R_386_JMP_SLOT) {
1407 "unexpected relocation type %d (not JMP_SLOT) in"
1408 " .rela.plt at idx %d; plt index names may be wrong!\n",
1414 symname = elf_strptr(bfelf->
elf,rstrsec,rsym.st_name);
1417 "skipping .rela.plt ELF symbol at .rela.plt idx %d;"
1418 " bad symbol strtab idx %d\n",
1419 j,(
int)rsym.st_name);
1423 len = strlen(symname) +
sizeof(
"@plt") + 1;
1424 if (len > pltsymbuf_len) {
1425 pltsymbuf =
realloc(pltsymbuf,len);
1426 pltsymbuf_len =
len;
1428 snprintf(pltsymbuf,len,
"%s@plt",symname);
1432 (
SMOFFSET)(shdr->sh_addr + j * shdr->sh_entsize),
1435 if (GELF_ST_BIND(rsym.st_info) == STB_GLOBAL
1436 || GELF_ST_BIND(rsym.st_info) == STB_WEAK)
1449 "added plt index ELF symbol %s at 0x%"PRIxADDR"\n",
1462 if (symtabsec > -1) {
1463 shdr = &bfelf->
shdrs[symtabsec];
1465 name = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
1470 scn = elf_getscn(bfelf->
elf,symtabsec);
1471 edata = elf_getdata(scn,NULL);
1472 if (!edata || !edata->d_size || !edata->d_buf) {
1473 verror(
"cannot get data for valid section %s in %s: %s",
1479 edata->d_size / (bfelf->
class == ELFCLASS32 ?
sizeof (Elf32_Sym) \
1480 :
sizeof (Elf64_Sym));
1483 "%s section in ELF file %s has %d symbols\n",
1488 sym = gelf_getsym(edata,ii,&sym_mem);
1490 vwarn(
"skipping ELF symbol with bad name strtab idx %d\n",
1495 stt = GELF_ST_TYPE(sym->st_info);
1505 if (stt == STT_NOTYPE && sym->st_shndx < bfelf->
ehdr.e_shnum) {
1506 if (bfelf->
shdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
1508 else if (bfelf->
shdrs[sym->st_shndx].sh_flags & SHF_ALLOC)
1512 if (!(stt == STT_OBJECT || stt == STT_COMMON || stt == STT_TLS
1514 #
if defined(STT_GNU_IFUNC)
1515 || stt == STT_GNU_IFUNC
1526 if (sym->st_shndx == SHN_UNDEF)
1532 if (sym->st_shndx == SHN_ABS && stt == STT_OBJECT && sym->st_value == 0)
1539 #ifdef DWDEBUG_NOUSE_STRTAB
1540 symname = strdup(&bf->
strtab[sym->st_name]);
1542 symname = &bf->
strtab[sym->st_name];
1546 || stt == STT_COMMON) \
1552 if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL
1553 || GELF_ST_BIND(sym->st_info) == STB_WEAK)
1583 if (sym->st_size > 0)
1587 zll = g_slist_prepend(zll,symbol);
1598 if (dynsymtabsec > -1) {
1599 shdr = &bfelf->
shdrs[dynsymtabsec];
1601 name = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
1605 scn = elf_getscn(bfelf->
elf,dynsymtabsec);
1606 edata = elf_getdata(scn,NULL);
1607 if (!edata || !edata->d_size || !edata->d_buf) {
1608 verror(
"cannot get data for valid section %s in %s: %s",
1614 edata->d_size / (bfelf->
class == ELFCLASS32 ?
sizeof (Elf32_Sym) \
1615 :
sizeof (Elf64_Sym));
1617 "%s section in ELF file %s has %d symbols\n",
1622 sym = gelf_getsym(edata,ii,&sym_mem);
1624 vwarn(
"skipping ELF symbol with bad name strtab idx %d\n",
1629 stt = GELF_ST_TYPE(sym->st_info);
1639 if (stt == STT_NOTYPE && sym->st_shndx < bfelf->
ehdr.e_shnum) {
1640 if (bfelf->
shdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
1642 else if (bfelf->
shdrs[sym->st_shndx].sh_flags & SHF_ALLOC)
1646 if (!(stt == STT_OBJECT || stt == STT_COMMON || stt == STT_TLS
1648 #
if defined(STT_GNU_IFUNC)
1649 || stt == STT_GNU_IFUNC
1660 if (sym->st_shndx == SHN_UNDEF)
1666 if (sym->st_shndx == SHN_ABS && stt == STT_OBJECT && sym->st_value == 0)
1676 "not creating duplicate dynsym %s (0x%"PRIxADDR")\n",
1685 #ifdef DWDEBUG_NOUSE_STRTAB
1686 symname = strdup(&bf->
dynstrtab[sym->st_name]);
1692 || stt == STT_COMMON) \
1698 if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL
1699 || GELF_ST_BIND(sym->st_info) == STB_WEAK)
1704 if (sym->st_value > 0)
1725 if (sym->st_value > 0) {
1726 if (sym->st_size > 0)
1730 zll = g_slist_prepend(zll,symbol);
1738 for (i = 0; i < bfelf->
ehdr.e_shnum; ++
i) {
1740 scn = elf_getscn(bfelf->
elf,i);
1742 if (!shdr || shdr->sh_size <= 0 || shdr->sh_addr <= 0)
1745 verror(
"could not find Elf section for section %d!\n",i);
1748 if (!(shdr->sh_flags & SHF_ALLOC))
1751 name = elf_strptr(bfelf->
elf,bfelf->
shstrndx,shdr->sh_name);
1753 if (shdr->sh_flags & SHF_EXECINSTR)
1770 "created section symbol %s (0x%"PRIxADDR"; %d bytes)\n",
1771 name,(
ADDR)shdr->sh_addr,shdr->sh_size);
1797 gint __symbol_sort_addr_desc(gconstpointer a,gconstpointer b) {
1798 struct symbol *sa = (
struct symbol *)a;
1799 struct symbol *sb = (
struct symbol *)b;
1809 zll = g_slist_sort(zll,__symbol_sort_addr_desc);
1815 "checking end of ELF symbol %s (0x%"PRIxADDR")\n",
1834 for (k = 0; k < array_list_len(tmp_ral); ++k) {
1836 array_list_item(tmp_ral,k);
1860 for (ii = 0; ii < bfelf->
ehdr.e_shnum; ++ii) {
1861 if (start >= bfelf->
shdrs[ii].sh_addr
1862 && start < (bfelf->
shdrs[ii].sh_addr
1863 + bfelf->
shdrs[ii].sh_size)) {
1865 sec_end = bfelf->
shdrs[ii].sh_addr
1866 + bfelf->
shdrs[ii].sh_size;
1873 "could not find section containing 0x%"PRIxADDR";"
1874 " not updating 0-length GLOBAL %s!\n",
1882 "could not find next global symbol after %s;"
1883 " using section(%d:%d) end 0x%"PRIxADDR"!\n",
1885 ii,bfelf->
shdrs[ii].sh_size,sec_end);
1889 "next global symbol after %s was past section"
1890 "(%d:%d); using section end 0x%"PRIxADDR"!\n",
1892 ii,bfelf->
shdrs[ii].sh_size,sec_end);
1903 "updating 0-length GLOBAL symbol %s to"
1918 "could not find a next range after %s;"
1919 " not updating 0-length symbol!\n",
1936 for (ii = 0; ii < bfelf->
ehdr.e_shnum; ++ii) {
1937 if (start >= bfelf->
shdrs[ii].sh_addr
1938 && start < (bfelf->
shdrs[ii].sh_addr
1939 + bfelf->
shdrs[ii].sh_size)) {
1941 sec_end = bfelf->
shdrs[ii].sh_addr
1942 + bfelf->
shdrs[ii].sh_size;
1949 "could not find section containing 0x%"PRIxADDR
";"
1950 " not updating 0-length GLOBAL %s!\n",
1957 "next global symbol after %s was past section"
1958 "(%d:%d); using section end 0x%"PRIxADDR
"!\n",
1960 ii,bfelf->
shdrs[ii].sh_size,sec_end);
1971 "updating 0-length symbol %s to 0x%"PRIxADDR
","
2010 "could not find a symbol following the PLT; assuming _header@plt is the whole PLT!\n");
2019 "could not find a symbol following the PLT within"
2020 " the PLT; assuming _header@plt is the whole PLT!\n");
2026 "setting _header@plt size to %d bytes.\n",
2041 #ifdef DWDEBUG_NOUSE_STRTAB
int symbol_insert_symbol(struct symbol *parent, struct symbol *child)
#define vwarnopt(level, area, flags, format,...)
struct scope * symbol_write_owned_scope(struct symbol *symbol)
void symbol_set_bytesize(struct symbol *s, uint32_t b)
#define symbol_set_external(s)
REFCNT binfile_free(struct binfile *binfile, int force)
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
struct symbol * symbol_get_one_member__int(struct symbol *symbol, char *member)
static uint64_t unsigned int i
#define v_g_slist_foreach(gslhead, gslcur, elm)
unsigned int size_is_bytes
unsigned int dynstrtablen
ADDR symbol_get_addr(struct symbol *symbol)
uint32_t symbol_get_bytesize(struct symbol *symbol)
uint32_t gnu_debuglinkfile_crc
#define verror(format,...)
#define vwarn(format,...)
const char *(* get_backend_name)(void)
struct binfile * binfile_open__int(char *filename, char *root_prefix, struct binfile_instance *bfinst)
#define CLRANGE_DATA(crd)
void symbol_set_addr(struct symbol *s, ADDR a)
#define vdebug(devel, areas, flags, format,...)
void * realloc(void *ptr, size_t size)
struct binfile * binfile_create(char *filename, struct binfile_ops *bfops, void *priv)
#define vdebugc(devel, areas, flags, format,...)
#define CLRANGE_START(crd)
void * calloc(size_t nmemb, size_t size)
struct arch * arch_get(arch_type_t at)
struct binfile_ops elf_binfile_ops
struct binfile_instance * instance
int binfile_close(struct binfile *binfile)
char * symbol_get_name(struct symbol *symbol)
void * malloc(size_t size)
#define SYMBOL_IS_FUNC(sym)
int clrange_add(clrange_t *clf, Word_t start, Word_t end, void *data)
struct array_list * clrange_find_next_exc(clrange_t *clf, Word_t index)
unsigned int num_sections
struct spf_config * config
debugfile_type_t has_debuginfo_type