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

📄 elf32-avr.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
        h = NULL;      else        h = sym_hashes[r_symndx - symtab_hdr->sh_info];    }  return true;}/* Perform a single relocation.  By default we use the standard BFD   routines, but a few relocs, we have to do them ourselves.  */static bfd_reloc_status_typeavr_final_link_relocate (howto, input_bfd, input_section,			 contents, rel, relocation)     reloc_howto_type *  howto;     bfd *               input_bfd;     asection *          input_section;     bfd_byte *          contents;     Elf_Internal_Rela * rel;     bfd_vma             relocation;{  bfd_reloc_status_type r = bfd_reloc_ok;  bfd_vma               x;  bfd_signed_vma	srel;  switch (howto->type)    {    case R_AVR_7_PCREL:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation;      srel += rel->r_addend;      srel -= rel->r_offset;      srel -= 2;	/* Branch instructions add 2 to the PC...  */      srel -= (input_section->output_section->vma +	       input_section->output_offset);      if (srel & 1)	return bfd_reloc_outofrange;      if (srel > ((1 << 7) - 1) || (srel < - (1 << 7)))	return bfd_reloc_overflow;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xfc07) | (((srel >> 1) << 3) & 0x3f8);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_13_PCREL:      contents   += rel->r_offset;      srel = (bfd_signed_vma) relocation;      srel += rel->r_addend;      srel -= rel->r_offset;      srel -= 2;	/* Branch instructions add 2 to the PC...  */      srel -= (input_section->output_section->vma +	       input_section->output_offset);      if (srel & 1)	return bfd_reloc_outofrange;      /* AVR addresses commands as words.  */      srel >>= 1;      /* Check for overflow.  */      if (srel < -2048 || srel > 2047)	{	  /* Apply WRAPAROUND if possible.  */	  switch (bfd_get_mach (input_bfd))	    {	    case bfd_mach_avr2:	    case bfd_mach_avr4:	      break;	    default:	      return bfd_reloc_overflow;	    }	}      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf000) | (srel & 0xfff);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_LO8_LDI:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_HI8_LDI:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      srel = (srel >> 8) & 0xff;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_HH8_LDI:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      srel = (srel >> 16) & 0xff;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_LO8_LDI_NEG:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      srel = -srel;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_HI8_LDI_NEG:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      srel = -srel;      srel = (srel >> 8) & 0xff;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_HH8_LDI_NEG:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      srel = -srel;      srel = (srel >> 16) & 0xff;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_LO8_LDI_PM:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      if (srel & 1)	return bfd_reloc_outofrange;      srel = srel >> 1;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_HI8_LDI_PM:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      if (srel & 1)	return bfd_reloc_outofrange;      srel = srel >> 1;      srel = (srel >> 8) & 0xff;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_HH8_LDI_PM:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      if (srel & 1)	return bfd_reloc_outofrange;      srel = srel >> 1;      srel = (srel >> 16) & 0xff;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_LO8_LDI_PM_NEG:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      srel = -srel;      if (srel & 1)	return bfd_reloc_outofrange;      srel = srel >> 1;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_HI8_LDI_PM_NEG:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      srel = -srel;      if (srel & 1)	return bfd_reloc_outofrange;      srel = srel >> 1;      srel = (srel >> 8) & 0xff;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_HH8_LDI_PM_NEG:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      srel = -srel;      if (srel & 1)	return bfd_reloc_outofrange;      srel = srel >> 1;      srel = (srel >> 16) & 0xff;      x = bfd_get_16 (input_bfd, contents);      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);      bfd_put_16 (input_bfd, x, contents);      break;    case R_AVR_CALL:      contents += rel->r_offset;      srel = (bfd_signed_vma) relocation + rel->r_addend;      if (srel & 1)	return bfd_reloc_outofrange;      srel = srel >> 1;      x = bfd_get_16 (input_bfd, contents);      x |= ((srel & 0x10000) | ((srel << 3) & 0x1f00000)) >> 16;      bfd_put_16 (input_bfd, x, contents);      bfd_put_16 (input_bfd, srel & 0xffff, contents+2);      break;    default:      r = _bfd_final_link_relocate (howto, input_bfd, input_section,				    contents, rel->r_offset,				    relocation, rel->r_addend);    }  return r;}/* Relocate an AVR ELF section.  */static booleanelf32_avr_relocate_section (output_bfd, info, input_bfd, input_section,			    contents, relocs, local_syms, local_sections)     bfd *output_bfd ATTRIBUTE_UNUSED;     struct bfd_link_info *info;     bfd *input_bfd;     asection *input_section;     bfd_byte *contents;     Elf_Internal_Rela *relocs;     Elf_Internal_Sym *local_syms;     asection **local_sections;{  Elf_Internal_Shdr *           symtab_hdr;  struct elf_link_hash_entry ** sym_hashes;  Elf_Internal_Rela *           rel;  Elf_Internal_Rela *           relend;  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;  sym_hashes = elf_sym_hashes (input_bfd);  relend     = relocs + input_section->reloc_count;  for (rel = relocs; rel < relend; rel ++)    {      reloc_howto_type *           howto;      unsigned long                r_symndx;      Elf_Internal_Sym *           sym;      asection *                   sec;      struct elf_link_hash_entry * h;      bfd_vma                      relocation;      bfd_reloc_status_type        r;      const char *                 name = NULL;      int                          r_type;      r_type = ELF32_R_TYPE (rel->r_info);      r_symndx = ELF32_R_SYM (rel->r_info);      if (info->relocateable)	{	  /* This is a relocateable link.  We don't have to change             anything, unless the reloc is against a section symbol,             in which case we have to adjust according to where the             section symbol winds up in the output section.  */	  if (r_symndx < symtab_hdr->sh_info)	    {	      sym = local_syms + r_symndx;	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)		{		  sec = local_sections [r_symndx];		  rel->r_addend += sec->output_offset + sym->st_value;		}	    }	  continue;	}      /* This is a final link.  */      howto  = elf_avr_howto_table + ELF32_R_TYPE (rel->r_info);      h      = NULL;      sym    = NULL;      sec    = NULL;      if (r_symndx < symtab_hdr->sh_info)	{	  sym = local_syms + r_symndx;	  sec = local_sections [r_symndx];	  relocation = (sec->output_section->vma			+ sec->output_offset			+ sym->st_value);	  name = bfd_elf_string_from_elf_section	    (input_bfd, symtab_hdr->sh_link, sym->st_name);	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;	}      else	{	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];	  while (h->root.type == bfd_link_hash_indirect		 || h->root.type == bfd_link_hash_warning)	    h = (struct elf_link_hash_entry *) h->root.u.i.link;	  name = h->root.root.string;	  if (h->root.type == bfd_link_hash_defined	      || h->root.type == bfd_link_hash_defweak)	    {	      sec = h->root.u.def.section;	      relocation = (h->root.u.def.value			    + sec->output_section->vma			    + sec->output_offset);	    }	  else if (h->root.type == bfd_link_hash_undefweak)	    {	      relocation = 0;	    }	  else	    {	      if (! ((*info->callbacks->undefined_symbol)		     (info, h->root.root.string, input_bfd,		      input_section, rel->r_offset, true)))		return false;	      relocation = 0;	    }	}      r = avr_final_link_relocate (howto, input_bfd, input_section,				   contents, rel, relocation);      if (r != bfd_reloc_ok)	{	  const char * msg = (const char *) NULL;	  switch (r)	    {	    case bfd_reloc_overflow:	      r = info->callbacks->reloc_overflow		(info, name, howto->name, (bfd_vma) 0,		 input_bfd, input_section, rel->r_offset);	      break;	    case bfd_reloc_undefined:	      r = info->callbacks->undefined_symbol		(info, name, input_bfd, input_section, rel->r_offset, true);	      break;	    case bfd_reloc_outofrange:	      msg = _("internal error: out of range error");	      break;	    case bfd_reloc_notsupported:	      msg = _("internal error: unsupported relocation error");	      break;	    case bfd_reloc_dangerous:	      msg = _("internal error: dangerous relocation");	      break;	    default:	      msg = _("internal error: unknown error");	      break;	    }	  if (msg)	    r = info->callbacks->warning	      (info, msg, name, input_bfd, input_section, rel->r_offset);	  if (! r)	    return false;	}    }  return true;}/* The final processing done just before writing out a AVR ELF object   file.  This gets the AVR architecture right based on the machine   number.  */static voidbfd_elf_avr_final_write_processing (abfd, linker)     bfd *abfd;     boolean linker ATTRIBUTE_UNUSED;{  unsigned long val;  switch (bfd_get_mach (abfd))    {    default:    case bfd_mach_avr2:      val = E_AVR_MACH_AVR2;      break;    case bfd_mach_avr1:      val = E_AVR_MACH_AVR1;      break;    case bfd_mach_avr3:      val = E_AVR_MACH_AVR3;      break;    case bfd_mach_avr4:      val = E_AVR_MACH_AVR4;      break;    case bfd_mach_avr5:      val = E_AVR_MACH_AVR5;      break;    }  elf_elfheader (abfd)->e_machine = EM_AVR;  elf_elfheader (abfd)->e_flags &= ~ EF_AVR_MACH;  elf_elfheader (abfd)->e_flags |= val;}/* Set the right machine number.  */static booleanelf32_avr_object_p (abfd)     bfd *abfd;{  int e_set = bfd_mach_avr2;  if (elf_elfheader (abfd)->e_machine == EM_AVR)    {      int e_mach = elf_elfheader (abfd)->e_flags & EF_AVR_MACH;      switch (e_mach)	{	default:	case E_AVR_MACH_AVR2:	  e_set = bfd_mach_avr2;	  break;	case E_AVR_MACH_AVR1:	  e_set = bfd_mach_avr1;	  break;	case E_AVR_MACH_AVR3:	  e_set = bfd_mach_avr3;	  break;	case E_AVR_MACH_AVR4:	  e_set = bfd_mach_avr4;	  break;	case E_AVR_MACH_AVR5:	  e_set = bfd_mach_avr5;	  break;	}    }  return bfd_default_set_arch_mach (abfd, bfd_arch_avr,				    e_set);}#define ELF_ARCH		bfd_arch_avr#define ELF_MACHINE_CODE	EM_AVR#define ELF_MAXPAGESIZE		1#define TARGET_LITTLE_SYM       bfd_elf32_avr_vec#define TARGET_LITTLE_NAME	"elf32-avr"#define elf_info_to_howto	             avr_info_to_howto_rela#define elf_info_to_howto_rel	             NULL#define elf_backend_relocate_section         elf32_avr_relocate_section#define elf_backend_gc_mark_hook             elf32_avr_gc_mark_hook#define elf_backend_gc_sweep_hook            elf32_avr_gc_sweep_hook#define elf_backend_check_relocs             elf32_avr_check_relocs#define elf_backend_can_gc_sections          1#define elf_backend_final_write_processing \					bfd_elf_avr_final_write_processing#define elf_backend_object_p		elf32_avr_object_p#include "elf32-target.h"

⌨️ 快捷键说明

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