gcc ARM32位置独立代码二进制偏移

iyr7buue  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(156)

我正在开发一个ARM裸机二进制文件,我正在尝试获得一个完全位置独立的二进制文件。除了全局变量之外,一切都正常。下面是我的代码:

int foo = 1;
int main() {
   return &foo;
}

我把它编译成这样:
第一个
(this不完整,但足以说明问题)
main()返回类似于0x100的值,它是从二进制文件开始的偏移量,而不是foo的绝对地址。
我很了解C型臂装配,但我不擅长连接器。任何帮助都很感激。

ntjbwcob

ntjbwcob1#

闪存.s

ldr sp,=0x1000
bl fun
b .

main.c

unsigned int x=5;
unsigned int *fun ( void )
{
    return &x;
}

flash.ld

MEMORY
{
    one   : ORIGIN = 0x00002000, LENGTH = 0x1000
    two   : ORIGIN = 0x00003000, LENGTH = 0x1000
    three : ORIGIN = 0x00004000, LENGTH = 0x1000
    four  : ORIGIN = 0x00005000, LENGTH = 0x1000
}
SECTIONS
{
    .text   : { *(.text*)   } > one    
    .rodata : { *(.rodata*) } > two    
    .bss    : { *(.bss*)    } > three  
    .data   : { *(.data*)   } > four   
}

建筑物

arm-linux-gnueabi-as --warn --fatal-warnings -mcpu=cortex-a7 flash.s -o flash.o
arm-linux-gnueabi-gcc -fpic -Wall -O2 -ffreestanding -mcpu=cortex-a7 -c main.c -o main.o
arm-linux-gnueabi-ld -nostdlib -nostartfiles -T flash.ld flash.o main.o -o main.elf
arm-linux-gnueabi-objdump -D main.elf > main.list
arm-linux-gnueabi-objcopy --srec-forceS3 main.elf -O srec main.srec
arm-linux-gnueabi-objcopy -O binary main.elf main.bin

检查

Disassembly of section .text:

00002000 <fun-0xc>:
    2000:   e3a0da01    mov sp, #4096   ; 0x1000
    2004:   eb000000    bl  200c <fun>
    2008:   eafffffe    b   2008 <fun-0x4>

0000200c <fun>:
    200c:   e59f300c    ldr r3, [pc, #12]   ; 2020 <fun+0x14>
    2010:   e59f200c    ldr r2, [pc, #12]   ; 2024 <fun+0x18>
    2014:   e08f3003    add r3, pc, r3
    2018:   e7930002    ldr r0, [r3, r2]
    201c:   e12fff1e    bx  lr
    2020:   00002fe8    andeq   r2, r0, r8, ror #31
    2024:   00000000    andeq   r0, r0, r0

Disassembly of section .data:

00005000 <x>:
    5000:   00000005    andeq   r0, r0, r5

Disassembly of section .got:

00005004 <.got>:
    5004:   00005000    andeq   r5, r0, r0

详细地

0000200c <fun>:
    load the offset to got into r3
    200c:   e59f300c    ldr r3, [pc, #12]   ; 2020 <fun+0x14>
    load the offset of x in the got into r2
    2010:   e59f200c    ldr r2, [pc, #12]   ; 2024 <fun+0x18>
    compute the address to the address of x
    2014:   e08f3003    add r3, pc, r3
    load the address of x into r0
    2018:   e7930002    ldr r0, [r3, r2]
    return the address of x
    201c:   e12fff1e    bx  lr
    2020:   00002fe8    andeq   r2, r0, r8, ror #31
    2024:   00000000    andeq   r0, r0, r0

使用链接器脚本

Disassembly of section .text:

00000000 <_text_start>:
   0:   e3a0da01    mov sp, #4096   ; 0x1000
   4:   eb000000    bl  c <fun>
   8:   eafffffe    b   8 <_text_start+0x8>

0000000c <fun>:
   c:   e59f300c    ldr r3, [pc, #12]   ; 20 <fun+0x14>
  10:   e59f200c    ldr r2, [pc, #12]   ; 24 <fun+0x18>
  14:   e08f3003    add r3, pc, r3
  18:   e7930002    ldr r0, [r3, r2]
  1c:   e12fff1e    bx  lr
  20:   00000010    andeq   r0, r0, r0, lsl r0
  24:   00000000    andeq   r0, r0, r0

Disassembly of section .data:

00000028 <x>:
  28:   00000005    andeq   r0, r0, r5

Disassembly of section .got:

0000002c <.got>:
  2c:   00000028    andeq   r0, r0, r8, lsr #32

x的地址是0x28,这就是它返回的结果。现在取决于你如何优化,以及你程序中的其他东西,答案可以是0x100。

相关问题