MAP 文件和 List 文件的解讀(一個例子)

Keil 在生成程序的時候显晶,可以生成兩個輔助文件非常有幫助道伟,他們分別是 map 文件和 list 文件敲董。
訪問Options for Target -> Listing 勾選對應(yīng)選項即可打開碳竟。
這兩個文件我僅能大概讀懂顽染,下面介紹一下如何根據(jù)PC和LR寄存器中的地址數(shù)據(jù)漾岳,通過map文件找到該指令所在的函數(shù),并根據(jù)list文件找到出錯的代碼行號粉寞。拋磚引玉尼荆,歡迎大牛拍磚:
map文件是連接器生成的二進制文件的信息,其中描述了各符號的交叉引用唧垦、函數(shù)和數(shù)據(jù)排布的順序和大小等各種有用信息捅儒。要根據(jù)指令地址查找函數(shù)主要關(guān)注map文件中的Image Symbol Table這一部分內(nèi)容。

Symbol Name Value Ov Type Size Object(Section)
main 0x00006245 Thumb Code 106 main.o(.text)
OnPowerOff 0x000062af Thumb Code 8 main.o(.text)
FAULT_PrintFaultRegs 0x000062dd Thumb Code 464 fault.o(.text)
FAULT_PrintGeneralRegs 0x000064ad Thumb Code 194 fault.o(.text)

隨意取出其中的一部分振亮,對于每行共有5列數(shù)據(jù)巧还,每行代表一個符號(函數(shù)和全局變量)的數(shù)據(jù)。分別是:“符號名坊秸,符號地址麸祷,類型,長度妇斤,所在的.o文件”摇锋。我們主要關(guān)注“符號名丹拯,符號地址和長度”這部分內(nèi)容。
根據(jù)地址查找函數(shù)名荸恕,就是檢索MAP文件的“Image Symbol Table”部分乖酬,查找到函數(shù)地址和所查詢地址最接近,且函數(shù)地址比所查詢地址小的函數(shù)融求。并根據(jù)函數(shù)的長度確認(rèn)是否在函數(shù)的范圍內(nèi)咬像。

舉一個真實的例子:
比如說在發(fā)生Hardfault錯誤時,使用上述Hardfault Handler示例代碼打印出的錯誤信息如下:

Exceptions:
r0 : 0x4006a000
r1 : 0x0000000a
r2 : 0x00000002
r3 : 0x00000003
r4 : 0x0001f420
r5 : 0x0001f420
r6 : 0x00000000
r7 : 0x00000000
r8 : 0x00000000
r9 : 0x00000000
r10 : 0x00000000
r11 : 0x00000000
r12 : 0x40048000
lr : 0x00010681
pc : 0x00010642
xpsr: 0x01000000
current xpsr: 0x00000003
current lr : 0xffffffe9
primask : 0x00000000
basepri : 0x00000000
faultmask: 0x00000000
control : 0x00000000
MMFSR : 0x00000000[]
BFSR : 0x00000400[IMPRECISERR|]
UFSR : 0x00000000[]
HFSR : 0x40000000[FORCED|]
DFSR : 0x00000008
MMFAR : 0xe000ed34
BFAR : 0xe000ed38

錯誤類型為“非精確的數(shù)據(jù)訪問違例”生宛。處理器自動壓入堆棧的PC寄存器的數(shù)據(jù)為0x00010642县昂,在map文件中查找字符串“0x000106”(故意抹去末尾數(shù)據(jù)),找到的兩個匹配數(shù)據(jù)陷舅,但是這里兩個地址都比出現(xiàn)錯誤的地址0x00010642大倒彰,錯誤并非發(fā)生在這兩個函數(shù)中。

FS_Lock 0x000104ef Thumb Code 24 fs.o(.text)
FS_Unlock 0x00010507 Thumb Code 10 fs.o(.text)
UART7816_Init 0x00010673 Thumb Code 16 uart7816.o(.text)
UART7816_SetBaudRate 0x00010683 Thumb Code 228 uart7816.o(.text)
UART7816_StartClock 0x00010767 Thumb Code 18 uart7816.o(.text)
UART7816_StopClock 0x00010779 Thumb Code 28 uart7816.o(.text)

接著擴大范圍繼續(xù)循環(huán)莱睁,搜索“0x000105”待讳,結(jié)果如下(僅關(guān)注Image Symbol Table部分):

.text 0x00010530 Section 0 uart7816.o(.text)
_timerInit 0x00010531 Thumb Code 58 uart7816.o(.text)
_gpioInit 0x0001056b Thumb Code 118 uart7816.o(.text)
_uartInit 0x000105e1 Thumb Code 146 uart7816.o(.text)

FS_Unlock 0x00010507 Thumb Code 10 fs.o(.text)

其中和0x00010642最為接近且小于0x00010642的為函數(shù)_uartInit,且函數(shù)地址0x000105e1+146大于0x00010642,仰剿,所以確認(rèn)發(fā)生錯誤的指令在函數(shù)_uartInit中创淡。
下面輪到List文件出場了,List文件實際上是編譯器生成的C代碼和匯編的對照表南吮,其中_uartInit的部分內(nèi)容如下:

_uartInit PROC
;;;110 static void _uartInit(void)
0000b0 48d2 LDR r0,|L1.1020|
;;;111 {
    ;;;112
    ;;;113 SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
    0000b2 6b40 LDR r0,[r0,#0x34]
    0000b4 f4406080 ORR r0,r0,#0x400
    0000b8 49d0 LDR r1,|L1.1020|
    0000ba 6348 STR r0,[r1,#0x34]
    ;;;114
    ;;;115 UART0_C2 &= (uint8_t)~(uint8_t)((UART_C2_TE_MASK | UART_C2_RE_MASK));
    0000bc 48d1 LDR r0,|L1.1028|
    0000be 78c0 LDRB r0,[r0,#3]
    0000c0 f00000f3 AND r0,r0,#0xf3
    0000c4 49cf LDR r1,|L1.1028|
    0000c6 70c8 STRB r0,[r1,#3]
    ;;;116
    ;;;117 UART0_BDH = UART_BDH_SBR(0x02);
    0000c8 2002 MOVS r0,#2
    0000ca 7008 STRB r0,[r1,#0]
    ;;;118
    ;;;119 UART0_BDL = UART_BDL_SBR(0xE8);
    0000cc 20e8 MOVS r0,#0xe8
    0000ce 7048 STRB r0,[r1,#1]
    ;;;120
    ;;;121 UART0_MA1 = UART_MA1_MA(0x00);
    0000d0 2000 MOVS r0,#0
    0000d2 7208 STRB r0,[r1,#8]
    ;;;122
    ;;;123 UART0_MA2 = UART_MA2_MA(0x00);
    0000d4 7248 STRB r0,[r1,#9]
    ;;;124
    ;;;125 UART0_C4 = UART_C4_BRFA(0x00);
    0000d6 7288 STRB r0,[r1,#0xa]
    ;;;126
    ;;;127 UART0_C1 = (UART_C1_M_MASK | UART_C1_PE_MASK);
    0000d8 2012 MOVS r0,#0x12
    0000da 7088 STRB r0,[r1,#2]
    ;;;128
    ;;;129 UART0_S2 = (UART_S2_LBKDIF_MASK | UART_S2_RXEDGIF_MASK);
    0000dc 20c0 MOVS r0,#0xc0
    0000de 7148 STRB r0,[r1,#5]
    ;;;130
    ;;;131 UART0_MODEM = 0x00U;
    0000e0 2000 MOVS r0,#0
    0000e2 7348 STRB r0,[r1,#0xd]
    ;;;132
    ;;;133 UART0_IR = UART_IR_TNP(0x00);
    0000e4 7388 STRB r0,[r1,#0xe]
    ;;;134
    ;;;135 UART0_TWFIFO = UART_TWFIFO_TXWATER(0x00);
    0000e6 74c8 STRB r0,[r1,#0x13]
    ;;;136
    ;;;137 UART0_RWFIFO = UART_RWFIFO_RXWATER(0x01);
    0000e8 2001 MOVS r0,#1
    0000ea 7548 STRB r0,[r1,#0x15]
    ;;;138
    ;;;139 UART0_SFIFO = UART_SFIFO_TXEMPT_MASK |
    0000ec 20c7 MOVS r0,#0xc7
    0000ee 7488 STRB r0,[r1,#0x12]
    ;;;140 UART_SFIFO_RXEMPT_MASK |
    ;;;141 UART_SFIFO_RXOF_MASK |
    ;;;142 UART_SFIFO_TXOF_MASK |
    ;;;143 UART_SFIFO_RXUF_MASK;
    ;;;144
    ;;;145 UART0_CFIFO = (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK);
    0000f0 20c0 MOVS r0,#0xc0
    0000f2 7448 STRB r0,[r1,#0x11]
    ;;;146
    ;;;147 UART0_PFIFO &= (uint8_t)~(uint8_t)(
        0000f4 4608 MOV r0,r1
        0000f6 7c00 LDRB r0,[r0,#0x10]
        0000f8 f0000077 AND r0,r0,#0x77
        0000fc 7408 STRB r0,[r1,#0x10]
        ;;;148 UART_PFIFO_TXFE_MASK |
        ;;;149 UART_PFIFO_RXFE_MASK
        ;;;150 );
    ;;;151
    ;;;152 UART0_WN7816 = UART_WN7816_GTN(0x00);
    0000fe 2000 MOVS r0,#0
    000100 7708 STRB r0,[r1,#0x1c]
    ;;;153
    ;;;154 UART0_WF7816 = UART_WF7816_GTFD(0x01);
    000102 2001 MOVS r0,#1
    000104 7748 STRB r0,[r1,#0x1d]
    ;;;155
    ;;;156 UART0_WP7816A_T0 = UART_WP7816A_T0_WI_H(0x00);
    000106 2000 MOVS r0,#0
    000108 49be LDR r1,|L1.1028|
    00010a 313c ADDS r1,r1,#0x3c
    00010c 7008 STRB r0,[r1,#0]
    ;;;157 UART0_WP7816B_T0 = UART_WP7816B_T0_WI_L(0x0A);
    00010e 210a MOVS r1,#0xa
    000110 48bc LDR r0,|L1.1028|
    000112 f880103d STRB r1,[r0,#0x3d]
;;;158 //UART0_WP7816 = UART_WP7816_WTX(0x0A);
;;;159
;;;160 UART0_ET7816 = (UART_ET7816_TXTHRESHOLD(0x00) | UART_ET7816_RXTHRESHOLD(0x00));
000116 2000 MOVS r0,#0
000118 49ba LDR r1,|L1.1028|
00011a 7788 STRB r0,[r1,#0x1e]
;;;161
;;;162 UART0_IS7816 = UART_IS7816_WT_MASK |
00011c 20f7 MOVS r0,#0xf7
00011e 7688 STRB r0,[r1,#0x1a]
;;;163 UART_IS7816_CWT_MASK |
;;;164 UART_IS7816_BWT_MASK |
;;;165 UART_IS7816_INITD_MASK |
;;;166 UART_IS7816_GTV_MASK |
;;;167 UART_IS7816_TXT_MASK |
;;;168 UART_IS7816_RXT_MASK;
;;;169
;;;170 UART0_IE7816 = 0x00U;
000120 2000 MOVS r0,#0
000122 7648 STRB r0,[r1,#0x19]
;;;171
;;;172 UART0_C7816 = (UART_C7816_INIT_MASK | UART_C7816_ISO_7816E_MASK);
000124 2005 MOVS r0,#5
000126 7608 STRB r0,[r1,#0x18]
;;;173 (void) UART0_S1;
000128 4608 MOV r0,r1
00012a 7900 LDRB r0,[r0,#4]
;;;174 (void) UART0_D;
00012c 4608 MOV r0,r1
00012e 79c0 LDRB r0,[r0,#7]
;;;175
;;;176 UART0_C5 &= (uint8_t)~(uint8_t)(
    000130 4608 MOV r0,r1
    000132 7ac0 LDRB r0,[r0,#0xb]
    000134 f0000010 AND r0,r0,#0x10
    000138 72c8 STRB r0,[r1,#0xb]
    ;;;177 UART_C5_TDMAS_MASK |
    ;;;178 UART_C5_RDMAS_MASK |
    ;;;179 0x4FU
    ;;;180 );
;;;181
;;;182 UART0_C3 = 0x00U;
00013a 2000 MOVS r0,#0
00013c 7188 STRB r0,[r1,#6]
;;;183
;;;184 UART0_C2 = 0x00U;
00013e 70c8 STRB r0,[r1,#3]
;;;185
;;;186 return;
;;;187 }
000140 4770 BX lr
;;;188
ENDP

出錯的地址是0x00010642琳彩,相對于函數(shù)起始地址0x000105e1的偏移為0x61,根據(jù)List文件中的內(nèi)容部凑,_UartInit中第一條指令在文件中的偏移是0xb0露乏,因此出錯代碼的偏移應(yīng)該是0x61+0xb0 = 0x111。因此可以定位出發(fā)生錯誤的語句在uart7816.c中的157行砚尽。
找到產(chǎn)生錯誤的語句后施无,在有針對性的查找CPU手冊中串口寄存器WP7816B的部分辉词,發(fā)現(xiàn)用錯了頭文件必孤,的確是訪問了非法的內(nèi)存區(qū)域。至此瑞躺,問題解決敷搪。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市幢哨,隨后出現(xiàn)的幾起案子赡勘,更是在濱河造成了極大的恐慌,老刑警劉巖捞镰,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闸与,死亡現(xiàn)場離奇詭異毙替,居然都是意外死亡,警方通過查閱死者的電腦和手機践樱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門厂画,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拷邢,你說我怎么就攤上這事袱院。” “怎么了瞭稼?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵忽洛,是天一觀的道長。 經(jīng)常有香客問我环肘,道長欲虚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任悔雹,我火速辦了婚禮苍在,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘荠商。我一直安慰自己寂恬,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布莱没。 她就那樣靜靜地躺著初肉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪饰躲。 梳的紋絲不亂的頭發(fā)上牙咏,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音嘹裂,去河邊找鬼妄壶。 笑死,一個胖子當(dāng)著我的面吹牛寄狼,可吹牛的內(nèi)容都是我干的丁寄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼泊愧,長吁一口氣:“原來是場噩夢啊……” “哼伊磺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起删咱,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤屑埋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后痰滋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摘能,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡续崖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了团搞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袜刷。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖莺丑,靈堂內(nèi)的尸體忽然破棺而出著蟹,到底是詐尸還是另有隱情,我是刑警寧澤梢莽,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布萧豆,位于F島的核電站,受9級特大地震影響昏名,放射性物質(zhì)發(fā)生泄漏涮雷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一轻局、第九天 我趴在偏房一處隱蔽的房頂上張望洪鸭。 院中可真熱鬧,春花似錦仑扑、人聲如沸览爵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜓竹。三九已至,卻和暖如春储藐,著一層夾襖步出監(jiān)牢的瞬間俱济,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工钙勃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛛碌,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓辖源,卻偏偏與公主長得像蔚携,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子同木,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355