* gas/config/tc-avr.h (TC_VALIDATE_FIX): Define. Disable fixups for PMEM

related expressions.
* bfd/elf32-avr.c (elf32_avr_relax_delete_bytes): Iterate over all of the
    bfd's sections for the reloc-addend adjustments.
This commit is contained in:
Nick Clifton 2006-05-05 17:46:47 +00:00
parent 605a56cbd3
commit 731608473a
4 changed files with 111 additions and 64 deletions

View File

@ -1,3 +1,8 @@
2006-05-05 Bjoern Haase <bjoern.m.haase@web.de>
* bfd/elf32-avr.c (elf32_avr_relax_delete_bytes): Iterate over all
of the bfd's sections for the reloc-addend adjustments.
2006-05-05 Martin Schwidefsky <schwidefsky@de.ibm.com>
* elf32-s390.c (invalid_tls_insn): Call bfd_set_error.

View File

@ -433,6 +433,7 @@ struct avr_reloc_map
unsigned int avr_pc_wrap_around = 0x10000000;
/* Calculates the effective distance of a pc relative jump/call. */
static int
avr_relative_distance_considering_wrap_around (unsigned int distance)
{
@ -455,10 +456,8 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
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;
}
@ -1085,10 +1084,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
(size_t) (toaddr - addr - count));
sec->size -= count;
/* Adjust all the relocs. */
/* Adjust all the reloc addresses. */
for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
{
bfd_vma symval;
bfd_vma old_reloc_address;
bfd_vma shrinked_insn_address;
@ -1111,15 +1109,37 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
irel->r_offset -= count;
}
}
/* The reloc's own addresses are now ok. However, we need to readjust
the reloc's addend if two conditions are met:
the reloc's addend, i.e. the reloc's value if two conditions are met:
1.) the reloc is relative to a symbol in this section that
is located in front of the shrinked instruction
2.) symbol plus addend end up behind the shrinked instruction.
This should happen only for local symbols that are progmem related. */
The most common case where this happens are relocs relative to
the section-start symbol.
/* Read this BFD's local symbols if we haven't done so already. */
This step needs to be done for all of the sections of the bfd. */
{
struct bfd_section *isec;
for (isec = abfd->sections; isec; isec = isec->next)
{
bfd_vma symval;
bfd_vma shrinked_insn_address;
shrinked_insn_address = (sec->output_section->vma
+ sec->output_offset + addr - count);
irelend = elf_section_data (isec)->relocs + isec->reloc_count;
for (irel = elf_section_data (isec)->relocs;
irel < irelend;
irel++)
{
/* Read this BFD's local symbols if we haven't done
so already. */
if (isymbuf == NULL && symtab_hdr->sh_info != 0)
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
@ -1143,7 +1163,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
symval = isym->st_value;
/* If the reloc is absolute, it will not have
a symbol or section associated with it. */
if (sym_sec)
if (sym_sec == sec)
{
symval += sym_sec->output_section->vma
+ sym_sec->output_offset;
@ -1164,15 +1184,15 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
irel->r_addend -= count;
if (DEBUG_RELAX)
printf ("Anchor symbol and relocation target bracket "
"shrinked insn address.\n"
"Need for new addend : 0x%x\n",
(unsigned int) irel->r_addend);
printf ("Relocation's addend needed to be fixed \n");
}
}
/* else...Reference symbol is absolute. No adjustment needed. */
}
/* else ... Reference symbol is extern. No need for adjusting the addend. */
/* else...Reference symbol is extern. No need for adjusting
the addend. */
}
}
}
/* Adjust the local symbols defined in this section. */

View File

@ -1,3 +1,8 @@
2006-05-05 Bjoern Haase <bjoern.m.haase@web.de>
* gas/config/tc-avr.h (TC_VALIDATE_FIX): Define. Disable fixups
for PMEM related expressions.
2006-05-05 Nick Clifton <nickc@redhat.com>
PR gas/2582

View File

@ -1,5 +1,5 @@
/* This file is tc-avr.h
Copyright 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
Copyright 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
@ -109,7 +109,7 @@ extern long md_pcrel_from_section (struct fix *, segT);
would print `12 34 56 78'. The default value is 4. */
#define LISTING_WORD_SIZE 2
/* AVR port uses `$' as a logical line separator */
/* AVR port uses `$' as a logical line separator. */
#define LEX_DOLLAR 0
/* An `.lcomm' directive with no explicit alignment parameter will
@ -120,3 +120,20 @@ extern long md_pcrel_from_section (struct fix *, segT);
also affected by this macro. The default definition will set
P2VAR to the truncated power of two of sizes up to eight bytes. */
#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) (P2VAR) = 0
/* We don't want gas to fixup the following program memory related relocations.
We will need them in case that we want to do linker relaxation.
We could in principle keep these fixups in gas when not relaxing.
However, there is no serious performance penilty when making the linker
make the fixup work. */
#define TC_VALIDATE_FIX(FIXP,SEG,SKIP) \
if ( FIXP->fx_r_type == BFD_RELOC_AVR_7_PCREL \
|| FIXP->fx_r_type == BFD_RELOC_AVR_13_PCREL \
|| FIXP->fx_r_type == BFD_RELOC_AVR_LO8_LDI_PM \
|| FIXP->fx_r_type == BFD_RELOC_AVR_HI8_LDI_PM \
|| FIXP->fx_r_type == BFD_RELOC_AVR_HH8_LDI_PM \
|| FIXP->fx_r_type == BFD_RELOC_AVR_16_PM) \
{ \
goto SKIP; \
}