diff options
Diffstat (limited to 'contrib/binutils/bfd/elf32-ppc.c')
-rw-r--r-- | contrib/binutils/bfd/elf32-ppc.c | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/contrib/binutils/bfd/elf32-ppc.c b/contrib/binutils/bfd/elf32-ppc.c index 31d9e0c..9abdf61 100644 --- a/contrib/binutils/bfd/elf32-ppc.c +++ b/contrib/binutils/bfd/elf32-ppc.c @@ -43,6 +43,7 @@ static boolean ppc_elf_relax_section PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); static bfd_reloc_status_type ppc_elf_addr16_ha_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static boolean ppc_elf_object_p PARAMS ((bfd *)); static boolean ppc_elf_set_private_flags PARAMS ((bfd *, flagword)); static boolean ppc_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *)); @@ -56,7 +57,7 @@ static boolean ppc_elf_create_dynamic_sections static boolean ppc_elf_section_from_shdr PARAMS ((bfd *, Elf32_Internal_Shdr *, - char *)); + const char *)); static boolean ppc_elf_fake_sections PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *)); @@ -70,7 +71,7 @@ static boolean ppc_elf_check_relocs PARAMS ((bfd *, asection *, const Elf_Internal_Rela *)); -static asection * ppc_elf_gc_mark_hook PARAMS ((bfd *abfd, +static asection * ppc_elf_gc_mark_hook PARAMS ((asection *sec, struct bfd_link_info *info, Elf_Internal_Rela *rel, struct elf_link_hash_entry *h, @@ -1380,6 +1381,27 @@ ppc_elf_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section, return bfd_reloc_continue; } +/* Fix bad default arch selected for a 32 bit input bfd when the + default is 64 bit. */ + +static boolean +ppc_elf_object_p (abfd) + bfd *abfd; +{ + if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 64) + { + Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd); + + if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS32) + { + /* Relies on arch after 64 bit default being 32 bit default. */ + abfd->arch_info = abfd->arch_info->next; + BFD_ASSERT (abfd->arch_info->bits_per_word == 32); + } + } + return true; +} + /* Function to set whether a module needs the -mrelocatable bit set. */ static boolean @@ -1407,7 +1429,7 @@ ppc_elf_merge_private_bfd_data (ibfd, obfd) boolean error; /* Check if we have the same endianess */ - if (_bfd_generic_verify_endian_match (ibfd, obfd) == false) + if (! _bfd_generic_verify_endian_match (ibfd, obfd)) return false; if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour @@ -1490,7 +1512,7 @@ static boolean ppc_elf_section_from_shdr (abfd, hdr, name) bfd *abfd; Elf32_Internal_Shdr *hdr; - char *name; + const char *name; { asection *newsect; flagword flags; @@ -2459,8 +2481,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -ppc_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +ppc_elf_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -2490,9 +2512,7 @@ ppc_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } @@ -2723,11 +2743,11 @@ ppc_elf_finish_dynamic_symbol (output_bfd, info, h, sym) else { BFD_ASSERT ((h->got.offset & 1) == 0); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset); rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_GLOB_DAT); rela.r_addend = 0; } + bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset); bfd_elf32_swap_reloca_out (output_bfd, &rela, ((Elf32_External_Rela *) srela->contents + srela->reloc_count)); @@ -3267,13 +3287,19 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, + sreloc->reloc_count)); ++sreloc->reloc_count; - /* This reloc will be computed at runtime, so there's no - need to do anything now, unless this is a RELATIVE - reloc in an unallocated section. */ - if (skip != -1 - || (input_section->flags & SEC_ALLOC) != 0 - || ELF32_R_TYPE (outrel.r_info) != R_PPC_RELATIVE) + if (skip == -1) continue; + + /* This reloc will be computed at runtime. We clear the memory + so that it contains predictable value. */ + if (! skip + && ((input_section->flags & SEC_ALLOC) != 0 + || ELF32_R_TYPE (outrel.r_info) != R_PPC_RELATIVE)) + { + relocation = howto->pc_relative ? outrel.r_offset : 0; + addend = 0; + break; + } } /* Arithmetic adjust relocations that aren't going into a @@ -3370,7 +3396,6 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, off &= ~1; else { - bfd_put_32 (output_bfd, relocation, sgot->contents + off); if (info->shared) { @@ -3392,8 +3417,10 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, srelgot->contents) + srelgot->reloc_count)); ++srelgot->reloc_count; + relocation = 0; } + bfd_put_32 (output_bfd, relocation, sgot->contents + off); local_got_offsets[r_symndx] |= 1; } @@ -3797,6 +3824,7 @@ ppc_elf_grok_psinfo (abfd, note) #define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags #define bfd_elf32_bfd_final_link _bfd_elf32_gc_common_final_link +#define elf_backend_object_p ppc_elf_object_p #define elf_backend_gc_mark_hook ppc_elf_gc_mark_hook #define elf_backend_gc_sweep_hook ppc_elf_gc_sweep_hook #define elf_backend_section_from_shdr ppc_elf_section_from_shdr |