diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5f28311099..fc52fc1b11e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Sat May 8 06:23:21 1999 Philip Blundell + + Based on patch by Scott Bambrough: + * config/arm/arm.h (NEED_PLT_GOT): New macro. Set to 0 if not + already defined. + * config/arm/elf.h (NEED_PLT_GOT): Define to flag_pic. + * config/arm/arm.md (call_symbol, call_value_symbol et al.): If + NEED_PLT_GOT is true, add explicit "(PLT)" to generated branches. + * config/arm/arm.c (output_func_epilogue, + output_return_instruction): Likewise for calls to abort. + Sat May 8 01:57:58 1999 Donn Terry (donn@interix.com) * calls.c (rtx_for_function_call): Extend function pointer being diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 03891cd0eb1..e2fe037ad56 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -5299,7 +5299,8 @@ output_return_instruction (operand, really_return, reverse) /* Otherwise, trap an attempted return by aborting. */ ops[0] = operand; - ops[1] = gen_rtx_SYMBOL_REF (Pmode, "abort"); + ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_GOT ? "abort(PLT)" + : "abort"); assemble_external_libcall (ops[1]); output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops); return ""; @@ -5553,7 +5554,8 @@ output_func_epilogue (f, frame_size) /* A volatile function should never return. Call abort. */ if (TARGET_ABORT_NORETURN && volatile_func) { - rtx op = gen_rtx_SYMBOL_REF (Pmode, "abort"); + rtx op; + op = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_GOT ? "abort(PLT)" : "abort"); assemble_external_libcall (op); output_asm_insn ("bl\t%a0", &op); goto epilogue_done; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index b15fe2178b6..ad2b865501a 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -476,6 +476,11 @@ extern int arm_is_6_or_7; #define TARGET_MEM_FUNCTIONS 1 #define OVERRIDE_OPTIONS arm_override_options () + +/* Nonzero if PIC code requires explicit qualifiers to generate + PLT and GOT relocs rather than the assembler doing so implicitly. + Subtargets can override this if required. */ +#define NEED_PLT_GOT 0 /* Target machine storage Layout. */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index cf132bc0af5..5696e11c302 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4246,7 +4246,10 @@ (match_operand:SI 1 "general_operand" "g")) (clobber (reg:SI 14))] "GET_CODE (operands[0]) == SYMBOL_REF" - "bl%?\\t%a0" + "* + { + return NEED_PLT_GOT ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\"; + }" [(set_attr "type" "call")]) (define_insn "*call_value_symbol" @@ -4255,7 +4258,10 @@ (match_operand:SI 2 "general_operand" "g"))) (clobber (reg:SI 14))] "GET_CODE(operands[1]) == SYMBOL_REF" - "bl%?\\t%a1" + "* + { + return NEED_PLT_GOT ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\"; + }" [(set_attr "type" "call")]) ;; Often the return insn will be the same as loading from memory, so set attr @@ -5993,7 +5999,7 @@ } output_return_instruction (NULL, FALSE, FALSE); - return \"b%?\\t%a0\"; + return NEED_PLT_GOT ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\"; }" [(set_attr "type" "call") (set_attr "length" "8")]) @@ -6021,7 +6027,7 @@ } output_return_instruction (NULL, FALSE, FALSE); - return \"b%?\\t%a1\"; + return NEED_PLT_GOT ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\"; }" [(set_attr "type" "call") (set_attr "length" "8")]) diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h index e6d8eb76230..d2ba8bb1da8 100644 --- a/gcc/config/arm/elf.h +++ b/gcc/config/arm/elf.h @@ -335,4 +335,7 @@ do { \ do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \ fputc ('\n', FILE); } while (0) +/* For PIC code we need to explicitly specify (PLT) and (GOT) relocs. */ +#define NEED_PLT_GOT flag_pic + #include "arm/aout.h"