Доступ к таблице символов ELF в C

Я пишу программу, чтобы имитировать elfdump -ecps

В настоящее время он печатает заголовок elf, заголовки программ и заголовки разделов правильно, но я застрял на последних нескольких частях таблицы символов.

желаемый результат в формате:

Symbol Table Section:  .dynsym
 index    value      size      type bind oth ver shndx          name
   [0]  0x00000000 0x00000000  NOTY LOCL  D    0 UNDEF          
   [1]  0x00025c0c 0x00000000  FUNC GLOB  D    2 UNDEF          .udiv
   [2]  0x00025e00 0x00000140  OBJT WEAK  D    1 .bss           _iob
   [3]  0x00025b24 0x00000000  OBJT GLOB  P    1 .got           _GLOBAL_OFFSET_TABLE_
   [4]  0x00013a44 0x0000001c  FUNC GLOB  D    1 .init          _init
...

можете ли вы сказать мне, где находятся oth, ver, shndx и name?

до сих пор я печатаю его со следующим:

//for each entry in the symbol table
for(i=0; i<num_sym; i++)
{
    //read the current symbol
    fread(&mysym,sizeof(Elf32_Sym),1,fp);
idx=mysym.st_name;

    //multiple lines to get formatting correct
    //prints index in brackets right aligned
    char buf[12];
    sprintf(buf, "[%d]", i);
    printf("%10s", buf);

    //value
    printf("  0x%.8x", mysym.st_value);
    //size
    printf(" 0x%.8x", mysym.st_size);

    //type
    switch (ELF32_ST_TYPE(mysym.st_info)) {
        case 0:
            printf("  NOTY");
            break;
        case 1:
            printf("  OBJT");
            break;
        case 2:
            printf("  FUNC");
            break;
        case 3:
            printf("  SECT");
            break;
        case 4:
            printf("  FILE");
            break;

        default:
            break;
    }

    //bind
    switch(ELF32_ST_BIND(mysym.st_info))
    {
        case 0: printf(" LOCL");
            break;
        case 1: printf(" GLOB");
            break;
        case 2: printf(" WEAK");
            break;
        case 3: printf("  NUM");
            break;

        default:
            break;
    }
    //TODO: oth
    //TODO: ver
    //TODO: shndx
    //TODO: name

}

Я читал через http://docs.oracle.com/cd/E19457-01/801-6737/801-6737.pdf (Глава 5), но не смогли найти ничего полезного

2 ответов


это в основном охватываемых Symbol Table начиная со страницы 119 документа, на который вы ссылаетесь.

Это на самом деле и структура вам нужно:

typedef struct {
    Elf32_Word    st_name;
    Elf32_Addr    st_value;
    Elf32_Word    st_size;
    unsigned char st_info;
    unsigned char st_other;
    Elf32_Half    st_shndx;
} Elf32_Sym;

наряду с подробной информацией о том, как найти информацию для связанных записей (в частности поиск имени от st_name полевой структуры).

к сожалению, этот документ, похоже, не охватывает, откуда берутся определенные вещи (например, версия), поэтому, когда я пытаюсь эмулировать другую программу, которая имеет источник доступен, I go to источник - на самом деле нет ничего более определенного, чем это: -)

начиная с строки 1665 этого файла, вы найдете elf_print_symtab() функция, которая отвечает за вывод интересующей вас информации. Он зовет get_versym() чтобы получить эту информацию, и из этого кода в строке 1632 вы можете увидеть, что он использует другой раздел для этого (символ версия раздел).

а, как видно здесь, этот тип раздела считается одним из специфичных для ОС, поэтому вы не найдете его в базовом стандарте, который касается только общего материала.


для Name есть еще один раздел, который содержит все строки. Вы должны использовать первое поле в "таблице заголовков разделов" в качестве индекса в заголовке раздела, чтобы получить реальную строку из этого строкового раздела. Вы можете найти много статей об этом с google.