X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-avr.c;h=2a6e743512d7d0e1123eed55b1dab88bff909060;hb=0a6a8b596b285d5c3cdf086ca85be59ff0a97071;hp=d6842a033047b7dbda7d54c278f379031de5e95b;hpb=827041555ac443bd57340060f3e034fd7b199dd8;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index d6842a0330..2a6e743512 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -1,5 +1,5 @@ /* AVR-specific support for 32-bit ELF - Copyright (C) 1999-2019 Free Software Foundation, Inc. + Copyright (C) 1999-2020 Free Software Foundation, Inc. Contributed by Denis Chertykov This file is part of BFD, the Binary File Descriptor library. @@ -767,7 +767,7 @@ elf_avr_new_section_hook (bfd *abfd, asection *sec) 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) @@ -875,7 +875,7 @@ static struct bfd_link_hash_table * 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) @@ -910,7 +910,7 @@ avr_relative_distance_considering_wrap_around (unsigned int distance) 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; @@ -1465,7 +1465,7 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, 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 { @@ -1536,9 +1536,8 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, 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; @@ -1621,6 +1620,7 @@ bfd_elf_avr_final_write_processing (bfd *abfd, 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. */ @@ -2354,8 +2354,7 @@ avr_property_record_compare (const void *ap, const void *bp) 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); } @@ -2643,16 +2642,28 @@ elf32_avr_relax_section (bfd *abfd, /* 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 @@ -3483,7 +3494,7 @@ elf32_avr_setup_section_lists (bfd *output_bfd, 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) @@ -3547,7 +3558,7 @@ get_local_syms (bfd *input_bfd, struct bfd_link_info *info) 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; @@ -3936,12 +3947,12 @@ internal_reloc_compare (const void *ap, const void *bp) /* 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; @@ -3973,7 +3984,7 @@ struct avr_find_section_data 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 @@ -3984,11 +3995,11 @@ avr_find_section_for_address (bfd *abfd, 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; } @@ -4011,7 +4022,7 @@ avr_elf32_load_records_from_section (bfd *abfd, asection *sec) 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; @@ -4114,8 +4125,7 @@ avr_elf32_load_records_from_section (bfd *abfd, asection *sec) { /* 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) @@ -4133,7 +4143,7 @@ avr_elf32_load_records_from_section (bfd *abfd, asection *sec) 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);