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:
Tristan Gingold 2012-11-14 10:29:46 +00:00
parent 16efefc9e1
commit f4716ee22e
2 changed files with 35 additions and 20 deletions

View File

@ -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

View File

@ -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;