mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-25 19:14:52 +08:00
* 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:
parent
605a56cbd3
commit
731608473a
@ -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>
|
2006-05-05 Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||||
|
|
||||||
* elf32-s390.c (invalid_tls_insn): Call bfd_set_error.
|
* elf32-s390.c (invalid_tls_insn): Call bfd_set_error.
|
||||||
|
144
bfd/elf32-avr.c
144
bfd/elf32-avr.c
@ -433,6 +433,7 @@ struct avr_reloc_map
|
|||||||
unsigned int avr_pc_wrap_around = 0x10000000;
|
unsigned int avr_pc_wrap_around = 0x10000000;
|
||||||
|
|
||||||
/* Calculates the effective distance of a pc relative jump/call. */
|
/* Calculates the effective distance of a pc relative jump/call. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
avr_relative_distance_considering_wrap_around (unsigned int distance)
|
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;
|
for (i = 0;
|
||||||
i < sizeof (avr_reloc_map) / sizeof (struct avr_reloc_map);
|
i < sizeof (avr_reloc_map) / sizeof (struct avr_reloc_map);
|
||||||
i++)
|
i++)
|
||||||
{
|
if (avr_reloc_map[i].bfd_reloc_val == code)
|
||||||
if (avr_reloc_map[i].bfd_reloc_val == code)
|
return &elf_avr_howto_table[avr_reloc_map[i].elf_reloc_val];
|
||||||
return &elf_avr_howto_table[avr_reloc_map[i].elf_reloc_val];
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1049,9 +1048,9 @@ elf32_avr_object_p (bfd *abfd)
|
|||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf32_avr_relax_delete_bytes (bfd *abfd,
|
elf32_avr_relax_delete_bytes (bfd *abfd,
|
||||||
asection *sec,
|
asection *sec,
|
||||||
bfd_vma addr,
|
bfd_vma addr,
|
||||||
int count)
|
int count)
|
||||||
{
|
{
|
||||||
Elf_Internal_Shdr *symtab_hdr;
|
Elf_Internal_Shdr *symtab_hdr;
|
||||||
unsigned int sec_shndx;
|
unsigned int sec_shndx;
|
||||||
@ -1085,10 +1084,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
|
|||||||
(size_t) (toaddr - addr - count));
|
(size_t) (toaddr - addr - count));
|
||||||
sec->size -= count;
|
sec->size -= count;
|
||||||
|
|
||||||
/* Adjust all the relocs. */
|
/* Adjust all the reloc addresses. */
|
||||||
for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
|
for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
|
||||||
{
|
{
|
||||||
bfd_vma symval;
|
|
||||||
bfd_vma old_reloc_address;
|
bfd_vma old_reloc_address;
|
||||||
bfd_vma shrinked_insn_address;
|
bfd_vma shrinked_insn_address;
|
||||||
|
|
||||||
@ -1111,69 +1109,91 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
|
|||||||
irel->r_offset -= count;
|
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:
|
|
||||||
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 reloc's own addresses are now ok. However, we need to readjust
|
||||||
|
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.
|
||||||
|
|
||||||
|
The most common case where this happens are relocs relative to
|
||||||
|
the section-start symbol.
|
||||||
|
|
||||||
|
This step needs to be done for all of the sections of the bfd. */
|
||||||
|
|
||||||
/* Read this BFD's local symbols if we haven't done so already. */
|
{
|
||||||
if (isymbuf == NULL && symtab_hdr->sh_info != 0)
|
struct bfd_section *isec;
|
||||||
{
|
|
||||||
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
|
|
||||||
if (isymbuf == NULL)
|
|
||||||
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
|
|
||||||
symtab_hdr->sh_info, 0,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
if (isymbuf == NULL)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the value of the symbol referred to by the reloc. */
|
for (isec = abfd->sections; isec; isec = isec->next)
|
||||||
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
|
{
|
||||||
{
|
bfd_vma symval;
|
||||||
/* A local symbol. */
|
bfd_vma shrinked_insn_address;
|
||||||
Elf_Internal_Sym *isym;
|
|
||||||
asection *sym_sec;
|
|
||||||
|
|
||||||
isym = isymbuf + ELF32_R_SYM (irel->r_info);
|
shrinked_insn_address = (sec->output_section->vma
|
||||||
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
|
+ sec->output_offset + addr - count);
|
||||||
symval = isym->st_value;
|
|
||||||
/* If the reloc is absolute, it will not have
|
|
||||||
a symbol or section associated with it. */
|
|
||||||
if (sym_sec)
|
|
||||||
{
|
|
||||||
symval += sym_sec->output_section->vma
|
|
||||||
+ sym_sec->output_offset;
|
|
||||||
|
|
||||||
if (DEBUG_RELAX)
|
irelend = elf_section_data (isec)->relocs + isec->reloc_count;
|
||||||
printf ("Checking if the relocation's "
|
for (irel = elf_section_data (isec)->relocs;
|
||||||
"addend needs corrections.\n"
|
irel < irelend;
|
||||||
"Address of anchor symbol: 0x%x \n"
|
irel++)
|
||||||
"Address of relocation target: 0x%x \n"
|
{
|
||||||
"Address of relaxed insn: 0x%x \n",
|
/* Read this BFD's local symbols if we haven't done
|
||||||
(unsigned int) symval,
|
so already. */
|
||||||
(unsigned int) (symval + irel->r_addend),
|
if (isymbuf == NULL && symtab_hdr->sh_info != 0)
|
||||||
(unsigned int) shrinked_insn_address);
|
{
|
||||||
|
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
|
||||||
|
if (isymbuf == NULL)
|
||||||
|
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
|
||||||
|
symtab_hdr->sh_info, 0,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
if (isymbuf == NULL)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (symval <= shrinked_insn_address
|
/* Get the value of the symbol referred to by the reloc. */
|
||||||
&& (symval + irel->r_addend) > shrinked_insn_address)
|
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
|
||||||
{
|
{
|
||||||
irel->r_addend -= count;
|
/* A local symbol. */
|
||||||
|
Elf_Internal_Sym *isym;
|
||||||
|
asection *sym_sec;
|
||||||
|
|
||||||
|
isym = isymbuf + ELF32_R_SYM (irel->r_info);
|
||||||
|
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
|
||||||
|
symval = isym->st_value;
|
||||||
|
/* If the reloc is absolute, it will not have
|
||||||
|
a symbol or section associated with it. */
|
||||||
|
if (sym_sec == sec)
|
||||||
|
{
|
||||||
|
symval += sym_sec->output_section->vma
|
||||||
|
+ sym_sec->output_offset;
|
||||||
|
|
||||||
if (DEBUG_RELAX)
|
if (DEBUG_RELAX)
|
||||||
printf ("Anchor symbol and relocation target bracket "
|
printf ("Checking if the relocation's "
|
||||||
"shrinked insn address.\n"
|
"addend needs corrections.\n"
|
||||||
"Need for new addend : 0x%x\n",
|
"Address of anchor symbol: 0x%x \n"
|
||||||
(unsigned int) irel->r_addend);
|
"Address of relocation target: 0x%x \n"
|
||||||
|
"Address of relaxed insn: 0x%x \n",
|
||||||
|
(unsigned int) symval,
|
||||||
|
(unsigned int) (symval + irel->r_addend),
|
||||||
|
(unsigned int) shrinked_insn_address);
|
||||||
|
|
||||||
|
if (symval <= shrinked_insn_address
|
||||||
|
&& (symval + irel->r_addend) > shrinked_insn_address)
|
||||||
|
{
|
||||||
|
irel->r_addend -= count;
|
||||||
|
|
||||||
|
if (DEBUG_RELAX)
|
||||||
|
printf ("Relocation's addend needed to be fixed \n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
/* else...Reference symbol is absolute. No adjustment needed. */
|
||||||
/* else ... Reference symbol is absolute. No adjustment needed. */
|
}
|
||||||
}
|
/* else...Reference symbol is extern. No need for adjusting
|
||||||
/* else ... Reference symbol is extern. No need for adjusting the addend. */
|
the addend. */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Adjust the local symbols defined in this section. */
|
/* Adjust the local symbols defined in this section. */
|
||||||
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
|
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
|
||||||
|
@ -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>
|
2006-05-05 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
PR gas/2582
|
PR gas/2582
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* This file is tc-avr.h
|
/* 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>
|
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. */
|
would print `12 34 56 78'. The default value is 4. */
|
||||||
#define LISTING_WORD_SIZE 2
|
#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
|
#define LEX_DOLLAR 0
|
||||||
|
|
||||||
/* An `.lcomm' directive with no explicit alignment parameter will
|
/* 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
|
also affected by this macro. The default definition will set
|
||||||
P2VAR to the truncated power of two of sizes up to eight bytes. */
|
P2VAR to the truncated power of two of sizes up to eight bytes. */
|
||||||
#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) (P2VAR) = 0
|
#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; \
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user