/* AVR-specific support for 32-bit ELF
- Copyright (C) 1999-2019 Free Software Foundation, Inc.
+ Copyright (C) 1999-2021 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of BFD, the Binary File Descriptor library.
/* Various hash macros and functions. */
#define avr_link_hash_table(p) \
- /* PR 3874: Check that we have an AVR style hash table before using it. */\
- (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
- == AVR_ELF_DATA ? ((struct elf32_avr_link_hash_table *) ((p)->hash)) : NULL)
+ ((is_elf_hash_table ((p)->hash) \
+ && elf_hash_table_id (elf_hash_table (p)) == AVR_ELF_DATA) \
+ ? (struct elf32_avr_link_hash_table *) (p)->hash : NULL)
#define avr_stub_hash_entry(ent) \
((struct elf32_avr_stub_hash_entry *)(ent))
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)
= (struct elf32_avr_link_hash_table *) obfd->link.hash;
/* Free the address mapping table. */
- if (htab->amt_stub_offsets != NULL)
- free (htab->amt_stub_offsets);
- if (htab->amt_destination_addr != NULL)
- free (htab->amt_destination_addr);
+ free (htab->amt_stub_offsets);
+ free (htab->amt_destination_addr);
bfd_hash_table_free (&htab->bstab);
_bfd_elf_link_hash_table_free (obfd);
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)
if (srel > ((1 << 7) - 1) || (srel < - (1 << 7)))
return bfd_reloc_overflow;
x = bfd_get_16 (input_bfd, contents);
- x = (x & 0xfc07) | (((srel >> 1) << 3) & 0x3f8);
+ x = (x & 0xfc07) | (((srel >> 1) * 8) & 0x3f8);
bfd_put_16 (input_bfd, x, contents);
break;
/* Relocate an AVR ELF section. */
-static bfd_boolean
+static int
elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info,
bfd *input_bfd,
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)
+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;
- _bfd_elf_final_write_processing (abfd, linker);
+ 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);
}
}
}
- if (internal_relocs != NULL
- && elf_section_data (sec)->relocs != internal_relocs)
+ if (elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return TRUE;
error_return:
- if (isymbuf != NULL
- && symtab_hdr->contents != (unsigned char *) isymbuf)
+ if (symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
- if (contents != NULL
- && elf_section_data (sec)->this_hdr.contents != contents)
+ if (elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
- if (internal_relocs != NULL
- && elf_section_data (sec)->relocs != internal_relocs)
+ if (elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return FALSE;
isymbuf, sections))
goto error_return;
- if (sections != NULL)
- free (sections);
- if (isymbuf != NULL
- && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (sections);
+ if (symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
return data;
error_return:
- if (sections != NULL)
- free (sections);
- if (isymbuf != NULL
- && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (sections);
+ if (symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
- if (internal_relocs != NULL
- && elf_section_data (input_section)->relocs != internal_relocs)
+ if (elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
return NULL;
}
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;
}
static struct avr_property_record_list *
avr_elf32_load_records_from_section (bfd *abfd, asection *sec)
{
- char *contents = NULL, *ptr;
+ bfd_byte *contents, *ptr;
bfd_size_type size, mem_size;
bfd_byte version, flags;
uint16_t record_count, i;
fs_data.section = NULL;
- size = bfd_get_section_size (sec);
- contents = bfd_malloc (size);
- bfd_get_section_contents (abfd, sec, contents, 0, size);
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto load_failed;
ptr = contents;
/* Load the relocations for the '.avr.prop' section if there are any, and
*/
/* Check we have at least got a headers worth of bytes. */
+ size = bfd_section_size (sec);
if (size < AVR_PROPERTY_SECTION_HEADER_SIZE)
goto load_failed;
- version = *((bfd_byte *) ptr);
+ version = *ptr;
ptr++;
- flags = *((bfd_byte *) ptr);
+ flags = *ptr;
ptr++;
- record_count = *((uint16_t *) ptr);
- ptr+=2;
+ record_count = bfd_get_16 (abfd, ptr);
+ ptr += 2;
BFD_ASSERT (ptr - contents == AVR_PROPERTY_SECTION_HEADER_SIZE);
/* Now allocate space for the list structure, and all of the list
}
}
- address = *((uint32_t *) ptr);
+ address = bfd_get_32 (abfd, ptr);
ptr += 4;
size -= 4;
{
/* 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);
+ r_list->records [i].type = *ptr;
ptr += 1;
size -= 1;
/* Just a 4-byte fill to load. */
if (size < 4)
goto load_failed;
- r_list->records [i].data.org.fill = *((uint32_t *) ptr);
+ r_list->records [i].data.org.fill = bfd_get_32 (abfd, ptr);
ptr += 4;
size -= 4;
break;
/* Just a 4-byte alignment to load. */
if (size < 4)
goto load_failed;
- r_list->records [i].data.align.bytes = *((uint32_t *) ptr);
+ r_list->records [i].data.align.bytes = bfd_get_32 (abfd, ptr);
ptr += 4;
size -= 4;
/* Just initialise PRECEDING_DELETED field, this field is
/* A 4-byte alignment, and a 4-byte fill to load. */
if (size < 8)
goto load_failed;
- r_list->records [i].data.align.bytes = *((uint32_t *) ptr);
+ r_list->records [i].data.align.bytes = bfd_get_32 (abfd, ptr);
ptr += 4;
- r_list->records [i].data.align.fill = *((uint32_t *) ptr);
+ r_list->records [i].data.align.fill = bfd_get_32 (abfd, ptr);
ptr += 4;
size -= 8;
/* Just initialise PRECEDING_DELETED field, this field is