internal relocation not fixed up

user1146332 picture user1146332 · Apr 10, 2012 · Viewed 22.1k times · Source

i recently started assembler programming for arm cores. My first little demos, only with the .text section, ran without any problems.

As a logical extension i wanted to structure the assembler code into the usual sections: .text, .data, .bss .

So i wrote the following simple program:

 .globl _start

 .section .text

 _start:
     b   main
     b   .
     b   .
     b   .
     b   .
     b   .
     b   .
     b   .  


 main:
    ldr r0, x
    nop

 .section .data

 x:  .word  0xf0f0f0f0

 .end

But

  /opt/arm/bin/arm-as -ggdb -mcpu=arm7tdmi demo.s -o demo.o

exits with the error

 prog.s: Assembler messages:
 prog.s:17: Error: internal_relocation (type: OFFSET_IMM) not fixed up
 make: *** [prog.o] Error 1

I have no clue why the assembler complains about relocation, because i thought that's the task of the linker. I could imagine that i have to tell the assembler that my .data section isn't located at the final memory postion at the assembling stage, but i can't find anything related.

Although i found a way to get the code assembled correctly, by replacing

 .section .data

by

 .org .

that is not a satisfying solution. Especially in view of the fact that the gas documentation highlight the sense of this section.

Maybe someone of you experts can help me to gain some wisdom

Answer

tangrs picture tangrs · Apr 16, 2012

It seems the only way you can do it is by grabbing the address of the variable and load a value from that address.

ldr r1,=x    ; get address of x
ldr r0,[r1]  ; load from that address

In a way, this also kind of makes sense. After all, what if the address of x (after linking) is too far away for a PC relative access? Since the compiler (which doesn't do the linking) does not know how far away the data section may be from the text section, it would refuse to compile that code just in case it isn't reachable.

By using this indirect way of accessing a variable, it is guaranteed that the variable will be reachable (or at least the compiler can be sure whether the variable is reachable or not).

Code adapted from http://www.zap.org.au/elec2041-cdrom/examples/intro/pseudo.s