为什么没有''在链接' -mthumb-only'时发出警告没有' -mthumb&#39 ;?的对象文件

时间:2016-07-19 16:19:20

标签: gcc arm binutils

在我使用gcc-arm-none-eabi 4.8binutils 2.26的设置中,当使用-mthumb单独编译目标文件时,我会得到相当不明确的行为,但在最后的链接步骤中使用{{1}没有从链接器收到任何警告。为什么会这样?

由于缺少标志,链接器选择了默认的multilib架构,因此未定义的行为可能(根据我首先要求的非常有用的FOSS开发人员)。但是,链接器为什么不警告这个问题呢?是否可以轻松地从对象和库文件中检测链接函数的ISA,以确定是否存在可疑的东西?

2 个答案:

答案 0 :(得分:2)

理想情况下,它应该从被链接的对象中知道。反汇编并检查不同对象的功能之间的相互作用。

我最近试图证明gnu工具/链接器在添加蹦床方面有多好。当它一直失败的时候。它会把蹦床放在一个方向而不是另一个方向(拇指往/来自手臂)。我认为这是一个来自C问题的汇编,我没有使用编译器使用的指令plethera,所以很可能就是这样。

设置一些测试用例相当简单,用arm构建的函数制作一个对象,用拇指构建另一个函数,让它们互相调用。在它周围放置足够的结构以使工具无错误地连接,然后进行反汇编和检查。

armstart.s

#on the main -------------
temp_obj = []
obj = [
    {'name':'a1', 'level':0},
    {'name':'a2', 'level':0},
    {'name':'a3', 'level':1},
    {'name':'a4', 'level':1},
    {'name':'a5', 'level':2},
    {'name':'a6', 'level':2},
]

the_result = myFunction(obj, temp_obj)

print(temp_obj)
#above print would result to an empty list
#this is my problem

#end of main body -------------


def myFunction(obj, new_temp_obj):
     inside_list = []
     for x in obj[:]:
         if x['level'] == 0:
              inside_list.append(x)
              obj.remove(x) #removing the element that was added to the inside_list

     new_temp_obj = obj[:] #copying the remaining element 

     print(new_temp_obj) 
     # the above print would result to
     #[{'name': 'a3', 'level': 1}, {'name': 'a4', 'level': 1}, {'name': 'a5', 'level': 2}, {'name': 'a6', 'level': 2}]

     return inside_list

notmain.c

.global _start
_start:
    bl notmain
    b hang
hang:   b .

one.c

extern unsigned int one ( unsigned int );
int notmain ( void )
{
    one(1);
    return(0);
}

two.c

extern unsigned int two ( unsigned int x );
unsigned int one ( unsigned int x )
{
    return(two(x+5));
}

生成文件

extern unsigned int one ( unsigned int x );
unsigned int two ( unsigned int x )
{
    return(one(x+7));
}

一些反汇编:

ARMGNU = arm-none-eabi
#ARMGNU = arm-linux-gnueabi

AOPS = --warn --fatal-warnings
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding

all : notmain.bin


clean:
    rm -f *.bin
    rm -f *.o
    rm -f *.elf
    rm -f *.list
    rm -f *.bc
    rm -f *.opt.s
    rm -f *.norm.s
    rm -f *.hex

armstart.o : armstart.s
    $(ARMGNU)-as $(AOPS) armstart.s -o armstart.o

notmain.o : notmain.c
    $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o

two.o : two.c
    $(ARMGNU)-gcc $(COPS) -mthumb -c two.c -o two.o

one.o : one.c
    $(ARMGNU)-gcc $(COPS) -c one.c -o one.o

notmain.bin : memmap armstart.o notmain.o one.o two.o
    $(ARMGNU)-ld -o notmain.elf -T memmap armstart.o notmain.o one.o two.o
    $(ARMGNU)-objdump -D notmain.elf > notmain.list
    $(ARMGNU)-objcopy notmain.elf notmain.hex -O ihex
    $(ARMGNU)-objcopy notmain.elf notmain.bin -O binary

本例中的工具链

20000024 <one>:
20000024:   e92d4010    push    {r4, lr}
20000028:   e2800005    add r0, r0, #5
2000002c:   eb000007    bl  20000050 <__two_from_arm>
20000030:   e8bd4010    pop {r4, lr}
20000034:   e12fff1e    bx  lr

20000038 <two>:
20000038:   b510        push    {r4, lr}
2000003a:   3007        adds    r0, #7
2000003c:   f000 f804   bl  20000048 <__one_from_thumb>
20000040:   bc10        pop {r4}
20000042:   bc02        pop {r1}
20000044:   4708        bx  r1
20000046:   46c0        nop         ; (mov r8, r8)

20000048 <__one_from_thumb>:
20000048:   4778        bx  pc
2000004a:   46c0        nop         ; (mov r8, r8)
2000004c:   eafffff4    b   20000024 <one>

20000050 <__two_from_arm>:
20000050:   e59fc000    ldr ip, [pc]    ; 20000058 <__two_from_arm+0x8>
20000054:   e12fff1c    bx  ip
20000058:   20000039    andcs   r0, r0, r9, lsr r0
2000005c:   00000000    andeq   r0, r0, r0

(binutils 2.26.20160125)

工作得非常好。

与gcc 5.4.0和binutils 2.26.1相同。

看看readelf之间我们看到的两个对象之间的差异:

arm-none-eabi-gcc (GCC) 6.1.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

答案 1 :(得分:0)

  

使用-mthumb单独编译目标文件,但在最后的链接步骤中使用ld将该标志保留在外,而不会从链接器收到任何警告。为什么会这样?

生成的可执行文件在大多数ARM平台上都可以正常工作,但微控制器配置文件(Cortex-M)除外。甚至有一个很好的理由将拇指代码与ARM库混合:代码大小。