与重定位code静态局部变量的问题 [英] Problems with static local variables with relocatable code

查看:300
本文介绍了与重定位code静态局部变量的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立这对裸机重定位code的项目。它是一个皮质M3的嵌入式应用。我没有一个动态链接程序,并已在我的启动code实现全部搬迁。

I am building a project which has relocatable code on bare metal. It is a Cortex M3 embedded application. I do not have a dynamic linker and have implemented all the relocations in my startup code.

主要是它是工作,但我的本地静态变量似乎被错误地定位。我编译我的code作为如果在内存位置0加载,但我实际上是在位于0x8000的内存中加载它就是 - 他们的地址是由我的可执行文件在内存中的偏移量抵消。静态局部变量有自己的存储地址为0x8000这是不好的偏移量。

Mostly it is working but my local static variables appear to be incorrectly located. Their address is offset by the amount that my executable is offset in memory - ie I compile my code as if it is loaded at memory location 0 but I actually load it in memory located at 0x8000. The static local variable have their memory address offset by 0x8000 which is not good.

我的全局变量是由GOT正确定位,但静态局部变量是不是在GOT所有(至少当我运行不出现 readelf -r )。我编我的code与 -fpic 和链接器 -fpic -pie 指定。我想我必须失去了编译和/或链接选项可以指示 GCC 使用GOT的静态局部变量,或者让它使用绝对寻址他们。

My global variables are located properly by the GOT but the static local variables are not in the GOT at all (at least they don't appear when I run readelf -r). I am compiling my code with -fpic and the linker has -fpic and -pie specified. I think I must be missing a compile and/or link option to either instruct gcc to use the GOT for the static local variables or to instruct it to use absolute addressing for them.

看来,目前code增加了PC的静态局部变量的位置。

It seems that currently the code adds the PC to the location of the static local variables.

推荐答案

我想我已经重复你所看到的:

I think I have repeated what you are seeing:


statloc.c

unsigned int glob;

unsigned int fun ( unsigned int a )
{
    static unsigned int loc;

    if(a==0) loc=7;
    return(a+glob+loc);
}


arm-none-linux-gnueabi-gcc -mcpu=cortex-m3 -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -fpic -pie -S statloc.c

这给出了:

    .cpu cortex-m3
    .fpu softvfp
    .thumb
    .text
    .align  2
    .global fun
    .thumb
    .thumb_func
fun:
    ldr r3, .L6
.LPIC2:
    add r3, pc
    cbnz    r0, .L5
    ldr r1, .L6+4
    movs    r2, #7
.LPIC1:
    add r1, pc
    ldr ip, .L6+8
    str r2, [r1, #0]
    ldr r1, [r3, ip]
    ldr r3, [r1, #0]
    adds    r0, r0, r3
    adds    r0, r0, r2
    bx  lr
.L5:
    ldr ip, .L6+8
    ldr r2, .L6+12
    ldr r1, [r3, ip]
.LPIC0:
    add r2, pc
    ldr r2, [r2]
    ldr r3, [r1, #0]
    adds    r0, r0, r3
    adds    r0, r0, r2
    bx  lr
.L7:
    .align  2
.L6:
    .word   _GLOBAL_OFFSET_TABLE_-(.LPIC2+4)
    .word   .LANCHOR0-(.LPIC1+4)
    .word   glob(GOT)
    .word   .LANCHOR0-(.LPIC0+4)
    .size   fun, .-fun
    .comm   glob,4,4
    .bss
    .align  2
.LANCHOR0 = . + 0
    .type   loc.823, %object
    .size   loc.823, 4
loc.823:
    .space  4

我还添加了启动code和编译的二进制和拆卸进一步了解/验证到底是怎么回事。

I also added startup code and compiled a binary and disassembled to further understand/verify what is going on.


this is the offset from the pc to the .got
    ldr r3, .L6  
add pc so r3 holds a position independent offset to the .got
    add r3, pc   
offset in the got for the address of the glob 
    ldr ip, .L6+8 
read the absolute address for the global variable from the got
    ldr r1, [r3, ip] 
finally read the global variable into r3
    ldr r3, [r1, #0] 


this is the offset from the pc to the static local in .bss
    ldr r2, .L6+12
add pc so that r2 holds a position independent offset to the static local
in .bss    
    add r2, pc
read the static local in .bss    
    ldr r2, [r2]

所以,如果你要改变那里的.text被加载并要改变其中两个.GOT和.bss相对于加载到.text区段,这是它,然后.GOT的内容是错误的,全局变量会从错误的地方加载。

So if you were to change where .text is loaded and were to change where both .got and .bss are loaded relative to .text and that is it then the contents of .got would be wrong and the global variable would be loaded from the wrong place.

如果你要改变那里的.text被加载,留下的.bss其中连接器把它和移动.GOT相对于.text区段。那么全球将在正确的位置上拉和地方不会

if you were to change where .text is loaded, leave .bss where the linker put it and move .got relative to .text. then the global would be pulled from the right place and the local would not

如果你要改变那里的.text被加载,更改其中两个.GOT和.bss相对于加载到.text区段和修改.GOT内容以反映的.text被加载,那么本地和全局变量会从正确的地方访问。

if you were to change where .text is loaded, change where both .got and .bss are loaded relative to .text and modify .got contents to reflect where .text is loaded, then both the local and global variable would be accessed from the right place.

所以,装载机和gcc / LD需要的所有保持同步。我立即建议是不要使用静态局部和只使用一个全球性的。这还是不约与位置无关code担心,这毕竟是一个Cortex-M3的,有点资源有限,只要定义的存储器映射锋线。我认为这个问题是怎么做的我做GCC使用.GOT本地全球化,一个我不知道答案,但服用象那个上面你可以通过很多的命令行选项工作,直到你找到一个简单的例子一个改变输出

So the loader and gcc/ld need to all be in sync. My immediate recommendation is to not use a static local and just use a global. That or dont worry about position independent code, it is a cortex-m3 after all and somewhat resource limited, just define the memory map up front. I assume the question is how do I make gcc use the .got for the local global, and that one I dont know the answer to, but taking a simple example like the one above you can work through the many command line options until you find one that changes the output.

这篇关于与重定位code静态局部变量的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆