gcc:xtensa LX106(ESP8266)缺少ELF可执行文件中的符号名称

时间:2019-02-07 20:05:06

标签: gcc esp8266

我的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条形符号?

感谢您的澄清

1 个答案:

答案 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)没有将其删除。