2019-12-18 Anthony Green <green@moxielogic.com>
[deliverable/binutils-gdb.git] / bfd / elf32-avr.c
index 7087606c935041836bda6aea226166372e22a717..f04cc94ff3456e0d97dcc2e3cbbcab3e5fa0c789 100644 (file)
@@ -1,5 +1,5 @@
 /* AVR-specific support for 32-bit ELF
-   Copyright (C) 1999-2018 Free Software Foundation, Inc.
+   Copyright (C) 1999-2019 Free Software Foundation, Inc.
    Contributed by Denis Chertykov <denisc@overta.ru>
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -25,7 +25,6 @@
 #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;
@@ -708,6 +707,12 @@ static const struct avr_reloc_map avr_reloc_map[] =
   { BFD_RELOC_32_PCREL,                    R_AVR_32_PCREL}
 };
 
+static const struct bfd_elf_special_section elf_avr_special_sections[] =
+{
+  { STRING_COMMA_LEN (".noinit"), 0, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
+  { NULL, 0,                     0, 0,            0 }
+};
+
 /* Meant to be filled one day with the wrap around address for the
    specific device.  I.e. should get the value 0x4000 for 16k devices,
    0x8000 for 32k devices and so on.
@@ -905,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;
@@ -1460,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
        {
@@ -1531,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;
 
@@ -1616,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.  */
@@ -2349,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);
 }
@@ -2638,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
@@ -3295,10 +3311,10 @@ avr_stub_name (const asection *symbol_section,
 
   len = 8 + 1 + 8 + 1 + 1;
   stub_name = bfd_malloc (len);
-
-  sprintf (stub_name, "%08x+%08x",
-          symbol_section->id & 0xffffffff,
-          (unsigned int) ((rela->r_addend & 0xffffffff) + symbol_offset));
+  if (stub_name != NULL)
+    sprintf (stub_name, "%08x+%08x",
+            symbol_section->id & 0xffffffff,
+            (unsigned int) ((rela->r_addend & 0xffffffff) + symbol_offset));
 
   return stub_name;
 }
@@ -3931,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;
 
@@ -3968,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
@@ -3979,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;
 }
 
@@ -4006,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;
@@ -4109,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)
@@ -4128,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);
@@ -4256,5 +4271,6 @@ avr_elf32_property_record_name (struct avr_property_record *rec)
 #define bfd_elf32_bfd_get_relocated_section_contents \
                                        elf32_avr_get_relocated_section_contents
 #define bfd_elf32_new_section_hook     elf_avr_new_section_hook
+#define elf_backend_special_sections   elf_avr_special_sections
 
 #include "elf32-target.h"
This page took 0.027883 seconds and 4 git commands to generate.