⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 obj-elf.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
static voidadjust_stab_sections (abfd, sec, xxx)     bfd *abfd;     asection *sec;     PTR xxx ATTRIBUTE_UNUSED;{  char *name;  asection *strsec;  char *p;  int strsz, nsyms;  if (strncmp (".stab", sec->name, 5))    return;  if (!strcmp ("str", sec->name + strlen (sec->name) - 3))    return;  name = (char *) alloca (strlen (sec->name) + 4);  strcpy (name, sec->name);  strcat (name, "str");  strsec = bfd_get_section_by_name (abfd, name);  if (strsec)    strsz = bfd_section_size (abfd, strsec);  else    strsz = 0;  nsyms = bfd_section_size (abfd, sec) / 12 - 1;  p = seg_info (sec)->stabu.p;  assert (p != 0);  bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);  bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);}#ifdef NEED_ECOFF_DEBUG/* This function is called by the ECOFF code.  It is supposed to   record the external symbol information so that the backend can   write it out correctly.  The ELF backend doesn't actually handle   this at the moment, so we do it ourselves.  We save the information   in the symbol.  */voidelf_ecoff_set_ext (sym, ext)     symbolS *sym;     struct ecoff_extr *ext;{  symbol_get_bfdsym (sym)->udata.p = (PTR) ext;}/* This function is called by bfd_ecoff_debug_externals.  It is   supposed to *EXT to the external symbol information, and return   whether the symbol should be used at all.  */static booleanelf_get_extr (sym, ext)     asymbol *sym;     EXTR *ext;{  if (sym->udata.p == NULL)    return false;  *ext = *(EXTR *) sym->udata.p;  return true;}/* This function is called by bfd_ecoff_debug_externals.  It has   nothing to do for ELF.  *//*ARGSUSED*/static voidelf_set_index (sym, indx)     asymbol *sym ATTRIBUTE_UNUSED;     bfd_size_type indx ATTRIBUTE_UNUSED;{}#endif /* NEED_ECOFF_DEBUG */voidelf_frob_symbol (symp, puntp)     symbolS *symp;     int *puntp;{  struct elf_obj_sy *sy_obj;#ifdef NEED_ECOFF_DEBUG  if (ECOFF_DEBUGGING)    ecoff_frob_symbol (symp);#endif  sy_obj = symbol_get_obj (symp);  if (sy_obj->size != NULL)    {      switch (sy_obj->size->X_op)	{	case O_subtract:	  S_SET_SIZE (symp,		      (S_GET_VALUE (sy_obj->size->X_add_symbol)		       + sy_obj->size->X_add_number		       - S_GET_VALUE (sy_obj->size->X_op_symbol)));	  break;	case O_constant:	  S_SET_SIZE (symp,		      (S_GET_VALUE (sy_obj->size->X_add_symbol)		       + sy_obj->size->X_add_number));	  break;	default:	  as_bad (_(".size expression too complicated to fix up"));	  break;	}      free (sy_obj->size);      sy_obj->size = NULL;    }  if (sy_obj->versioned_name != NULL)    {      char *p;      p = strchr (sy_obj->versioned_name, ELF_VER_CHR);      know (p != NULL);      /* This symbol was given a new name with the .symver directive.         If this is an external reference, just rename the symbol to         include the version string.  This will make the relocs be         against the correct versioned symbol.	 If this is a definition, add an alias.  FIXME: Using an alias	 will permit the debugging information to refer to the right	 symbol.  However, it's not clear whether it is the best	 approach.  */      if (! S_IS_DEFINED (symp))	{	  /* Verify that the name isn't using the @@ syntax--this is             reserved for definitions of the default version to link             against.  */	  if (p[1] == ELF_VER_CHR)	    {	      as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),		      sy_obj->versioned_name);	      *puntp = true;	    }	  S_SET_NAME (symp, sy_obj->versioned_name);	}      else	{	  if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR)	    {	      size_t l;	      /* The @@@ syntax is a special case. It renames the		 symbol name to versioned_name with one `@' removed.  */	      l = strlen (&p[3]) + 1;	      memmove (&p [2], &p[3], l);	      S_SET_NAME (symp, sy_obj->versioned_name);	    }	  else	    {	      symbolS *symp2;	      /* FIXME: Creating a new symbol here is risky.  We're		 in the final loop over the symbol table.  We can		 get away with it only because the symbol goes to		 the end of the list, where the loop will still see		 it.  It would probably be better to do this in		 obj_frob_file_before_adjust.  */	      symp2 = symbol_find_or_make (sy_obj->versioned_name);	      /* Now we act as though we saw symp2 = sym.  */	      S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));	      /* Subtracting out the frag address here is a hack		 because we are in the middle of the final loop.  */	      S_SET_VALUE (symp2,			   (S_GET_VALUE (symp)			    - symbol_get_frag (symp)->fr_address));	      symbol_set_frag (symp2, symbol_get_frag (symp));	      /* This will copy over the size information.  */	      copy_symbol_attributes (symp2, symp);	      if (S_IS_WEAK (symp))		S_SET_WEAK (symp2);	      if (S_IS_EXTERNAL (symp))		S_SET_EXTERNAL (symp2);	    }	}    }  /* Double check weak symbols.  */  if (S_IS_WEAK (symp))    {      if (S_IS_COMMON (symp))	as_bad (_("Symbol `%s' can not be both weak and common"),		S_GET_NAME (symp));    }#ifdef TC_MIPS  /* The Irix 5 and 6 assemblers set the type of any common symbol and     any undefined non-function symbol to STT_OBJECT.  We try to be     compatible, since newer Irix 5 and 6 linkers care.  However, we     only set undefined symbols to be STT_OBJECT if we are on Irix,     because that is the only time gcc will generate the necessary     .global directives to mark functions.  */  if (S_IS_COMMON (symp))    symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;  if (strstr (TARGET_OS, "irix") != NULL      && ! S_IS_DEFINED (symp)      && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0)    symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;#endif#if 0 /* TC_PPC */  /* If TC_PPC is defined, we used to force the type of a symbol to be     BSF_OBJECT if it was otherwise unset.  This was required by some     version of VxWorks.  Thomas de Lellis <tdel@windriver.com> says     that this is no longer needed, so it is now commented out.  */  if ((symbol_get_bfdsym (symp)->flags       & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0      && S_IS_DEFINED (symp))    symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;#endif}voidelf_frob_file (){  bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);#ifdef elf_tc_final_processing  elf_tc_final_processing ();#endif}/* It removes any unneeded versioned symbols from the symbol table.  */voidelf_frob_file_before_adjust (){  if (symbol_rootP)    {      symbolS *symp;      for (symp = symbol_rootP; symp; symp = symbol_next (symp))	if (symbol_get_obj (symp)->versioned_name)	  {	    if (!S_IS_DEFINED (symp))	      {		char *p;		/* The @@@ syntax is a special case. If the symbol is		   not defined, 2 `@'s will be removed from the		   versioned_name.  */		p = strchr (symbol_get_obj (symp)->versioned_name,			    ELF_VER_CHR);		know (p != NULL);		if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR)		  {		    size_t l = strlen (&p[3]) + 1;		    memmove (&p [1], &p[3], l);		  }		if (symbol_used_p (symp) == 0		    && symbol_used_in_reloc_p (symp) == 0)		  symbol_remove (symp, &symbol_rootP, &symbol_lastP);	      }	  }    }}/* It is required that we let write_relocs have the opportunity to   optimize away fixups before output has begun, since it is possible   to eliminate all fixups for a section and thus we never should   have generated the relocation section.  */voidelf_frob_file_after_relocs (){#ifdef NEED_ECOFF_DEBUG  if (ECOFF_DEBUGGING)    /* Generate the ECOFF debugging information.  */    {      const struct ecoff_debug_swap *debug_swap;      struct ecoff_debug_info debug;      char *buf;      asection *sec;      debug_swap	= get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;      know (debug_swap != (const struct ecoff_debug_swap *) NULL);      ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);      /* Set up the pointers in debug.  */#define SET(ptr, offset, type) \    debug.ptr = (type) (buf + debug.symbolic_header.offset)      SET (line, cbLineOffset, unsigned char *);      SET (external_dnr, cbDnOffset, PTR);      SET (external_pdr, cbPdOffset, PTR);      SET (external_sym, cbSymOffset, PTR);      SET (external_opt, cbOptOffset, PTR);      SET (external_aux, cbAuxOffset, union aux_ext *);      SET (ss, cbSsOffset, char *);      SET (external_fdr, cbFdOffset, PTR);      SET (external_rfd, cbRfdOffset, PTR);      /* ssext and external_ext are set up just below.  */#undef SET      /* Set up the external symbols.  */      debug.ssext = debug.ssext_end = NULL;      debug.external_ext = debug.external_ext_end = NULL;      if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,				       elf_get_extr, elf_set_index))	as_fatal (_("Failed to set up debugging information: %s"),		  bfd_errmsg (bfd_get_error ()));      sec = bfd_get_section_by_name (stdoutput, ".mdebug");      assert (sec != NULL);      know (stdoutput->output_has_begun == false);      /* We set the size of the section, call bfd_set_section_contents	 to force the ELF backend to allocate a file position, and then	 write out the data.  FIXME: Is this really the best way to do	 this?  */      sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);      /* Pass BUF to bfd_set_section_contents because this will         eventually become a call to fwrite, and ISO C prohibits         passing a NULL pointer to a stdio function even if the         pointer will not be used.  */      if (! bfd_set_section_contents (stdoutput, sec, (PTR) buf,				      (file_ptr) 0, (bfd_size_type) 0))	as_fatal (_("Can't start writing .mdebug section: %s"),		  bfd_errmsg (bfd_get_error ()));      know (stdoutput->output_has_begun == true);      know (sec->filepos != 0);      if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,				   sec->filepos))	as_fatal (_("Could not write .mdebug section: %s"),		  bfd_errmsg (bfd_get_error ()));    }#endif /* NEED_ECOFF_DEBUG */}#ifdef SCO_ELF/* Heavily plagarized from obj_elf_version.  The idea is to emit the   SCO specific identifier in the .notes section to satisfy the SCO   linker.   This looks more complicated than it really is.  As opposed to the   "obvious" solution, this should handle the cross dev cases   correctly.  (i.e, hosting on a 64 bit big endian processor, but   generating SCO Elf code) Efficiency isn't a concern, as there   should be exactly one of these sections per object module.   SCO OpenServer 5 identifies it's ELF modules with a standard ELF   .note section.   int_32 namesz  = 4 ;  Name size   int_32 descsz  = 12 ; Descriptive information   int_32 type    = 1 ;   char   name[4] = "SCO" ; Originator name ALWAYS SCO + NULL   int_32 version = (major ver # << 16)  | version of tools ;   int_32 source  = (tool_id << 16 ) | 1 ;   int_32 info    = 0 ;    These are set by the SCO tools, but we                           don't know enough about the source			   environment to set them.  SCO ld currently			   ignores them, and recommends we set them			   to zero.  */#define SCO_MAJOR_VERSION 0x1#define SCO_MINOR_VERSION 0x1voidsco_id (){  char *name;  unsigned int c;  char ch;  char *p;  asection *seg = now_seg;  subsegT subseg = now_subseg;  Elf_Internal_Note i_note;  Elf_External_Note e_note;  asection *note_secp = (asection *) NULL;  int i, len;  /* create the .note section */  note_secp = subseg_new (".note", 0);  bfd_set_section_flags (stdoutput,			 note_secp,			 SEC_HAS_CONTENTS | SEC_READONLY);  /* process the version string */  i_note.namesz = 4;  i_note.descsz = 12;		/* 12 descriptive bytes */  i_note.type = NT_VERSION;	/* Contains a version string */  p = frag_more (sizeof (i_note.namesz));  md_number_to_chars (p, (valueT) i_note.namesz, 4);  p = frag_more (sizeof (i_note.descsz));  md_number_to_chars (p, (valueT) i_note.descsz, 4);  p = frag_more (sizeof (i_note.type));  md_number_to_chars (p, (valueT) i_note.type, 4);  p = frag_more (4);  strcpy (p, "SCO");  /* Note: this is the version number of the ELF we're representing */  p = frag_more (4);  md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);  /* Here, we pick a magic number for ourselves (yes, I "registered"     it with SCO.  The bottom bit shows that we are compat with the     SCO ABI.  */  p = frag_more (4);  md_number_to_chars (p, 0x4c520000 | 0x0001, 4);  /* If we knew (or cared) what the source language options were, we'd     fill them in here.  SCO has given us permission to ignore these     and just set them to zero.  */  p = frag_more (4);  md_number_to_chars (p, 0x0000, 4);  frag_align (2, 0, 0);  /* We probably can't restore the current segment, for there likely     isn't one yet...  */  if (seg && subseg)    subseg_set (seg, subseg);}#endif /* SCO_ELF */static intelf_separate_stab_sections (){#ifdef NEED_ECOFF_DEBUG  return (!ECOFF_DEBUGGING);#else  return 1;#endif}static voidelf_init_stab_section (seg)     segT seg;{#ifdef NEED_ECOFF_DEBUG  if (!ECOFF_DEBUGGING)#endif    obj_elf_init_stab_section (seg);}const struct format_ops elf_format_ops ={  bfd_target_elf_flavour,  0,	/* dfl_leading_underscore */  1,	/* emit_section_symbols */  elf_begin,  elf_file_symbol,  elf_frob_symbol,  elf_frob_file,  elf_frob_file_before_adjust,  elf_frob_file_after_relocs,  elf_s_get_size, elf_s_set_size,  elf_s_get_align, elf_s_set_align,  elf_s_get_other,  elf_s_set_other,  0,	/* s_get_desc */  0,	/* s_set_desc */  0,	/* s_get_type */  0,	/* s_set_type */  elf_copy_symbol_attributes,#ifdef NEED_ECOFF_DEBUG  ecoff_generate_asm_lineno,  ecoff_stab,#else  0,	/* generate_asm_lineno */  0,	/* process_stab */#endif  elf_separate_stab_sections,  elf_init_stab_section,  elf_sec_sym_ok_for_reloc,  elf_pop_insert,#ifdef NEED_ECOFF_DEBUG  elf_ecoff_set_ext,#else  0,	/* ecoff_set_ext */#endif  elf_obj_read_begin_hook,  elf_obj_symbol_new_hook};

⌨️ 快捷键说明

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