elf32-ppc.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,931 行 · 第 1/5 页
C
1,931 行
} } else if ((insn & 0xFc00Fffe) == 0x4c000420) { /* Instruction is BCCTRx */ if ((!BO0(insn) || !BO2(insn)) && !BO4(insn)) { /* This branch is predicted as not-taken. If this is a forward branch, it is problematic. Since we can't tell statically if it will branch forward, always set the prediction bit. */ insn |= 0x00200000; /* set the prediction bit */ modified = true; } } else if ((insn & 0xFc00Fffe) == 0x4c000020) { /* Instruction is BCLRx */ if ((!BO0(insn) || !BO2(insn)) && !BO4(insn)) { /* This branch is predicted as not-taken. If this is a forward branch, it is problematic. Since we can't tell statically if it will branch forward, always set the prediction bit. */ insn |= 0x00200000; /* set the prediction bit */ modified = true; } }#undef BO0#undef BO2#undef BO4 if (modified) { bfd_put_32 (abfd, insn, contents + isec_offset); section_modified = true; } } } if (section_modified) { elf_section_data (isec)->this_hdr.contents = contents; free_contents = NULL; } } if (rela_comb != NULL) { free (rela_comb); rela_comb = NULL; } if (free_relocs != NULL) { free (free_relocs); free_relocs = NULL; } if (free_contents != NULL) { if (! link_info->keep_memory) free (free_contents); else { /* Cache the section contents for elf_link_input_bfd. */ elf_section_data (isec)->this_hdr.contents = contents; } free_contents = NULL; } return true;error_return: if (rela_comb != NULL) free (rela_comb); if (free_relocs != NULL) free (free_relocs); if (free_contents != NULL) free (free_contents); return false;}static reloc_howto_type *ppc_elf_reloc_type_lookup (abfd, code) bfd *abfd ATTRIBUTE_UNUSED; bfd_reloc_code_real_type code;{ enum elf_ppc_reloc_type ppc_reloc = R_PPC_NONE; if (!ppc_elf_howto_table[R_PPC_ADDR32]) /* Initialize howto table if needed. */ ppc_elf_howto_init (); switch ((int) code) { default: return (reloc_howto_type *) NULL; case BFD_RELOC_NONE: ppc_reloc = R_PPC_NONE; break; case BFD_RELOC_32: ppc_reloc = R_PPC_ADDR32; break; case BFD_RELOC_PPC_BA26: ppc_reloc = R_PPC_ADDR24; break; case BFD_RELOC_16: ppc_reloc = R_PPC_ADDR16; break; case BFD_RELOC_LO16: ppc_reloc = R_PPC_ADDR16_LO; break; case BFD_RELOC_HI16: ppc_reloc = R_PPC_ADDR16_HI; break; case BFD_RELOC_HI16_S: ppc_reloc = R_PPC_ADDR16_HA; break; case BFD_RELOC_PPC_BA16: ppc_reloc = R_PPC_ADDR14; break; case BFD_RELOC_PPC_BA16_BRTAKEN: ppc_reloc = R_PPC_ADDR14_BRTAKEN; break; case BFD_RELOC_PPC_BA16_BRNTAKEN: ppc_reloc = R_PPC_ADDR14_BRNTAKEN; break; case BFD_RELOC_PPC_B26: ppc_reloc = R_PPC_REL24; break; case BFD_RELOC_PPC_B16: ppc_reloc = R_PPC_REL14; break; case BFD_RELOC_PPC_B16_BRTAKEN: ppc_reloc = R_PPC_REL14_BRTAKEN; break; case BFD_RELOC_PPC_B16_BRNTAKEN: ppc_reloc = R_PPC_REL14_BRNTAKEN; break; case BFD_RELOC_16_GOTOFF: ppc_reloc = R_PPC_GOT16; break; case BFD_RELOC_LO16_GOTOFF: ppc_reloc = R_PPC_GOT16_LO; break; case BFD_RELOC_HI16_GOTOFF: ppc_reloc = R_PPC_GOT16_HI; break; case BFD_RELOC_HI16_S_GOTOFF: ppc_reloc = R_PPC_GOT16_HA; break; case BFD_RELOC_24_PLT_PCREL: ppc_reloc = R_PPC_PLTREL24; break; case BFD_RELOC_PPC_COPY: ppc_reloc = R_PPC_COPY; break; case BFD_RELOC_PPC_GLOB_DAT: ppc_reloc = R_PPC_GLOB_DAT; break; case BFD_RELOC_PPC_LOCAL24PC: ppc_reloc = R_PPC_LOCAL24PC; break; case BFD_RELOC_32_PCREL: ppc_reloc = R_PPC_REL32; break; case BFD_RELOC_32_PLTOFF: ppc_reloc = R_PPC_PLT32; break; case BFD_RELOC_32_PLT_PCREL: ppc_reloc = R_PPC_PLTREL32; break; case BFD_RELOC_LO16_PLTOFF: ppc_reloc = R_PPC_PLT16_LO; break; case BFD_RELOC_HI16_PLTOFF: ppc_reloc = R_PPC_PLT16_HI; break; case BFD_RELOC_HI16_S_PLTOFF: ppc_reloc = R_PPC_PLT16_HA; break; case BFD_RELOC_GPREL16: ppc_reloc = R_PPC_SDAREL16; break; case BFD_RELOC_32_BASEREL: ppc_reloc = R_PPC_SECTOFF; break; case BFD_RELOC_LO16_BASEREL: ppc_reloc = R_PPC_SECTOFF_LO; break; case BFD_RELOC_HI16_BASEREL: ppc_reloc = R_PPC_SECTOFF_HI; break; case BFD_RELOC_HI16_S_BASEREL: ppc_reloc = R_PPC_SECTOFF_HA; break; case BFD_RELOC_CTOR: ppc_reloc = R_PPC_ADDR32; break; case BFD_RELOC_PPC_TOC16: ppc_reloc = R_PPC_TOC16; break; case BFD_RELOC_PPC_EMB_NADDR32: ppc_reloc = R_PPC_EMB_NADDR32; break; case BFD_RELOC_PPC_EMB_NADDR16: ppc_reloc = R_PPC_EMB_NADDR16; break; case BFD_RELOC_PPC_EMB_NADDR16_LO: ppc_reloc = R_PPC_EMB_NADDR16_LO; break; case BFD_RELOC_PPC_EMB_NADDR16_HI: ppc_reloc = R_PPC_EMB_NADDR16_HI; break; case BFD_RELOC_PPC_EMB_NADDR16_HA: ppc_reloc = R_PPC_EMB_NADDR16_HA; break; case BFD_RELOC_PPC_EMB_SDAI16: ppc_reloc = R_PPC_EMB_SDAI16; break; case BFD_RELOC_PPC_EMB_SDA2I16: ppc_reloc = R_PPC_EMB_SDA2I16; break; case BFD_RELOC_PPC_EMB_SDA2REL: ppc_reloc = R_PPC_EMB_SDA2REL; break; case BFD_RELOC_PPC_EMB_SDA21: ppc_reloc = R_PPC_EMB_SDA21; break; case BFD_RELOC_PPC_EMB_MRKREF: ppc_reloc = R_PPC_EMB_MRKREF; break; case BFD_RELOC_PPC_EMB_RELSEC16: ppc_reloc = R_PPC_EMB_RELSEC16; break; case BFD_RELOC_PPC_EMB_RELST_LO: ppc_reloc = R_PPC_EMB_RELST_LO; break; case BFD_RELOC_PPC_EMB_RELST_HI: ppc_reloc = R_PPC_EMB_RELST_HI; break; case BFD_RELOC_PPC_EMB_RELST_HA: ppc_reloc = R_PPC_EMB_RELST_HA; break; case BFD_RELOC_PPC_EMB_BIT_FLD: ppc_reloc = R_PPC_EMB_BIT_FLD; break; case BFD_RELOC_PPC_EMB_RELSDA: ppc_reloc = R_PPC_EMB_RELSDA; break; case BFD_RELOC_VTABLE_INHERIT: ppc_reloc = R_PPC_GNU_VTINHERIT; break; case BFD_RELOC_VTABLE_ENTRY: ppc_reloc = R_PPC_GNU_VTENTRY; break; } return ppc_elf_howto_table[(int) ppc_reloc];};/* Set the howto pointer for a PowerPC ELF reloc. */static voidppc_elf_info_to_howto (abfd, cache_ptr, dst) bfd *abfd ATTRIBUTE_UNUSED; arelent *cache_ptr; Elf32_Internal_Rela *dst;{ if (!ppc_elf_howto_table[R_PPC_ADDR32]) /* Initialize howto table if needed. */ ppc_elf_howto_init (); BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max); cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)];}/* Handle the R_PPC_ADDR16_HA reloc. */static bfd_reloc_status_typeppc_elf_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) bfd *abfd ATTRIBUTE_UNUSED; arelent *reloc_entry; asymbol *symbol; PTR data ATTRIBUTE_UNUSED; asection *input_section; bfd *output_bfd; char **error_message ATTRIBUTE_UNUSED;{ bfd_vma relocation; if (output_bfd != NULL) { reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; } if (reloc_entry->address > input_section->_cooked_size) return bfd_reloc_outofrange; if (bfd_is_com_section (symbol->section)) relocation = 0; else relocation = symbol->value; relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset; relocation += reloc_entry->addend; reloc_entry->addend += (relocation & 0x8000) << 1; return bfd_reloc_continue;}/* Function to set whether a module needs the -mrelocatable bit set. */static booleanppc_elf_set_private_flags (abfd, flags) bfd *abfd; flagword flags;{ BFD_ASSERT (!elf_flags_init (abfd) || elf_elfheader (abfd)->e_flags == flags); elf_elfheader (abfd)->e_flags = flags; elf_flags_init (abfd) = true; return true;}/* Copy backend specific data from one object module to another */static booleanppc_elf_copy_private_bfd_data (ibfd, obfd) bfd *ibfd; bfd *obfd;{ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) return true; BFD_ASSERT (!elf_flags_init (obfd) || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags); elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; elf_flags_init (obfd) = true; return true;}/* Merge backend specific data from an object file to the output object file when linking */static booleanppc_elf_merge_private_bfd_data (ibfd, obfd) bfd *ibfd; bfd *obfd;{ flagword old_flags; flagword new_flags; boolean error; /* Check if we have the same endianess */ if (_bfd_generic_verify_endian_match (ibfd, obfd) == false) return false; if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) return true; new_flags = elf_elfheader (ibfd)->e_flags; old_flags = elf_elfheader (obfd)->e_flags; if (!elf_flags_init (obfd)) /* First call, no flags set */ { elf_flags_init (obfd) = true; elf_elfheader (obfd)->e_flags = new_flags; } else if (new_flags == old_flags) /* Compatible flags are ok */ ; else /* Incompatible flags */ { /* Warn about -mrelocatable mismatch. Allow -mrelocatable-lib to be linked with either. */ error = false; if ((new_flags & EF_PPC_RELOCATABLE) != 0 && (old_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0) { error = true; (*_bfd_error_handler) (_("%s: compiled with -mrelocatable and linked with modules compiled normally"), bfd_get_filename (ibfd)); } else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0 && (old_flags & EF_PPC_RELOCATABLE) != 0) { error = true; (*_bfd_error_handler) (_("%s: compiled normally and linked with modules compiled with -mrelocatable"), bfd_get_filename (ibfd)); } /* The output is -mrelocatable-lib iff both the input files are. */ if (! (new_flags & EF_PPC_RELOCATABLE_LIB)) elf_elfheader (obfd)->e_flags &= ~EF_PPC_RELOCATABLE_LIB; /* The output is -mrelocatable iff it can't be -mrelocatable-lib, but each input file is either -mrelocatable or -mrelocatable-lib. */ if (! (elf_elfheader (obfd)->e_flags & EF_PPC_RELOCATABLE_LIB) && (new_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE)) && (old_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE))) elf_elfheader (obfd)->e_flags |= EF_PPC_RELOCATABLE; /* Do not warn about eabi vs. V.4 mismatch, just or in the bit if any module uses it */ elf_elfheader (obfd)->e_flags |= (new_flags & EF_PPC_EMB); new_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB); old_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB); /* Warn about any other mismatches */ if (new_flags != old_flags) { error = true; (*_bfd_error_handler) (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"), bfd_get_filename (ibfd), (long) new_flags, (long) old_flags); } if (error) { bfd_set_error (bfd_error_bad_value); return false; } } return true;}/* Handle a PowerPC specific section when reading an object file. This is called when elfcode.h finds a section with an unknown type. */static booleanppc_elf_section_from_shdr (abfd, hdr, name) bfd *abfd; Elf32_Internal_Shdr *hdr; char *name;{ asection *newsect; flagword flags; if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) return false; newsect = hdr->bfd_section; flags = bfd_get_section_flags (abfd, newsect); if (hdr->sh_flags & SHF_EXCLUDE) flags |= SEC_EXCLUDE; if (hdr->sh_type == SHT_ORDERED) flags |= SEC_SORT_ENTRIES; bfd_set_section_flags (abfd, newsect, flags); return true;}/* Set up any other section flags and such that may be necessary. */static booleanppc_elf_fake_sections (abfd, shdr, asect) bfd *abfd ATTRIBUTE_UNUSED; Elf32_Internal_Shdr *shdr; asection *asect;{ if ((asect->flags & SEC_EXCLUDE) != 0) shdr->sh_flags |= SHF_EXCLUDE; if ((asect->flags & SEC_SORT_ENTRIES) != 0) shdr->sh_type = SHT_ORDERED; return true;}/* Create a special linker section */static elf_linker_section_t *ppc_elf_create_linker_section (abfd, info, which) bfd *abfd; struct bfd_link_info *info; enum elf_linker_section_enum which;{ bfd *dynobj = elf_hash_table (info)->dynobj; elf_linker_section_t *lsect; /* Record the first bfd section that needs the special section */ if (!dynobj) dynobj = elf_hash_table (info)->dynobj = abfd;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?