当前位置: 首页 > news >正文

GNU编译器(GCC):编译的4个过程及.elf、.list、.map文件功能说明

0 参考资料

GNU-LD-v2.30-中文手册.pdf
GNU linker.pdf

1 前言

一个完整的编译工具链应该包含以下4个部分:
(1)编译器
(2)汇编器
(3)链接器
(4)lib库
在GNU工具链中,对应的是:
(1)编译器:GCC(GNU Compiler Collection,GNU编译器套件)
(2)汇编器:GAS(GNU Assembler,GNU汇编器)
(3)链接器:LD(GNU Linker,GNU链接器)
(4)lib库:glibc(GNU C Library,GNU C 库)
本文介绍GNU编译器(GCC)编译的4个过程及.elf、.list、.map文件功能。

2 GNU编译器(GCC):编译的4个过程及.elf、.list、.map文件功能说明

2.1 GCC编译的4个阶段

在这里插入图片描述
GCC编译按顺序分成4个阶段:预处理、编译、汇编、链接。详细操作见上图。

2.2 .elf、.list、.map文件功能说明

2.2 .elf文件

elf全称是Executable and Linkable Format(可执行链接格式),生成于汇编阶段(目标文件.o就是elf格式文件)。
一个elf文件主要由三部分组成:elf头(ELF Header)、程序头表(Program Header Table)、节区头表(Section Header Table)。elf头包含了有关elf文件的基本信息如文件类型、机器类型、段数量及位置等;程序头表描述了文件中各个段的信息;节区头表描述了文件中各个节区的信息。
在Windows下可以使用安装了AnyELF插件的Total Commander工具查看.elf文件,参考博客:Windows上浏览ELF文件。下图是使用该插件查看到的.elf文件实例:
在这里插入图片描述

2.2 .list文件

.list文件扩展名一般为.list或.lst,是纯文本文件。它由.elf文件反汇编(也就是将机器码转换为汇编)得来。里面包含了指令地址、指令机器码、指令机器码反汇编得到的汇编指令。如下所示:
在这里插入图片描述
通过.list文件我们可以很清晰看到源码和最终生成的汇编语句、机器码、指令地址,对调试阶段排查bug非常有用。

2.3 .map文件

.map文件扩展名一般是.map,是纯文本文件。它里面描述了程序的源代码和目标代码之间的映射关系,主要包括以下几个关键部分:
(1)模块、段(入口)交叉引用。描述了各个源文件之间函数调用关系,展示了哪些函数调用了其它函数,以及这些调用在内存中的位置
(2)删除镜像未使用的程序段。描述了哪些会被删除的程序段,便于开发者确认哪些代码被优化掉了
(3)内存分布。这也是.map最常用的功能,它描述了各个段(.text段、.data段、.bss段)在内存中的地址及大小
(4)映射组件大小。.map文件还会给出整个镜像代码占用的总空间信息
以下是一个.map文件实例:
在这里插入图片描述

2.3 如何生成.list、.map文件

生成方法参考stm32MP135工程的makefile文件:

Tool invocations

################################################################################
# Automatically-generated file. Do not edit!
# Toolchain: GNU Tools for STM32 (12.3.rel1)
################################################################################-include ../makefile.initRM := rm -rf# All of the sources participating in the build are defined here
-include sources.mk
-include Core/Startup/subdir.mk
-include Core/Net/subdir.mk
-include Core/Drivers/STM32MP13xx_HAL_Driver/Src/subdir.mk
-include Core/Common/subdir.mk
-include Core/Bsp/subdir.mk
-include objects.mkifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(S_DEPS)),)
-include $(S_DEPS)
endif
ifneq ($(strip $(S_UPPER_DEPS)),)
-include $(S_UPPER_DEPS)
endif
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
endif-include ../makefile.defsOPTIONAL_TOOL_DEPS := \
$(wildcard ../makefile.defs) \
$(wildcard ../makefile.init) \
$(wildcard ../makefile.targets) \BUILD_ARTIFACT_NAME := stm32MP135
BUILD_ARTIFACT_EXTENSION := elf
BUILD_ARTIFACT_PREFIX :=
BUILD_ARTIFACT := $(BUILD_ARTIFACT_PREFIX)$(BUILD_ARTIFACT_NAME)$(if $(BUILD_ARTIFACT_EXTENSION),.$(BUILD_ARTIFACT_EXTENSION),)# Add inputs and outputs from these tool invocations to the build variables 
EXECUTABLES += \
stm32MP135.elf \MAP_FILES += \
stm32MP135.map \SIZE_OUTPUT += \
default.size.stdout \OBJDUMP_LIST += \
stm32MP135.list \# All Target
all:+@$(MAKE) --no-print-directory main-build && $(MAKE) --no-print-directory post-build# Main-build Target
main-build: stm32MP135.elf secondary-outputs# Tool invocations
stm32MP135.elf stm32MP135.map: $(OBJS) $(USER_OBJS) D:\stm32MP135\Application\STM32MP135DAEX_RAM.ld makefile objects.list $(OPTIONAL_TOOL_DEPS)arm-none-eabi-gcc -o "stm32MP135.elf" @"objects.list" $(USER_OBJS) $(LIBS) -mcpu=cortex-a7 -T"D:\stm32MP135\Application\STM32MP135DAEX_RAM.ld" --specs=nosys.specs -Wl,-Map="stm32MP135.map" -Wl,--gc-sections -static  -mfpu=vfpv4-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group@echo 'Finished building target: $@'@echo ' 'default.size.stdout: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)arm-none-eabi-size  $(EXECUTABLES)@echo 'Finished building: $@'@echo ' 'stm32MP135.list: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)arm-none-eabi-objdump -h -S $(EXECUTABLES) > "stm32MP135.list"@echo 'Finished building: $@'@echo ' '# Other Targets
clean:-$(RM) stm32MP135.elf stm32MP135.list stm32MP135.map default.size.stdout-@echo ' 'post-build:"C:\STM32Cube\Repository\STM32Cube_FW_MP13_V1.1.0\Utilities\ImageHeader\postbuild_STM32MP13.sh" "D:\ST\STM32CubeIDE_1.15.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.12.3.rel1.win32_1.0.100.202403111256\tools\bin"  "stm32MP135"-@echo ' 'secondary-outputs: $(SIZE_OUTPUT) $(OBJDUMP_LIST)fail-specified-linker-script-missing:@echo 'Error: Cannot find the specified linker script. Check the linker settings in the build configuration.'@exit 2warn-no-linker-script-specified:@echo 'Warning: No linker script specified. Check the linker settings in the build configuration.'.PHONY: all clean dependents main-build fail-specified-linker-script-missing warn-no-linker-script-specified post-build-include ../makefile.targets

http://www.mrgr.cn/news/33830.html

相关文章:

  • 【HAProxy06】企业级反向代理HAProxy调度算法之其他算法
  • LabVIEW 实现 find_nearest_neighbors 功能(二维平面上的最近邻查找)
  • 开源库推荐,OpenMVG三维重建
  • 【Elasticsearch】Elasticsearch集成Spring Boot
  • 苍穹外卖 数据可视化
  • caozha-pinyin(中文转拼音源码)
  • 【Android】BottomSheet基本用法总结(BottomSheetDialog,BottomSheetDialogFragment)
  • 聚簇索引和非聚簇索引的定义和区别
  • Codeforces Round 974 (Div. 3) G. Milky Days
  • 布草洗涤-酒店分楼层统计报表--———未来之窗行业应用跨平台架构
  • 中小企业体系技术抽象沉淀-异地灾备篇
  • Linux:环境变量
  • 【9月22日小雪】A股下周趋势分析
  • 自然语言处理NLP:文本预处理Text Pre-Processing
  • 【Python报错已解决】TypeError: ‘<‘ not supported between instances of ‘str‘ and ‘int‘
  • 浅谈Linux中文件与目录的ACL
  • python函数的一些介绍
  • C++——将数组a[5]={-1,2,9,-5,7}中小于0的元素置成0。并将其结果输出(要求:用数组名作为函数的参数来实现)
  • Python爬虫之urllib模块详解
  • 双向链表:实现、操作与分析【算法 17】
  • 传输层 II(TCP协议——协议的特点、报文段、连接管理)【★★★★】
  • cnn机器学习时python版本不兼容报错
  • tb的数数问题(牛客小白月赛)
  • 算法打卡:第十一章 图论part04
  • “Boolean yes=TRUE;“是正确的boolean变量声明???
  • 干货 | 2024数智新时代制造业数字化创新实践白皮书(免费下载)