diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2009-03-14 09:16:01 +0000 |
---|---|---|
committer | Richard Sandiford <rdsandiford@googlemail.com> | 2009-03-14 09:16:01 +0000 |
commit | 12b2cce9148e4cfdc9f135cfa1a21485be51dc5b (patch) | |
tree | 9d4e86818c270ad7f8d3572552a1ff66b3c24816 | |
parent | 0e3212adedf457b6f7b877b18667190cc79f0848 (diff) | |
download | gdb-12b2cce9148e4cfdc9f135cfa1a21485be51dc5b.zip gdb-12b2cce9148e4cfdc9f135cfa1a21485be51dc5b.tar.gz gdb-12b2cce9148e4cfdc9f135cfa1a21485be51dc5b.tar.bz2 |
bfd/
* coff-rs6000.c (xcoff_reloc_type_br): Make the branch absolute
if the target is absolute. Fix comment typo.
(xcoff_ppc_relocate_section): Remove FIXME.
* coff64-rs6000.c (xcoff64_reloc_type_br): Make the branch absolute
if the target is absolute.
ld/testsuite/
* ld-powerpc/aix-abs-branch-1.im, ld-powerpc/aix-abs-branch-1.ex,
ld-powerpc/aix-abs-branch-1.s,
ld-powerpc/aix-abs-branch-1.dd: New test.
* ld-powerpc/aix52.exp: Run it.
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/coff-rs6000.c | 53 | ||||
-rw-r--r-- | bfd/coff64-rs6000.c | 45 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/aix-abs-branch-1.dd | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/aix-abs-branch-1.ex | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/aix-abs-branch-1.im | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/aix-abs-branch-1.s | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/aix52.exp | 6 |
9 files changed, 126 insertions, 23 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9182ef2..818054c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,13 @@ 2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com> + * coff-rs6000.c (xcoff_reloc_type_br): Make the branch absolute + if the target is absolute. Fix comment typo. + (xcoff_ppc_relocate_section): Remove FIXME. + * coff64-rs6000.c (xcoff64_reloc_type_br): Make the branch absolute + if the target is absolute. + +2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com> + * xcofflink.c (xcoff_mark, xcoff_link_input_bfd): Don't copy R_POS and R_NEG relocations against absolute symbols to the .loader section. diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 1db66e7..0a849d1 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -2947,11 +2947,13 @@ xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, bfd_byte *contents; { struct xcoff_link_hash_entry *h; + bfd_vma section_offset; if (0 > rel->r_symndx) return FALSE; h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx]; + section_offset = rel->r_vaddr - input_section->vma; /* If we see an R_BR or R_RBR reloc which is jumping to global linkage code, and it is followed by an appropriate cror nop @@ -2962,12 +2964,12 @@ xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, cror. */ if (NULL != h && bfd_link_hash_defined == h->root.type - && rel->r_vaddr - input_section->vma + 8 <= input_section->size) + && section_offset + 8 <= input_section->size) { bfd_byte *pnext; unsigned long next; - pnext = contents + (rel->r_vaddr - input_section->vma) + 4; + pnext = contents + section_offset + 4; next = bfd_get_32 (input_bfd, pnext); /* The _ptrgl function is magic. It is used by the AIX @@ -2977,12 +2979,12 @@ xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, if (next == 0x4def7b82 /* cror 15,15,15 */ || next == 0x4ffffb82 /* cror 31,31,31 */ || next == 0x60000000) /* ori r0,r0,0 */ - bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */ + bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r2,20(r1) */ } else { - if (next == 0x80410014) /* lwz r1,20(r1) */ + if (next == 0x80410014) /* lwz r2,20(r1) */ bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */ } } @@ -2998,16 +3000,41 @@ xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, howto->complain_on_overflow = complain_overflow_dont; } - howto->pc_relative = TRUE; + /* The original PC-relative relocation is biased by -r_vaddr, so adding + the value below will give the absolute target address. */ + *relocation = val + addend + rel->r_vaddr; + howto->src_mask &= ~3; howto->dst_mask = howto->src_mask; - /* A PC relative reloc includes the section address. */ - addend += input_section->vma; - - *relocation = val + addend; - *relocation -= (input_section->output_section->vma - + input_section->output_offset); + if (h != NULL + && h->root.type == bfd_link_hash_defined + && bfd_is_abs_section (h->root.u.def.section) + && section_offset + 4 <= input_section->size) + { + bfd_byte *ptr; + bfd_vma insn; + + /* Turn the relative branch into an absolute one by setting the + AA bit. */ + ptr = contents + section_offset; + insn = bfd_get_32 (input_bfd, ptr); + insn |= 2; + bfd_put_32 (input_bfd, insn, ptr); + + /* Make the howto absolute too. */ + howto->pc_relative = FALSE; + howto->complain_on_overflow = complain_overflow_bitfield; + } + else + { + /* Use a PC-relative howto and subtract the instruction's address + from the target address we calculated above. */ + howto->pc_relative = TRUE; + *relocation -= (input_section->output_section->vma + + input_section->output_offset + + section_offset); + } return TRUE; } @@ -3323,9 +3350,7 @@ xcoff_complain_overflow_unsigned_func (input_bfd, val, relocation, howto) R_RBR: A relative branch which may be modified to become an - absolute branch. FIXME: We don't implement this, - although we should for symbols of storage mapping class - XMC_XO. + absolute branch. R_RL: The PowerPC AIX ABI describes this as a load which may be diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 1448917..71a02c2 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -1117,11 +1117,13 @@ xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, bfd_byte *contents; { struct xcoff_link_hash_entry *h; + bfd_vma section_offset; if (0 > rel->r_symndx) return FALSE; h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx]; + section_offset = rel->r_vaddr - input_section->vma; /* If we see an R_BR or R_RBR reloc which is jumping to global linkage code, and it is followed by an appropriate cror nop @@ -1132,12 +1134,12 @@ xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, cror. */ if (NULL != h && bfd_link_hash_defined == h->root.type - && rel->r_vaddr - input_section->vma + 8 <= input_section->size) + && section_offset + 8 <= input_section->size) { bfd_byte *pnext; unsigned long next; - pnext = contents + (rel->r_vaddr - input_section->vma) + 4; + pnext = contents + section_offset + 4; next = bfd_get_32 (input_bfd, pnext); /* The _ptrgl function is magic. It is used by the AIX compiler to call @@ -1166,16 +1168,41 @@ xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, howto->complain_on_overflow = complain_overflow_dont; } - howto->pc_relative = TRUE; + /* The original PC-relative relocation is biased by -r_vaddr, so adding + the value below will give the absolute target address. */ + *relocation = val + addend + rel->r_vaddr; + howto->src_mask &= ~3; howto->dst_mask = howto->src_mask; - /* A PC relative reloc includes the section address. */ - addend += input_section->vma; - - *relocation = val + addend; - *relocation -= (input_section->output_section->vma - + input_section->output_offset); + if (h != NULL + && h->root.type == bfd_link_hash_defined + && bfd_is_abs_section (h->root.u.def.section) + && section_offset + 4 <= input_section->size) + { + bfd_byte *ptr; + bfd_vma insn; + + /* Turn the relative branch into an absolute one by setting the + AA bit. */ + ptr = contents + section_offset; + insn = bfd_get_32 (input_bfd, ptr); + insn |= 2; + bfd_put_32 (input_bfd, insn, ptr); + + /* Make the howto absolute too. */ + howto->pc_relative = FALSE; + howto->complain_on_overflow = complain_overflow_bitfield; + } + else + { + /* Use a PC-relative howto and subtract the instruction's address + from the target address we calculated above. */ + howto->pc_relative = TRUE; + *relocation -= (input_section->output_section->vma + + input_section->output_offset + + section_offset); + } return TRUE; } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index b02892b..55e3a92 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com> + * ld-powerpc/aix-abs-branch-1.im, ld-powerpc/aix-abs-branch-1.ex, + ld-powerpc/aix-abs-branch-1.s, + ld-powerpc/aix-abs-branch-1.dd: New test. + * ld-powerpc/aix52.exp: Run it. + +2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com> + * ld-powerpc/aix-abs-reloc-1.ex, ld-powerpc/aix-abs-reloc-1.im, ld-powerpc/aix-abs-reloc-1.od, ld-powerpc/aix-abs-reloc-1.s: New test. * ld-powerpc/aix52.exp: Run it. diff --git a/ld/testsuite/ld-powerpc/aix-abs-branch-1.dd b/ld/testsuite/ld-powerpc/aix-abs-branch-1.dd new file mode 100644 index 0000000..6bfd136 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-abs-branch-1.dd @@ -0,0 +1,14 @@ + +.* + + +Disassembly of section \.text: + +0*10000000 <foo>: + *10000000:.* bla * 144d000 <.*> + *10000004:.* l(wz|) * r1,80\(r1\) + *10000008:.* bla * 1451000 <.*> + *1000000c:.* (oril * r0,r0,0|nop) + *10000010:.* bla * 1452800 <.*> + *10000014:.* (oril * r0,r0,0|nop) + *10000018:.* bla * 1450000 <.*> diff --git a/ld/testsuite/ld-powerpc/aix-abs-branch-1.ex b/ld/testsuite/ld-powerpc/aix-abs-branch-1.ex new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-abs-branch-1.ex @@ -0,0 +1 @@ +foo diff --git a/ld/testsuite/ld-powerpc/aix-abs-branch-1.im b/ld/testsuite/ld-powerpc/aix-abs-branch-1.im new file mode 100644 index 0000000..0efbfc9 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-abs-branch-1.im @@ -0,0 +1 @@ +bar 0x1450000 diff --git a/ld/testsuite/ld-powerpc/aix-abs-branch-1.s b/ld/testsuite/ld-powerpc/aix-abs-branch-1.s new file mode 100644 index 0000000..82c322f --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-abs-branch-1.s @@ -0,0 +1,14 @@ + .globl foo + .csect foo[PR] +foo: + bl bar - 0x3000 + lwz 1,80(1) + bl bar + 0x1000 + .ifeq size - 32 + lwz 2,20(1) + .else + ld 2,40(1) + .endif + bl bar + 0x2800 + nop + bl bar diff --git a/ld/testsuite/ld-powerpc/aix52.exp b/ld/testsuite/ld-powerpc/aix52.exp index 1263796..632d0b9 100644 --- a/ld/testsuite/ld-powerpc/aix52.exp +++ b/ld/testsuite/ld-powerpc/aix52.exp @@ -65,6 +65,12 @@ proc run_aix_test { size name ldopts asopts sources tools output } { } set aix52tests { + {"Absolute branch test 1" + "-shared -bI:aix-abs-branch-1.im -bE:aix-abs-branch-1.ex" + "" {aix-abs-branch-1.s} + {{objdump {-dR} aix-abs-branch-1.dd}} + "aix-abs-branch-1.so"} + {"Relocations against absolute symbols 1" "-shared -bI:aix-abs-reloc-1.im -bE:aix-abs-reloc-1.ex" {} {aix-abs-reloc-1.s} |