map文件浅析

map文件浅析

map文件简介

内容

配置

概念

map文件内容详解

Section Cross References—模块、段(入口)交叉引用

Removing Unused input sections from the image—移除未调用模块

Image Symbol Table—映射符号表

Memory Map of the image—内存(映射)分布

Image component sizes—存储组成大小

map文件简介

内容

首先我们需要了解map文件是什么,map文件是通过编译器编译之后,集程序、数据及IO空间的一种映射文件;一般出现内存越界或溢出,又或者是代码优化的情况,首先想到的就是分析map文件,通过map文件可以知道函数大小,入口地址等一些重要信息,总共分为五大类

Section Cross References:模块、段(入口)交叉引用

Removing Unused input sections from the image:移除未调用模块

Image Symbol Table:映射符号表

Memory Map of the image:内存(映射)分布

Image component sizes:存储组成大小

配置

其次就是配置,由于笔者这里大多数是使用keil,所有就展示的keil的配置(虽然大概率就是已经配置好的);路径是先点击魔法棒,然后Listing选项卡中,最后在Linker Listing:map.map勾选即可

Memory Map:内存映射

Callgraph:图像映射

Symbols:符号

Cross Reference:交叉引用

Size Info:大小信息

Totals Info:统计信息

Unused Section Info:未调用模块信息

Veneers Info:装饰信息

最后的map文件可以在~\xxx\MDK-ARM\xxx中找到

概念

最后是关于map文件基本概念

段(section):描述映像文件的代码和数据块

RO:Read-Only的缩写,包括RO-data(只读数据)和RO-code(代码)

RW:Read-Write的缩写,主要是RW-data,RW-data由程序初始化初始值

ZI:Zero-initialized的缩写,主要是ZI-data,由编译器初始化为0

.text:与RO-code同义

.constdata:与RO-data同义

.bss:与ZI-data同义

.data:与RW-data同义

map文件内容详解

Section Cross References—模块、段(入口)交叉引用

当我们打开map文件的时候,第一大块就是Section Cross References,主要内容是是各个源文件生成的模块、段(定义的入口)之间相互引用的关系

例如: main.o(i.SystemClock_Config) refers to stm32f1xx_hal_rcc.o(i.HAL_RCC_OscConfig) for HAL_RCC_OscConfig,意思是main模块中SystemClock_Config引用了 stm32f1xx_hal_rcc模块中HAL_RCC_OscConfig函数

需要注意的是,在map文件中i指的是独立函数,是一种编译器优化编译的一种方式,可以精确地控制每个函数的位置,或者删除没用的函数,通俗来讲也就是可以在map文件看到更多信息以及更精准的定位

Removing Unused input sections from the image—移除未调用模块

在代码中没有被调用的模块会在map文件生成列表,最后会在这部分显现出来

例如:Removing stm32f1xx_hal_rcc_ex.o(i.HAL_RCCEx_GetPeriphCLKConfig), (44 bytes).,意思是删除了stm32f1xx_hal_rcc_ex模块的HAL_RCCEx_GetPeriphCLKConfig函数,大小是44字节

除此以外,最后会有一个汇总,删除了180个模块,共计7710字节

Image Symbol Table—映射符号表

这部分分为两块,一块是Local Symbols,主要静态函数,变量以及常量;另外一块是Global Symbols,主要是外部函数和全局变量

Symbol Name:符号的名称以及路径

Value:地址

Type:符号的类型,常见的大概是四种

Number

Section

Thumb Code

Data

Size:大小,单位是字节

Object(Section):表示符号所在的目标文件及其对应的段

我们从这部分可以看出一些函数或变量的地址

Memory Map of the image—内存(映射)分布

在执行映像之前,必须将已初始化的RW数据从ROM中复制到RAM中的执行地址并创建ZI Section(初始化为0的变量区)

这里引用rtthread文档中的内存分布图

STM32 在上电启动之后默认从 Flash 启动,启动之后会将 RW 段中的 RW-data(初始化的全局变量)搬运到 RAM 中,但不会搬运 RO 段,即 CPU 的执行代码从 Flash 中读取,另外根据编译器给出的 ZI 地址和大小分配出 ZI 段,并将这块 RAM 区域清零

Exec Addr:执行地址,即当程序运行时,该段在内存中将被加载到的地址

Load Addr:加载地址,即当程序从存储器(如 Flash)加载到内存时,该段最初加载到的地址,由上图可以知道,启动之后RO是不会变的,但RW是会移动到RAM里面,所以在RO中Exec Addr和Load Addr是一致的,但RW会不一样且Load Addr比Exec Addr大

Size:段的大小,以字节为单位

Type:段的类型

Code:表示可执行代码

Data:表示数据段,包括已初始化的全局变量等

RO Data:只读数据,如常量、字符串字面值等

Attr:段的属性,在RO中Attr都是RO,在RW中Attr都是RW

Idx:索引号,表示该段在符号表中的索引位置,通常用于区分符号表中的不同段

E Section Name:段的名称

Object:目标文件

Image component sizes—存储组成大小

Code (inc. data):代码部分(即可执行指令)及其包含的任何初始化数据的总大小,包括.text段和任何被标记为只读的初始化数据(如.rodata段)

RO Data:只读数据的总大小。这部分通常包括常量字符串、枚举、常量数组等,存储在.rodata段中

RW Data:可读可写数据的总大小。这部分包含已初始化的全局变量和静态变量,存储在.data段中

ZI Data:零初始化数据的总大小。这部分通常包含未初始化的全局变量和静态变量,存储在.bss段中

Debug:表示与调试相关的数据占用空间,包括调试符号、调试信息

Object Name:目标文件的名称

RAM=RW=1.62KB

ROM=ROM = 2.44KB

相关推荐

小红书怎样加别人V才不会被禁言
线上365bet正网

小红书怎样加别人V才不会被禁言

07-06 👁️‍🗨️ 6574
完美世界 完美游戏 完美点卷充值
365彩票app下载苹果版

完美世界 完美游戏 完美点卷充值

09-30 👁️‍🗨️ 6177
【科普知识】支原体肺炎为什么难治?家庭护理注意什么?
在京东上批发进货的步骤是什么?如何高效完成采购流程?
岁末装备盘点分析 553防具荣耀命运歧路
线上365bet正网

岁末装备盘点分析 553防具荣耀命运歧路

09-20 👁️‍🗨️ 1408
华为手机盲人模式怎么解除
365彩票app下载苹果版

华为手机盲人模式怎么解除

11-15 👁️‍🗨️ 4531
DEA入门必备软件推荐--DEARUN
bt365注册

DEA入门必备软件推荐--DEARUN

09-18 👁️‍🗨️ 9183
战狼2票房56亿吴京赚多少 吴京和卢靖姗的片酬分别是多少
免費泰文到英文翻譯器
线上365bet正网

免費泰文到英文翻譯器

07-15 👁️‍🗨️ 9053