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 + -
显示快捷键?