【问题标题】:Generating %pc relative address of constant data生成常量数据的%pc相对地址
【发布时间】:2011-02-25 19:00:27
【问题描述】:

有没有办法让 gcc 生成%pc 常量的相对地址?即使字符串出现在文本段中,arm-elf-gcc 也会生成一个指向数据的常量指针,通过%pc 相对地址加载指针的地址,然后取消引用它。由于各种原因,我需要跳过中间步骤。例如,这个简单的函数:

const char * filename(void)
{
    static const char _filename[]
            __attribute__((section(".text")))
            = "logfile";
    return _filename;
}

生成(使用 arm-elf-gcc-4.3.2 -nostdlib -c -O3 -W -Wall logfile.c 编译时):

00000000 <filename>:
   0:   e59f0000        ldr     r0, [pc, #0]    ; 8 <filename+0x8>
   4:   e12fff1e        bx      lr
   8:   0000000c        .word   0x0000000c

0000000c <_filename.1175>:
   c:   66676f6c        .word   0x66676f6c
  10:   00656c69        .word   0x00656c69

我原以为它会产生类似的东西:

filename:
    add r0, pc, #0
    bx lr
_filename.1175:
    .ascii "logfile\000"

有问题的代码需要部分与位置无关,因为它会在加载时重新定位到内存中,但还要与未编译的代码集成-fPIC,因此没有全局偏移表。

我目前的工作是调用非内联函数(通过%pc 相对地址完成)以使用类似于@ 987654329@代码有效:

static intptr_t
__attribute__((noinline))
find_offset( void )
{
    uintptr_t pc;
    asm __volatile__ (
            "mov %0, %%pc" : "=&r"(pc)
    );

    return pc - 8 - (uintptr_t) find_offset;
}

但是这种技术需要手动修复所有个数据引用,所以上面例子中的filename()函数会变成:

const char * filename(void)
{
    static const char _filename[]
            __attribute__((section(".text")))
            = "logfile";
    return _filename + find_offset();
}

【问题讨论】:

    标签: gcc arm fpic relative-addressing


    【解决方案1】:

    嗯,也许您必须将其编译为 -fPIC 才能获得 PIC。或者干脆用汇编写,汇编比你写的C容易多了。

    00000000 : 0:e59f300c ldr r3,[pc,#12]; 14 4: e59f000c ldr r0, [pc, #12] ; 18 8: e08f3003 添加 r3, pc, r3 c: e0830000 添加 r0, r3, r0 10:e12fff1e bx lr 14: 00000004 andeq r0, r0, r4 18: 00000000 andeq r0, r0, r0 0000001c: 1c:66676f6c strbtvs r6,[r7],-ip,ror #30 20: 00656c69 rsbeq r6, r5, r9, ror #24

    你收到的警告和我一样吗?

    /tmp/ccySyaUE.s:汇编程序消息: /tmp/ccySyaUE.s:35:警告:忽略 .text 更改的部分属性

    【讨论】:

    • 是的,我确实收到了同样的警告。最简单的破解方法是添加一个虚假的换行符和注释:__attribute__((section(".text\n#")))。它不能用 -fPIC 编译,因为 ROM 中有位于显式地址的函数。组装适用于我,但不适用于系统的其他用户......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多