/* AVR-specific support for 32-bit ELF
- Copyright (C) 1999-2018 Free Software Foundation, Inc.
+ Copyright (C) 1999-2020 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of BFD, the Binary File Descriptor library.
#include "elf-bfd.h"
#include "elf/avr.h"
#include "elf32-avr.h"
-#include "bfd_stdint.h"
/* Enable debugging printout at stdout with this variable. */
static bfd_boolean debug_relax = FALSE;
if (!sec->used_by_bfd)
{
struct elf_avr_section_data *sdata;
- bfd_size_type amt = sizeof (*sdata);
+ size_t amt = sizeof (*sdata);
sdata = bfd_zalloc (abfd, amt);
if (sdata == NULL)
elf32_avr_link_hash_table_create (bfd *abfd)
{
struct elf32_avr_link_hash_table *htab;
- bfd_size_type amt = sizeof (*htab);
+ size_t amt = sizeof (*htab);
htab = bfd_zmalloc (amt);
if (htab == NULL)
unsigned int wrap_around_mask = avr_pc_wrap_around - 1;
int dist_with_wrap_around = distance & wrap_around_mask;
- if (dist_with_wrap_around > ((int) (avr_pc_wrap_around >> 1)))
+ if (dist_with_wrap_around >= ((int) (avr_pc_wrap_around >> 1)))
dist_with_wrap_around -= avr_pc_wrap_around;
return dist_with_wrap_around;
name = bfd_elf_string_from_elf_section
(input_bfd, symtab_hdr->sh_link, sym->st_name);
- name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+ name = name == NULL ? bfd_section_name (sec) : name;
}
else
{
file. This gets the AVR architecture right based on the machine
number. */
-static void
-bfd_elf_avr_final_write_processing (bfd *abfd,
- bfd_boolean linker ATTRIBUTE_UNUSED)
+static bfd_boolean
+bfd_elf_avr_final_write_processing (bfd *abfd)
{
unsigned long val;
elf_elfheader (abfd)->e_machine = EM_AVR;
elf_elfheader (abfd)->e_flags &= ~ EF_AVR_MACH;
elf_elfheader (abfd)->e_flags |= val;
+ return _bfd_elf_final_write_processing (abfd);
}
/* Set the right machine number. */
return (a->offset - b->offset);
if (a->section != b->section)
- return (bfd_get_section_vma (a->section->owner, a->section)
- - bfd_get_section_vma (b->section->owner, b->section));
+ return bfd_section_vma (a->section) - bfd_section_vma (b->section);
return (a->type - b->type);
}
/* Compute the distance from this insn to the branch target. */
gap = value - dot;
+ /* The ISA manual states that addressable range is PC - 2k + 1 to
+ PC + 2k. In bytes, that would be -4094 <= PC <= 4096. The range
+ is shifted one word to the right, because pc-relative instructions
+ implicitly add one word i.e. rjmp 0 jumps to next insn, not the
+ current one.
+ Therefore, for the !shrinkable case, the range is as above.
+ If shrinkable, then the current code only deletes bytes 3 and
+ 4 of the absolute call/jmp, so the forward jump range increases
+ by 2 bytes, but the backward (negative) jump range remains
+ the same. */
+
+
/* Check if the gap falls in the range that can be accommodated
in 13bits signed (It is 12bits when encoded, as we deal with
word addressing). */
- if (!shrinkable && ((int) gap >= -4096 && (int) gap <= 4095))
+ if (!shrinkable && ((int) gap >= -4094 && (int) gap <= 4096))
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
+ is two bytes farther on the positive direction because the call
or jump target will be closer by two bytes after the
relaxation. */
- else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4097))
+ else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4098))
distance_short_enough = 1;
/* Here we handle the wrap-around case. E.g. for a 16k device
unsigned int top_id, top_index;
asection *section;
asection **input_list, **list;
- bfd_size_type amt;
+ size_t amt;
struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
if (htab == NULL || htab->no_stubs)
unsigned int bfd_indx;
Elf_Internal_Sym *local_syms, **all_local_syms;
struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
- bfd_size_type amt;
+ size_t amt;
if (htab == NULL)
return -1;
/* Return true if ADDRESS is within the vma range of SECTION from ABFD. */
static bfd_boolean
-avr_is_section_for_address (bfd *abfd, asection *section, bfd_vma address)
+avr_is_section_for_address (asection *section, bfd_vma address)
{
bfd_vma vma;
bfd_size_type size;
- vma = bfd_get_section_vma (abfd, section);
+ vma = bfd_section_vma (section);
if (address < vma)
return FALSE;
perform any checks, and just returns. */
static void
-avr_find_section_for_address (bfd *abfd,
+avr_find_section_for_address (bfd *abfd ATTRIBUTE_UNUSED,
asection *section, void *data)
{
struct avr_find_section_data *fs_data
return;
/* If this section isn't part of the addressable code content, skip it. */
- if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0
- && (bfd_get_section_flags (abfd, section) & SEC_CODE) == 0)
+ if ((bfd_section_flags (section) & SEC_ALLOC) == 0
+ && (bfd_section_flags (section) & SEC_CODE) == 0)
return;
- if (avr_is_section_for_address (abfd, section, fs_data->address))
+ if (avr_is_section_for_address (section, fs_data->address))
fs_data->section = section;
}
fs_data.section = NULL;
- size = bfd_get_section_size (sec);
+ size = bfd_section_size (sec);
contents = bfd_malloc (size);
bfd_get_section_contents (abfd, sec, contents, 0, size);
ptr = contents;
{
/* Try to find section and offset from address. */
if (fs_data.section != NULL
- && !avr_is_section_for_address (abfd, fs_data.section,
- address))
+ && !avr_is_section_for_address (fs_data.section, address))
fs_data.section = NULL;
if (fs_data.section == NULL)
r_list->records [i].section = fs_data.section;
r_list->records [i].offset
- = address - bfd_get_section_vma (abfd, fs_data.section);
+ = address - bfd_section_vma (fs_data.section);
}
r_list->records [i].type = *((bfd_byte *) ptr);