7

I have a program which uses the mmap system call:

map_start = mmap(0, fd_stat.st_size, PROT_READ | PROT_WRITE , MAP_SHARED, fd, 0)

and a header variable:

header = (Elf32_Ehdr *) map_start;

How can I access the symbol table and print its whole content with the header variable?

Mateusz Piotrowski
  • 6,087
  • 9
  • 44
  • 71
kitsuneFox
  • 1,093
  • 3
  • 14
  • 30

2 Answers2

9

You get the section table by looking at the e_shoff field of the elf header:

sections = (Elf32_Shdr *)((char *)map_start + header->e_shoff);

You can now search throught the section table for the section with type SHT_SYMBTAB, which is the symbol table.

for (i = 0; i < header->e_shnum; i++)
    if (sections[i].sh_type == SHT_SYMTAB) {
        symtab = (Elf32_Sym *)((char *)map_start + sections[i].sh_offset);
        break; }

Of course, you should also do lots of sanity checking in case your file is not an ELF file or has been corrupted in some way.

The linux elf(5) manual page has lots of info about the format.

Chris Dodd
  • 101,438
  • 11
  • 111
  • 197
  • ok,thank you, but now, how can i get the amount of the symbols in the symbols table? – kitsuneFox May 22 '14 at 20:31
  • 3
    `sh_size` tells you the size of the symbol table (in bytes); divide by `sh_entsize` (which should be the same as `sizeof(Elf32_Sym)`) to get the number of entries. – Chris Dodd May 22 '14 at 20:43
1

Here is an example: https://docs.oracle.com/cd/E19683-01/817-0679/6mgfb878d/index.html

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libelf.h>
#include <gelf.h>

void
main(int argc, char **argv)
{
    Elf         *elf;
    Elf_Scn     *scn = NULL;
    GElf_Shdr   shdr;
    Elf_Data    *data;
    int         fd, ii, count;

    elf_version(EV_CURRENT);

    fd = open(argv[1], O_RDONLY);
    elf = elf_begin(fd, ELF_C_READ, NULL);

    while ((scn = elf_nextscn(elf, scn)) != NULL) {
        gelf_getshdr(scn, &shdr);
        if (shdr.sh_type == SHT_SYMTAB) {
            /* found a symbol table, go print it. */
            break;
        }
    }

    data = elf_getdata(scn, NULL);
    count = shdr.sh_size / shdr.sh_entsize;

    /* print the symbol names */
    for (ii = 0; ii < count; ++ii) {
        GElf_Sym sym;
        gelf_getsym(data, ii, &sym);
        printf("%s\n", elf_strptr(elf, shdr.sh_link, sym.st_name));
    }
    elf_end(elf);
    close(fd);
}
YongHao Hu
  • 2,394
  • 13
  • 21