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

📄 elf32-avr.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
/* AVR-specific support for 32-bit ELF   Copyright 1999, 2000 Free Software Foundation, Inc.   Contributed by Denis Chertykov <denisc@overta.ru>This file is part of BFD, the Binary File Descriptor library.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */#include "bfd.h"#include "sysdep.h"#include "libbfd.h"#include "elf-bfd.h"#include "elf/avr.h"static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));static void avr_info_to_howto_rela  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));static asection *elf32_avr_gc_mark_hook  PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,	   struct elf_link_hash_entry *, Elf_Internal_Sym *));static boolean elf32_avr_gc_sweep_hook  PARAMS ((bfd *, struct bfd_link_info *, asection *,	   const Elf_Internal_Rela *));static boolean elf32_avr_check_relocs  PARAMS ((bfd *, struct bfd_link_info *, asection *,	   const Elf_Internal_Rela *));static bfd_reloc_status_type avr_final_link_relocate  PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,	   Elf_Internal_Rela *, bfd_vma));static boolean elf32_avr_relocate_section  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));static void bfd_elf_avr_final_write_processing PARAMS ((bfd *, boolean));static boolean elf32_avr_object_p PARAMS ((bfd *));/* Use RELA instead of REL */#undef USE_RELstatic reloc_howto_type elf_avr_howto_table[] ={  HOWTO (R_AVR_NONE,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_NONE",		/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false),		/* pcrel_offset */  HOWTO (R_AVR_32,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_32",		/* name */	 false,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 7 bit PC relative relocation.  */  HOWTO (R_AVR_7_PCREL,		/* type */	 1,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 7,			/* bitsize */	 true,			/* pc_relative */	 3,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc, /* special_function */	 "R_AVR_7_PCREL",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 true),			/* pcrel_offset */  /* A 13 bit PC relative relocation.  */  HOWTO (R_AVR_13_PCREL,	/* type */	 1,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 13,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc, /* special_function */	 "R_AVR_13_PCREL",	/* name */	 false,			/* partial_inplace */	 0xfff,			/* src_mask */	 0xfff,			/* dst_mask */	 true),			/* pcrel_offset */  /* A 16 bit absolute relocation.  */  HOWTO (R_AVR_16,		/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_16",		/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 16 bit absolute relocation for command address.  */  HOWTO (R_AVR_16_PM,		/* type */	 1,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_16_PM",		/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A low 8 bit absolute relocation of 16 bit address.     For LDI command.  */  HOWTO (R_AVR_LO8_LDI,		/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_LO8_LDI",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A high 8 bit absolute relocation of 16 bit address.     For LDI command.  */  HOWTO (R_AVR_HI8_LDI,		/* type */	 8,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_HI8_LDI",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A high 6 bit absolute relocation of 22 bit address.     For LDI command.  */  HOWTO (R_AVR_HH8_LDI,		/* type */	 16,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_HH8_LDI",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A negative low 8 bit absolute relocation of 16 bit address.     For LDI command.  */  HOWTO (R_AVR_LO8_LDI_NEG,	/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_LO8_LDI_NEG",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A hegative high 8 bit absolute relocation of 16 bit address.     For LDI command.  */  HOWTO (R_AVR_HI8_LDI_NEG,	/* type */	 8,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_HI8_LDI_NEG",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A hegative high 6 bit absolute relocation of 22 bit address.     For LDI command.  */  HOWTO (R_AVR_HH8_LDI_NEG,	/* type */	 16,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_HH8_LDI_NEG",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A low 8 bit absolute relocation of 24 bit program memory address.     For LDI command.  */  HOWTO (R_AVR_LO8_LDI_PM,	/* type */	 1,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_LO8_LDI_PM",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A high 8 bit absolute relocation of 16 bit program memory address.     For LDI command.  */  HOWTO (R_AVR_HI8_LDI_PM,	/* type */	 9,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_HI8_LDI_PM",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A high 8 bit absolute relocation of 24 bit program memory address.     For LDI command.  */  HOWTO (R_AVR_HH8_LDI_PM,	/* type */	 17,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_HH8_LDI_PM",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A low 8 bit absolute relocation of a negative 24 bit     program memory address.  For LDI command.  */  HOWTO (R_AVR_LO8_LDI_PM_NEG,	/* type */	 1,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_LO8_LDI_PM_NEG", /* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A high 8 bit absolute relocation of a negative 16 bit     program memory address.  For LDI command.  */  HOWTO (R_AVR_HI8_LDI_PM_NEG,	/* type */	 9,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_HI8_LDI_PM_NEG", /* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A high 8 bit absolute relocation of a negative 24 bit     program memory address.  For LDI command.  */  HOWTO (R_AVR_HH8_LDI_PM_NEG,	/* type */	 17,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_HH8_LDI_PM_NEG", /* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* Relocation for CALL command in ATmega.  */  HOWTO (R_AVR_CALL,		/* type */	 1,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 23,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_AVR_CALL",		/* name */	 false,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 false)			/* pcrel_offset */};/* Map BFD reloc types to AVR ELF reloc types.  */struct avr_reloc_map{  bfd_reloc_code_real_type bfd_reloc_val;  unsigned int elf_reloc_val;}; static const struct avr_reloc_map avr_reloc_map[] ={  { BFD_RELOC_NONE,                 R_AVR_NONE },  { BFD_RELOC_32,                   R_AVR_32 },  { BFD_RELOC_AVR_7_PCREL,          R_AVR_7_PCREL },  { BFD_RELOC_AVR_13_PCREL,         R_AVR_13_PCREL },  { BFD_RELOC_16,                   R_AVR_16 },  { BFD_RELOC_AVR_16_PM,            R_AVR_16_PM },  { BFD_RELOC_AVR_LO8_LDI,          R_AVR_LO8_LDI},  { BFD_RELOC_AVR_HI8_LDI,          R_AVR_HI8_LDI },  { BFD_RELOC_AVR_HH8_LDI,          R_AVR_HH8_LDI },  { BFD_RELOC_AVR_LO8_LDI_NEG,      R_AVR_LO8_LDI_NEG },  { BFD_RELOC_AVR_HI8_LDI_NEG,      R_AVR_HI8_LDI_NEG },  { BFD_RELOC_AVR_HH8_LDI_NEG,      R_AVR_HH8_LDI_NEG },  { BFD_RELOC_AVR_LO8_LDI_PM,       R_AVR_LO8_LDI_PM },  { BFD_RELOC_AVR_HI8_LDI_PM,       R_AVR_HI8_LDI_PM },  { BFD_RELOC_AVR_HH8_LDI_PM,       R_AVR_HH8_LDI_PM },  { BFD_RELOC_AVR_LO8_LDI_PM_NEG,   R_AVR_LO8_LDI_PM_NEG },  { BFD_RELOC_AVR_HI8_LDI_PM_NEG,   R_AVR_HI8_LDI_PM_NEG },  { BFD_RELOC_AVR_HH8_LDI_PM_NEG,   R_AVR_HH8_LDI_PM_NEG },  { BFD_RELOC_AVR_CALL,             R_AVR_CALL }};static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup (abfd, code)     bfd *abfd ATTRIBUTE_UNUSED;     bfd_reloc_code_real_type code;{  unsigned int i;  for (i = 0;       i < sizeof (avr_reloc_map) / sizeof (struct avr_reloc_map);       i++)    {      if (avr_reloc_map[i].bfd_reloc_val == code)	return &elf_avr_howto_table[avr_reloc_map[i].elf_reloc_val];    }  return NULL;}/* Set the howto pointer for an AVR ELF reloc.  */static voidavr_info_to_howto_rela (abfd, cache_ptr, dst)     bfd *abfd ATTRIBUTE_UNUSED;     arelent *cache_ptr;     Elf32_Internal_Rela *dst;{  unsigned int r_type;  r_type = ELF32_R_TYPE (dst->r_info);  BFD_ASSERT (r_type < (unsigned int) R_AVR_max);  cache_ptr->howto = &elf_avr_howto_table[r_type];}static asection *elf32_avr_gc_mark_hook (abfd, info, rel, h, sym)     bfd *abfd;     struct bfd_link_info *info ATTRIBUTE_UNUSED;     Elf_Internal_Rela *rel;     struct elf_link_hash_entry *h;     Elf_Internal_Sym *sym;{  if (h != NULL)    {      switch (ELF32_R_TYPE (rel->r_info))	{	default:	  switch (h->root.type)	    {	    case bfd_link_hash_defined:	    case bfd_link_hash_defweak:	      return h->root.u.def.section;	    case bfd_link_hash_common:	      return h->root.u.c.p->section;	    default:	      break;	    }	}    }  else    {      if (!(elf_bad_symtab (abfd)	    && ELF_ST_BIND (sym->st_info) != STB_LOCAL)	  && !((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)	       && sym->st_shndx != SHN_COMMON))	{	  return bfd_section_from_elf_index (abfd, sym->st_shndx);	}    }  return NULL;}static booleanelf32_avr_gc_sweep_hook (abfd, info, sec, relocs)     bfd *abfd ATTRIBUTE_UNUSED;     struct bfd_link_info *info ATTRIBUTE_UNUSED;     asection *sec ATTRIBUTE_UNUSED;     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;{  /* We don't use got and plt entries for avr.  */  return true;}/* Look through the relocs for a section during the first phase.   Since we don't do .gots or .plts, we just need to consider the   virtual table relocs for gc.  */static booleanelf32_avr_check_relocs (abfd, info, sec, relocs)     bfd *abfd;     struct bfd_link_info *info;     asection *sec;     const Elf_Internal_Rela *relocs;{  Elf_Internal_Shdr *symtab_hdr;  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;  const Elf_Internal_Rela *rel;  const Elf_Internal_Rela *rel_end;  if (info->relocateable)    return true;  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;  sym_hashes = elf_sym_hashes (abfd);  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);  if (!elf_bad_symtab (abfd))    sym_hashes_end -= symtab_hdr->sh_info;  rel_end = relocs + sec->reloc_count;  for (rel = relocs; rel < rel_end; rel++)    {      struct elf_link_hash_entry *h;      unsigned long r_symndx;      r_symndx = ELF32_R_SYM (rel->r_info);      if (r_symndx < symtab_hdr->sh_info)

⌨️ 快捷键说明

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