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

📄 reloc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
  }  /*     Work out which section the relocation is targetted at and the    initial relocation command value.    */  if (symbol->section == &bfd_com_section) {    relocation = 0;  }  else {    relocation = symbol->value;  }  reloc_target_output_section = symbol->section->output_section;  if (output_bfd && howto->partial_inplace==false) {    output_base = 0;  }  else {    output_base = reloc_target_output_section->vma;  }  relocation += output_base +   symbol->section->output_offset;    relocation += reloc_entry->addend ;  if(reloc_entry->address > input_section->_cooked_size)  {    return bfd_reloc_outofrange;  }            if (howto->pc_relative == true)  {    /*      Anything which started out as pc relative should end up that      way too.             There are two ways we can see a pcrel instruction. Sometimes      the pcrel displacement has been partially calculated, it      includes the distance from the start of the section to the      instruction in it (eg sun3), and sometimes the field is      totally blank - eg m88kbcs.      */            relocation -=      input_section->output_section->vma + input_section->output_offset;    if (howto->pcrel_offset == true) {      relocation -= reloc_entry->address;    }  }  if (output_bfd!= (bfd *)NULL) {    if ( howto->partial_inplace == false)  {      /*	This is a partial relocation, and we want to apply the relocation	to the reloc entry rather than the raw data. Modify the reloc	inplace to reflect what we now know.	*/      reloc_entry->addend = relocation  ;      reloc_entry->address +=  input_section->output_offset;      return flag;    }    else     {      /* This is a partial relocation, but inplace, so modify the	 reloc record a bit. 	 	 If we've relocated with a symbol with a section, change	 into a ref to  the section belonging to the symbol	 */      reloc_entry->addend = relocation  ;      reloc_entry->address +=  input_section->output_offset;    }  }  else   {        reloc_entry->addend = 0;  }    /*     Either we are relocating all the way, or we don't want to apply    the relocation to the reloc entry (probably because there isn't    any room in the output format to describe addends to relocs)    */  relocation >>= howto->rightshift;  /* Shift everything up to where it's going to be used */     relocation <<= howto->bitpos;  /* Wait for the day when all have the mask in them */  /* What we do:     i instruction to be left alone     o offset within instruction     r relocation offset to apply     S src mask     D dst mask     N ~dst mask     A part 1     B part 2     R result          Do this:     i i i i i o o o o o        from bfd_get<size>     and           S S S S S    to get the size offset we want     +   r r r r r r r r r r  to get the final value to place     and           D D D D D  to chop to right size     -----------------------     A A A A A      And this:     ...   i i i i i o o o o o  from bfd_get<size>     and   N N N N N            get instruction     -----------------------     ...   B B B B B          And then:            B B B B B            or              A A A A A          -----------------------     R R R R R R R R R R        put into bfd_put<size>     */#define DOIT(x) \  x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))   switch (howto->size)   {    case 0:    {      char x = bfd_get_8(abfd, (char *)data + addr);      DOIT(x);      bfd_put_8(abfd,x, (unsigned char *) data + addr);    }     break;    case 1:    {       short x = bfd_get_16(abfd, (bfd_byte *)data + addr);      DOIT(x);      bfd_put_16(abfd, x,   (unsigned char *)data + addr);    }     break;    case 2:    {      long  x = bfd_get_32(abfd, (bfd_byte *) data + addr);      DOIT(x);      bfd_put_32(abfd,x,    (bfd_byte *)data + addr);    }           break;    case -2:    {      long  x = bfd_get_32(abfd, (bfd_byte *) data + addr);      relocation = -relocation;      DOIT(x);      bfd_put_32(abfd,x,    (bfd_byte *)data + addr);    }           break;    case 3:     /* Do nothing */     break;    default:     return bfd_reloc_other;   }  return flag;}/*DOCDDINODE	howto manager,  , typedef arelent, RelocationsSECTION	The howto manager 	When an application wants to create a relocation, but doesn't	know what the target machine might call it, it can find out by	using this bit of code.*//*TYPEDEF	bfd_reloc_code_typeDESCRIPTION	The insides of a reloc codeCODE_FRAGMENT..typedef enum bfd_reloc_code_real ..{.       {* 16 bits wide, simple reloc *}.  BFD_RELOC_16,        ..       {* 8 bits wide, but used to form an address like 0xffnn *}.  BFD_RELOC_8_FFnn,..       {* 8 bits wide, simple *}.  BFD_RELOC_8,..       {* 8 bits wide, pc relative *}.  BFD_RELOC_8_PCREL,..       {* The type of reloc used to build a contructor table - at the.          moment probably a 32 bit wide abs address, but the cpu can.          choose. *}..  BFD_RELOC_CTOR,..       {* 32 bits wide, simple reloc *}.  BFD_RELOC_32,.	{* 32 bits, PC-relative *}.  BFD_RELOC_32_PCREL,..	{* High 22 bits of 32-bit value; simple reloc.  *}.  BFD_RELOC_HI22,.	{* Low 10 bits.  *}.  BFD_RELOC_LO10,..	{* Reloc types used for i960/b.out.  *}.  BFD_RELOC_24_PCREL,.  BFD_RELOC_I960_CALLJ,..  BFD_RELOC_16_PCREL,.	{* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit.	   word displacement, e.g. for SPARC) *}.  BFD_RELOC_32_PCREL_S2,..  {* now for the sparc/elf codes *}.  BFD_RELOC_NONE,		{* actually used *}.  BFD_RELOC_SPARC_WDISP22,.  BFD_RELOC_SPARC22,.  BFD_RELOC_SPARC13,.  BFD_RELOC_SPARC_BASE13,.  BFD_RELOC_SPARC_GOT10,.  BFD_RELOC_SPARC_GOT13,.  BFD_RELOC_SPARC_GOT22,.  BFD_RELOC_SPARC_PC10,.  BFD_RELOC_SPARC_PC22,.  BFD_RELOC_SPARC_WPLT30,.  BFD_RELOC_SPARC_COPY,.  BFD_RELOC_SPARC_GLOB_DAT,.  BFD_RELOC_SPARC_JMP_SLOT,.  BFD_RELOC_SPARC_RELATIVE,.  BFD_RELOC_SPARC_UA32,..  {* this one is a.out specific? *}.  BFD_RELOC_SPARC_BASE22,..  {* this must be the highest numeric value *}.  BFD_RELOC_UNUSED. } bfd_reloc_code_real_type;*//*SECTION	bfd_reloc_type_lookupSYNOPSIS	CONST struct reloc_howto_struct *	bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code);DESCRIPTION	This routine returns a pointer to a howto struct which when	invoked, will perform the supplied relocation on data from the	architecture noted.*/CONST struct reloc_howto_struct *DEFUN(bfd_reloc_type_lookup,(abfd, code),      bfd *abfd AND      bfd_reloc_code_real_type code){  return BFD_SEND (abfd, reloc_type_lookup, (abfd, code));}static reloc_howto_type bfd_howto_32 = HOWTO(0, 00,2,32,false,0,false,true,0,"VRT32", false,0xffffffff,0xffffffff,true);/*INTERNAL_FUNCTION	bfd_default_reloc_type_lookupSYNOPSIS	CONST struct reloc_howto_struct *bfd_default_reloc_type_lookup	(CONST struct bfd_arch_info *,         bfd_reloc_code_real_type  code);DESCRIPTION	Provides a default relocation lookuperer for any architectue */CONST struct reloc_howto_struct *DEFUN(bfd_default_reloc_type_lookup,(arch,  code),     CONST struct bfd_arch_info *arch AND      bfd_reloc_code_real_type  code){    switch (code)     {       case BFD_RELOC_CTOR:	/* The type of reloc used in a ctor, which will be as wide as the	   address - so either a 64, 32, or 16 bitter.. */	switch (arch->bits_per_address) {	   case 64:	    BFD_FAIL();	   case 32:	    return &bfd_howto_32;	   case 16:	    BFD_FAIL();	   default:	    BFD_FAIL();	}       default:	BFD_FAIL();    }return (CONST struct reloc_howto_struct *)NULL;}/*INTERNAL_FUNCTION	bfd_generic_relax_sectionSYNOPSIS	boolean bfd_generic_relax_section	 (bfd *abfd,	  asection *section,	  asymbol **symbols);DESCRIPTION	Provides default handling for relaxing for back ends which	don't do relaxing -- i.e., does nothing.*/booleanDEFUN(bfd_generic_relax_section,(abfd, section, symbols),      bfd *abfd AND      asection *section AND      asymbol **symbols){    return false;  }		/*INTERNAL_FUNCTION	bfd_generic_get_relocated_section_contentsSYNOPSIS	bfd_byte *	   bfd_generic_get_relocated_section_contents(bfd *abfd,	     struct bfd_seclet_struct  *seclet,	     bfd_byte *data)DESCRIPTION	Provides default handling of relocation effort for back ends	which can't be bothered to do it efficiently.*/bfd_byte *DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet, data),      bfd *abfd AND      struct bfd_seclet_struct *seclet AND      bfd_byte *data){  extern bfd_error_vector_type bfd_error_vector;  /* Get enough memory to hold the stuff */  bfd *input_bfd = seclet->u.indirect.section->owner;  asection *input_section = seclet->u.indirect.section;  bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,						       input_section);  arelent **reloc_vector = (arelent **) alloca(reloc_size);    /* read in the section */  bfd_get_section_contents(input_bfd,			   input_section,			   data,			   0,			   input_section->_raw_size);  /* We're not relaxing the section, so just copy the size info */  input_section->_cooked_size = input_section->_raw_size;  input_section->reloc_done = true;    if (bfd_canonicalize_reloc(input_bfd, 			     input_section,			     reloc_vector,			     seclet->u.indirect.symbols) )  {    arelent **parent;    for (parent = reloc_vector;  * parent != (arelent *)NULL;	 parent++)     {       bfd_reloc_status_type r=       bfd_perform_relocation(input_bfd,			      *parent,			      data,			      input_section, 0);            if (r != bfd_reloc_ok)       {	switch (r)	{	case bfd_reloc_undefined:	  bfd_error_vector.undefined_symbol(*parent, seclet);	  break;	case bfd_reloc_dangerous: 	  bfd_error_vector.reloc_dangerous(*parent, seclet);	  break;	case bfd_reloc_outofrange:	case bfd_reloc_overflow:	  bfd_error_vector.reloc_value_truncated(*parent, seclet);	  break;	default:	  abort();	  break;	}      }    }      }  return data;  }

⌨️ 快捷键说明

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