SOURCES: crossavr32-binutils.patch (NEW) - based on http://www.avr...

bszx bszx at pld-linux.org
Mon Jul 23 22:11:05 CEST 2007


Author: bszx                         Date: Mon Jul 23 20:11:05 2007 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- based on
http://www.avr32linux.org/twiki/bin/viewfile/Main/DevelopmentTools?rev=1;filename=500-avr32.patch.gz

---- Files affected:
SOURCES:
   crossavr32-binutils.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/crossavr32-binutils.patch
diff -u /dev/null SOURCES/crossavr32-binutils.patch:1.1
--- /dev/null	Mon Jul 23 22:11:05 2007
+++ SOURCES/crossavr32-binutils.patch	Mon Jul 23 22:11:00 2007
@@ -0,0 +1,28182 @@
+diff -Nrup binutils-2.17/bfd/archures.c binutils-2.17-atmel/bfd/archures.c
+--- binutils-2.17/bfd/archures.c	2006-03-06 14:42:03.000000000 +0100
++++ binutils-2.17-atmel/bfd/archures.c	2007-02-12 15:37:09.000000000 +0100
+@@ -334,6 +334,9 @@ DESCRIPTION
+ .#define bfd_mach_avr3		3
+ .#define bfd_mach_avr4		4
+ .#define bfd_mach_avr5		5
++.  bfd_arch_avr32,     {* Atmel AVR32 *}
++.#define bfd_mach_avr32_ap	7000
++.#define bfd_mach_avr32_uc	3000
+ .  bfd_arch_bfin,        {* ADI Blackfin *}
+ .#define bfd_mach_bfin          1
+ .  bfd_arch_cr16c,       {* National Semiconductor CompactRISC. *}
+@@ -423,6 +426,7 @@ extern const bfd_arch_info_type bfd_alph
+ extern const bfd_arch_info_type bfd_arc_arch;
+ extern const bfd_arch_info_type bfd_arm_arch;
+ extern const bfd_arch_info_type bfd_avr_arch;
++extern const bfd_arch_info_type bfd_avr32_arch;
+ extern const bfd_arch_info_type bfd_bfin_arch;
+ extern const bfd_arch_info_type bfd_cr16c_arch;
+ extern const bfd_arch_info_type bfd_cris_arch;
+@@ -490,6 +494,7 @@ static const bfd_arch_info_type * const 
+     &bfd_arc_arch,
+     &bfd_arm_arch,
+     &bfd_avr_arch,
++    &bfd_avr32_arch,
+     &bfd_bfin_arch,
+     &bfd_cr16c_arch,
+     &bfd_cris_arch,
+diff -Nrup binutils-2.17/bfd/bfd-in2.h binutils-2.17-atmel/bfd/bfd-in2.h
+--- binutils-2.17/bfd/bfd-in2.h	2006-03-26 01:38:42.000000000 +0100
++++ binutils-2.17-atmel/bfd/bfd-in2.h	2007-02-20 16:08:43.000000000 +0100
+@@ -1931,6 +1931,9 @@ enum bfd_architecture
+ #define bfd_mach_avr3          3
+ #define bfd_mach_avr4          4
+ #define bfd_mach_avr5          5
++  bfd_arch_avr32,     /* Atmel AVR32 */
++#define bfd_mach_avr32_ap      7000
++#define bfd_mach_avr32_uc      3000
+   bfd_arch_bfin,        /* ADI Blackfin */
+ #define bfd_mach_bfin          1
+   bfd_arch_cr16c,       /* National Semiconductor CompactRISC. */
+@@ -3577,6 +3580,87 @@ instructions  */
+ instructions  */
+   BFD_RELOC_AVR_6_ADIW,
+ 
++/* Difference between two labels: L2 - L1. The value of L1 is encoded
++as sym + addend, while the initial difference after assembly is
++inserted into the object file by the assembler.  */
++  BFD_RELOC_AVR32_DIFF32,
++  BFD_RELOC_AVR32_DIFF16,
++  BFD_RELOC_AVR32_DIFF8,
++
++/* Reference to a symbol through the Global Offset Table. The linker
++will allocate an entry for symbol in the GOT and insert the offset
++of this entry as the relocation value.  */
++  BFD_RELOC_AVR32_GOT32,
++  BFD_RELOC_AVR32_GOT16,
++  BFD_RELOC_AVR32_GOT8,
++
++/* Normal (non-pc-relative) code relocations. Alignment and signedness
++is indicated by the suffixes. S means signed, U means unsigned. W
++means word-aligned, H means halfword-aligned, neither means
++byte-aligned (no alignment.) SUB5 is the same relocation as 16S.  */
++  BFD_RELOC_AVR32_21S,
++  BFD_RELOC_AVR32_16U,
++  BFD_RELOC_AVR32_16S,
++  BFD_RELOC_AVR32_SUB5,
++  BFD_RELOC_AVR32_8S_EXT,
++  BFD_RELOC_AVR32_8S,
++
++/* PC-relative relocations are signed if neither 'U' nor 'S' is
++specified. However, we explicitly tack on a 'B' to indicate no
++alignment, to avoid confusion with data relocs. All of these resolve
++to sym + addend - offset, except the one with 'N' (negated) suffix.
++This particular one resolves to offset - sym - addend.  */
++  BFD_RELOC_AVR32_22H_PCREL,
++  BFD_RELOC_AVR32_18W_PCREL,
++  BFD_RELOC_AVR32_16B_PCREL,
++  BFD_RELOC_AVR32_16N_PCREL,
++  BFD_RELOC_AVR32_14UW_PCREL,
++  BFD_RELOC_AVR32_11H_PCREL,
++  BFD_RELOC_AVR32_10UW_PCREL,
++  BFD_RELOC_AVR32_9H_PCREL,
++  BFD_RELOC_AVR32_9UW_PCREL,
++
++/* Subtract the link-time address of the GOT from (symbol + addend)
++and insert the result.  */
++  BFD_RELOC_AVR32_GOTPC,
++
++/* Reference to a symbol through the GOT. The linker will allocate an
++entry for symbol in the GOT and insert the offset of this entry as
++the relocation value. addend must be zero. As usual, 'S' means
++signed, 'W' means word-aligned, etc.  */
++  BFD_RELOC_AVR32_GOTCALL,
++  BFD_RELOC_AVR32_LDA_GOT,
++  BFD_RELOC_AVR32_GOT21S,
++  BFD_RELOC_AVR32_GOT18SW,
++  BFD_RELOC_AVR32_GOT16S,
++
++/* 32-bit constant pool entry. I don't think 8- and 16-bit entries make
++a whole lot of sense.  */
++  BFD_RELOC_AVR32_32_CPENT,
++
++/* Constant pool references. Some of these relocations are signed,
++others are unsigned. It doesn't really matter, since the constant
++pool always comes after the code that references it.  */
++  BFD_RELOC_AVR32_CPCALL,
++  BFD_RELOC_AVR32_16_CP,
++  BFD_RELOC_AVR32_9W_CP,
++
++/* sym must be the absolute symbol. The addend specifies the alignment
++order, e.g. if addend is 2, the linker must add padding so that the
++next address is aligned to a 4-byte boundary.  */
++  BFD_RELOC_AVR32_ALIGN,
++
++/* Code relocations that will never make it to the output file.  */
++  BFD_RELOC_AVR32_14UW,
++  BFD_RELOC_AVR32_10UW,
++  BFD_RELOC_AVR32_10SW,
++  BFD_RELOC_AVR32_STHH_W,
++  BFD_RELOC_AVR32_7UW,
++  BFD_RELOC_AVR32_6S,
++  BFD_RELOC_AVR32_6UW,
++  BFD_RELOC_AVR32_4UH,
++  BFD_RELOC_AVR32_3U,
++
+ /* Direct 12 bit.  */
+   BFD_RELOC_390_12,
+ 
+diff -Nrup binutils-2.17/bfd/config.bfd binutils-2.17-atmel/bfd/config.bfd
+--- binutils-2.17/bfd/config.bfd	2006-04-05 14:41:57.000000000 +0200
++++ binutils-2.17-atmel/bfd/config.bfd	2007-02-12 15:37:09.000000000 +0100
+@@ -317,6 +317,10 @@ case "${targ}" in
+     targ_underscore=yes
+     ;;
+ 
++  avr32-*-*)
++    targ_defvec=bfd_elf32_avr32_vec
++    ;;
++
+   c30-*-*aout* | tic30-*-*aout*)
+     targ_defvec=tic30_aout_vec
+     ;;
+diff -Nrup binutils-2.17/bfd/configure.in binutils-2.17-atmel/bfd/configure.in
+--- binutils-2.17/bfd/configure.in	2006-06-23 20:17:07.000000000 +0200
++++ binutils-2.17-atmel/bfd/configure.in	2007-02-12 15:37:09.000000000 +0100
+@@ -8,7 +8,7 @@ AC_CONFIG_SRCDIR([libbfd.c])
+ AC_CANONICAL_TARGET
+ AC_ISC_POSIX
+ 
+-AM_INIT_AUTOMAKE(bfd, 2.17)
++AM_INIT_AUTOMAKE(bfd, 2.17.atmel.0.0.99)
+ 
+ dnl These must be called before AM_PROG_LIBTOOL, because it may want
+ dnl to call AC_CHECK_PROG.
+@@ -583,6 +583,7 @@ do
+     bfd_efi_app_ia64_vec)	tb="$tb efi-app-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;;
+     bfd_elf32_am33lin_vec)	tb="$tb elf32-am33lin.lo elf32.lo $elf" ;;
+     bfd_elf32_avr_vec)		tb="$tb elf32-avr.lo elf32.lo $elf" ;;
++    bfd_elf32_avr32_vec)	tb="$tb elf32-avr32.lo elf32.lo $elf" ;;
+     bfd_elf32_bfin_vec)		tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
+     bfd_elf32_bfinfdpic_vec)	tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
+     bfd_elf32_big_generic_vec) 	tb="$tb elf32-gen.lo elf32.lo $elf" ;;
+diff -Nrup binutils-2.17/bfd/cpu-avr32.c binutils-2.17-atmel/bfd/cpu-avr32.c
+--- binutils-2.17/bfd/cpu-avr32.c	1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.17-atmel/bfd/cpu-avr32.c	2006-11-10 15:05:48.000000000 +0100
+@@ -0,0 +1,49 @@
++/* BFD library support routines for AVR32.
++   Copyright 2003-2006 Atmel Corporation.
++
++   Written by Haavard Skinnemoen, Atmel Norway, <hskinnemoen at atmel.com>
++
++   This is part of BFD, the Binary File Descriptor library.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the 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 of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
++
++#include "bfd.h"
++#include "sysdep.h"
++#include "libbfd.h"
++
++#define N(machine, print, default, next)			\
++  {								\
++    32,				/* 32 bits in a word */		\
++    32,				/* 32 bits in an address */	\
++    8,				/* 8 bits in a byte */		\
++    bfd_arch_avr32,		/* architecture */		\
++    machine,			/* machine */			\
++    "avr32",			/* arch name */			\
++    print,			/* printable name */		\
++    1,				/* section align power */	\
++    default,			/* the default machine? */	\
++    bfd_default_compatible,					\
++    bfd_default_scan,						\
++    next,							\
++  }
++
++static const bfd_arch_info_type cpu_info[] =
++{
++  N(bfd_mach_avr32_ap, "avr32:ap", FALSE, &cpu_info[1]),
++  N(bfd_mach_avr32_uc, "avr32:uc", FALSE, NULL),
++};
++
++const bfd_arch_info_type bfd_avr32_arch =
++  N(bfd_mach_avr32_ap, "avr32:ap", TRUE, &cpu_info[0]);
+diff -Nrup binutils-2.17/bfd/elf32-avr32.c binutils-2.17-atmel/bfd/elf32-avr32.c
+--- binutils-2.17/bfd/elf32-avr32.c	1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.17-atmel/bfd/elf32-avr32.c	2007-02-12 15:37:09.000000000 +0100
+@@ -0,0 +1,3847 @@
++/* AVR32-specific support for 32-bit ELF.
++   Copyright 2003-2006 Atmel Corporation.
++
++   Written by Haavard Skinnemoen, Atmel Norway, <hskinnemoen at atmel.com>
++
++   This file is part of BFD, the Binary File Descriptor library.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the 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 of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
++
++#include "bfd.h"
++#include "sysdep.h"
++#include "bfdlink.h"
++#include "libbfd.h"
++#include "elf-bfd.h"
++#include "elf/avr32.h"
++
++#define xDEBUG
++#define xRELAX_DEBUG
++
++#ifdef DEBUG
++# define pr_debug(fmt, args...) fprintf(stderr, fmt, ##args)
++#else
++# define pr_debug(fmt, args...) do { } while (0)
++#endif
++
++#ifdef RELAX_DEBUG
++# define RDBG(fmt, args...) fprintf(stderr, fmt, ##args)
++#else
++# define RDBG(fmt, args...) do { } while (0)
++#endif
++
++/* When things go wrong, we want it to blow up, damnit! */
++#undef BFD_ASSERT
++#undef abort
++#define BFD_ASSERT(expr)					\
++  do								\
++    {								\
++      if (!(expr))						\
++	{							\
++	  bfd_assert(__FILE__, __LINE__);			\
++	  abort();						\
++	}							\
++    }								\
++  while (0)
++
++/* The name of the dynamic interpreter. This is put in the .interp section. */
++#define ELF_DYNAMIC_INTERPRETER		"/lib/ld.so.1"
++
++#define AVR32_GOT_HEADER_SIZE		8
++#define AVR32_FUNCTION_STUB_SIZE	8
++
++#define ELF_R_INFO(x, y) ELF32_R_INFO(x, y)
++#define ELF_R_TYPE(x) ELF32_R_TYPE(x)
++#define ELF_R_SYM(x) ELF32_R_SYM(x)
++
++#define NOP_OPCODE 0xd703
++
++
++/* Mapping between BFD relocations and ELF relocations */
++
++static reloc_howto_type *
++bfd_elf32_bfd_reloc_type_lookup(bfd *abfd, bfd_reloc_code_real_type code);
++static void
++avr32_info_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst);
++
++/* Generic HOWTO */
++#define GENH(name, align, size, bitsize, pcrel, bitpos, complain, mask)	\
++  HOWTO(name, align, size, bitsize, pcrel, bitpos,			\
++	complain_overflow_##complain, bfd_elf_generic_reloc, #name,	\
++	FALSE, 0, mask, pcrel)
++
++static reloc_howto_type elf_avr32_howto_table[] = {
++  /*   NAME		 ALN SZ BSZ PCREL  BP COMPLAIN  MASK	    */
++  GENH(R_AVR32_NONE,	  0, 0, 0,  FALSE, 0, dont,	0x00000000),
++
++  GENH(R_AVR32_32,	  0, 2, 32, FALSE, 0, dont,	0xffffffff),
++  GENH(R_AVR32_16,	  0, 1, 16, FALSE, 0, bitfield,	0x0000ffff),
++  GENH(R_AVR32_8,	  0, 0,  8, FALSE, 0, bitfield,	0x000000ff),
++  GENH(R_AVR32_32_PCREL,  0, 2, 32, TRUE,  0, signed,   0xffffffff),
++  GENH(R_AVR32_16_PCREL,  0, 1, 16, TRUE,  0, signed,   0x0000ffff),
++  GENH(R_AVR32_8_PCREL,	  0, 0,  8, TRUE,  0, signed,   0x000000ff),
++
++  /* Difference between two symbol (sym2 - sym1).  The reloc encodes
++     the value of sym1.  The field contains the difference before any
++     relaxing is done.  */
++  GENH(R_AVR32_DIFF32,	  0, 2, 32, FALSE, 0, dont,	0xffffffff),
++  GENH(R_AVR32_DIFF16,	  0, 1, 16, FALSE, 0, signed,	0x0000ffff),
++  GENH(R_AVR32_DIFF8,	  0, 0,  8, FALSE, 0, signed,	0x000000ff),
++
++  GENH(R_AVR32_GOT32,	  0, 2, 32, FALSE, 0, signed,	0xffffffff),
++  GENH(R_AVR32_GOT16,	  0, 1, 16, FALSE, 0, signed,	0x0000ffff),
++  GENH(R_AVR32_GOT8,	  0, 0,  8, FALSE, 0, signed,	0x000000ff),
++
++  GENH(R_AVR32_21S,	  0, 2, 21, FALSE, 0, signed,	0x1e10ffff),
++  GENH(R_AVR32_16U,	  0, 2, 16, FALSE, 0, unsigned,	0x0000ffff),
++  GENH(R_AVR32_16S,	  0, 2, 16, FALSE, 0, signed,	0x0000ffff),
++  GENH(R_AVR32_8S,	  0, 1,  8, FALSE, 4, signed,	0x00000ff0),
++  GENH(R_AVR32_8S_EXT,	  0, 2,  8, FALSE, 0, signed,	0x000000ff),
++
++  GENH(R_AVR32_22H_PCREL, 1, 2, 21, TRUE,  0, signed,	0x1e10ffff),
++  GENH(R_AVR32_18W_PCREL, 2, 2, 16, TRUE,  0, signed,	0x0000ffff),
++  GENH(R_AVR32_16B_PCREL, 0, 2, 16, TRUE,  0, signed,	0x0000ffff),
++  GENH(R_AVR32_16N_PCREL, 0, 2, 16, TRUE,  0, signed,	0x0000ffff),
++  GENH(R_AVR32_14UW_PCREL, 2, 2, 12, TRUE, 0, unsigned, 0x0000f0ff),
++  GENH(R_AVR32_11H_PCREL, 1, 1, 10, TRUE,  4, signed,	0x00000ff3),
++  GENH(R_AVR32_10UW_PCREL, 2, 2, 8, TRUE,  0, unsigned, 0x000000ff),
++  GENH(R_AVR32_9H_PCREL,  1, 1,  8, TRUE,  4, signed,	0x00000ff0),
++  GENH(R_AVR32_9UW_PCREL, 2, 1,  7, TRUE,  4, unsigned,	0x000007f0),
++
++  GENH(R_AVR32_HI16,	 16, 2, 16, FALSE, 0, dont,	0x0000ffff),
++  GENH(R_AVR32_LO16,	  0, 2, 16, FALSE, 0, dont,	0x0000ffff),
++
++  GENH(R_AVR32_GOTPC,	  0, 2, 32, FALSE, 0, dont,	0xffffffff),
++  GENH(R_AVR32_GOTCALL,   2, 2, 21, FALSE, 0, signed,	0x1e10ffff),
++  GENH(R_AVR32_LDA_GOT,	  2, 2, 21, FALSE, 0, signed,	0x1e10ffff),
++  GENH(R_AVR32_GOT21S,	  0, 2, 21, FALSE, 0, signed,	0x1e10ffff),
++  GENH(R_AVR32_GOT18SW,	  2, 2, 16, FALSE, 0, signed,	0x0000ffff),
++  GENH(R_AVR32_GOT16S,	  0, 2, 16, FALSE, 0, signed,	0x0000ffff),
++  GENH(R_AVR32_GOT7UW,	  2, 1,  5, FALSE, 4, unsigned, 0x000001f0),
++
++  GENH(R_AVR32_32_CPENT,  0, 2, 32, FALSE, 0, dont,	0xffffffff),
++  GENH(R_AVR32_CPCALL,	  2, 2, 16, TRUE,  0, signed,	0x0000ffff),
++  GENH(R_AVR32_16_CP,	  0, 2, 16, TRUE,  0, signed,	0x0000ffff),
++  GENH(R_AVR32_9W_CP,	  2, 1,  7, TRUE,  4, unsigned, 0x000007f0),
++
++  GENH(R_AVR32_RELATIVE,  0, 2, 32, FALSE, 0, signed,	0xffffffff),
++  GENH(R_AVR32_GLOB_DAT,  0, 2, 32, FALSE, 0, dont,	0xffffffff),
++  GENH(R_AVR32_JMP_SLOT,  0, 2, 32, FALSE, 0, dont,	0xffffffff),
++
++  GENH(R_AVR32_ALIGN,	 0,  1, 0,  FALSE, 0, unsigned, 0x00000000),
++};
++
++struct elf_reloc_map
++{
++  bfd_reloc_code_real_type bfd_reloc_val;
++  unsigned char elf_reloc_val;
++};
++
++static const struct elf_reloc_map avr32_reloc_map[] =
++{
++  { BFD_RELOC_NONE,			R_AVR32_NONE },
++
++  { BFD_RELOC_32,			R_AVR32_32 },
++  { BFD_RELOC_16,			R_AVR32_16 },
++  { BFD_RELOC_8,			R_AVR32_8 },
++  { BFD_RELOC_32_PCREL,			R_AVR32_32_PCREL },
++  { BFD_RELOC_16_PCREL,			R_AVR32_16_PCREL },
++  { BFD_RELOC_8_PCREL,			R_AVR32_8_PCREL },
++  { BFD_RELOC_AVR32_DIFF32,		R_AVR32_DIFF32 },
++  { BFD_RELOC_AVR32_DIFF16,		R_AVR32_DIFF16 },
++  { BFD_RELOC_AVR32_DIFF8,		R_AVR32_DIFF8 },
++  { BFD_RELOC_AVR32_GOT32,		R_AVR32_GOT32 },
++  { BFD_RELOC_AVR32_GOT16,		R_AVR32_GOT16 },
++  { BFD_RELOC_AVR32_GOT8,		R_AVR32_GOT8 },
++
++  { BFD_RELOC_AVR32_21S,		R_AVR32_21S },
++  { BFD_RELOC_AVR32_16U,		R_AVR32_16U },
++  { BFD_RELOC_AVR32_16S,		R_AVR32_16S },
++  { BFD_RELOC_AVR32_SUB5,		R_AVR32_16S },
++  { BFD_RELOC_AVR32_8S_EXT,		R_AVR32_8S_EXT },
++  { BFD_RELOC_AVR32_8S,			R_AVR32_8S },
++
++  { BFD_RELOC_AVR32_22H_PCREL,		R_AVR32_22H_PCREL },
++  { BFD_RELOC_AVR32_18W_PCREL,		R_AVR32_18W_PCREL },
++  { BFD_RELOC_AVR32_16B_PCREL,		R_AVR32_16B_PCREL },
++  { BFD_RELOC_AVR32_16N_PCREL,		R_AVR32_16N_PCREL },
++  { BFD_RELOC_AVR32_11H_PCREL,		R_AVR32_11H_PCREL },
++  { BFD_RELOC_AVR32_10UW_PCREL,		R_AVR32_10UW_PCREL },
++  { BFD_RELOC_AVR32_9H_PCREL,		R_AVR32_9H_PCREL },
++  { BFD_RELOC_AVR32_9UW_PCREL,		R_AVR32_9UW_PCREL },
++
++  { BFD_RELOC_HI16,			R_AVR32_HI16 },
++  { BFD_RELOC_LO16,			R_AVR32_LO16 },
++
++  { BFD_RELOC_AVR32_GOTPC,		R_AVR32_GOTPC },
++  { BFD_RELOC_AVR32_GOTCALL,		R_AVR32_GOTCALL },
++  { BFD_RELOC_AVR32_LDA_GOT,		R_AVR32_LDA_GOT },
++  { BFD_RELOC_AVR32_GOT21S,		R_AVR32_GOT21S },
++  { BFD_RELOC_AVR32_GOT18SW,		R_AVR32_GOT18SW },
++  { BFD_RELOC_AVR32_GOT16S,		R_AVR32_GOT16S },
++  /* GOT7UW should never be generated by the assembler */
++
++  { BFD_RELOC_AVR32_32_CPENT,		R_AVR32_32_CPENT },
++  { BFD_RELOC_AVR32_CPCALL,		R_AVR32_CPCALL },
++  { BFD_RELOC_AVR32_16_CP,		R_AVR32_16_CP },
++  { BFD_RELOC_AVR32_9W_CP,		R_AVR32_9W_CP },
++
++  { BFD_RELOC_AVR32_ALIGN,		R_AVR32_ALIGN },
++};
++
++static reloc_howto_type *
++bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
++				 bfd_reloc_code_real_type code)
++{
++  unsigned int i;
++
++  for (i = 0; i < sizeof(avr32_reloc_map) / sizeof(struct elf_reloc_map); i++)
++    {
++      if (avr32_reloc_map[i].bfd_reloc_val == code)
++	return &elf_avr32_howto_table[avr32_reloc_map[i].elf_reloc_val];
++    }
++
++  return NULL;
++}
++
++static void
++avr32_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
++		     arelent *cache_ptr,
++		     Elf_Internal_Rela *dst)
++{
++  unsigned int r_type;
++
++  r_type = ELF32_R_TYPE (dst->r_info);
++  BFD_ASSERT (r_type < (unsigned int) R_AVR32_max);
++  cache_ptr->howto = &elf_avr32_howto_table[r_type];
++}
++
++
++/* AVR32 ELF linker hash table and associated hash entries. */
++
++static struct bfd_hash_entry *
++avr32_elf_link_hash_newfunc(struct bfd_hash_entry *entry,
++			    struct bfd_hash_table *table,
++			    const char *string);
++static void
++avr32_elf_copy_indirect_symbol(struct bfd_link_info *info,
++			       struct elf_link_hash_entry *dir,
++			       struct elf_link_hash_entry *ind);
++static struct bfd_link_hash_table *
++avr32_elf_link_hash_table_create(bfd *abfd);
++
++/*
++  Try to limit memory usage to something reasonable when sorting the
++  GOT.  If we ever get more than this many references to the same
++  symbol, we may need to do something special.
++*/
++#define MAX_NR_GOT_HOLES	8192
++
++/*
++  AVR32 GOT entry.  We need to keep track of refcounts and offsets
++  simultaneously, since we need the offsets during relaxation, and we
++  also want to be able to drop GOT entries during relaxation. In
++  addition to this, we want to keep the list of GOT entries sorted so
++  that we can keep the most-used entries at the lowest offsets.
++*/
++struct got_entry
++{
++  struct got_entry *next;
++  struct got_entry **pprev;
++  int refcount;
++  bfd_signed_vma offset;
++};
++
++struct elf_avr32_link_hash_entry
++{
++  struct elf_link_hash_entry root;
++
++  /* Number of runtime relocations against this symbol.  */
++  unsigned int possibly_dynamic_relocs;
++
++  /* If there are anything but R_AVR32_GOT18 relocations against this
++     symbol, it means that someone may be taking the address of the
++     function, and we should therefore not create a stub.  */
++  bfd_boolean no_fn_stub;
++
++  /* If there is a R_AVR32_32 relocation in a read-only section
++     against this symbol, we could be in trouble. If we're linking a
++     shared library or this symbol is defined in one, it means we must
++     emit a run-time reloc for it and that's not allowed in read-only
++     sections.  */
++  asection *readonly_reloc_sec;
++  bfd_vma readonly_reloc_offset;
++
++  /* Record which frag (if any) contains the symbol.  This is used
++     during relaxation in order to avoid having to update all symbols
++     whenever we move something.  For local symbols, this information
++     is in the local_sym_frag member of struct elf_obj_tdata.  */
++  struct fragment *sym_frag;
++};
++#define avr32_elf_hash_entry(ent) ((struct elf_avr32_link_hash_entry *)(ent))
++
++struct elf_avr32_link_hash_table
++{
++  struct elf_link_hash_table root;
++
++  /* Shortcuts to get to dynamic linker sections.  */
++  asection *sgot;
++  asection *srelgot;
++  asection *sreldyn;
++  asection *sstub;
++
++  /* We use a variation of Pigeonhole Sort to sort the GOT.  After the
++     initial refcounts have been determined, we initialize
++     nr_got_holes to the highest refcount ever seen and allocate an
++     array of nr_got_holes entries for got_hole.  Each GOT entry is
++     then stored in this array at the index given by its refcount.
++
++     When a GOT entry has its refcount decremented during relaxation,
++     it is moved to a lower index in the got_hole array.
++   */
++  struct got_entry **got_hole;
++  int nr_got_holes;
++
++  /* Dynamic relocations to local symbols.  Only used when linking a
++     shared library and -Bsymbolic is not given.  */
++  unsigned int local_dynamic_relocs;
++
++  bfd_boolean relocations_analyzed;
++  bfd_boolean symbols_adjusted;
++  bfd_boolean repeat_pass;
++  unsigned int relax_iteration;
++  unsigned int relax_pass;
++};
++#define avr32_elf_hash_table(p)				\
++  ((struct elf_avr32_link_hash_table *)((p)->hash))
++
++static struct bfd_hash_entry *
++avr32_elf_link_hash_newfunc(struct bfd_hash_entry *entry,
++			    struct bfd_hash_table *table,
++			    const char *string)
++{
++  struct elf_avr32_link_hash_entry *ret = avr32_elf_hash_entry(entry);
++
++  /* Allocate the structure if it hasn't already been allocated by a
++     subclass */
++  if (ret == NULL)
++    ret = (struct elf_avr32_link_hash_entry *)
++      bfd_hash_allocate(table, sizeof(struct elf_avr32_link_hash_entry));
++
++  if (ret == NULL)
++    return NULL;
++
++  memset(ret, 0, sizeof(struct elf_avr32_link_hash_entry));
++
++  /* Give the superclass a chance */
++  ret = (struct elf_avr32_link_hash_entry *)
++    _bfd_elf_link_hash_newfunc((struct bfd_hash_entry *)ret, table, string);
++
++  return (struct bfd_hash_entry *)ret;
++}
++
++/* Copy data from an indirect symbol to its direct symbol, hiding the
++   old indirect symbol.  Process additional relocation information.
++   Also called for weakdefs, in which case we just let
++   _bfd_elf_link_hash_copy_indirect copy the flags for us.  */
++
++static void
++avr32_elf_copy_indirect_symbol(struct bfd_link_info *info,
++			       struct elf_link_hash_entry *dir,
++			       struct elf_link_hash_entry *ind)
++{
++  struct elf_avr32_link_hash_entry *edir, *eind;
++
++  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
++
++  if (ind->root.type != bfd_link_hash_indirect)
++    return;
++
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list