Line 1501... |
Line 1501... |
for (isec = abfd->sections; isec; isec = isec->next)
|
for (isec = abfd->sections; isec; isec = isec->next)
|
{
|
{
|
bfd_vma symval;
|
bfd_vma symval;
|
bfd_vma shrinked_insn_address;
|
bfd_vma shrinked_insn_address;
|
|
|
|
if (isec->reloc_count == 0)
|
|
continue;
|
|
|
shrinked_insn_address = (sec->output_section->vma
|
shrinked_insn_address = (sec->output_section->vma
|
+ sec->output_offset + addr - count);
|
+ sec->output_offset + addr - count);
|
|
|
irelend = elf_section_data (isec)->relocs + isec->reloc_count;
|
irel = elf_section_data (isec)->relocs;
|
for (irel = elf_section_data (isec)->relocs;
|
/* PR 12161: Read in the relocs for this section if necessary. */
|
|
if (irel == NULL)
|
|
irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, FALSE);
|
|
|
|
for (irelend = irel + isec->reloc_count;
|
irel < irelend;
|
irel < irelend;
|
irel++)
|
irel++)
|
{
|
{
|
/* Read this BFD's local symbols if we haven't done
|
/* Read this BFD's local symbols if we haven't done
|
so already. */
|
so already. */
|
Line 1562... |
Line 1569... |
/* 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. */
|
}
|
}
|
|
|
|
if (elf_section_data (isec)->relocs == NULL)
|
|
free (irelend - isec->reloc_count);
|
}
|
}
|
}
|
}
|
|
|
/* 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;
|
Line 1647... |
Line 1657... |
Elf_Internal_Rela *irel, *irelend;
|
Elf_Internal_Rela *irel, *irelend;
|
bfd_byte *contents = NULL;
|
bfd_byte *contents = NULL;
|
Elf_Internal_Sym *isymbuf = NULL;
|
Elf_Internal_Sym *isymbuf = NULL;
|
struct elf32_avr_link_hash_table *htab;
|
struct elf32_avr_link_hash_table *htab;
|
|
|
|
/* If 'shrinkable' is FALSE, do not shrink by deleting bytes while
|
|
relaxing. Such shrinking can cause issues for the sections such
|
|
as .vectors and .jumptables. Instead the unused bytes should be
|
|
filled with nop instructions. */
|
|
bfd_boolean shrinkable = TRUE;
|
|
|
|
if (!strcmp (sec->name,".vectors")
|
|
|| !strcmp (sec->name,".jumptables"))
|
|
shrinkable = FALSE;
|
|
|
if (link_info->relocatable)
|
if (link_info->relocatable)
|
(*link_info->callbacks->einfo)
|
(*link_info->callbacks->einfo)
|
(_("%P%F: --relax and -r may not be used together\n"));
|
(_("%P%F: --relax and -r may not be used together\n"));
|
|
|
htab = avr_link_hash_table (link_info);
|
htab = avr_link_hash_table (link_info);
|
Line 1803... |
Line 1823... |
+ sec->output_offset + irel->r_offset);
|
+ sec->output_offset + irel->r_offset);
|
|
|
/* Compute the distance from this insn to the branch target. */
|
/* Compute the distance from this insn to the branch target. */
|
gap = value - dot;
|
gap = value - dot;
|
|
|
/* If the distance is within -4094..+4098 inclusive, then we can
|
/* Check if the gap falls in the range that can be accommodated
|
relax this jump/call. +4098 because the call/jump target
|
in 13bits signed (It is 12bits when encoded, as we deal with
|
will be closer after the relaxation. */
|
word addressing). */
|
if ((int) gap >= -4094 && (int) gap <= 4098)
|
if (!shrinkable && ((int) gap >= -4096 && (int) gap <= 4095))
|
|
distance_short_enough = 1;
|
|
/* If shrinkable, then we can check for a range of distance which
|
|
is two bytes farther on both the directions because the call
|
|
or jump target will be closer by two bytes after the
|
|
relaxation. */
|
|
else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4097))
|
distance_short_enough = 1;
|
distance_short_enough = 1;
|
|
|
/* Here we handle the wrap-around case. E.g. for a 16k device
|
/* Here we handle the wrap-around case. E.g. for a 16k device
|
we could use a rjmp to jump from address 0x100 to 0x3d00!
|
we could use a rjmp to jump from address 0x100 to 0x3d00!
|
In order to make this work properly, we need to fill the
|
In order to make this work properly, we need to fill the
|
Line 1880... |
Line 1906... |
|
|
/* Fix the relocation's type. */
|
/* Fix the relocation's type. */
|
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
R_AVR_13_PCREL);
|
R_AVR_13_PCREL);
|
|
|
/* Check for the vector section. There we don't want to
|
/* We should not modify the ordering if 'shrinkable' is
|
modify the ordering! */
|
FALSE. */
|
|
if (!shrinkable)
|
if (!strcmp (sec->name,".vectors")
|
|
|| !strcmp (sec->name,".jumptables"))
|
|
{
|
{
|
/* Let's insert a nop. */
|
/* Let's insert a nop. */
|
bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 2);
|
bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 2);
|
bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 3);
|
bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 3);
|
}
|
}
|