Rivers Shall
Rivers Shall

Reputation: 561

How to interpret `p_size` in ELF files?

Recently, I have been playing around ELF format files. And I tried to solve a problem:

Given the eip, print the name of the function in the ELF executable file

And I can do this with symbol table and string table. Since I only need to deal with those symbols whose type is STT_FUNC, I wrote the following program:

for (i = 0; i < nr_symtab_entry; ++i) {
  if ((symtab[i].st_info == STT_FUNC) &&
      eip <  symtab[i].st_value + symtab[i].st_size &&
      eip >= symtab[i].st_value) {
        strcpy(funcName, strtab + symtab[i].st_name);
  }
}

where symtab is the symbol table, strtab is the string table.

But after several tests, I realized that the program above is wrong. After several trials, I changed it into this:

for (i = 0; i < nr_symtab_entry; ++i) {
  if ((symtab[i].st_info & STT_FUNC) &&
      eip <  symtab[i].st_value + symtab[i].st_size &&
      eip >= symtab[i].st_value) {
        strcpy(funcName, strtab + symtab[i].st_name);
  }
}

Then it worked! But when I man elf, the manual told me:

st_info This member specifies the symbol’s type and binding attributes

It didn't mention whether it is a bit flag or not. And then I encountered a problem which needs me to check whether a segment is PT_LOAD. And the manual, again, does not specify whether it is a bit flag or not. So I come here to ask for help---Is PT_LOAD also a bit flag? Is every symbol-constant like thing in ELF file a bit flag?


It seems that st_info can be interpreted by specific macros. But how about p_type?

Upvotes: 0

Views: 144

Answers (1)

KamilCuk
KamilCuk

Reputation: 141533

Use:

if (ELF32_ST_TYPE(symtab[i].st_info) == STT_FUNC && ...

like for example kernel does in linux kernel/module.c.

The ELF32_ST_TYPE is used to extract type of a symbol from the st_info. I can't find the list of which symbols are types of a symbol anywhere, but inspecting #define ELF32_ST_TYPE(info) ((info) & 0xf) and definitions in elf.h I can be pretty sure ELF32_ST_TYPE(st_info) is equal to one of the following macros:

#define STT_NOTYPE  0
#define STT_OBJECT  1
#define STT_FUNC    2
#define STT_SECTION 3
#define STT_FILE    4
#define STT_COMMON  5
#define STT_TLS     6

In man elf there it is:

There are macros for packing and unpacking the binding and type fields:

ELF32_ST_BIND(info), ELF64_ST_BIND(info)
Extract a binding from an st_info value.

ELF32_ST_TYPE(info), ELF64_ST_TYPE(info)
Extract a type from an st_info value.

ELF32_ST_INFO(bind, type), ELF64_ST_INFO(bind, type)
Convert a binding and a type into an st_info value.

Upvotes: 2

Related Questions