第三章:编译链构建产物的初步学习
编译链(Toolchain)是指用于将源代码转换为可执行文件的一组工具。典型的编译链包括编译器、汇编器、链接器和库等。构建产物(Build Artifacts)是通过编译链生成的各种文件,如可执行文件、库文件、对象文件等。
MAP文件
MAP文件是通过编译器编译之后,集程序、数据及IO空间的一种映射文件。在工程的编译中,常出现可执行文件和.o文件,另外还有MAP文件。他主要用于描述程序的内存布局。在代码编译的过程中,MAP文件记录了程序中每个符号的地址、内存布局等信息。
在出现crash后通过分析MAP文件,可以知道函数大小,入口地址等一些重要信息,方便找出crash原因。
打开MAP文件后,发现在map文件中首先记录了归档成员信息,将相关库和目标文件放在一起,方便在链接和编译中使用。
Discarded input sections中记录了在处理输入数据时被遗弃和忽略的部分。
|
内存配置情况 ,记录着ROM起始地址为0x22000000,长度为0x00010000,可执行 可写入
链接器使用情况、符号的映射和地址信息。
加载链接器桩(stub)的相关信息。链接器桩是一些小的代码片段,用于在链接过程中处理特定的情况或提供必要的支持。
以.debug_info段为例,其中包含着每个条目的起始地址,大小和它所属的目标文件。
通过观察MAP文件,可以详细了解程序中各个部分的内存布局和大小。.MAP文件详细列出了程序中所有的符号(函数、变量等)及其对应的地址。通过这些信息,我们可以知道每个符号在内存中的位置,有助于后续的调试和优化。MAP文件通常用来进行调试、优化、验证操作。可以快速了解程序的内存布局,定位代码的地址和数据存储的位置,也可以观察内存的使用情况、有助于优化代码,缩小可执行程序的大小,节省内存空间。
.MAP文件描述了程序的内存布局,包括代码段、数据段、堆和栈的位置及大小。
.MAP文件描述了符号地址和大小信息,方便快速定位函数和变量位置,更容易找到和修复bug。
.MAP文件描述了模块的链接和内存占用情况,管理者可以删除不必要的代码进行性能优化。
链接脚本LD文件
ld文件的基本概念
ld文件是交叉编译后生成的用于控制链接器行为的脚本文件。它定义了如何将编译后的目标文件(object files)组织成最终的可执行文件或固件镜像。ld文件的主要目的是将多个目标文件和库文件链接生成最终的可执行文件。
链接器的基本概念
链接器是编程工具链中的一个关键组件,它的主要任务是将多个目标文件(通常是编译后的代码)和库文件组合成一个可执行文件或库。
输入文件: 目标文件或链接脚本文件。
输出文件: 目标文件或可执行文件。
链接脚本文件的解析
ld文件按照关键词进行解析,常用关键词解析如下:
ENTRY命令:
运行一个程序时第一个被执行到的指令的"入口点"。
MEMORY命令:
内存块配置命令,一个连接脚本最多一个’MEMORY’命令。
SECTIONS命令:
’段’命令,段中又包含多个’节’, SECTIONS命令告诉连接器如何把输入节映射到输出节, 如何把输入节放入到内存中。
ALTGN命令:
以多少位对齐,例如ALTGN(4)表示以4位对齐。
.命令:
一个点“.”可以用来获取当前内存地址。
举例说明如下:
MEMORY 其后包含着存储的起始地址信息和长度。
GROUP指令用于指定()内的文件是一个组,这些文件多是静态库文件,链接器会将这三个文件当作整体处理,使他们之间的符号可以正常解析。
SECTION指令定义和控制输出文件中各个段(section)的布局和属性。他描述了程序中的各个段的地址布局以及链接时被如何分配。
下面这个例子首先解释了.sram_text段的起始地址和需要加载到的地址。将该组文件中的.text段链接到RAMX中。对齐方式是32字节。
|
DISCARD指令描述了被弃用的段或者符号,这些不会在最终的可执行文件中出现。
程序的编译
大家都知道一个程序的执行过程为:预处理-编译-汇编-链接。从根本来讲计算机只认识0和1(有电和无电)。
这四个步骤可以简单概括为:
- 预处理器将源代码转换为扩展的源代码。
- 编译器将扩展的源代码转换为汇编代码。
- 汇编器将汇编代码转换为机器码。
- 链接器通过链接脚本的指导,将目标文件与库或者其他文件链接起来生成可执行文件。