coff-ppc.c

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

C
2,197
字号
		    fixit = true;		  }	      }	    if (fixit && info->base_file)	      {		/* So if this is non pcrelative, and is referenced		   to a section or a common symbol, then it needs a reloc */		/* relocation to a symbol in a section which		   isn't absolute - we output the address here		   to a file */		bfd_vma addr =  toc_section->output_section->vma		  + toc_section->output_offset + our_toc_offset;		if (coff_data(output_bfd)->pe)		  addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;		fwrite (&addr, 1,4, (FILE *) info->base_file);	      }	    /* FIXME: this test is conservative */	    if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN &&		our_toc_offset > toc_section->_raw_size)	      {		(*_bfd_error_handler)		  (_("%s: Relocation exceeds allocated TOC (%x)"),		   bfd_get_filename (input_bfd),		   toc_section->_raw_size);		bfd_set_error (bfd_error_bad_value);		return false;	      }	    /* Now we know the relocation for this toc reference */	    relocation =  our_toc_offset + TOC_LOAD_ADJUSTMENT;	    rstat = _bfd_relocate_contents (howto,					    input_bfd,					    relocation,					    loc);	  }	  break;	case IMAGE_REL_PPC_IFGLUE:	  {	    /* To solve this, we need to know whether or not the symbol */	    /* appearing on the call instruction is a glue function or not.  */	    /* A glue function must announce itself via a IMGLUE reloc, and */	    /* the reloc contains the required toc restore instruction */	    bfd_vma x;	    const char *my_name;	    DUMP_RELOC2(howto->name, rel);	    if (h != 0)	      {		my_name = h->root.root.root.string;		if (h->symbol_is_glue == 1)		  {		    x = bfd_get_32 (input_bfd, loc);		    bfd_put_32 (input_bfd, h->glue_insn, loc);		  }	      }	  }	  break;	case IMAGE_REL_PPC_SECREL:	  /* Unimplemented: codeview debugging information */	  /* For fast access to the header of the section	     containing the item.  */	  break;	case IMAGE_REL_PPC_SECTION:	  /* Unimplemented: codeview debugging information */	  /* Is used to indicate that the value should be relative	     to the beginning of the section that contains the	     symbol */	  break;	case IMAGE_REL_PPC_ABSOLUTE:	  {	    const char *my_name;	    if (h == 0)		my_name = (syms+symndx)->_n._n_name;	    else	      {		my_name = h->root.root.root.string;	      }	    fprintf (stderr,		    _("Warning: unsupported reloc %s <file %s, section %s>\n"),		    howto->name,		    bfd_get_filename(input_bfd),		    input_section->name);	    fprintf (stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n",		    rel->r_symndx, my_name, (long) rel->r_vaddr,		    (unsigned long) rel->r_vaddr);	  }	  break;	case IMAGE_REL_PPC_IMGLUE:	  {	    /* There is nothing to do now. This reloc was noted in the first	       pass over the relocs, and the glue instruction extracted */	    const char *my_name;	    if (h->symbol_is_glue == 1)	      break;	    my_name = h->root.root.root.string;	    (*_bfd_error_handler)	      (_("%s: Out of order IMGLUE reloc for %s"),	       bfd_get_filename (input_bfd), my_name);	    bfd_set_error (bfd_error_bad_value);	    return false;	  }	case IMAGE_REL_PPC_ADDR32NB:	  {	    struct coff_link_hash_entry *myh = 0;	    const char *name = 0;	    DUMP_RELOC2(howto->name, rel);	    if (strncmp(".idata$2",input_section->name,8) == 0 && first_thunk_address == 0)	      {		/* set magic values */		int idata5offset;		struct coff_link_hash_entry *myh = 0;		myh = coff_link_hash_lookup (coff_hash_table (info),					     "__idata5_magic__",					     false, false, true);		first_thunk_address = myh->root.u.def.value +		  sec->output_section->vma +		    sec->output_offset -		      pe_data(output_bfd)->pe_opthdr.ImageBase;		idata5offset = myh->root.u.def.value;		myh = coff_link_hash_lookup (coff_hash_table (info),					     "__idata6_magic__",					     false, false, true);		thunk_size = myh->root.u.def.value - idata5offset;		myh = coff_link_hash_lookup (coff_hash_table (info),					     "__idata4_magic__",					     false, false, true);		import_table_size = myh->root.u.def.value;	      }	    if (h == 0)	      { /* it is a file local symbol */		sym = syms + symndx;		name = sym->_n._n_name;	      }	    else	      {		char *target = 0;		name = h->root.root.root.string;		if (strcmp(".idata$2", name) == 0)		  target = "__idata2_magic__";		else if (strcmp(".idata$4", name) == 0)		  target = "__idata4_magic__";		else if (strcmp(".idata$5", name) == 0)		  target = "__idata5_magic__";		if (target != 0)		  {		    myh = 0;		    myh = coff_link_hash_lookup (coff_hash_table (info),						 target,						 false, false, true);		    if (myh == 0)		      {			/* Missing magic cookies. Something is very wrong.  */			abort ();		      }		    val = myh->root.u.def.value +		      sec->output_section->vma + sec->output_offset;		    if (first_thunk_address == 0)		      {			int idata5offset;			myh = coff_link_hash_lookup (coff_hash_table (info),						     "__idata5_magic__",						     false, false, true);			first_thunk_address = myh->root.u.def.value +			  sec->output_section->vma +			    sec->output_offset -			      pe_data(output_bfd)->pe_opthdr.ImageBase;			idata5offset = myh->root.u.def.value;			myh = coff_link_hash_lookup (coff_hash_table (info),						     "__idata6_magic__",						     false, false, true);			thunk_size = myh->root.u.def.value - idata5offset;			myh = coff_link_hash_lookup (coff_hash_table (info),						     "__idata4_magic__",						     false, false, true);			import_table_size = myh->root.u.def.value;		      }		  }	      }	    rstat = _bfd_relocate_contents (howto,		      	      input_bfd,			      val -			      pe_data(output_bfd)->pe_opthdr.ImageBase,			      loc);	  }	  break;	case IMAGE_REL_PPC_REL24:	  DUMP_RELOC2(howto->name, rel);	  val -= (input_section->output_section->vma		  + input_section->output_offset);	  rstat = _bfd_relocate_contents (howto,					  input_bfd,					  val,					  loc);	  break;	case IMAGE_REL_PPC_ADDR16:	case IMAGE_REL_PPC_ADDR24:	case IMAGE_REL_PPC_ADDR32:	  DUMP_RELOC2(howto->name, rel);	  rstat = _bfd_relocate_contents (howto,					  input_bfd,					  val,					  loc);	  break;	}      if ( info->base_file )	{	  /* So if this is non pcrelative, and is referenced	     to a section or a common symbol, then it needs a reloc */	  if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))	    {	      /* relocation to a symbol in a section which		 isn't absolute - we output the address here		 to a file */	      bfd_vma addr = rel->r_vaddr		- input_section->vma		+ input_section->output_offset		  + input_section->output_section->vma;	      if (coff_data(output_bfd)->pe)		{		  addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;		}	      fwrite (&addr, 1,4, (FILE *) info->base_file);	    }	}      switch (rstat)	{	default:	  abort ();	case bfd_reloc_ok:	  break;	case bfd_reloc_overflow:	  {	    const char *name;	    char buf[SYMNMLEN + 1];	    if (symndx == -1)	      name = "*ABS*";	    else if (h != NULL)	      name = h->root.root.root.string;	    else if (sym == NULL)	      name = "*unknown*";	    else if (sym->_n._n_n._n_zeroes == 0		     && sym->_n._n_n._n_offset != 0)	      name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;	    else	      {		strncpy (buf, sym->_n._n_name, SYMNMLEN);		buf[SYMNMLEN] = '\0';		name = buf;	      }	    if (! ((*info->callbacks->reloc_overflow)		   (info, name, howto->name,		    (bfd_vma) 0, input_bfd,		    input_section, rel->r_vaddr - input_section->vma)))	      {		return false;	      }	  }	}    }  return true;}#ifdef COFF_IMAGE_WITH_PE/* FIXME: BFD should not use global variables.  This file is compiled   twice, and these variables are shared.  This is confusing and   weird.  */long int global_toc_size = 4;bfd* bfd_of_toc_owner = 0;long int import_table_size;long int first_thunk_address;long int thunk_size;struct list_ele *head;struct list_ele *tail;static char *h1 = N_("\n\t\t\tTOC MAPPING\n\n");static char *h2 = N_(" TOC    disassembly  Comments       Name\n");static char *h3 = N_(" Offset  spelling                   (if present)\n");voiddump_toc (vfile)     PTR vfile;{  FILE *file = (FILE *) vfile;  struct list_ele *t;  fprintf (file, _(h1));  fprintf (file, _(h2));  fprintf (file, _(h3));  for (t = head; t != 0; t=t->next)    {      const char *cat = "";      if (t->cat == priv)	cat = _("private       ");      else if (t->cat == pub)	cat = _("public        ");      else if (t->cat == data)	cat = _("data-in-toc   ");      if (t->offset > global_toc_size)	{	  if (t->offset <= global_toc_size + thunk_size)	    cat = _("IAT reference ");	  else	    {	      fprintf (file,		      _("**** global_toc_size %ld(%lx), thunk_size %ld(%lx)\n"),		      global_toc_size, global_toc_size, thunk_size, thunk_size);	      cat = _("Out of bounds!");	    }	}      fprintf (file,	      " %04lx    (%d)", (unsigned long) t->offset, t->offset - 32768);      fprintf (file,	      "    %s %s\n",	      cat, t->name);    }  fprintf (file, "\n");}booleanppc_allocate_toc_section (info)     struct bfd_link_info *info ATTRIBUTE_UNUSED;{  asection *s;  bfd_byte *foo;  static char test_char = '1';  if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */    return true;  if (bfd_of_toc_owner == 0)    {      /* No toc owner? Something is very wrong.  */      abort ();    }  s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME);  if (s == NULL)    {      /* No toc section? Something is very wrong.  */      abort ();    }  foo = (bfd_byte *) bfd_alloc(bfd_of_toc_owner, global_toc_size);  memset(foo, test_char, global_toc_size);  s->_raw_size = s->_cooked_size = global_toc_size;  s->contents = foo;  return true;}booleanppc_process_before_allocation (abfd, info)     bfd *abfd;     struct bfd_link_info *info;{  asection *sec;  struct internal_reloc *i, *rel;  /* here we have a bfd that is to be included on the link. We have a hook     to do reloc rummaging, before section sizes are nailed down.  */  _bfd_coff_get_external_symbols(abfd);  /* rummage around all the relocs and map the toc */  sec = abfd->sections;  if (sec == 0)    {      return true;    }  for (; sec != 0; sec = sec->next)  {    if (sec->reloc_count == 0)      continue;    /* load the relocs */    /* FIXME: there may be a storage leak here */    i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);    if (i == 0)      abort ();    for (rel=i;rel<i+sec->reloc_count;++rel)      {	unsigned short r_type  = EXTRACT_TYPE (rel->r_type);	unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);	boolean ok = true;	DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);	switch(r_type)	  {	  case IMAGE_REL_PPC_TOCREL16:

⌨️ 快捷键说明

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