From adca2a186e811c5122418d379a10d6b295157a89 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Thu, 26 May 2016 09:26:09 +0100 Subject: [PATCH] base/asm-common.h: Use new literal-pool stuff for ARM PIC macros. 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 | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/base/asm-common.h b/base/asm-common.h index aa6b4c3e..32c05430 100644 --- a/base/asm-common.h +++ b/base/asm-common.h @@ -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 -- 2.11.0