2012-11-14 Tristan Gingold <gingold@adacore.com>
* mach-o.c (bfd_mach_o_canonicalize_one_reloc): Add a special handling for non-scattered pairs. Update comments.
This commit is contained in:
parent
16efefc9e1
commit
f4716ee22e
|
@ -1,3 +1,8 @@
|
||||||
|
2012-11-14 Tristan Gingold <gingold@adacore.com>
|
||||||
|
|
||||||
|
* mach-o.c (bfd_mach_o_canonicalize_one_reloc): Add a special
|
||||||
|
handling for non-scattered pairs. Update comments.
|
||||||
|
|
||||||
2012-11-13 Joe Seymour <jseymour@codesourcery.com>
|
2012-11-13 Joe Seymour <jseymour@codesourcery.com>
|
||||||
|
|
||||||
* elf.c (rewrite_elf_program_header): Allocate elf_segment_map
|
* elf.c (rewrite_elf_program_header): Allocate elf_segment_map
|
||||||
|
|
50
bfd/mach-o.c
50
bfd/mach-o.c
|
@ -1018,7 +1018,7 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
|
||||||
addr = bfd_get_32 (abfd, raw->r_address);
|
addr = bfd_get_32 (abfd, raw->r_address);
|
||||||
res->sym_ptr_ptr = NULL;
|
res->sym_ptr_ptr = NULL;
|
||||||
res->addend = 0;
|
res->addend = 0;
|
||||||
|
|
||||||
if (addr & BFD_MACH_O_SR_SCATTERED)
|
if (addr & BFD_MACH_O_SR_SCATTERED)
|
||||||
{
|
{
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
@ -1056,22 +1056,35 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
|
|
||||||
/* Non-scattered relocation. */
|
/* Non-scattered relocation. */
|
||||||
reloc.r_scattered = 0;
|
reloc.r_scattered = 0;
|
||||||
|
|
||||||
/* The value and info fields have to be extracted dependent on target
|
/* The value and info fields have to be extracted dependent on target
|
||||||
endian-ness. */
|
endian-ness. */
|
||||||
bfd_mach_o_swap_in_non_scattered_reloc (abfd, &reloc, raw->r_symbolnum);
|
bfd_mach_o_swap_in_non_scattered_reloc (abfd, &reloc, raw->r_symbolnum);
|
||||||
num = reloc.r_value;
|
num = reloc.r_value;
|
||||||
|
|
||||||
if (reloc.r_extern)
|
if (reloc.r_extern)
|
||||||
sym = syms + num;
|
{
|
||||||
else if (reloc.r_scattered
|
/* An external symbol number. */
|
||||||
|| (reloc.r_type != BFD_MACH_O_GENERIC_RELOC_PAIR))
|
sym = syms + num;
|
||||||
|
}
|
||||||
|
else if (num == 0x00ffffff)
|
||||||
|
{
|
||||||
|
/* The 'symnum' in a non-scattered PAIR is 0x00ffffff. But as this
|
||||||
|
is generic code, we don't know wether this is really a PAIR.
|
||||||
|
This value is almost certainly not a valid section number, hence
|
||||||
|
this specific case to avoid an assertion failure.
|
||||||
|
Target specific swap_reloc_in routine should adjust that. */
|
||||||
|
sym = bfd_abs_section_ptr->symbol_ptr_ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
|
/* A section number. */
|
||||||
BFD_ASSERT (num != 0);
|
BFD_ASSERT (num != 0);
|
||||||
BFD_ASSERT (num <= mdata->nsects);
|
BFD_ASSERT (num <= mdata->nsects);
|
||||||
|
|
||||||
sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
|
sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
|
||||||
/* For a symbol defined in section S, the addend (stored in the
|
/* For a symbol defined in section S, the addend (stored in the
|
||||||
binary) contains the address of the section. To comply with
|
binary) contains the address of the section. To comply with
|
||||||
|
@ -1080,26 +1093,23 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
|
||||||
the vma of the section. */
|
the vma of the section. */
|
||||||
res->addend = -mdata->sections[num - 1]->addr;
|
res->addend = -mdata->sections[num - 1]->addr;
|
||||||
}
|
}
|
||||||
else /* ... The 'symnum' in a non-scattered PAIR will be 0x00ffffff. */
|
/* Note: Pairs for PPC LO/HI/HA are not scattered, but contain the offset
|
||||||
{
|
in the lower 16bits of the address value. So we have to find the
|
||||||
/* Pairs for PPC LO/HI/HA are not scattered, but contain the offset
|
'symbol' from the preceding reloc. We do this even though the
|
||||||
in the lower 16bits of the address value. So we have to find the
|
section symbol is probably not needed here, because NULL symbol
|
||||||
'symbol' from the preceding reloc. We do this even thoough the
|
values cause an assert in generic BFD code. This must be done in
|
||||||
section symbol is probably not needed here, because NULL symbol
|
the PPC swap_reloc_in routine. */
|
||||||
values cause an assert in generic BFD code. */
|
|
||||||
sym = (res - 1)->sym_ptr_ptr;
|
|
||||||
}
|
|
||||||
res->sym_ptr_ptr = sym;
|
res->sym_ptr_ptr = sym;
|
||||||
|
|
||||||
/* The 'address' is just r_address.
|
/* The 'address' is just r_address.
|
||||||
??? maybe this should be masked with 0xffffff for safety. */
|
??? maybe this should be masked with 0xffffff for safety. */
|
||||||
res->address = addr;
|
res->address = addr;
|
||||||
reloc.r_address = addr;
|
reloc.r_address = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have set up a reloc with all the information present, so the swapper can
|
/* We have set up a reloc with all the information present, so the swapper
|
||||||
modify address, value and addend fields, if necessary, to convey information
|
can modify address, value and addend fields, if necessary, to convey
|
||||||
in the generic BFD reloc that is mach-o specific. */
|
information in the generic BFD reloc that is mach-o specific. */
|
||||||
|
|
||||||
if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
|
if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue