This patch forces the use of GOT relocations instead of GOTOFF when
compiling execute-in-place (XIP) code. I've defined XIP as the
combination of -fpic and -msingle-pic-base.
There is room for improvement in using GOTOFF relocations for symbols
that will be in the same addressing space as the GOT (.data likely)
and PC relative relocations for symbols that will be in the same
addressing space as the PC (.text and .rodata likely).
I'm open to suggestions for the name of the new predicate, which I've
named local_symbol_p here. I had named it use_gotoff_p at one point.
Cheers,
Shaun
2006-06-29 Shaun Jackman <sjackman@gmail.com>
* config/arm/arm.c (local_symbol_p): New function.
(legitimize_pic_address, arm_assemble_integer): Use it to prevent
GOTOFF relocations to the .text segment in execute-in-place code.
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c (revision 115074)
+++ config/arm/arm.c (working copy)
@@ -3193,6 +3193,17 @@
return 1;
}
+static int
+local_symbol_p(rtx x)
+{
+ /* Execute-in-place code fails if a GOTOFF relocation is used to
+ * adress a local symbol in the .text segment. */
+ if (flag_pic && TARGET_SINGLE_PIC_BASE)
+ return 0;
+ return GET_CODE (x) == LABEL_REF
+ || (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (x));
+}
+
rtx
legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
{
@@ -3271,10 +3282,7 @@
else
emit_insn (gen_pic_load_addr_thumb (address, orig));
- if ((GET_CODE (orig) == LABEL_REF
- || (GET_CODE (orig) == SYMBOL_REF &&
- SYMBOL_REF_LOCAL_P (orig)))
- && NEED_GOT_RELOC)
+ if (NEED_GOT_RELOC && local_symbol_p (orig))
pic_ref = gen_rtx_PLUS (Pmode, cfun->machine->pic_reg, address);
else
{
@@ -11292,12 +11300,10 @@
if (NEED_GOT_RELOC && flag_pic && making_const_table &&
(GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
{
- if (GET_CODE (x) == SYMBOL_REF
- && (CONSTANT_POOL_ADDRESS_P (x)
- || SYMBOL_REF_LOCAL_P (x)))
+ if ((GET_CODE (x) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x))
+ || local_symbol_p (x))
fputs ("(GOTOFF)", asm_out_file);
- else if (GET_CODE (x) == LABEL_REF)
- fputs ("(GOTOFF)", asm_out_file);
else
fputs ("(GOT)", asm_out_file);
}