以下是对这些ELF内部结构体的详细中文注释:
/* ELF文件头结构 (Elf_Internal_Ehdr) */
typedef struct elf_internal_ehdr {
unsigned char e_ident[EI_NIDENT]; /* ELF魔数(0x7F+'E'+'L'+'F')和标识信息 */
bfd_vma e_entry; /* 程序入口点虚拟地址 */
bfd_size_type e_phoff; /* 程序头表在文件中的偏移量 */
bfd_size_type e_shoff; /* 节头表在文件中的偏移量 */
unsigned long e_version; /* 文件版本号(通常为EV_CURRENT) */
unsigned long e_flags; /* 处理器特定标志 */
unsigned short e_type; /* 文件类型(ET_REL/ET_EXEC/ET_DYN等) */
unsigned short e_machine; /* 目标机器架构(EM_X86_64/EM_ARM等) */
unsigned int e_ehsize; /* ELF头大小(字节) */
unsigned int e_phentsize; /* 程序头表中每个条目的大小 */
unsigned int e_phnum; /* 程序头表条目数量 */
unsigned int e_shentsize; /* 节头表中每个条目的大小 */
unsigned int e_shnum; /* 节头表条目数量 */
unsigned int e_shstrndx; /* 节名称字符串表的节索引 */
} Elf_Internal_Ehdr;
/* 程序头结构 (描述段信息) */
struct elf_internal_phdr {
unsigned long p_type; /* 段类型(PT_LOAD/PT_DYNAMIC等) */
unsigned long p_flags; /* 段标志(PF_R/PF_W/PF_X组合) */
bfd_vma p_offset; /* 段在文件中的偏移量 */
bfd_vma p_vaddr; /* 段在内存中的虚拟地址 */
bfd_vma p_paddr; /* 段在内存中的物理地址(通常同虚拟地址) */
bfd_vma p_filesz; /* 段在文件中的大小 */
bfd_vma p_memsz; /* 段在内存中的大小(可能大于filesz) */
bfd_vma p_align; /* 段对齐要求(字节对齐) */
};
/* 节头结构 */
typedef struct elf_internal_shdr {
unsigned int sh_name; /* 节名称(在字符串表中的索引) */
unsigned int sh_type; /* 节类型(SHT_PROGBITS/SHT_NOBITS等) */
bfd_vma sh_flags; /* 节标志(SHF_WRITE/SHF_ALLOC等) */
bfd_vma sh_addr; /* 节在内存中的虚拟地址 */
file_ptr sh_offset; /* 节在文件中的偏移量 */
bfd_size_type sh_size; /* 节的大小(字节) */
unsigned int sh_link; /* 关联节的索引(根据节类型不同含义不同) */
unsigned int sh_info; /* 附加信息(根据节类型不同含义不同) */
bfd_vma sh_addralign; /* 节对齐要求 */
bfd_size_type sh_entsize; /* 条目大小(对于表类型的节) */
/* 内部使用的缓存信息 */
asection * bfd_section; /* 关联的BFD节结构 */
unsigned char *contents; /* 节内容缓存 */
} Elf_Internal_Shdr;
/* 压缩头结构 */
typedef struct elf_internal_chdr {
unsigned int ch_type; /* 压缩类型(ELFCOMPRESS_ZLIB等) */
bfd_size_type ch_size; /* 未压缩数据的大小 */
bfd_vma ch_addralign; /* 未压缩数据的对齐要求 */
} Elf_Internal_Chdr;
/* 符号表条目结构 */
struct elf_internal_sym {
bfd_vma st_value; /* 符号值(地址/偏移量) */
bfd_vma st_size; /* 符号大小 */
unsigned long st_name; /* 符号名称(字符串表索引) */
unsigned char st_info; /* 类型和绑定属性(STT_*/STB_*组合) */
unsigned char st_other; /* 可见性和目标特定信息 */
unsigned char st_target_internal; /* 目标架构内部信息 */
unsigned int st_shndx; /* 关联的节索引(SHN_ABS/SHN_COMMON等) */
};
/* 注释段结构 */
typedef struct elf_internal_note {
unsigned long namesz; /* 所有者名称的字节长度 */
unsigned long descsz; /* 描述数据的字节长度 */
unsigned long type; /* 描述数据类型(NT_GNU_ABI_TAG等) */
char * namedata; /* 名称数据起始位置 */
char * descdata; /* 描述数据起始位置 */
bfd_vma descpos; /* 描述数据在文件中的偏移量 */
} Elf_Internal_Note;
/* 重定位条目结构(带加数) */
typedef struct elf_internal_rela {
bfd_vma r_offset; /* 需要重定位的位置 */
bfd_vma r_info; /* 符号索引和重定位类型 */
bfd_vma r_addend; /* 用于计算的常量加数 */
} Elf_Internal_Rela;
/* 动态段条目结构 */
typedef struct elf_internal_dyn {
bfd_vma d_tag; /* 动态条目类型(DT_NEEDED/DT_SYMTAB等) */
union {
bfd_vma d_val; /* 整数值 */
bfd_vma d_ptr; /* 指针值 */
} d_un;
} Elf_Internal_Dyn;
/* 版本定义结构(SHT_GNU_verdef节) */
typedef struct elf_internal_verdef {
unsigned short vd_version; /* 结构版本 */
unsigned short vd_flags; /* 标志(VER_FLG_BASE/VER_FLG_WEAK) */
unsigned short vd_ndx; /* 版本索引 */
unsigned short vd_cnt; /* 关联的verdaux条目数 */
unsigned long vd_hash; /* 版本名称的哈希值 */
unsigned long vd_aux; /* 到verdaux条目的偏移量 */
unsigned long vd_next; /* 下一个verdef的偏移量 */
/* 以下字段由BFD在读入时设置 */
bfd * vd_bfd; /* 所属BFD */
const char * vd_nodename; /* 版本名称 */
struct elf_internal_verdef *vd_nextdef; /* 指向下一个verdef */
struct elf_internal_verdaux *vd_auxptr; /* 指向关联的verdaux */
unsigned int vd_exp_refno; /* 链接器使用的引用编号 */
} Elf_Internal_Verdef;
/* 版本定义辅助结构 */
typedef struct elf_internal_verdaux {
unsigned long vda_name; /* 版本名称的字符串表偏移 */
unsigned long vda_next; /* 下一个verdaux的偏移量 */
/* 以下字段由BFD在读入时设置 */
const char *vda_nodename; /* 版本名称字符串 */
struct elf_internal_verdaux *vda_nextptr; /* 指向下一个verdaux */
} Elf_Internal_Verdaux;
/* 版本需求结构(SHT_GNU_verneed节) */
typedef struct elf_internal_verneed {
unsigned short vn_version; /* 结构版本 */
unsigned short vn_cnt; /* 关联的vernaux条目数 */
unsigned long vn_file; /* 库名称的字符串表偏移 */
unsigned long vn_aux; /* 到vernaux条目的偏移量 */
unsigned long vn_next; /* 下一个verneed的偏移量 */
/* 以下字段由BFD在读入时设置 */
bfd * vn_bfd; /* 所属BFD */
const char * vn_filename; /* 库名称字符串 */
struct elf_internal_vernaux *vn_auxptr; /* 指向关联的vernaux */
struct elf_internal_verneed *vn_nextref; /* 指向下一个verneed */
} Elf_Internal_Verneed;
/* 版本需求辅助结构 */
typedef struct elf_internal_vernaux {
unsigned long vna_hash; /* 依赖名称的哈希值 */
unsigned short vna_flags; /* 标志 */
unsigned short vna_other; /* 未使用 */
unsigned long vna_name; /* 版本名称的字符串表偏移 */
unsigned long vna_next; /* 下一个vernaux的偏移量 */
/* 以下字段由BFD在读入时设置 */
const char *vna_nodename; /* 版本名称字符串 */
struct elf_internal_vernaux *vna_nextptr; /* 指向下一个vernaux */
} Elf_Internal_Vernaux;
/* 版本符号结构(SHT_GNU_versym节) */
typedef struct elf_internal_versym {
unsigned short vs_vers; /* 版本索引 */
} Elf_Internal_Versym;
/* 符号信息结构 */
typedef struct {
unsigned short int si_boundto; /* 符号绑定目标 */
unsigned short int si_flags; /* 符号标志 */
} Elf_Internal_Syminfo;
/* 辅助向量结构(用于核心转储) */
typedef struct {
bfd_vma a_type; /* 辅助向量类型(AT_*) */
bfd_vma a_val; /* 辅助向量值 */
} Elf_Internal_Auxv;
/* 程序段映射结构(描述节如何分配到段) */
struct elf_segment_map {
struct elf_segment_map *next; /* 下一个段 */
unsigned long p_type; /* 段类型 */
unsigned long p_flags; /* 段标志 */
bfd_vma p_paddr; /* 段物理地址 */
bfd_vma p_vaddr_offset; /* 段虚拟地址偏移量 */
bfd_vma p_align; /* 段对齐 */
bfd_vma p_size; /* 段大小 */
/* 标志位字段 */
unsigned int p_flags_valid : 1; /* p_flags是否有效 */
unsigned int p_paddr_valid : 1; /* p_paddr是否有效 */
unsigned int p_align_valid : 1; /* p_align是否有效 */
unsigned int p_size_valid : 1; /* p_size是否有效 */
unsigned int includes_filehdr : 1; /* 是否包含文件头 */
unsigned int includes_phdrs : 1; /* 是否包含程序头表 */
unsigned int no_sort_lma : 1; /* 是否禁止LMA排序 */
unsigned int idx; /* 原始排序索引 */
unsigned int count; /* 包含的节数量 */
asection *sections[1]; /* 节指针数组(实际长度由count决定) */
};
关键结构说明:
-
ELF文件头(Elf_Internal_Ehdr):
- 包含ELF文件的元信息,如目标架构、文件类型、程序/节头表位置等
-
e_ident
前4字节必须是\x7FELF
-
程序头(Elf_Internal_Phdr):
- 描述如何将文件映射到内存的段(Segment)信息
- PT_LOAD类型的段会被实际加载到内存
-
节头(Elf_Internal_Shdr):
- 描述ELF文件中的各个节(Section)
- 包含节类型、大小、位置等元信息
-
动态链接相关结构:
-
Elf_Internal_Dyn
描述动态链接器需要的信息 -
Elf_Internal_Verdef/Elf_Internal_Verdaux
处理符号版本控制
-
-
符号表结构(Elf_Internal_Sym):
- 包含符号名称、值、大小和绑定信息
-
st_shndx
特殊值如SHN_UNDEF(未定义)、SHN_ABS(绝对符号)
这些结构体共同构成了ELF文件的完整描述,涵盖了从文件头到各个节区、符号表、重定位信息等所有核心数据。