diff options
-rw-r--r-- | gas/ChangeLog | 5 | ||||
-rw-r--r-- | gas/config/tc-mips.c | 100 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/mips/elf-rel15.d | 14 | ||||
-rw-r--r-- | gas/testsuite/gas/mips/elf-rel15.s | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/mips/mips.exp | 2 |
6 files changed, 56 insertions, 74 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 9df96ef..1a1bb29 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2003-06-12 Richard Sandiford <rsandifo@redhat.com> + + * config/tc-mips.c (append_insn): In a compound relocation, take the + field width from the final (outermost) operator. + 2003-06-11 Richard Henderson <rth@redhat.com> * dw2gencfi.c (struct cfi_escape_data): New. diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 5d58d40..938148c 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -2154,13 +2154,20 @@ append_insn (place, ip, address_expr, reloc_type) } else { - reloc_howto_type *howto; - need_reloc: /* Don't generate a reloc if we are writing into a variant frag. */ if (place == NULL) { - howto = bfd_reloc_type_lookup (stdoutput, reloc_type[0]); + reloc_howto_type *howto; + int i; + + /* In a compound relocation, it is the final (outermost) + operator that determines the relocated field. */ + for (i = 1; i < 3; i++) + if (reloc_type[i] == BFD_RELOC_UNUSED) + break; + + howto = bfd_reloc_type_lookup (stdoutput, reloc_type[i - 1]); fixp[0] = fix_new_exp (frag_now, f - frag_now->fr_literal, bfd_get_reloc_size(howto), address_expr, @@ -2207,77 +2214,22 @@ append_insn (place, ip, address_expr, reloc_type) hi_fixup->seg = now_seg; } - if (reloc_type[1] != BFD_RELOC_UNUSED) - { - /* FIXME: This symbol can be one of - RSS_UNDEF, RSS_GP, RSS_GP0, RSS_LOC. */ - address_expr->X_op = O_absent; - address_expr->X_add_symbol = 0; - address_expr->X_add_number = 0; - - howto = bfd_reloc_type_lookup (stdoutput, reloc_type[1]); - fixp[1] = fix_new_exp (frag_now, f - frag_now->fr_literal, - bfd_get_reloc_size(howto), - address_expr, FALSE, reloc_type[1]); - - /* These relocations can have an addend that won't fit in - 4 octets for 64bit assembly. */ - if (HAVE_64BIT_GPRS - && ! howto->partial_inplace - && (reloc_type[1] == BFD_RELOC_16 - || reloc_type[1] == BFD_RELOC_32 - || reloc_type[1] == BFD_RELOC_MIPS_JMP - || reloc_type[1] == BFD_RELOC_HI16_S - || reloc_type[1] == BFD_RELOC_LO16 - || reloc_type[1] == BFD_RELOC_GPREL16 - || reloc_type[1] == BFD_RELOC_MIPS_LITERAL - || reloc_type[1] == BFD_RELOC_GPREL32 - || reloc_type[1] == BFD_RELOC_64 - || reloc_type[1] == BFD_RELOC_CTOR - || reloc_type[1] == BFD_RELOC_MIPS_SUB - || reloc_type[1] == BFD_RELOC_MIPS_HIGHEST - || reloc_type[1] == BFD_RELOC_MIPS_HIGHER - || reloc_type[1] == BFD_RELOC_MIPS_SCN_DISP - || reloc_type[1] == BFD_RELOC_MIPS_REL16 - || reloc_type[1] == BFD_RELOC_MIPS_RELGOT)) - fixp[1]->fx_no_overflow = 1; - - if (reloc_type[2] != BFD_RELOC_UNUSED) - { - address_expr->X_op = O_absent; - address_expr->X_add_symbol = 0; - address_expr->X_add_number = 0; - - howto = bfd_reloc_type_lookup (stdoutput, reloc_type[2]); - fixp[2] = fix_new_exp (frag_now, - f - frag_now->fr_literal, - bfd_get_reloc_size(howto), - address_expr, FALSE, - reloc_type[2]); - - /* These relocations can have an addend that won't fit in - 4 octets for 64bit assembly. */ - if (HAVE_64BIT_GPRS - && ! howto->partial_inplace - && (reloc_type[2] == BFD_RELOC_16 - || reloc_type[2] == BFD_RELOC_32 - || reloc_type[2] == BFD_RELOC_MIPS_JMP - || reloc_type[2] == BFD_RELOC_HI16_S - || reloc_type[2] == BFD_RELOC_LO16 - || reloc_type[2] == BFD_RELOC_GPREL16 - || reloc_type[2] == BFD_RELOC_MIPS_LITERAL - || reloc_type[2] == BFD_RELOC_GPREL32 - || reloc_type[2] == BFD_RELOC_64 - || reloc_type[2] == BFD_RELOC_CTOR - || reloc_type[2] == BFD_RELOC_MIPS_SUB - || reloc_type[2] == BFD_RELOC_MIPS_HIGHEST - || reloc_type[2] == BFD_RELOC_MIPS_HIGHER - || reloc_type[2] == BFD_RELOC_MIPS_SCN_DISP - || reloc_type[2] == BFD_RELOC_MIPS_REL16 - || reloc_type[2] == BFD_RELOC_MIPS_RELGOT)) - fixp[2]->fx_no_overflow = 1; - } - } + /* Add fixups for the second and third relocations, if given. + Note that the ABI allows the second relocation to be + against RSS_UNDEF, RSS_GP, RSS_GP0 or RSS_LOC. At the + moment we only use RSS_UNDEF, but we could add support + for the others if it ever becomes necessary. */ + for (i = 1; i < 3; i++) + if (reloc_type[i] != BFD_RELOC_UNUSED) + { + address_expr->X_op = O_absent; + address_expr->X_add_symbol = 0; + address_expr->X_add_number = 0; + + fixp[i] = fix_new_exp (frag_now, fixp[0]->fx_where, + fixp[0]->fx_size, address_expr, + FALSE, reloc_type[i]); + } } } } diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 1ef04ab..8458294 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-06-12 Richard Sandiford <rsandifo@redhat.com> + + * gas/mips/elf-rel15.[sd]: New test. + * gas/mips/mips.exp: Run it. + 2003-06-11 Richard Henderson <rth@redhat.com> * gas/cfi/cfi-common-3.[ds]: New. diff --git a/gas/testsuite/gas/mips/elf-rel15.d b/gas/testsuite/gas/mips/elf-rel15.d new file mode 100644 index 0000000..7bb7878 --- /dev/null +++ b/gas/testsuite/gas/mips/elf-rel15.d @@ -0,0 +1,14 @@ +#objdump: -dr +#as: -mabi=n32 -mips3 + +.*: file format .* + +Disassembly of section \.text: + +00000000 <foo>: + 0: 3c020000 lui v0,0x0 + 0: R_MIPS_GPREL16 \.text + 0: R_MIPS_SUB \*ABS\* + 0: R_MIPS_HI16 \*ABS\* + 4: 23bdffe4 addi sp,sp,-28 + ... diff --git a/gas/testsuite/gas/mips/elf-rel15.s b/gas/testsuite/gas/mips/elf-rel15.s new file mode 100644 index 0000000..c0bc623 --- /dev/null +++ b/gas/testsuite/gas/mips/elf-rel15.s @@ -0,0 +1,4 @@ +foo: + lui $2,%hi(%neg(%gp_rel(foo))) + sub $sp,$sp,28 + .space 16 diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp index 9bb3772..2330443 100644 --- a/gas/testsuite/gas/mips/mips.exp +++ b/gas/testsuite/gas/mips/mips.exp @@ -645,6 +645,8 @@ if { [istarget mips*-*-*] } then { run_dump_test "elf-rel14" if $has_newabi { + run_dump_test "elf-rel15" + run_dump_test "elf-rel-got-n32" run_dump_test "elf-rel-xgot-n32" run_dump_test "elf-rel-got-n64" |