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.
This commit is contained in:
parent
0e3212aded
commit
12b2cce914
|
@ -1,3 +1,11 @@
|
|||
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
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
|
||||
*relocation = val + addend;
|
||||
*relocation -= (input_section->output_section->vma
|
||||
+ input_section->output_offset);
|
||||
/* 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
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
|
||||
*relocation = val + addend;
|
||||
*relocation -= (input_section->output_section->vma
|
||||
+ input_section->output_offset);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
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,
|
||||
|
|
|
@ -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 <.*>
|
|
@ -0,0 +1 @@
|
|||
foo
|
|
@ -0,0 +1 @@
|
|||
bar 0x1450000
|
|
@ -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
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue