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, &section_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, &section_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, &section_header) != &section_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;
}

Reply via email to