编译工具链 之四 .MAP 文件、.LST 文件

这篇具有很好参考价值的文章主要介绍了编译工具链 之四 .MAP 文件、.LST 文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  .map 文件和 .lst 文件是嵌入式开发中最有用的俩调试辅助文件。现在主要从事 RISC-V 架构,主要与 GCC 打交道,今天就重点学习一下 GCC 的 .map 文件、.lst 文件,并辅助以 ARMCC 和 IAR 作为对比。

  本文中的 DEMO 主要是使用 https://gitee.com/itexp/STM32_BareMetal 这个代码,其中配置好了 ARM-MDK、IAR、ECLIPSE 等众多常用开发工具的项目工程。

编译

  .map 文件和 .lst 文件就是编译工具链给出的构建过程的一些 LOG 文件。要编译出最终的可执行程序,通常需要编译、链接、转换这三个阶段。其中,编译即编译器将源码翻译成对象文件,链接即链接器将各个对象文件组合成最终可执行程序。现代编译器通常产生一个通用格式(通常是带有调试信息)的最终可执行程序(ELF 文件),然后使用相应的工具从中提取出实际的纯可执行程序。
.map文件,Toolchain,linux,c++,toolchain,gcc,map
  能独立提供编译工具链的厂家并不多,嵌入式平台则更少,主要就是 ARM、IAR、GNU、LLVM。其中,ARM、IAR 是收费的专用软件,其支持的架构有限,而 GNU 的 GCC 则是一款支持众多架构的开源编译套件;LLVM 则是后起之秀,同样也支持众多架构,目前用的不如 GCC 广泛!如下是常用编译器:
.map文件,Toolchain,linux,c++,toolchain,gcc,map

编译工具链及基本概念参见独立博文 编译工具链 之一 基本概念、组成部分、交叉编译工具链、命名规则

.map 文件

  .map 文件对应的中文名应该是映射文件,用来展示(映射)项目构建的链接阶段的细节。通常包含程序的全局符号、交叉引用和内存映射等等信息。目前,常见的编译器套件(实际是其中的链接器),例如, GCC、ARMCC、IAR 都可以生成 .map 文件。

GCC

  GCC 编译工具链中的链接器、汇编器、objdump 等工具都位于 GNU Binutils 中,他们的相关文档可以直接在官网下载。相比于 ARMCC 和 IAR,GCC 的 MAP 文件中的内容比较少!

产生方式

  在 GCC 中,MAP 文件就是由链接器 ld 通过使用命令 -Map=mapfile 来输出 map 文件。需要注意,如果同时使用了 --print-map 则会只将 MAP 内容输出到编译窗口,而不会生成 MAP 文件。
.map文件,Toolchain,linux,c++,toolchain,gcc,map
  需要注意的是,如果使用了编译器 gcc 作为入口(通常都是这么做,不会直接调用链接器),则需要使用 -Wl,-Map,FILE 的方式来将参数传递给链接器。编译器参数 -Wl 是专门用来传递参数给链接器的。同样,如果使用了 -Xlinker --print-map 则只会将 MAP 信息输出到编译窗口,而不会再生成 MAP 文件!
.map文件,Toolchain,linux,c++,toolchain,gcc,map
  在实际开发中,ECLIPSE 的相关配置如下所示。目前没有该明白,为何它要以 g++ 作为链接器的入口!
.map文件,Toolchain,linux,c++,toolchain,gcc,map

内容介绍

  在理解内容之前,有必要先了解一下工具链提供的存档文件(Archive File)。前面说过,工具链提供了 lib 这一部分, lib 中的各个函数的实现是已经进行了预编译的,并且把预编译的各种 .o 文件打包成为存档文件(.a 文件)。编译单元即一个 .o 文件。

GCC 的 MAP 文件相比于 ARMCC 和 IAR 内容少了很多

存档文件引用关系

  MAP 文件的第一部分内容列出了我们项目中所使用的标准库中提供的函数的基本调用情况,基本格式如下:

存档文件 (编译单元)
    			调用存档文件中接口的文件(调用的符号)

  如下图所示的示例,表示 crt0.o 中正在调用 exit 这个接口,而 exit 位于 lib_a-exit.o 这个文件中,而 lib_a-exit.o 这个文件存在于 libg.a 这个存档文件中!
.map文件,Toolchain,linux,c++,toolchain,gcc,map

丢弃的输入段

  MAP 文件的第二部分内容列出了链接器在生成最终可执行文件时丢弃的输入段,每行一个,四列的含义从左到右依次为节区名、地址、节区大小、节区所在的编译单元。注意,如果节区位于存档文件中,则最后一列是存档文件 + (编译单元)。
.map文件,Toolchain,linux,c++,toolchain,gcc,map

内存配置

  MAP 文件的第三部分内容列出了我们的内存(存储)配置情况,每行一个,四列的含义从左到右依次为存储的名字、起始地址、大小(字节)、属性(r:读、x:执行、w:写)
.map文件,Toolchain,linux,c++,toolchain,gcc,map

链接脚本和内存映射

  关于链接脚本我们后面在详细介绍,这部分链接脚本就是一些 MRI 兼容的链接脚本命令,简单来说,使用 MRI 兼容的链接脚本命令引入一些对象文件(.o)。 MRI 兼容的链接脚本命令是用于早期链接器的,在 ld 手册中有说明,现在存在的唯一的目的就是兼容!
.map文件,Toolchain,linux,c++,toolchain,gcc,map
  这部分最有用的是紧随其后的内存映射,这部分列出了所有符号在内存(存储)中的物理地址,这部分就是在辅助调试时最常用的!
.map文件,Toolchain,linux,c++,toolchain,gcc,map

ARM

产生方式

  参见博文 ARM 之十 ARMCC(Keil) map 文件(映射文件)详解。

内容介绍

  参见博文 ARM 之十 ARMCC(Keil) map 文件(映射文件)详解。

IAR

产生方式

  由链接器参数 --map 来产生。当启用 MAP 文件后,链接器支持的其他一些参数的输出就会输出到 MAP 文件中。
.map文件,Toolchain,linux,c++,toolchain,gcc,map

内容介绍

  暂无,后续有需要再补充!文章来源地址https://www.toymoban.com/news/detail-717646.html

.lst 文件

  .lst 文件全称是 Assembler list file,主要用来存储汇编程序列表数据,它通常会拥有比 .map 文件更详细的信息。借助 .lst 文件,同时通过查看栈帧结构(可以通过查看相应的手册来确定栈帧的组成),通过在 .lst 文件中查找 lr 的地址所在的位置,就能立刻定位到问题。

GCC

  GCC 编译工具链中的链接器、汇编器、objdump 等工具都位于 GNU Binutils 中,他们的相关文档可以直接在官网下载。

产生方式

  .lst 文件通常是由汇编器产生的,对于 GCC 的汇编器 as,通过使用命令 -a[cdghlmns]=[FILE] 来输出 lst 文件。但需要注意的是,-a[cdghlmns]=[FILE] 参数是独立使用汇编器 as 的时候才生效的。
.map文件,Toolchain,linux,c++,toolchain,gcc,map
  与上面说的 MAP 文件产生一样,如果使用了编译器 gcc 作为入口(通常都是这么做,不会直接调用汇编器),则需要使用 -Wa,-a,FILE 的方式来将参数传递给汇编器。编译器参数 -Wa 是专门用来传递参数给汇编器的。
.map文件,Toolchain,linux,c++,toolchain,gcc,map
  在实际开发中,我们经常写 -Wa,-adhlns="$@.lst",这样,每编译一个源文件就会产生一个对应的 .lst 文件。需要注意的是,如果是高级语言文件(例如 C 语言),我们需要配置编译器的参数,不要以为仅仅配置汇编器 as 就行(在多数工具中编译器和汇编器是独立配置的)!
.map文件,Toolchain,linux,c++,toolchain,gcc,map
  注意:在 ECLIPSE 中,它把 objdump 输出文件名也定为了 .lstobjdump 实际是解析 ELF 文件的工具,与 LIST 文件本没啥关系。 在 ECLIPSE 中,通过如下配置就会默认启用命令 objdump --source --all-headers --demangle --line-numbers --wide "xxx.elf" > "xxx.lst" 来生成最终调试文件对应的 lst 文件,以此来辅助调试。
.map文件,Toolchain,linux,c++,toolchain,gcc,map

内容介绍

  在实际开发中,汇编器 as 产生的 LST 文件基本很少使用,使用最多的是使用 objdump 工具产生的最终调试程序对应的 LST 文件。这里我们主要就介绍 objdump 产生的 LST 文件。上面说过了, objdump 输出的实际是 ELF 文件内容,详细介绍见独立博文 Linux 之二十 详解 ELF 文件。

–source、–demangle、 --line-numbers、–wide

  就是将反汇编与 C 源码混合在一起显示出来。并且尽可能的翻译成人能看懂的代码(翻译符号名、对应行号)!

–all-headers

  该命令会输出 Program Header,Sections 以及 SYMBOL TABLE 这个三部分的内容。编译工具产生的最终可执行文件是符合 ELF 规范的二进制文件,这里的输出内容其实都是 ELF 文件的内容,关于 ELF 文件,可以参考 ARM 之一 ELF 文件、镜像(Image)文件、可执行文件、对象文件 详解。

  • Program Header:这个就是 ELF 文件的程序头
    .map文件,Toolchain,linux,c++,toolchain,gcc,map
  • Sections: 这个就是从 ELF 文件中的提取的节区信息,共由 8 列组成,每列的含义说明如下:
    .map文件,Toolchain,linux,c++,toolchain,gcc,map
    • 第一列(Idx):从 0 开始的索引号
    • 第二列(Name): 节的名字
    • 第三列(Size):节的大小(字节)
    • 第四列(VMA):Virtual Memory Address 的缩写,表示该节在运行时的地址
    • 第五列(LMA):Load Memory Address 的缩写,表示该节的加载地址
    • 第六列(File off):该节在文件中的偏移
    • 第七列(Algn):对齐字节数,只能是 2 的正整数次幂,由于纯文本没办法显示幂,这里使用 ** 表示!
    • 第八列(Flags):该节的属性标志
  • SYMBOL TABLE:这个就是从 ELF 文件中的提取的符号表,由 5 列组成,每列的含义说明如下:
    .map文件,Toolchain,linux,c++,toolchain,gcc,map
    • 第一列:符号的值,通常就是符号的物理地址
    • 第二列:这是一组符号标识,共由 7 个标识符组成,某些标识符可以是空格。
      • 第一个标识符:取值如下
        • l : Local Symbol
        • g: Global Symbol
        • u: Unique global Symbol
        • ! :其他情况
      • 第二个标识符:取值为 w 表示弱符号(Weak),否则为空格表示强符号(Strong)
      • 第三个标识符:取值为 C 表示构造函数(Constructor ),否则为空格表示普通符号
      • 第四个标识符:取值为 W 表示警告符号(Warning),否则为空格表示普通符号。警告符号的名称是一条消息,当警告符号后面的符号被引用时显示出来。
      • 第五个标识符:
        • I: 该符号是对另一个符号的间接引用
        • i: 在 reloc 处理期间计算的函数
        • :空格表示普通符号
      • 第六个标识符:
        • d: 调试符号
        • D: 动态符号
        • :空格表示普通符号
      • 第七个标识符:
        • F : 符号是函数的名称(Function )
        • f: 一个文件(file)
        • O: 一个对象(Object)
        • :空格表示普通符号
    • 第三列:符号对应的节区。如果该节是绝对的(即没有与任何节连接),则是 *ABS*,如果该节在被转储的文件中被引用,但在那里没有定义,则是 *UND*
    • 第四列:对于普通符号是对齐方式,对于其他符号则是大小
    • 第五列:符号名字

ARM

产生方式

  使用编译器 armcc 的参数 -asm 以及汇编器 armasm的参数 --list=file 来输出 lst 文件,两者分别针对 C 语言源文件和汇编源文件生效!
.map文件,Toolchain,linux,c++,toolchain,gcc,map

内容介绍

  暂无,后续有需要再补充!

IAR

产生方式

  使用编译器 iccarm 的参数 -l 以及使用汇编器 iasmarm 的参数 -L 来输出 lst 文件,两者分别针对 C 语言源文件和汇编源文件生效!
.map文件,Toolchain,linux,c++,toolchain,gcc,map

内容介绍

  暂无,后续有需要再补充!

参考

  1. https://dzone.com/articles/creating-disassembly-listings-with-gnu-tools-and-e
  2. https://interrupt.memfault.com/blog/get-the-most-out-of-the-linker-map-file
  3. https://sourceware.org/binutils/docs-2.40/binutils.html#index-objdump

到了这里,关于编译工具链 之四 .MAP 文件、.LST 文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MDK Keil查看map文件及编译占用内存信息、函数入口地址

    一、在哪里打开map文件查看 (1)第一种,在keil软件下,双击你的工程名,map就会弹出 (2)第二种,点击魔术棒,查看 Lis文件输出的位置入口 我的在output...文件下,那我们工程的文件夹下,找到output 二、查看map文件信息 (1)函数定义的位置信息 如图,这些你定义函数的

    2024年02月05日
    浏览(48)
  • 嵌入式科普(5)ARM GNU Toolchain相关概念和逻辑

    一、目的/概述 二、资料来源 三、逻辑和包含关系 四、Arm GNU Toolchain最常用的命令 嵌入式科普(5)ARM GNU Toolchain相关概念和逻辑 对比高集成度的IDE(MDK、IAR等),Linux开发需要自己写Makefile等多种脚本。eclipse、Visual Studio等需要了解预处理、编译、汇编、链接的过程,但无需自己完

    2024年02月03日
    浏览(43)
  • VSCode+CMake+Arm GNU Toolchain搭建GD32开发环境

    一个串口收发简单例子。 https://github.com/Huffer342-WSH/GD32_CMake_Example 可以下载该工程,稍微了解一点cmake就可以简单修改直接使用。 GD32 CMake example 使用到的工具 编译与烧录 命令行 VSCode 调试 配合VSCode的marus25.cortex-debug插件实现调试功能 RTT使用方法 marus25.cortex-debug 手动连接 注意

    2024年02月11日
    浏览(40)
  • Xcode升级到15.0 解决DT_TOOLCHAIN_DIR问题

    根据个人开发遇到的问题做的总结,公司要求Xcode 14.2 ,Swift 5.7开发,由于升级了Mac 14.0系统后,Xcode 14.2不能使用,解决方案目前有2个 一、在原来Xcode 14.2 的显示包内容,如图 二、升级到Xcode的15.0后,报一下错误         DT_TOOLCHAIN_DIR cannot be used to evaluate LIBRARY_SEARCH_PATHS, u

    2024年02月07日
    浏览(39)
  • DL环境安装之GCC9,Python9与IDE连接远程环境:python notebook,解释器,C toolchain

    系统自带的cc可能比较低4.8.5?,yum直接安装的gcc也比较低,有些较新的c/c++项目无法编译 其他 各种OS yum源配置下载参考这里 yum直接安装前置依赖,yum/rpm离线安装下载参考这里 gcc源码包下载,解压后进入解压目录进行编译安装,4核并行编译用了2小时左右,嫌慢可参考后面的

    2024年02月12日
    浏览(62)
  • 几个Flutter常见诊断错误与解决Android toolchain - develop for Android devices X Unable to locate Android SDK

    几个Flutter常见诊断错误与解决 jcLee95:https://blog.csdn.net/qq_28550263 https://blog.csdn.net/qq_28550263/article/details/132869987 问题描述 原因分析 这个错误表示找不到Android SDK。可能的原因是Android Studio没有安装或者安装路径没有正确配置。 解决办法 问题描述 原因与解决 这个错误信息表明

    2024年02月04日
    浏览(56)
  • 记LGSVL Map Annotation(1) LGSVL本地编译记录、安装

    主要的编译参考来着官方文件 安装unity hub 安装2020.3.3f1在unity hub上 但是我发现没有2020.3.3f1,只有2020.3.3f1c1,其实c1就是中国版,没有什么影响 安装GIT 安装Git LFS 验证git-lfs(输出Git LFS initialized就🆗了) 官方: 打开终端并导航到要将模拟器下载到的位置 如果你想模拟器在你的

    2024年02月09日
    浏览(33)
  • xml转map工具类

    背景:最近遇到接口返回是xml,所以需要整一个转换的工具类,方便后续其他xml处理。 依赖引入: 工具类代码如下: 总结:虽然可以直接取xml节点,但是为了方便自己跟方便他人,还是写了一个工具类出来,这样别人有需要也可以使用。

    2024年02月12日
    浏览(31)
  • Visual Studio(2022)生成链接过程的.map映射文件以及.map映射文件的内容说明

    /MAP(生成映射文件) | Microsoft Learn         1. 右键项目属性, 连接器 - 常规 - 启用增量链接,设置为否。如下图:         2. 连接器 - 调试                 生成调试信息  设置为  生成调试信息 (/DEBUG)                 生成程序数据库文件  设置为 指定路径文件名,

    2024年02月10日
    浏览(55)
  • 将Xml转为Map集合工具类

    2024年02月20日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包