mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
Add linker relaxation support for the AVR
This commit is contained in:
parent
b92a518e73
commit
df406460e9
@ -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
|
||||
|
@ -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,
|
||||
|
1047
bfd/elf32-avr.c
1047
bfd/elf32-avr.c
File diff suppressed because it is too large
Load Diff
@ -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",
|
||||
|
10
bfd/reloc.c
10
bfd/reloc.c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 *));
|
||||
|
@ -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:
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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}
|
||||
|
Loading…
Reference in New Issue
Block a user