Various changes for PIC code on ARM...

Richard Earnshaw
Sun Feb 28 18:15:00 GMT 1999

> My changes are modelled after the way the i386 guys did their PIC support.  It
> seemed like the best way at the time, as they seemed to be driving the
> compiler/assembler/linker forward.  How do the NetBSD guys mark a branch as
> having to go through the PLT, or whether something needs a GOT or GOTOFF reloc?

I guess they are most closely modelled on that used by the SPARC (since it 
was another RISC processor that also supported a.out format).

Basically, there are three types of PIC relocation: 
1) A 32-bit PC-relative used to load the address of the GOT into the PIC 
2) A 26-bit JMPSLOT relocation, used on branch and branch-with-link 
instructions (I think this is basically the same as a normal branch 
3) A GOT-offset based relocation, containing the offset into the GOT from 
the PIC register of the address of the symbol requested.

The assembler recognizes the correct type for each of the relocations 
automatically, the only slight hack being that types 1 and 3 are 
distinguished by the fact that type 1 will only be applied to the symbol 

Take for example the simple piece of code

int foo;

int bar()
  return foo;

This assembles in PIC mode to:

        .global _bar
        mov     ip, sp
        stmfd   sp!, {sl, fp, ip, lr, pc}
        sub     fp, ip, #4
        ldr     sl, L3
        add     sl, pc, sl
        bl      _wibble
        ldr     r3, L3+4
        ldr     r3, [sl, r3]
        ldr     r0, [r3, #0]
        ldmea   fp, {sl, fp, sp, pc}
        .align  0
        .word   __GLOBAL_OFFSET_TABLE_+. - (L2+4)
        .word   _foo

And when assembled with as -k, the output is (from objdump)

00000000 <_bar>:
   0:   e1a0c00d        mov     ip, sp
   4:   e92ddc00        stmdb   sp!, {sl, fp, ip, lr, pc}
   8:   e24cb004        sub     fp, ip, #4
   c:   e59fa014        ldr     sl, 28 <L3>
  10:   e08fa00a        add     sl, pc, sl
  14:   ebfffffe        bl      14 <_bar+0x14>
                        14: JMPSLOT     _wibble
  18:   e59f300c        ldr     r3, 2c <L3+0x4>
  1c:   e79a3003        ldr     r3, [sl, r3]
  20:   e5930000        ldr     r0, [r3]
  24:   e91bac00        ldmdb   fp, {sl, fp, sp, pc}

00000028 <L3>:
  28:   00000010        andeq   r0, r0, r0, lsl r0
                        28: DISP32      __GLOBAL_OFFSET_TABLE_
  2c:   00000000        andeq   r0, r0, r0
                        2c: GOT32       _foo

More information about the Gcc-patches mailing list