如何解释 ELF 文件中的“p_size”?

How to interpret `p_size` in ELF files?

最近一直在玩ELF格式的文件。我试图解决一个问题:

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

我可以用符号 table 和字符串 table 来做到这一点。由于我只需要处理那些类型为STT_FUNC的符号,我写了如下程序:

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);
  }
}

其中 symtab 是符号 table,strtab 是字符串 table。

但是经过几次测试,我发现上面的程序是错误的。试了几次,改成这样:

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);
  }
}

然后成功了!但是当我man elf的时候,手册告诉我:

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

它没有提到它是否是位标志。然后我遇到了一个问题,需要我检查一个段是否是PT_LOAD。并且手册再次没有指定它是否是位标志。所以才来这里求助---PT_LOAD也是位flag吗? ELF文件中的每个符号常量之类的东西都是位标志吗?


好像st_info可以通过特定的宏来解释。但是 p_type 呢?

使用:

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

就像内核在 linux kernel/module.c 中所做的那样。

ELF32_ST_TYPE用于从st_info中提取一个符号的类型。我在任何地方都找不到哪些符号是符号类型的列表,但是检查 #define ELF32_ST_TYPE(info) ((info) & 0xf)elf.h 中的定义我可以很确定 ELF32_ST_TYPE(st_info) 等于以下宏之一:

#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

man elf里面是:

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.