Add linker relaxation support for the AVR

This commit is contained in:
Nick Clifton 2006-03-03 15:25:31 +00:00
parent b92a518e73
commit df406460e9
11 changed files with 1171 additions and 24 deletions

View File

@ -1,3 +1,19 @@
2006-03-03 Bjoern Haase <bjoern.m.haase@web.de>
* elf32-avr.c (avr_reloc_map): Insert BFD_RELOC_AVR_MS8_LDI
and R_AVR_MS8_LDI
(bfd_elf_avr_final_write_processing): Set
EF_AVR_LINKRELAX_PREPARED in e_flags field.
(elf32_avr_relax_section): New function.
(elf32_avr_relax_delete_bytes): New function.
(elf32_avr_get_relocated_section_contents): New function.
(avr_pc_wrap_around): New function.
(avr_relative_distance_considering_wrap_around): New function.
(avr_final_link_relocate): Handle negative int8t_t immediate for R_AVR_LDI.
* reloc.c: Add BFD_RELOC_AVR_MS8_LDI and BFD_RELOC_AVR_LDI_NEG
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
2006-03-02 DJ Delorie <dj@redhat.com>
* elf32-m32c.c (m32c_offset_for_reloc): Fix local symbol

View File

@ -8,7 +8,8 @@
/* Main header file for the bfd library -- portable access to object files.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
Contributed by Cygnus Support.
@ -3483,6 +3484,10 @@ of data memory address) into 8 bit immediate value of LDI insn. */
of program memory address) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_HH8_LDI,
/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
of 32 bit value) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_MS8_LDI,
/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
(usually data memory address) into 8 bit immediate value of SUBI insn. */
BFD_RELOC_AVR_LO8_LDI_NEG,
@ -3497,6 +3502,10 @@ SUBI insn. */
of LDI or SUBI insn. */
BFD_RELOC_AVR_HH8_LDI_NEG,
/* This is a 16 bit reloc for the AVR that stores negated 8 bit value (msb
of 32 bit value) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_MS8_LDI_NEG,
/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually
command address) into 8 bit immediate value of LDI insn. */
BFD_RELOC_AVR_LO8_LDI_PM,

File diff suppressed because it is too large Load Diff

View File

@ -1474,9 +1474,11 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_AVR_LO8_LDI",
"BFD_RELOC_AVR_HI8_LDI",
"BFD_RELOC_AVR_HH8_LDI",
"BFD_RELOC_AVR_MS8_LDI",
"BFD_RELOC_AVR_LO8_LDI_NEG",
"BFD_RELOC_AVR_HI8_LDI_NEG",
"BFD_RELOC_AVR_HH8_LDI_NEG",
"BFD_RELOC_AVR_MS8_LDI_NEG",
"BFD_RELOC_AVR_LO8_LDI_PM",
"BFD_RELOC_AVR_HI8_LDI_PM",
"BFD_RELOC_AVR_HH8_LDI_PM",

View File

@ -3585,6 +3585,11 @@ ENUM
ENUMDOC
This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
of program memory address) into 8 bit immediate value of LDI insn.
ENUM
BFD_RELOC_AVR_MS8_LDI
ENUMDOC
This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
of 32 bit value) into 8 bit immediate value of LDI insn.
ENUM
BFD_RELOC_AVR_LO8_LDI_NEG
ENUMDOC
@ -3602,6 +3607,11 @@ ENUMDOC
This is a 16 bit reloc for the AVR that stores negated 8 bit value
(most high 8 bit of program memory address) into 8 bit immediate value
of LDI or SUBI insn.
ENUM
BFD_RELOC_AVR_MS8_LDI_NEG
ENUMDOC
This is a 16 bit reloc for the AVR that stores negated 8 bit value (msb
of 32 bit value) into 8 bit immediate value of LDI insn.
ENUM
BFD_RELOC_AVR_LO8_LDI_PM
ENUMDOC

View File

@ -1,3 +1,16 @@
2006-03-03 Bjoern Haase <bjoern.m.haase@web.de>
* config/tc-avr.c (avr_mod_hash_value): New function.
(md_apply_fix, exp_mod): Use BFD_RELOC_HH8_LDI and
BFD_RELOC_MS8_LDI for hlo8() and hhi8()
(md_begin): Set linkrelax variable to 1, use avr_mod_hash_value
instead of int avr_ldi_expression: use avr_mod_hash_value instead
of (int).
(tc_gen_reloc): Handle substractions of symbols, if possible do
fixups, abort otherwise.
* config/tc-avr.h (TC_LINKRELAX_FIXUP, TC_VALIDATE_FIX,
tc_fix_adjustable): Define.
2006-03-02 James E Wilson <wilson@specifix.com>
* config/tc-ia64.c (emit_one_bundle): For IA64_OPCODE_LAST, if we

View File

@ -170,8 +170,8 @@ static struct exp_mod_s exp_mod[] =
{"pm_hi8", BFD_RELOC_AVR_HI8_LDI_PM, BFD_RELOC_AVR_HI8_LDI_PM_NEG, 0},
{"lo8", BFD_RELOC_AVR_LO8_LDI, BFD_RELOC_AVR_LO8_LDI_NEG, 1},
{"pm_lo8", BFD_RELOC_AVR_LO8_LDI_PM, BFD_RELOC_AVR_LO8_LDI_PM_NEG, 0},
{"hlo8", -BFD_RELOC_AVR_LO8_LDI, -BFD_RELOC_AVR_LO8_LDI_NEG, 0},
{"hhi8", -BFD_RELOC_AVR_HI8_LDI, -BFD_RELOC_AVR_HI8_LDI_NEG, 0},
{"hlo8", BFD_RELOC_AVR_HH8_LDI, BFD_RELOC_AVR_HH8_LDI_NEG, 0},
{"hhi8", BFD_RELOC_AVR_MS8_LDI, BFD_RELOC_AVR_MS8_LDI_NEG, 0},
};
/* A union used to store indicies into the exp_mod[] array
@ -1081,15 +1081,11 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
break;
case -BFD_RELOC_AVR_LO8_LDI:
bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 16), where);
break;
case BFD_RELOC_AVR_HI8_LDI:
bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 8), where);
break;
case -BFD_RELOC_AVR_HI8_LDI:
case BFD_RELOC_AVR_MS8_LDI:
bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 24), where);
break;
@ -1101,15 +1097,11 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value), where);
break;
case -BFD_RELOC_AVR_LO8_LDI_NEG:
bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 16), where);
break;
case BFD_RELOC_AVR_HI8_LDI_NEG:
bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 8), where);
break;
case -BFD_RELOC_AVR_HI8_LDI_NEG:
case BFD_RELOC_AVR_MS8_LDI_NEG:
bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 24), where);
break;
@ -1195,6 +1187,32 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED,
{
arelent *reloc;
if (fixp->fx_addsy && fixp->fx_subsy)
{
long value = 0;
if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
|| S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
"Difference of symbols in different sections is not supported");
return NULL;
}
/* We are dealing with two symbols defined in the same section.
Let us fix-up them here. */
value += S_GET_VALUE (fixp->fx_addsy);
value -= S_GET_VALUE (fixp->fx_subsy);
/* When fx_addsy and fx_subsy both are zero, md_apply_fix
only takes it's second operands for the fixup value. */
fixp->fx_addsy = NULL;
fixp->fx_subsy = NULL;
md_apply_fix (fixp, (valueT *) &value, NULL);
return NULL;
}
reloc = xmalloc (sizeof (arelent));
reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));

View File

@ -1,3 +1,8 @@
2006-03-03 Bjoern Haase <bjoern.m.haase@web.de>
* avr.h (R_AVR_MS8_LDI,R_AVR_MS8_LDI_NEG): Add.
(EF_AVR_LINKRELAX_PREPARED): Add.
2006-03-02 Ben Elliston <bje@au.ibm.com>
Import from the GCC tree:

View File

@ -26,6 +26,10 @@
/* Processor specific flags for the ELF header e_flags field. */
#define EF_AVR_MACH 0xf
/* If bit #7 is set, it is assumed that the elf file uses local symbols
as reference for the relocations so that linker relaxation is possible. */
#define EF_AVR_LINKRELAX_PREPARED 0x80
#define E_AVR_MACH_AVR1 1
#define E_AVR_MACH_AVR2 2
#define E_AVR_MACH_AVR3 3
@ -56,6 +60,8 @@ START_RELOC_NUMBERS (elf_avr_reloc_type)
RELOC_NUMBER (R_AVR_LDI, 19)
RELOC_NUMBER (R_AVR_6, 20)
RELOC_NUMBER (R_AVR_6_ADIW, 21)
RELOC_NUMBER (R_AVR_MS8_LDI, 22)
RELOC_NUMBER (R_AVR_MS8_LDI_NEG, 23)
END_RELOC_NUMBERS (R_AVR_max)
#endif /* _ELF_AVR_H */

View File

@ -1,3 +1,10 @@
2006-03-03 Bjoern Haase <bjoern.m.haase@web.de>
* scripttempl/avr.sc: Add *(.jumptables) *(.lowtext) sections.
Add KEEP() directives.
Add *(.data*) *(.rodata) and *(.rodata*) and *(.bss*) to .data and
.bss output sections.
2006-03-03 Richard Sandiford <richard@codesourcery.com>
* emulparams/vxworks.sh (VXWORKS_BASE_EM_FILE): New variable.

View File

@ -75,6 +75,7 @@ SECTIONS
.text :
{
*(.vectors)
KEEP(*(.vectors))
${CONSTRUCTING+ __ctors_start = . ; }
${CONSTRUCTING+ *(.ctors) }
@ -82,34 +83,65 @@ SECTIONS
${CONSTRUCTING+ __dtors_start = . ; }
${CONSTRUCTING+ *(.dtors) }
${CONSTRUCTING+ __dtors_end = . ; }
KEEP(SORT(*)(.ctors))
KEEP(SORT(*)(.dtors))
/* For data that needs to reside in the lower 64k of progmem */
*(.progmem.gcc*)
*(.progmem*)
${RELOCATING+. = ALIGN(2);}
/* for future tablejump instruction arrays for 3 byte pc devices */
*(.jumptables)
*(.jumptables*)
/* for code that needs to reside in the lower 128k progmem */
*(.lowtext)
*(.lowtext*)
*(.init0) /* Start here after reset. */
KEEP (*(.init0))
*(.init1)
KEEP (*(.init1))
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
KEEP (*(.init2))
*(.init3)
KEEP (*(.init3))
*(.init4) /* Initialize data and BSS. */
KEEP (*(.init4))
*(.init5)
KEEP (*(.init5))
*(.init6) /* C++ constructors. */
KEEP (*(.init6))
*(.init7)
KEEP (*(.init7))
*(.init8)
KEEP (*(.init8))
*(.init9) /* Call main(). */
KEEP (*(.init9))
*(.text)
${RELOCATING+. = ALIGN(2);}
*(.text.*)
${RELOCATING+. = ALIGN(2);}
*(.fini9) /* _exit() starts here. */
KEEP (*(.fini9))
*(.fini8)
KEEP (*(.fini8))
*(.fini7)
KEEP (*(.fini7))
*(.fini6) /* C++ destructors. */
KEEP (*(.fini6))
*(.fini5)
KEEP (*(.fini5))
*(.fini4)
KEEP (*(.fini4))
*(.fini3)
KEEP (*(.fini3))
*(.fini2)
KEEP (*(.fini2))
*(.fini1)
KEEP (*(.fini1))
*(.fini0) /* Infinite loop after program termination. */
KEEP (*(.fini0))
${RELOCATING+ _etext = . ; }
} ${RELOCATING+ > text}
@ -117,6 +149,9 @@ SECTIONS
{
${RELOCATING+ PROVIDE (__data_start = .) ; }
*(.data)
*(.data*)
*(.rodata) /* We need to include .rodata here if gcc is used */
*(.rodata*) /* with -fdata-sections. */
*(.gnu.linkonce.d*)
${RELOCATING+. = ALIGN(2);}
${RELOCATING+ _edata = . ; }
@ -127,6 +162,7 @@ SECTIONS
{
${RELOCATING+ PROVIDE (__bss_start = .) ; }
*(.bss)
*(.bss*)
*(COMMON)
${RELOCATING+ PROVIDE (__bss_end = .) ; }
} ${RELOCATING+ > data}