diff --git a/gas/ChangeLog b/gas/ChangeLog index dbb75ebfa76..5d56137d27c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2002-02-09 Richard Henderson + + * config/tc-alpha.c (O_samegp): New. + (USER_RELOC_P): Include it. + (alpha_reloc_op_tag, debug_exp, find_macro_match): Add it. + (md_apply_fix3): Handle BFD_RELOC_ALPHA_BRSGP. + (alpha_force_relocation, alpha_fix_adjustable): Likewise. + (alpha_validate_fix): New. + * config/tc-alpha.h (TC_VALIDATE_FIX): New. + 2002-02-09 Hans-Peter Nilsson * doc/c-cris.texi: New. diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c index 44c651b755a..ae6f76b9500 100644 --- a/gas/config/tc-alpha.c +++ b/gas/config/tc-alpha.c @@ -117,6 +117,7 @@ struct alpha_macro { #define O_gprelhigh O_md9 /* !gprelhigh relocation */ #define O_gprellow O_md10 /* !gprellow relocation */ #define O_gprel O_md11 /* !gprel relocation */ +#define O_samegp O_md12 /* !samegp relocation */ #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1) #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2) @@ -128,7 +129,7 @@ struct alpha_macro { #define LITUSE_BYTOFF 2 #define LITUSE_JSR 3 -#define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprel) +#define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_samegp) /* Macros for extracting the type and number of encoded register tokens */ @@ -498,7 +499,8 @@ static const struct alpha_reloc_op_tag { DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1), DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0), DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0), - DEF(gprel, BFD_RELOC_GPREL16, 0, 0) + DEF(gprel, BFD_RELOC_GPREL16, 0, 0), + DEF(samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0) }; #undef DEF @@ -1219,6 +1221,11 @@ md_apply_fix3 (fixP, valP, seg) } return; +#ifdef OBJ_ELF + case BFD_RELOC_ALPHA_BRSGP: + return; +#endif + #ifdef OBJ_ECOFF case BFD_RELOC_ALPHA_LITERAL: md_number_to_chars (fixpos, value, 2); @@ -1364,6 +1371,49 @@ alpha_define_label (sym) alpha_insn_label = sym; } +/* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and + let it get resolved at assembly time. */ + +void +alpha_validate_fix (f) + fixS *f; +{ +#ifdef OBJ_ELF + int offset = 0; + const char *name; + + if (f->fx_r_type != BFD_RELOC_ALPHA_BRSGP) + return; + + if (! S_IS_DEFINED (f->fx_addsy)) + return; + + switch (S_GET_OTHER (f->fx_addsy) & STO_ALPHA_STD_GPLOAD) + { + case STO_ALPHA_NOPV: + break; + case STO_ALPHA_STD_GPLOAD: + offset = 8; + break; + default: + if (S_IS_LOCAL (f->fx_addsy)) + name = ""; + else + name = S_GET_NAME (f->fx_addsy); + as_bad_where (f->fx_file, f->fx_line, + _("!samegp reloc against symbol without .prologue: %s"), + name); + break; + } + + if (! (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy))) + { + f->fx_r_type = BFD_RELOC_23_PCREL_S2; + f->fx_offset += offset; + } +#endif +} + /* Return true if we must always emit a reloc for a type and false if there is some hope of resolving it at assembly time. */ @@ -1388,6 +1438,7 @@ alpha_force_relocation (f) case BFD_RELOC_ALPHA_GPREL_LO16: case BFD_RELOC_ALPHA_LINKAGE: case BFD_RELOC_ALPHA_CODEADDR: + case BFD_RELOC_ALPHA_BRSGP: case BFD_RELOC_VTABLE_INHERIT: case BFD_RELOC_VTABLE_ENTRY: return 1; @@ -1422,6 +1473,7 @@ alpha_fix_adjustable (f) case BFD_RELOC_ALPHA_GPDISP_HI16: case BFD_RELOC_ALPHA_GPDISP_LO16: case BFD_RELOC_ALPHA_GPDISP: + case BFD_RELOC_ALPHA_BRSGP: return 0; case BFD_RELOC_ALPHA_LITERAL: @@ -1763,6 +1815,7 @@ debug_exp (tok, ntok) case O_pregister: name = "O_pregister"; break; case O_cpregister: name = "O_cpregister"; break; case O_literal: name = "O_literal"; break; + case O_lituse_addr: name = "O_lituse_addr"; break; case O_lituse_base: name = "O_lituse_base"; break; case O_lituse_bytoff: name = "O_lituse_bytoff"; break; case O_lituse_jsr: name = "O_lituse_jsr"; break; @@ -1770,8 +1823,7 @@ debug_exp (tok, ntok) case O_gprelhigh: name = "O_gprelhigh"; break; case O_gprellow: name = "O_gprellow"; break; case O_gprel: name = "O_gprel"; break; - case O_md11: name = "O_md11"; break; - case O_md12: name = "O_md12"; break; + case O_samegp: name = "O_samegp"; break; case O_md13: name = "O_md13"; break; case O_md14: name = "O_md14"; break; case O_md15: name = "O_md15"; break; @@ -2166,6 +2218,7 @@ find_macro_match (first_macro, tok, pntok) case O_gprelhigh: case O_gprellow: case O_gprel: + case O_samegp: goto match_failed; default: diff --git a/gas/config/tc-alpha.h b/gas/config/tc-alpha.h index fb428f9f32e..5505861316d 100644 --- a/gas/config/tc-alpha.h +++ b/gas/config/tc-alpha.h @@ -39,12 +39,14 @@ #define NEED_LITERAL_POOL #define REPEAT_CONS_EXPRESSIONS +extern void alpha_validate_fix PARAMS ((struct fix *)); extern int alpha_force_relocation PARAMS ((struct fix *)); extern int alpha_fix_adjustable PARAMS ((struct fix *)); extern unsigned long alpha_gprmask, alpha_fprmask; extern valueT alpha_gp_value; +#define TC_VALIDATE_FIX(FIXP,SEGTYPE,SKIP) alpha_validate_fix (FIXP) #define TC_FORCE_RELOCATION(FIXP) alpha_force_relocation (FIXP) #define tc_fix_adjustable(FIXP) alpha_fix_adjustable (FIXP) #define RELOC_REQUIRES_SYMBOL diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 1c5d1dee441..df5f10881cd 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2002-02-09 Richard Henderson + + * gas/alpha/elf-reloc-5.s, gas/alpha/elf-reloc-5.d: New. + * gas/alpha/elf-reloc-6.s, gas/alpha/elf-reloc-6.l: New. + * gas/alpha/alpha.exp: Run them. + 2002-02-08 Chris Demetriou * gas/mips/mips.exp: Document (but do not XFAIL) currently-failing diff --git a/gas/testsuite/gas/alpha/alpha.exp b/gas/testsuite/gas/alpha/alpha.exp index db16022ec5b..89a63345a7f 100644 --- a/gas/testsuite/gas/alpha/alpha.exp +++ b/gas/testsuite/gas/alpha/alpha.exp @@ -27,6 +27,8 @@ if { [istarget alpha*-*-*] } then { run_list_test "elf-reloc-2" "" run_list_test "elf-reloc-3" "" run_dump_test "elf-reloc-4" + run_dump_test "elf-reloc-5" + run_list_test "elf-reloc-6" "" } run_dump_test "fp" diff --git a/gas/testsuite/gas/alpha/elf-reloc-5.d b/gas/testsuite/gas/alpha/elf-reloc-5.d new file mode 100644 index 00000000000..0fd9261c170 --- /dev/null +++ b/gas/testsuite/gas/alpha/elf-reloc-5.d @@ -0,0 +1,28 @@ +#objdump: -dr +#name: alpha elf-reloc-5 + +.*: file format elf64-alpha + +Disassembly of section \.text: + +0*0000000 <_start>: + 0: 05 00 e0 c3 br 18 + 4: 04 00 e0 c3 br 18 + 8: 04 00 e0 c3 br 1c + c: 05 00 e0 c3 br 24 + 10: 00 00 e0 c3 br 14 <_start\+0x14> + 10: BRSGP undef + 14: 00 00 e0 c3 br 18 + 14: BRSGP extern + +0*0000018 : + 18: 1f 04 ff 47 nop + +0*000001c : + 1c: 00 00 bb 27 ldah gp,0\(t12\) + 1c: GPDISP \.text\+0x4 + 20: 00 00 bd 23 lda gp,0\(gp\) + 24: 1f 04 ff 47 nop + +0*0000028 : + 28: 1f 04 ff 47 nop diff --git a/gas/testsuite/gas/alpha/elf-reloc-5.s b/gas/testsuite/gas/alpha/elf-reloc-5.s new file mode 100644 index 00000000000..f8934a5d765 --- /dev/null +++ b/gas/testsuite/gas/alpha/elf-reloc-5.s @@ -0,0 +1,31 @@ + .text + .align 2 +_start: + br $31, nopv + br $31, nopv !samegp + br $31, stdgp + br $31, stdgp !samegp + + br $31, undef !samegp + br $31, extern !samegp + +.ent nopv +nopv: + .prologue 0 + nop +.end nopv + +.ent stdgp +stdgp: + ldgp $29,0($27) + .prologue 1 + nop +.end stdgp + +.globl extern +.ent extern +extern: + .prologue 0 + nop +.end extern + diff --git a/gas/testsuite/gas/alpha/elf-reloc-6.l b/gas/testsuite/gas/alpha/elf-reloc-6.l new file mode 100644 index 00000000000..85ee392c6c1 --- /dev/null +++ b/gas/testsuite/gas/alpha/elf-reloc-6.l @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*:8: Error: !samegp reloc against symbol without \.prologue: nopro +.*:10: Error: !samegp reloc against symbol without \.prologue: diff --git a/gas/testsuite/gas/alpha/elf-reloc-6.s b/gas/testsuite/gas/alpha/elf-reloc-6.s new file mode 100644 index 00000000000..af8fb1a7a36 --- /dev/null +++ b/gas/testsuite/gas/alpha/elf-reloc-6.s @@ -0,0 +1,31 @@ + br $31, undef + br $31, undef !samegp + br $31, nopv + br $31, nopv !samegp + br $31, stdgp + br $31, stdgp !samegp + br $31, nopro + br $31, nopro !samegp + br $31, 1f + br $31, 1f !samegp + +1: nop + +.ent nopv +nopv: + .prologue 0 + nop +.end nopv + +.ent stdgp +stdgp: + ldgp $29,0($27) + .prologue 1 + nop +.end stdgp + +.ent nopro +nopro: + nop +.end nopro +