elf64-alpha.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,160 行 · 第 1/5 页

C
2,160
字号
     char *name;{  asection *newsect;  /* There ought to be a place to keep ELF backend specific flags, but     at the moment there isn't one.  We just keep track of the     sections by their name, instead.  Fortunately, the ABI gives     suggested names for all the MIPS specific sections, so we will     probably get away with this.  */  switch (hdr->sh_type)    {    case SHT_ALPHA_DEBUG:      if (strcmp (name, ".mdebug") != 0)	return false;      break;#ifdef ERIC_neverdef    case SHT_ALPHA_REGINFO:      if (strcmp (name, ".reginfo") != 0	  || hdr->sh_size != sizeof (Elf64_External_RegInfo))	return false;      break;#endif    default:      return false;    }  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))    return false;  newsect = hdr->bfd_section;  if (hdr->sh_type == SHT_ALPHA_DEBUG)    {      if (! bfd_set_section_flags (abfd, newsect,				   (bfd_get_section_flags (abfd, newsect)				    | SEC_DEBUGGING)))	return false;    }#ifdef ERIC_neverdef  /* For a .reginfo section, set the gp value in the tdata information     from the contents of this section.  We need the gp value while     processing relocs, so we just get it now.  */  if (hdr->sh_type == SHT_ALPHA_REGINFO)    {      Elf64_External_RegInfo ext;      Elf64_RegInfo s;      if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext,				      (file_ptr) 0, sizeof ext))	return false;      bfd_alpha_elf64_swap_reginfo_in (abfd, &ext, &s);      elf_gp (abfd) = s.ri_gp_value;    }#endif  return true;}/* Set the correct type for an Alpha ELF section.  We do this by the   section name, which is a hack, but ought to work.  */static booleanelf64_alpha_fake_sections (abfd, hdr, sec)     bfd *abfd;     Elf64_Internal_Shdr *hdr;     asection *sec;{  register const char *name;  name = bfd_get_section_name (abfd, sec);  if (strcmp (name, ".mdebug") == 0)    {      hdr->sh_type = SHT_ALPHA_DEBUG;      /* In a shared object on Irix 5.3, the .mdebug section has an         entsize of 0.  FIXME: Does this matter?  */      if ((abfd->flags & DYNAMIC) != 0 )	hdr->sh_entsize = 0;      else	hdr->sh_entsize = 1;    }#ifdef ERIC_neverdef  else if (strcmp (name, ".reginfo") == 0)    {      hdr->sh_type = SHT_ALPHA_REGINFO;      /* In a shared object on Irix 5.3, the .reginfo section has an         entsize of 0x18.  FIXME: Does this matter?  */      if ((abfd->flags & DYNAMIC) != 0)	hdr->sh_entsize = sizeof (Elf64_External_RegInfo);      else	hdr->sh_entsize = 1;      /* Force the section size to the correct value, even if the	 linker thinks it is larger.  The link routine below will only	 write out this much data for .reginfo.  */      hdr->sh_size = sec->_raw_size = sizeof (Elf64_External_RegInfo);    }  else if (strcmp (name, ".hash") == 0	   || strcmp (name, ".dynamic") == 0	   || strcmp (name, ".dynstr") == 0)    {      hdr->sh_entsize = 0;      hdr->sh_info = SIZEOF_ALPHA_DYNSYM_SECNAMES;    }#endif  else if (strcmp (name, ".sdata") == 0	   || strcmp (name, ".sbss") == 0	   || strcmp (name, ".lit4") == 0	   || strcmp (name, ".lit8") == 0)    hdr->sh_flags |= SHF_ALPHA_GPREL;  return true;}/* Hook called by the linker routine which adds symbols from an object   file.  We use it to put .comm items in .sbss, and not .bss.  */static booleanelf64_alpha_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)     bfd *abfd;     struct bfd_link_info *info;     const Elf_Internal_Sym *sym;     const char **namep ATTRIBUTE_UNUSED;     flagword *flagsp ATTRIBUTE_UNUSED;     asection **secp;     bfd_vma *valp;{  if (sym->st_shndx == SHN_COMMON      && !info->relocateable      && sym->st_size <= bfd_get_gp_size (abfd))    {      /* Common symbols less than or equal to -G nn bytes are	 automatically put into .sbss.  */      asection *scomm = bfd_get_section_by_name (abfd, ".scommon");      if (scomm == NULL)	{	  scomm = bfd_make_section (abfd, ".scommon");	  if (scomm == NULL	      || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC						       | SEC_IS_COMMON						       | SEC_LINKER_CREATED)))	    return false;	}      *secp = scomm;      *valp = sym->st_size;    }  return true;}/* Create the .got section.  */static booleanelf64_alpha_create_got_section(abfd, info)     bfd *abfd;     struct bfd_link_info *info ATTRIBUTE_UNUSED;{  asection *s;  if (bfd_get_section_by_name (abfd, ".got"))    return true;  s = bfd_make_section (abfd, ".got");  if (s == NULL      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD					   | SEC_HAS_CONTENTS					   | SEC_IN_MEMORY					   | SEC_LINKER_CREATED))      || !bfd_set_section_alignment (abfd, s, 3))    return false;  alpha_elf_tdata (abfd)->got = s;  return true;}/* Create all the dynamic sections.  */static booleanelf64_alpha_create_dynamic_sections (abfd, info)     bfd *abfd;     struct bfd_link_info *info;{  asection *s;  struct elf_link_hash_entry *h;  /* We need to create .plt, .rela.plt, .got, and .rela.got sections.  */  s = bfd_make_section (abfd, ".plt");  if (s == NULL      || ! bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD					    | SEC_HAS_CONTENTS					    | SEC_IN_MEMORY					    | SEC_LINKER_CREATED					    | SEC_CODE))      || ! bfd_set_section_alignment (abfd, s, 3))    return false;  /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the     .plt section.  */  h = NULL;  if (! (_bfd_generic_link_add_one_symbol	 (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,	  (bfd_vma) 0, (const char *) NULL, false,	  get_elf_backend_data (abfd)->collect,	  (struct bfd_link_hash_entry **) &h)))    return false;  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;  h->type = STT_OBJECT;  if (info->shared      && ! _bfd_elf_link_record_dynamic_symbol (info, h))    return false;  s = bfd_make_section (abfd, ".rela.plt");  if (s == NULL      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD					   | SEC_HAS_CONTENTS					   | SEC_IN_MEMORY					   | SEC_LINKER_CREATED					   | SEC_READONLY))      || ! bfd_set_section_alignment (abfd, s, 3))    return false;  /* We may or may not have created a .got section for this object, but     we definitely havn't done the rest of the work.  */  if (!elf64_alpha_create_got_section (abfd, info))    return false;  s = bfd_make_section(abfd, ".rela.got");  if (s == NULL      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD					   | SEC_HAS_CONTENTS					   | SEC_IN_MEMORY					   | SEC_LINKER_CREATED					   | SEC_READONLY))      || !bfd_set_section_alignment (abfd, s, 3))    return false;  /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the     dynobj's .got section.  We don't do this in the linker script     because we don't want to define the symbol if we are not creating     a global offset table.  */  h = NULL;  if (!(_bfd_generic_link_add_one_symbol	(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL,	 alpha_elf_tdata(abfd)->got, (bfd_vma) 0, (const char *) NULL,	 false, get_elf_backend_data (abfd)->collect,	 (struct bfd_link_hash_entry **) &h)))    return false;  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;  h->type = STT_OBJECT;  if (info->shared      && ! _bfd_elf_link_record_dynamic_symbol (info, h))    return false;  elf_hash_table (info)->hgot = h;  return true;}/* Read ECOFF debugging information from a .mdebug section into a   ecoff_debug_info structure.  */static booleanelf64_alpha_read_ecoff_info (abfd, section, debug)     bfd *abfd;     asection *section;     struct ecoff_debug_info *debug;{  HDRR *symhdr;  const struct ecoff_debug_swap *swap;  char *ext_hdr = NULL;  swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;  memset (debug, 0, sizeof (*debug));  ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size);  if (ext_hdr == NULL && swap->external_hdr_size != 0)    goto error_return;  if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,				swap->external_hdr_size)      == false)    goto error_return;  symhdr = &debug->symbolic_header;  (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);  /* The symbolic header contains absolute file offsets and sizes to     read.  */#define READ(ptr, offset, count, size, type)				\  if (symhdr->count == 0)						\    debug->ptr = NULL;							\  else									\    {									\      debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count));	\      if (debug->ptr == NULL)						\	goto error_return;						\      if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0	\	  || (bfd_read (debug->ptr, size, symhdr->count,		\			abfd) != size * symhdr->count))			\	goto error_return;						\    }  READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);  READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);  READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);  READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);  READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);  READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),	union aux_ext *);  READ (ss, cbSsOffset, issMax, sizeof (char), char *);  READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);  READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);  READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);  READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);#undef READ  debug->fdr = NULL;  debug->adjust = NULL;  return true; error_return:  if (ext_hdr != NULL)    free (ext_hdr);  if (debug->line != NULL)    free (debug->line);  if (debug->external_dnr != NULL)    free (debug->external_dnr);  if (debug->external_pdr != NULL)    free (debug->external_pdr);  if (debug->external_sym != NULL)    free (debug->external_sym);  if (debug->external_opt != NULL)    free (debug->external_opt);  if (debug->external_aux != NULL)    free (debug->external_aux);  if (debug->ss != NULL)    free (debug->ss);  if (debug->ssext != NULL)    free (debug->ssext);  if (debug->external_fdr != NULL)    free (debug->external_fdr);  if (debug->external_rfd != NULL)    free (debug->external_rfd);  if (debug->external_ext != NULL)    free (debug->external_ext);  return false;}/* Alpha ELF local labels start with '$'.  */static booleanelf64_alpha_is_local_label_name (abfd, name)     bfd *abfd ATTRIBUTE_UNUSED;     const char *name;{  return name[0] == '$';}/* Alpha ELF follows MIPS ELF in using a special find_nearest_line   routine in order to handle the ECOFF debugging information.  We   still call this mips_elf_find_line because of the slot   find_line_info in elf_obj_tdata is declared that way.  */struct mips_elf_find_line{  struct ecoff_debug_info d;  struct ecoff_find_line i;};static booleanelf64_alpha_find_nearest_line (abfd, section, symbols, offset, filename_ptr,			       functionname_ptr, line_ptr)     bfd *abfd;     asection *section;     asymbol **symbols;     bfd_vma offset;     const char **filename_ptr;     const char **functionname_ptr;     unsigned int *line_ptr;{  asection *msec;  if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,				     filename_ptr, functionname_ptr,				     line_ptr, 0,				     &elf_tdata (abfd)->dwarf2_find_line_info))    return true;  msec = bfd_get_section_by_name (abfd, ".mdebug");  if (msec != NULL)    {      flagword origflags;      struct mips_elf_find_line *fi;      const struct ecoff_debug_swap * const swap =	get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;      /* If we are called during a link, alpha_elf_final_link may have	 cleared the SEC_HAS_CONTENTS field.  We force it back on here	 if appropriate (which it normally will be).  */      origflags = msec->flags;      if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)	msec->flags |= SEC_HAS_CONTENTS;      fi = elf_tdata (abfd)->find_line_info;      if (fi == NULL)	{	  bfd_size_type external_fdr_size;	  char *fraw_src;	  char *fraw_end;	  struct fdr *fdr_ptr;	  fi = ((struct mips_elf_find_line *)		bfd_zalloc (abfd, sizeof (struct mips_elf_find_line)));	  if (fi == NULL)	    {	      msec->flags = origflags;	      return false;	    }	  if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d))	    {	      msec->flags = origflags;	      return

⌨️ 快捷键说明

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