On Thu, Aug 06, 2015 at 05:14:25PM +0200, Kai Wasserbäch wrote: > > Could you compile the following with: > > gcc -g -lelf -o elfrel elfrel.c > > this does not work for several reasons: > 1. I certainly need -std=c99 for the inline initialisation of the > counter in the for() statement.
Ah, yes, this system has gcc 5.1 which defaults to gnu11. > 2. *section (first used in »gelf_getshdr(section, §ion_header)«) isn't > defined/filled anywhere: > [...] > Long story short: did you paste the entire/correct code? Drat, so sorry. I must have copy/pasted an earlier version, that didn't even compile. Attached is a version I double checked, that includes one extra check (the size of the .text section). It gives the following output for me: $ for i in 794488_elfs/libelf*/*; do ./elfrel $i; done file: 794488_elfs/libelf1/dump.elf.EL5kJT .text code size: 24 Nothing found file: 794488_elfs/libelf1/dump.elf.J4EnbO .text code size: 11c symbols: 5 1: not global or undefined 2: not global or undefined 3: not global or undefined 4: not global or undefined 5: 0 relocations: 2 0: 10, SCRATCH_RSRC_DWORD1 1: 2c, SCRATCH_RSRC_DWORD0 file: 794488_elfs/libelfg0/dump.elf.7NnBvc .text code size: 24 Nothing found file: 794488_elfs/libelfg0/dump.elf.ahPsJJ .text code size: 11c symbols: 5 1: not global or undefined 2: not global or undefined 3: not global or undefined 4: not global or undefined 5: 0 relocations: 2 0: 10, SCRATCH_RSRC_DWORD1 1: 2c, SCRATCH_RSRC_DWORD0 file: 794488_elfs/libelfg0/dump.elf.DYTjdO .text code size: 28 Nothing found file: 794488_elfs/libelfg0/dump.elf.Lke6Xg .text code size: 38 Nothing found Could you run it against old/new libelf to see if anything is different. If not, then I am looking for the bug in the wrong place. Thanks, Mark
#include <gelf.h> #include <stdio.h> #include <string.h> #include <inttypes.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main (int argc, char **argv) { elf_version(EV_CURRENT); printf ("file: %s\n", argv[1]); int fd = open (argv[1], O_RDONLY); Elf *elf = elf_begin (fd, ELF_C_READ, NULL); size_t section_str_index; elf_getshdrstrndx(elf, §ion_str_index); size_t reloc_count, symbol_sh_link, symbol_count; Elf_Data *relocs, *symbols; Elf_Scn *section = NULL; while ((section = elf_nextscn(elf, section))) { const char *name; GElf_Shdr section_header; if (gelf_getshdr(section, §ion_header) != §ion_header) { fprintf(stderr, "Failed to read ELF section header\n"); return -1; } name = elf_strptr(elf, section_str_index, section_header.sh_name); if (strncmp(name, ".symtab", 7) == 0) { symbols = elf_getdata(section, NULL); symbol_sh_link = section_header.sh_link; symbol_count = section_header.sh_size / section_header.sh_entsize; } else if (strcmp (name, ".rel.text") == 0) { relocs = elf_getdata(section, NULL); reloc_count = section_header.sh_size / section_header.sh_entsize; } else if (strcmp (name, ".text") == 0) { Elf_Data *section_data = elf_getdata(section, NULL); printf (".text code size: %zx\n", section_data->d_size); } } if (!relocs || !symbols || !reloc_count) { printf("Nothing found\n"); return -1; } printf ("symbols: %zd\n", symbol_count); GElf_Sym symbol; size_t i = 0; while (gelf_getsym (symbols, i++, &symbol)) { if (GELF_ST_BIND(symbol.st_info) != STB_GLOBAL || symbol.st_shndx == 0) { printf ("%zd: not global or undefined\n", i); continue; } printf ("%zd: %" PRIx64 "\n", i, symbol.st_value); } printf ("relocations: %zd\n", reloc_count); for (size_t i = 0; i < reloc_count; i++) { GElf_Sym symbol; GElf_Rel rel; char *symbol_name; gelf_getrel(relocs, i, &rel); gelf_getsym(symbols, GELF_R_SYM(rel.r_info), &symbol); symbol_name = elf_strptr(elf, symbol_sh_link, symbol.st_name); printf ("%zd: %" PRIx64 ", %s\n", i, rel.r_offset, symbol_name); } return 0; }