elfcode.h

来自「基于4个mips核的noc设计」· C头文件 代码 · 共 1,567 行 · 第 1/4 页

H
1,567
字号
/* Translate an ELF reloc from external format to internal format.  */INLINE voidelf_swap_reloc_in (abfd, src, dst)     bfd *abfd;     const Elf_External_Rel *src;     Elf_Internal_Rel *dst;{  dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset);  dst->r_info = get_word (abfd, (bfd_byte *) src->r_info);}INLINE voidelf_swap_reloca_in (abfd, src, dst)     bfd *abfd;     const Elf_External_Rela *src;     Elf_Internal_Rela *dst;{  dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset);  dst->r_info = get_word (abfd, (bfd_byte *) src->r_info);  dst->r_addend = get_signed_word (abfd, (bfd_byte *) src->r_addend);}/* Translate an ELF reloc from internal format to external format.  */INLINE voidelf_swap_reloc_out (abfd, src, dst)     bfd *abfd;     const Elf_Internal_Rel *src;     Elf_External_Rel *dst;{  put_word (abfd, src->r_offset, dst->r_offset);  put_word (abfd, src->r_info, dst->r_info);}INLINE voidelf_swap_reloca_out (abfd, src, dst)     bfd *abfd;     const Elf_Internal_Rela *src;     Elf_External_Rela *dst;{  put_word (abfd, src->r_offset, dst->r_offset);  put_word (abfd, src->r_info, dst->r_info);  put_signed_word (abfd, src->r_addend, dst->r_addend);}INLINE voidelf_swap_dyn_in (abfd, p, dst)     bfd *abfd;     const PTR p;     Elf_Internal_Dyn *dst;{  const Elf_External_Dyn *src = (const Elf_External_Dyn *) p;  dst->d_tag = get_word (abfd, src->d_tag);  dst->d_un.d_val = get_word (abfd, src->d_un.d_val);}INLINE voidelf_swap_dyn_out (abfd, src, p)     bfd *abfd;     const Elf_Internal_Dyn *src;     PTR p;{  Elf_External_Dyn *dst = (Elf_External_Dyn *) p;  put_word (abfd, src->d_tag, dst->d_tag);  put_word (abfd, src->d_un.d_val, dst->d_un.d_val);}/* ELF .o/exec file reading *//* Begin processing a given object.   First we validate the file by reading in the ELF header and checking   the magic number.  */static INLINE booleanelf_file_p (x_ehdrp)     Elf_External_Ehdr *x_ehdrp;{  return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0)	  && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1)	  && (x_ehdrp->e_ident[EI_MAG2] == ELFMAG2)	  && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3));}/* Check to see if the file associated with ABFD matches the target vector   that ABFD points to.   Note that we may be called several times with the same ABFD, but different   target vectors, most of which will not match.  We have to avoid leaving   any side effects in ABFD, or any data it points to (like tdata), if the   file does not match the target vector.  */const bfd_target *elf_object_p (abfd)     bfd *abfd;{  Elf_External_Ehdr x_ehdr;	/* Elf file header, external form */  Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */  Elf_External_Shdr x_shdr;	/* Section header table entry, external form */  Elf_Internal_Shdr *i_shdrp = NULL; /* Section header table, internal form */  unsigned int shindex;  char *shstrtab;		/* Internal copy of section header stringtab */  struct elf_backend_data *ebd;  struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);  struct sec *preserved_sections = abfd->sections;  unsigned int preserved_section_count = abfd->section_count;  enum bfd_architecture previous_arch = bfd_get_arch (abfd);  unsigned long previous_mach = bfd_get_mach (abfd);  struct elf_obj_tdata *new_tdata = NULL;  asection *s;  /* Clear section information, since there might be a recognized bfd that     we now check if we can replace, and we don't want to append to it.  */  abfd->sections = NULL;  abfd->section_count = 0;  /* Read in the ELF header in external format.  */  if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))    {      if (bfd_get_error () != bfd_error_system_call)	goto got_wrong_format_error;      else	goto got_no_match;    }  /* Now check to see if we have a valid ELF file, and one that BFD can     make use of.  The magic number must match, the address size ('class')     and byte-swapping must match our XVEC entry, and it must have a     section header table (FIXME: See comments re sections at top of this     file).  */  if ((elf_file_p (&x_ehdr) == false) ||      (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) ||      (x_ehdr.e_ident[EI_CLASS] != ELFCLASS))    goto got_wrong_format_error;  /* Check that file's byte order matches xvec's */  switch (x_ehdr.e_ident[EI_DATA])    {    case ELFDATA2MSB:		/* Big-endian */      if (! bfd_header_big_endian (abfd))	goto got_wrong_format_error;      break;    case ELFDATA2LSB:		/* Little-endian */      if (! bfd_header_little_endian (abfd))	goto got_wrong_format_error;      break;    case ELFDATANONE:		/* No data encoding specified */    default:			/* Unknown data encoding specified */      goto got_wrong_format_error;    }  /* Allocate an instance of the elf_obj_tdata structure and hook it up to     the tdata pointer in the bfd.  */  new_tdata = ((struct elf_obj_tdata *)	       bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)));  if (new_tdata == NULL)    goto got_no_match;  elf_tdata (abfd) = new_tdata;  /* Now that we know the byte order, swap in the rest of the header */  i_ehdrp = elf_elfheader (abfd);  elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);#if DEBUG & 1  elf_debug_file (i_ehdrp);#endif  /* Reject ET_CORE (header indicates core file, not object file) */  if (i_ehdrp->e_type == ET_CORE)    goto got_wrong_format_error;  /* If there is no section header table, we're hosed.  */  if (i_ehdrp->e_shoff == 0)    goto got_wrong_format_error;  /* As a simple sanity check, verify that the what BFD thinks is the     size of each section header table entry actually matches the size     recorded in the file.  */  if (i_ehdrp->e_shentsize != sizeof (x_shdr))    goto got_wrong_format_error;  ebd = get_elf_backend_data (abfd);  /* Check that the ELF e_machine field matches what this particular     BFD format expects.  */  if (ebd->elf_machine_code != i_ehdrp->e_machine      && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1)      && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2))    {      const bfd_target * const *target_ptr;      if (ebd->elf_machine_code != EM_NONE)	goto got_wrong_format_error;      /* This is the generic ELF target.  Let it match any ELF target	 for which we do not have a specific backend.  */      for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)	{	  struct elf_backend_data *back;	  if ((*target_ptr)->flavour != bfd_target_elf_flavour)	    continue;	  back = (struct elf_backend_data *) (*target_ptr)->backend_data;	  if (back->elf_machine_code == i_ehdrp->e_machine	      || (back->elf_machine_alt1 != 0		  && back->elf_machine_alt1 == i_ehdrp->e_machine)	      || (back->elf_machine_alt2 != 0		  && back->elf_machine_alt2 == i_ehdrp->e_machine))	    {	      /* target_ptr is an ELF backend which matches this		 object file, so reject the generic ELF target.  */	      goto got_wrong_format_error;	    }	}    }  if (i_ehdrp->e_type == ET_EXEC)    abfd->flags |= EXEC_P;  else if (i_ehdrp->e_type == ET_DYN)    abfd->flags |= DYNAMIC;  if (i_ehdrp->e_phnum > 0)    abfd->flags |= D_PAGED;  if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0))    {      /* It's OK if this fails for the generic target.  */      if (ebd->elf_machine_code != EM_NONE)	goto got_no_match;    }  /* Remember the entry point specified in the ELF file header.  */  bfd_set_start_address (abfd, i_ehdrp->e_entry);  /* Allocate space for a copy of the section header table in     internal form, seek to the section header table in the file,     read it in, and convert it to internal form.  */  i_shdrp = ((Elf_Internal_Shdr *)	     bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum));  elf_elfsections (abfd) = ((Elf_Internal_Shdr **)			    bfd_alloc (abfd,				       sizeof (i_shdrp) * i_ehdrp->e_shnum));  if (!i_shdrp || !elf_elfsections (abfd))    goto got_no_match;  if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) != 0)    goto got_no_match;  for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++)    {      if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd) != sizeof (x_shdr))	goto got_no_match;      elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);      elf_elfsections (abfd)[shindex] = i_shdrp + shindex;      /* If the section is loaded, but not page aligned, clear         D_PAGED.  */      if ((i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0	  && i_shdrp[shindex].sh_type != SHT_NOBITS	  && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset)	       % ebd->maxpagesize)	      != 0))	abfd->flags &= ~D_PAGED;    }  if (i_ehdrp->e_shstrndx)    {      if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx))	goto got_no_match;    }  /* Read in the program headers.  */  if (i_ehdrp->e_phnum == 0)    elf_tdata (abfd)->phdr = NULL;  else    {      Elf_Internal_Phdr *i_phdr;      unsigned int i;      elf_tdata (abfd)->phdr = ((Elf_Internal_Phdr *)				bfd_alloc (abfd,					   (i_ehdrp->e_phnum					    * sizeof (Elf_Internal_Phdr))));      if (elf_tdata (abfd)->phdr == NULL)	goto got_no_match;      if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0)	goto got_no_match;      i_phdr = elf_tdata (abfd)->phdr;      for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)	{	  Elf_External_Phdr x_phdr;	  if (bfd_read ((PTR) &x_phdr, sizeof x_phdr, 1, abfd)	      != sizeof x_phdr)	    goto got_no_match;	  elf_swap_phdr_in (abfd, &x_phdr, i_phdr);	}    }  /* Read in the string table containing the names of the sections.  We     will need the base pointer to this table later.  */  /* We read this inline now, so that we don't have to go through     bfd_section_from_shdr with it (since this particular strtab is     used to find all of the ELF section names.) */  shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx);  if (!shstrtab)    goto got_no_match;  /* Once all of the section headers have been read and converted, we     can start processing them.  Note that the first section header is     a dummy placeholder entry, so we ignore it.  */  for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)    {      if (! bfd_section_from_shdr (abfd, shindex))	goto got_no_match;    }  /* Let the backend double check the format and override global     information.  */  if (ebd->elf_backend_object_p)    {      if ((*ebd->elf_backend_object_p) (abfd) == false)	goto got_wrong_format_error;    }  /* If we have created any reloc sections that are associated with     debugging sections, mark the reloc sections as debugging as well.  */  for (s = abfd->sections; s != NULL; s = s->next)    {      if ((elf_section_data (s)->this_hdr.sh_type == SHT_REL	   || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)	  && elf_section_data (s)->this_hdr.sh_info > 0)	{	  unsigned long targ_index;	  asection *targ_sec;	  targ_index = elf_section_data (s)->this_hdr.sh_info;	  targ_sec = bfd_section_from_elf_index (abfd, targ_index);	  if (targ_sec != NULL	      && (targ_sec->flags & SEC_DEBUGGING) != 0)	    s->flags |= SEC_DEBUGGING;	}    }  return (abfd->xvec); got_wrong_format_error:  /* There is way too much undoing of half-known state here.  The caller,     bfd_check_format_matches, really shouldn't iterate on live bfd's to     check match/no-match like it does.  We have to rely on that a call to     bfd_default_set_arch_mach with the previously known mach, undoes what     was done by the first bfd_default_set_arch_mach (with mach 0) here.     For this to work, only elf-data and the mach may be changed by the     target-specific elf_backend_object_p function.  Note that saving the     whole bfd here and restoring it would be even worse; the first thing     you notice is that the cached bfd file position gets out of sync.  */  bfd_default_set_arch_mach (abfd, previous_arch, previous_mach);  bfd_set_error (bfd_error_wrong_format); got_no_match:  if (new_tdata != NULL      && new_tdata->elf_sect_ptr != NULL)    bfd_release (abfd, new_tdata->elf_sect_ptr);  if (i_shdrp != NULL)    bfd_release (abfd, i_shdrp);  if (new_tdata != NULL)    bfd_release (abfd, new_tdata);  elf_tdata (abfd) = preserved_tdata;  abfd->sections = preserved_sections;  abfd->section_count = preserved_section_count;  return (NULL);}/* ELF .o/exec file writing *//* Write out the relocs.  */voidelf_write_relocs (abfd, sec, data)     bfd *abfd;     asection *sec;     PTR data;{  boolean *failedp = (boolean *) data;  Elf_Internal_Shdr *rela_hdr;  Elf_External_Rela *outbound_relocas;  Elf_External_Rel *outbound_relocs;  unsigned int idx;  int use_rela_p;  asymbol *last_sym = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?