我的Xtensa LX106 CPU(ESP8266)的gcc(5.2.0)有一个问题,当* .map文件中存在某些符号名称时,它们似乎忽略了可执行文件(ELF)中的某些符号名称,我试图理解原因。 / p>
这是* .map文件的一部分
*fill* 0x4021487b 0x0
*fill* 0x4021487b 0x0
*fill* 0x4021487b 0x1
.text.inc_byte_array
0x4021487c 0x1d W:\sensor_ovi\sw\sensor\app\esp8266\lib300\libwpa.a(common.o)
0x4021487c inc_byte_array
*fill* 0x40214899 0x3
.text.hex2num 0x4021489c 0x33 W:\sensor_ovi\sw\sensor\app\esp8266\lib300\libwpa.a(common.o)
*fill* 0x402148cf 0x0
*fill* 0x402148cf 0x0
*fill* 0x402148cf 0x0
*fill* 0x402148cf 0x1
.text.os_get_time
0x402148d0 0x4 W:\sensor_ovi\sw\sensor\app\esp8266\lib300\libwpa.a(os_xtensa.o)
0x402148d0 os_get_time
*fill* 0x402148d4 0x0
*fill* 0x402148d4 0x0
*fill* 0x402148d4 0x0
如您所见,inc_byte_array()与hex2num()并没有什么区别,因为两个函数都被使用了,所以它们被链接了。
但是objdump找不到符号hex2num(),它完全丢失了。 结果,转储的组装是错误的:
4021487c <inc_byte_array>:
inc_byte_array():
4021487c: 530b addi.n a5, a3, -1
4021487e: 1513a6 blti a3, 1, 40214897 <inc_byte_array+0x1b>
40214881: 352a add.n a3, a5, a2
40214883: 220b addi.n a2, a2, -1
40214885: 000342 l8ui a4, a3, 0
40214888: 441b addi.n a4, a4, 1
4021488a: 744040 extui a4, a4, 0, 8
4021488d: 004342 s8i a4, a3, 0
40214890: 34cc bnez.n a4, 40214897 <inc_byte_array+0x1b>
40214892: 330b addi.n a3, a3, -1
40214894: ed9327 bne a3, a2, 40214885 <inc_byte_array+0x9>
40214897: f00d ret.n
//在这里停止inc_byte_array()
40214899: 000000 ill
//这是链接器填充 fill 0x40214899 0x3
//,并从此处开始hex2num(),但ELF缺少符号:(
4021489c: f32c movi.n a3, 47
4021489e: 09b327 bgeu a3, a2, 402148ab <inc_byte_array+0x2f>
402148a1: 943c movi.n a4, 57
402148a3: 043427 bltu a4, a2, 402148ab <inc_byte_array+0x2f>
402148a6: d0c222 addi a2, a2, -48
402148a9: f00d ret.n
402148ab: 60a052 movi a5, 96
402148ae: 0ab527 bgeu a5, a2, 402148bc <inc_byte_array+0x40>
402148b1: 66a062 movi a6, 102
402148b4: 043627 bltu a6, a2, 402148bc <inc_byte_array+0x40>
402148b7: a9c222 addi a2, a2, -87
402148ba: f00d ret.n
402148bc: 074c movi.n a7, 64
402148be: 09b727 bgeu a7, a2, 402148cb <inc_byte_array+0x4f>
402148c1: 684c movi.n a8, 70
402148c3: 043827 bltu a8, a2, 402148cb <inc_byte_array+0x4f>
402148c6: c9c222 addi a2, a2, -55
402148c9: f00d ret.n
402148cb: f27c movi.n a2, -1
402148cd: f00d ret.n
402148cf: 020c00 andb b0, b12, b0
现在这是一个简单的示例,直接调用hex2num()即可。 但是在某些情况下,ASM转储是完全错误的,因为因为缺少符号,所以objdump只会使函数之前转储的文字混乱 (Xtensa LX106与Cortex M0相似)
此外,例如* .map在某些情况下也是错误的
libwpa.a :(。literal。 .text。*) .text.hostapd_derive_psk 0x40210000 0x56 W:\ sensor_ovi \ sw \ sensor \ app \ esp8266 \ lib300 \ libwpa.a(ap_config.o) 填充 0x40210056 0x2 .text.hostapd_setup_wpa_psk 0x40210058 0x31 W:\ sensor_ovi \ sw \ sensor \ app \ esp8266 \ lib300 \ libwpa.a(ap_config.o) 0x35(放松之前的大小) 0x40210058 hostapd_setup_wpa_psk
所以我们应该在40210000处找到hostapd_derive_psk(),大小为0x56,然后填充2个字节,然后在0x40210058处找到hostapd_setup_wpa_psk()
这是objdump转储的内容:
40210000 <hostapd_setup_wpa_psk-0x58>:
//完全缺少符号hostapd_derive_psk() 40210000:241630 extui a1,a3、6、3 40210003:DF6540切除 40210006:2ac840100e583ffe {排除; extui a0,a0,0,2;添加a12,a10,a8} 4021000e:b44000 extui a4,a0、0、12 40210011:0018 l32i.n a1,a0,0 40210013:FB3140切除 40210016:ff .byte 0xff 40210017:22a142 movi a4,0x122 4021001a:f0c112 addi a1,a1,-16 4021001d:11c9 s32i.n a12,a1,4 4021001f:0109 s32i.n a0,a1,0 40210021:02cd mov.n a12,a2 40210023:023c movi.n a2,48 40210025:fff801 l32r a0,40210008 <_irom0_text_start + 0x8> 40210028:0000c0电话x0 a0 4021002b:ac29 s32i.n a2,a12,40 4021002d:32cc bnez.n a2,40210034 <_irom0_text_start + 0x34> 4021002f:f27c movi.n a2,-1 40210031:000606 j 4021004d <_irom0_text_start + 0x4d> 40210034:bc28 l32i.n a2,a12、44 40210036:fff501 l32r a0、4021000c <_irom0_text_start + 0xc> 40210039:0000c0电话x0 a0 4021003c:fff231 l32r a3,40210004 <_irom0_text_start + 0x4> 4021003f:ac28 l32i.n a2,a12、40 40210041:042c电影a4、32 40210043:228b addn.n a2,a2,8 40210045:fff201 l32r a0、40210010 <_irom0_text_start + 0x10> 40210048:0000c0电话x0 a0 4021004b:020c影片A2,0 4021004d:11c8 l32i.n a12,a1,4 4021004f:0108 l32i.n a0,a1,0 40210051:10c112 addi a1,a1、16 40210054:f00d ret.n 40210056:120000 andbc b0,b0,b0
40210058 <hostapd_setup_wpa_psk>:
hostapd_setup_wpa_psk():
//正确 40210058:f0c112 addi a1,a1,-16 4021005b:016102 s32i a0,a1、4 4021005e:0f2202 l32i a0,a2、60 40210061:01b016 beqz a0,40210080 40210064:e208 l32i.n a0,a2、56 40210066:0129 s32i.n a2,a1,0 40210068:00dc bnez.n a0,4021007c 4021006a:10c222 addi a2,a2、16 4021006d:fffa45 call0 40210014
//糟糕,我们拨打了40210014的电话,该电话未在任何地方列出,甚至在* .map中也没有!
<_ irom0_text_start + 0x14> 40210070:0042d6 bgez a2,40210078 ...
所以让我们手动转储以获取正确的代码
xtensa-lx106-elf-objdump -dz --start-address = 0x40210014 --stop-address = 0x40210057 sensor.elf> sensor.txt
如您所见,这是正确的转储汇编代码
40210014: fffb31 l32r a3, 40210000 <_irom0_text_start>
40210017: 22a142 movi a4, 0x122
4021001a: f0c112 addi a1, a1, -16
4021001d: 11c9 s32i.n a12, a1, 4
4021001f: 0109 s32i.n a0, a1, 0
40210021: 02cd mov.n a12, a2
40210023: 023c movi.n a2, 48
40210025: fff801 l32r a0, 40210008 <_irom0_text_start+0x8>
40210028: 0000c0 callx0 a0
4021002b: ac29 s32i.n a2, a12, 40
4021002d: 32cc bnez.n a2, 40210034 <_irom0_text_start+0x34>
4021002f: f27c movi.n a2, -1
40210031: 000606 j 4021004d <_irom0_text_start+0x4d>
40210034: bc28 l32i.n a2, a12, 44
40210036: fff501 l32r a0, 4021000c <_irom0_text_start+0xc>
40210039: 0000c0 callx0 a0
4021003c: fff231 l32r a3, 40210004 <_irom0_text_start+0x4>
4021003f: ac28 l32i.n a2, a12, 40
40210041: 042c movi.n a4, 32
40210043: 228b addi.n a2, a2, 8
40210045: fff201 l32r a0, 40210010 <_irom0_text_start+0x10>
40210048: 0000c0 callx0 a0
4021004b: 020c movi.n a2, 0
4021004d: 11c8 l32i.n a12, a1, 4
4021004f: 0108 l32i.n a0, a1, 0
40210051: 10c112 addi a1, a1, 16
40210054: f00d ret.n
40210056: 120000 andbc b0, b0, b0
回到原始问题,为什么* .map文件中存在gcc条形符号?
感谢您的澄清
答案 0 :(得分:0)
我的Xtensa LX106 CPU(ESP8266)的gcc(5.2.0)存在问题,当* .map中存在某些符号名称时,似乎从可执行文件(ELF)中省略了这些符号名称
提供的地图文件摘录未显示符号hex2num,仅显示了一个名为.text.hex2num的输入节。在编译器放置的函数之后调用该部分(通过-ffunction-sections切换到gcc启用此行为)。
objdump找不到符号hex2num(),它完全丢失了。
如果您对源库libwpa.a进行了自读,则会发现该符号也丢失了:
File: libwpa.a(common.o)
Symbol table '.symtab' contains 35 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 SECTION LOCAL DEFAULT 11
2: 00000000 0 SECTION LOCAL DEFAULT 13
3: 00000000 0 SECTION LOCAL DEFAULT 14
4: 00000000 0 SECTION LOCAL DEFAULT 16
5: 00000000 0 SECTION LOCAL DEFAULT 18
6: 00000000 0 SECTION LOCAL DEFAULT 20
7: 00000000 0 SECTION LOCAL DEFAULT 22
8: 00000000 0 SECTION LOCAL DEFAULT 24
9: 00000000 0 SECTION LOCAL DEFAULT 1
10: 00000000 0 SECTION LOCAL DEFAULT 2
11: 00000000 0 SECTION LOCAL DEFAULT 3
12: 00000000 0 SECTION LOCAL DEFAULT 4
13: 00000000 0 SECTION LOCAL DEFAULT 5
14: 00000000 0 SECTION LOCAL DEFAULT 6
15: 00000000 0 SECTION LOCAL DEFAULT 7
16: 00000000 0 SECTION LOCAL DEFAULT 8
17: 00000000 0 SECTION LOCAL DEFAULT 9
18: 00000000 0 SECTION LOCAL DEFAULT 10
19: 00000000 0 SECTION LOCAL DEFAULT 26
20: 00000000 0 SECTION LOCAL DEFAULT 27
21: 00000000 0 SECTION LOCAL DEFAULT 28
22: 00000000 0 SECTION LOCAL DEFAULT 30
23: 00000000 29 FUNC GLOBAL DEFAULT 11 inc_byte_array
24: 00000008 57 FUNC GLOBAL DEFAULT 16 hex2byte
25: 00000004 68 FUNC GLOBAL DEFAULT 18 hexstr2bin
26: 0000001c 145 FUNC GLOBAL DEFAULT 20 wpa_get_ntp_timestamp
27: 00000000 0 NOTYPE GLOBAL DEFAULT UND os_get_time
28: 00000000 0 NOTYPE GLOBAL DEFAULT UND ets_memcpy
29: 00000034 266 FUNC GLOBAL DEFAULT 22 wpa_config_parse_string
30: 00000000 0 NOTYPE GLOBAL DEFAULT UND ets_strlen
31: 00000000 0 NOTYPE GLOBAL DEFAULT UND pvPortMalloc
32: 00000000 0 NOTYPE GLOBAL DEFAULT UND vPortFree
33: 00000000 0 NOTYPE GLOBAL DEFAULT UND ets_strrchr
34: 0000000c 72 FUNC GLOBAL DEFAULT 24 dup_binstr
源库中不存在符号hex2num,在链接最终的ELF图像的过程中,gcc(或更具体地说,ld)没有将其删除。