chiark / gitweb /
base/asm-common.h: Use new literal-pool stuff for ARM PIC macros.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 26 May 2016 08:26:09 +0000 (09:26 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 24 Jun 2016 00:17:37 +0000 (01:17 +0100)
The support in GAS for the ARM literal-loading syntax is entirely
hopeless.

  * It unnecessarily refuses to allow expressions involving external
    symbols as literal values (e.g., `ldr r0, =_GLOBAL_OFFSET_TABLE_ -
    . - 12').  I've checked: if you modify GAS to remove the pointless
    check, then it produces the right result.

  * It doesn't use the enhanced expression evaluator which understands
    relocation annotations (so you can't say `ldr r0, =foo(GOT)').
    Indeed, this evaluator is internal to the handler for `.word' and
    friends.  Fixing this would be rather hard work, and involve
    uprating the literal-pool machinery quite a bit.

Instead, use the new subsection-based fake literal pool handling
machinery `_LIT' and `_ENDLIT' and some per-macro symbols with awful
names.

This also removes the magic knowledge which the previous version of the
`ldgot' had about the right PC offset, which would have been wrong for
Thumb code.

base/asm-common.h

index aa6b4c3e40696794d60b255bb1a110c4158d7b49..32c054301364decce6f7bf9090bd5c9cf128c7dc 100644 (file)
@@ -184,16 +184,27 @@ _where_am_i.\got :
 // Maybe load GOT address into GOT.
        .macro  ldgot   cond=, got=GOTREG
 #if WANT_PIC
-       ldr\cond \got, =_GLOBAL_OFFSET_TABLE_ - . - 12
+       ldr\cond \got, .L$_ldgot$\@
+.L$_ldgot_pc$\@:
        add\cond \got, pc, \got
+       _LIT
+       .balign 4
+.L$_ldgot$\@:
+       .word   _GLOBAL_OFFSET_TABLE_ - .L$_ldgot_pc$\@ - 8
+       _ENDLIT
 #endif
        .endm
 
 // Load address of external symbol ADDR into REG, maybe using GOT.
        .macro  leaext  reg, addr, cond=, got=GOTREG
 #if WANT_PIC
-       ldr\cond \reg, =\addr(GOT)
+       ldr\cond \reg, .L$_leaext$\@
        ldr\cond \reg, [\got, \reg]
+       _LIT
+       .balign 4
+.L$_leaext$\@:
+       .word   \addr(GOT)
+       _ENDLIT
 #else
        ldr\cond \reg, =\addr
 #endif