1.15 ELF文件解析
在Windows操作系统下,编译后的Go文本文件最终会生成以.exe为后缀的PE格式的可执行文件,而在Linux和类UNIX操作系统下,会生成ELF格式的可执行文件。除机器码外,在可执行文件中还可能包含调试信息、动态链接库信息、符号表信息。ELF(Executable and Linkable Format)是类UNIX操作系统下最常见的可执行且可链接的文件格式。有许多工具可以完成对ELF文件的探索查看,如readelf、objdump。下面使用readelf查看ELF文件的头信息:
ELF包含多个segment与section。debug/elf包中给出了一些调试ELF的API,以下程序可以打印出ELF文件中section的信息。
通过readelf工具查看ELF文件中section的信息。
segment包含多个section,它描述程序如何映射到内存中,如哪些section需要导入内存、采取只读模式还是读写模式、内存对齐大小等。以下是section与segment的对应关系。
并不是所有的section都需要导入内存,当Type为LOAD时,代表section需要被导入内存。后面的Flg代表内存的读写模式。包含.text的代码区代表可以被读和执行,包含.data与.bss的全局变量可以被读写,其中,为了满足垃圾回收的需要还区分了是否包含指针的区域。包含.rodata常量数据的区域代表只读区,其中,.itablink为与Go语言接口相关的全局符号表,详见第12章。.gopclntab包含程序计数器PC与源代码行的对应关系。
一个Hello World程序一共包含25个section,可以看到并不是所有section都需要导入内存,同时,该程序包含单独存储调试信息的区域。如.note.go.buildid包含Go程序唯一的ID,可以通过objdump工具在.note.go.buildid中查找到每个Go程序唯一的ID。
另外,.go.buildinfo section包含Go程序的构建信息,“go version”命令会查找该区域的信息获取Go语言版本号。