VS生成map文件

1.如何设置生成map文件

打开项目属性-》链接器-》调试--》生成映射文件: 选择 是(/map)

链接阶段生成的map文件

命令行参数是/map

map就是一个映射文件,猜测是映射符号和地址之间的关系。因为真正的执行阶段不需要符号的信息,只需要地址。而exe里面应该就是都是地址,不知道是具体的符号。而pdb正好是符号信息。

2.map文件内容

map文件的类型就是 Linker Address Map

pdb和map文件均为调试用

pdb记录数据和调试信息(https://docs.microsoft.com/zh-cn/cpp/build/reference/debug-generate-debug-info?view=msvc-160

map记录地址、长度等信息(https://docs.microsoft.com/zh-cn/cpp/build/reference/map-generate-mapfile?view=msvc-160

网上介绍map文件内容的资料比较少,下面是搜到的参考的资料

https://blogs.msdn.microsoft.com/hopperx/2006/09/14/using-map-files-part-1/

map文件是一个text文件,文本文件,所以可以打开文本编辑器查看。

1.首部信息

第一行 模块名字(不修改就是文件名啦)

第二行  link.exe 链接模块的时间戳(from the program file header ,not the file system)

第三行 首选的加载地址(可简记为 PLA ) Preferred load address,只是首选而已,不一定是真正的加载到这个地址。一般exe的首选地址都是00400000。一般exe就是这个地址,但是dll就不一定了,因为dll有很多,不可能都加载到这个地址上,如果这个地址已经被用了,就用进行地址rebase

2.段(section)信息——information about the sections in this module

这里说的段是section 而不是segment,segment会把权限相同的section给合并了的。具体见之前的文章。

a list of groups in the program.

Start 使用的是 段地址形式 = 段号 : 段内偏移

Length 自然就是这个section的长度。

Name 段的名字 (group name)

Class 段的类型(数据段 代码段)

1.sections的介绍:

参考:https://docs.microsoft.com/zh-cn/windows/desktop/Debug/pe-format#section-data

Section Name

Content

Characteristics

.text 

只读

Executable code (free format)

IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IIMAGE_SCN_MEM_READ 

.bss 

读写

Uninitialized data (free format) 

IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE 

.data 

读写

Initialized data (free format) 

IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE 

.rdata 

Read-only initialized data 

IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ

.edata 

Export tables 

IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ 

.idata 

Import tables 

IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE 

.xdata 

Exception information (free format) 

IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ







1   .text 代码段是存放了程序代码的数据,假如机器 中有数个进程运行相同的一个程序,那么它们就可以使用同一个代码段。

2   .bss 和 .data 挨在一起,都是放在一个段里的,0004段。

bss段由于都是到时候初始化为0,所以不需要包含字节数据 better save space

全局变量 如果初始化了就放在data区,如果没有初始化就放在bss区 

.bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);

而.data却需要占用,其内容由程序初始化。

(const全局变量和static全局变量不知道放在哪里,找不到。)

3   .rdata Read-only initialized data:只读的初始化的数据:比如const数据

  .edata Export tables : 其他映像文件可以访问的符号,通常在dll中会有导出符号

5   .idata Import tables

2.内存分布

图来自 https://blog.csdn.net/u014470361/article/details/79297601

对应上述map中的段区。 低地址开始 只读,读写,运行时分配

0002 应该是代码区,只读

0003 应该是常量区,只读

0004 应该是静态区

堆区和栈区 在程序运行起来以后才会有,所以map中没有对应的。

3.函数信息——actual symbolic information

the entry point.

前面的 Address 是分段地址,0000,0001,0002、、、表示段号,后面的表示段内的偏移 。

可以推算出:

0001 段的起始地址是 0x00001000

0002 段的起始地址是 0x00011000

截取一行分析:

Rva+Base = 00411690

因为base是Referred Load Address,Base = 00400000

所以Rva = 00011690 RVA是 Relative Virtual Address 称为相对虚拟地址, 是基于Base来说

也就是相对于基地址的偏移是00011690

也就是等于前面的Address

0002:00000690 = 00011690 (0002段起始地址从 00011000开始 + 690 = 11690)

1.后面有代表的是 function 函数信息。

2.后面的main.obj 说明这个函数来着 main.obj (main.obj  main.cpp-->main.obj ),说明前面两个函数所在的源文件应该是main.c 或者 main.cpp

解析符号名:

打开vs的控制台窗口。输入:

undname 符号名

https://stackoverflow.com/questions/13777681/demangling-in-msvc

4.静态符号

猜你喜欢

转载自blog.csdn.net/u013015629/article/details/110507771