coff-m68k.c

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

C
532
字号
    return bfd_reloc_continue;  if (bfd_is_com_section (symbol->section))    {      /* We are relocating a common symbol.  The current value in the	 object file is ORIG + OFFSET, where ORIG is the value of the	 common symbol as seen by the object file when it was compiled	 (this may be zero if the symbol was undefined) and OFFSET is	 the offset into the common symbol (normally zero, but may be	 non-zero when referring to a field in a common structure).	 ORIG is the negative of reloc_entry->addend, which is set by	 the CALC_ADDEND macro below.  We want to replace the value in	 the object file with NEW + OFFSET, where NEW is the value of	 the common symbol which we are going to put in the final	 object file.  NEW is symbol->value.  */      diff = symbol->value + reloc_entry->addend;    }  else    {      /* For some reason bfd_perform_relocation always effectively	 ignores the addend for a COFF target when producing	 relocateable output.  This seems to be always wrong for 386	 COFF, so we handle the addend here instead.  */      diff = reloc_entry->addend;    }#define DOIT(x) \  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))  if (diff != 0)    {      reloc_howto_type *howto = reloc_entry->howto;      unsigned char *addr = (unsigned char *) data + reloc_entry->address;      switch (howto->size)	{	case 0:	  {	    char x = bfd_get_8 (abfd, addr);	    DOIT (x);	    bfd_put_8 (abfd, x, addr);	  }	  break;	case 1:	  {	    short x = bfd_get_16 (abfd, addr);	    DOIT (x);	    bfd_put_16 (abfd, x, addr);	  }	  break;	case 2:	  {	    long x = bfd_get_32 (abfd, addr);	    DOIT (x);	    bfd_put_32 (abfd, x, addr);	  }	  break;	default:	  abort ();	}    }  /* Now let bfd_perform_relocation finish everything up.  */  return bfd_reloc_continue;}/* Compute the addend of a reloc.  If the reloc is to a common symbol,   the object file contains the value of the common symbol.  By the   time this is called, the linker may be using a different symbol   from a different object file with a different value.  Therefore, we   hack wildly to locate the original symbol from this file so that we   can make the correct adjustment.  This macro sets coffsym to the   symbol from the original file, and uses it to set the addend value   correctly.  If this is not a common symbol, the usual addend   calculation is done, except that an additional tweak is needed for   PC relative relocs.   FIXME: This macro refers to symbols and asect; these are from the   calling function, not the macro arguments.  */#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)		\  {								\    coff_symbol_type *coffsym = (coff_symbol_type *) NULL;	\    if (ptr && bfd_asymbol_bfd (ptr) != abfd)			\      coffsym = (obj_symbols (abfd)				\	         + (cache_ptr->sym_ptr_ptr - symbols));		\    else if (ptr)						\      coffsym = coff_symbol_from (abfd, ptr);			\    if (coffsym != (coff_symbol_type *) NULL			\	&& coffsym->native->u.syment.n_scnum == 0)		\      cache_ptr->addend = - coffsym->native->u.syment.n_value;	\    else if (ptr && bfd_asymbol_bfd (ptr) == abfd		\	     && ptr->section != (asection *) NULL)		\      cache_ptr->addend = - (ptr->section->vma + ptr->value);	\    else							\      cache_ptr->addend = 0;					\    if (ptr && (reloc.r_type == R_PCRBYTE			\		|| reloc.r_type == R_PCRWORD			\		|| reloc.r_type == R_PCRLONG))			\      cache_ptr->addend += asect->vma;				\  }#ifndef coff_rtype_to_howto/* coff-m68k.c uses the special COFF backend linker.  We need to   adjust common symbols.  */static reloc_howto_type *m68kcoff_common_addend_rtype_to_howto (abfd, sec, rel, h, sym, addendp)     bfd *abfd ATTRIBUTE_UNUSED;     asection *sec;     struct internal_reloc *rel;     struct coff_link_hash_entry *h;     struct internal_syment *sym;     bfd_vma *addendp;{  arelent relent;  reloc_howto_type *howto;  RTYPE2HOWTO (&relent, rel);  howto = relent.howto;  if (howto->pc_relative)    *addendp += sec->vma;  if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)    {      /* This is a common symbol.  The section contents include the	 size (sym->n_value) as an addend.  The relocate_section	 function will be adding in the final value of the symbol.  We	 need to subtract out the current size in order to get the	 correct result.  */      BFD_ASSERT (h != NULL);      *addendp -= sym->n_value;    }  /* If the output symbol is common (in which case this must be a     relocateable link), we need to add in the final size of the     common symbol.  */  if (h != NULL && h->root.type == bfd_link_hash_common)    *addendp += h->root.u.c.size;  return howto;}#define coff_rtype_to_howto m68kcoff_common_addend_rtype_to_howto#endif /* ! defined (coff_rtype_to_howto) */#endif /* COFF_COMMON_ADDEND */#if !defined ONLY_DECLARE_RELOCS && ! defined STATIC_RELOCS/* Given a .data section and a .emreloc in-memory section, store   relocation information into the .emreloc section which can be   used at runtime to relocate the section.  This is called by the   linker when the --embedded-relocs switch is used.  This is called   after the add_symbols entry point has been called for all the   objects, and before the final_link entry point is called.  */booleanbfd_m68k_coff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)     bfd *abfd;     struct bfd_link_info *info;     asection *datasec;     asection *relsec;     char **errmsg;{  char *extsyms;  bfd_size_type symesz;  struct internal_reloc *irel, *irelend;  bfd_byte *p;  BFD_ASSERT (! info->relocateable);  *errmsg = NULL;  if (datasec->reloc_count == 0)    return true;  extsyms = obj_coff_external_syms (abfd);  symesz = bfd_coff_symesz (abfd);  irel = _bfd_coff_read_internal_relocs (abfd, datasec, true, NULL, false,					 NULL);  irelend = irel + datasec->reloc_count;  relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 12);  if (relsec->contents == NULL)    return false;  p = relsec->contents;  for (; irel < irelend; irel++, p += 12)    {      asection *targetsec;      /* We are going to write a four byte longword into the runtime       reloc section.  The longword will be the address in the data       section which must be relocated.  It is followed by the name       of the target section NUL-padded or truncated to 8       characters.  */      /* We can only relocate absolute longword relocs at run time.  */      if (irel->r_type != R_RELLONG)	{	  *errmsg = _("unsupported reloc type");	  bfd_set_error (bfd_error_bad_value);	  return false;	}      if (irel->r_symndx == -1)	targetsec = bfd_abs_section_ptr;      else	{	  struct coff_link_hash_entry *h;	  h = obj_coff_sym_hashes (abfd)[irel->r_symndx];	  if (h == NULL)	    {	      struct internal_syment isym;	      bfd_coff_swap_sym_in (abfd, extsyms + symesz * irel->r_symndx,				    &isym);	      targetsec = coff_section_from_bfd_index (abfd, isym.n_scnum);	    }	  else if (h->root.type == bfd_link_hash_defined		   || h->root.type == bfd_link_hash_defweak)	    targetsec = h->root.u.def.section;	  else	    targetsec = NULL;	}      bfd_put_32 (abfd,		  (irel->r_vaddr - datasec->vma + datasec->output_offset), p);      memset (p + 4, 0, 8);      if (targetsec != NULL)	strncpy (p + 4, targetsec->output_section->name, 8);    }  return true;}#endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS  */#define coff_bfd_is_local_label_name m68k_coff_is_local_label_name#define coff_relocate_section _bfd_coff_generic_relocate_section#include "coffcode.h"#ifndef TARGET_SYM#define TARGET_SYM m68kcoff_vec#endif#ifndef TARGET_NAME#define TARGET_NAME "coff-m68k"#endif#ifdef NAMES_HAVE_UNDERSCORECREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL)#elseCREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, 0, NULL)#endif

⌨️ 快捷键说明

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