编译工具链 之四 ARM-MDK、IAR、GCC 的 .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 文件),然后使用相应的工具从中提取出实际的纯可执行程序。
在这里插入图片描述
  能独立提供编译工具链的厂家并不多,嵌入式平台则更少,主要就是 ARM、IAR、GNU、LLVM。其中,ARM、IAR 是收费的专用软件,其支持的架构有限,而 GNU 的 GCC 则是一款支持众多架构的开源编译套件;LLVM 则是后起之秀,同样也支持众多架构,目前用的不如 GCC 广泛!如下是常用编译器:
在这里插入图片描述

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

.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 文件。
在这里插入图片描述
  需要注意的是,如果使用了编译器 gcc 作为入口(通常都是这么做,不会直接调用链接器),则需要使用 -Wl,-Map,FILE 的方式来将参数传递给链接器。编译器参数 -Wl 是专门用来传递参数给链接器的。同样,如果使用了 -Xlinker --print-map 则只会将 MAP 信息输出到编译窗口,而不会再生成 MAP 文件!
在这里插入图片描述
  在实际开发中,ECLIPSE 的相关配置如下所示。目前没有该明白,为何它要以 g++ 作为链接器的入口!
在这里插入图片描述

内容介绍

  在理解内容之前,有必要先了解一下工具链提供的存档文件(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 文件的第二部分内容列出了链接器在生成最终可执行文件时丢弃的输入段,每行一个,四列的含义从左到右依次为节区名、地址、节区大小、节区所在的编译单元。注意,如果节区位于存档文件中,则最后一列是存档文件 + (编译单元)。
在这里插入图片描述

内存配置

  MAP 文件的第三部分内容列出了我们的内存(存储)配置情况,每行一个,四列的含义从左到右依次为存储的名字、起始地址、大小(字节)、属性(r:读、x:执行、w:写)
在这里插入图片描述

链接脚本和内存映射

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

ARM

产生方式

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

内容介绍

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

IAR

产生方式

  由链接器参数 --map 来产生。当启用 MAP 文件后,链接器支持的其他一些参数的输出就会输出到 MAP 文件中。
暂无

内容介绍

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

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

内容介绍

  在实际开发中,汇编器 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 文件的程序头
    在这里插入图片描述
  • Sections: 这个就是从 ELF 文件中的提取的节区信息,共由 8 列组成,每列的含义说明如下:
    在这里插入图片描述
    • 第一列(Idx):从 0 开始的索引号
    • 第二列(Name): 节的名字
    • 第三列(Size):节的大小(字节)
    • 第四列(VMA):Virtual Memory Address 的缩写,表示该节在运行时的地址
    • 第五列(LMA):Load Memory Address 的缩写,表示该节的加载地址
    • 第六列(File off):该节在文件中的偏移
    • 第七列(Algn):对齐字节数,只能是 2 的正整数次幂,由于纯文本没办法显示幂,这里使用 ** 表示!
    • 第八列(Flags):该节的属性标志
  • SYMBOL TABLE:这个就是从 ELF 文件中的提取的符号表,由 5 列组成,每列的含义说明如下:
    在这里插入图片描述
    • 第一列:符号的值,通常就是符号的物理地址
    • 第二列:这是一组符号标识,共由 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 语言源文件和汇编源文件生效!
在这里插入图片描述

内容介绍

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

IAR

产生方式

  使用编译器 iccarm 的参数 -l 以及使用汇编器 iasmarm 的参数 -L 来输出 lst 文件,两者分别针对 C 语言源文件和汇编源文件生效!
在这里插入图片描述

内容介绍

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

参考

  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
  • 16
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: monoframework-mdk-6.12.0.182.macos10.xamarin.universal.pkg是一个软件包文件名。这个软件包是用于在macOS环境下安装Xamarin开发框架的。Xamarin是跨平台移动应用开发工具,允许开发人员使用C#编写应用程序并在iOS,Android和Windows Phone上运行。 MDK代表Mono Development Kit,是一个允许开发人员在多个平台上创建和运行基于.NET的应用程序和服务的软件包。6.12.0.182指的是这个软件包的版本号,其中包含针对Mono和Xamarin的修复和改进。 这个软件包运行在macOS 10操作系统上,在安装后可以使用Visual Studio for Mac或Xamarin Studio进行开发。这个软件包的目的是简化开发和调试Xamarin应用程序的过程,同时提供完整的.NET开发环境。此外,这个软件包还包含基本的Mono运行时和常用的基础库。 总之,monoframework-mdk-6.12.0.182.macos10.xamarin.universal.pkg是Xamarin平台的一个重要组成部分,允许开发人员在macOS上使用C#开发应用程序并在多个平台上运行。 ### 回答2: monoframework-mdk-6.12.0.182.macos10.xamarin.universal.pkg是一个用于Mac操作系统的安装包,主要包含Mono Framework,一个跨平台的开源框架,可以在不同的操作系统中运行C#和其他.NET语言的应用程序。Mono Framework提供了类似于Microsoft .NET Framework的运行时环境,可以编译和运行.NET应用程序,但是它还支持一些其他的功能,比如跨平台开发、组件的模块化等。这个安装包是一个全面的Mono开发环境,包括Mono Runtime、.NET编译器、调试器和其他工具,可以支持开发和调试各种类型的应用程序。此外,它还包括了Xamarin Universal安装包,可以让开发者使用Xamarin开发iOS、Android和Mac平台的应用程序。总之,monoframework-mdk-6.12.0.182.macos10.xamarin.universal.pkg是一个完整的开发环境,支持多种开发语言、跨平台开发和多项开发工具,是Mac操作系统下开发.NET应用程序的重要工具。 ### 回答3: monoframework-mdk-6.12.0.182.macos10.xamarin.universal.pkg是一个用于macOS系统的软件包。它是Mono框架的一个版本,Mono是一个开源的跨平台的.NET运行时环境,支持C#和Visual Basic等编程语言。该软件包包含Mono运行时和相关工具,可用于在macOS系统上开发和运行.NET应用程序。其中,6.12.0.182是该软件包的版本号,表示其在一系列更改和更新后发布的最新版本。macos10表示此软件包支持的最低macOS版本为10.0。xamarin.universal则意味着该软件包支持Xamarin开发平台,它是一款用于创建本地iOS、Android和macOS应用程序的跨平台开发工具。总之,如果你想在你的macOS系统上进行NET开发,那么该软件包就是你需要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZC·Shou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值