btrace: remove leftover comment
[deliverable/binutils-gdb.git] / bfd / elf32-avr.c
index a0a5c6975edb1b9c3d88408a256df19ddae36a0d..ef88f024f0f5af9298d7a248dbe4ce77ef95bc65 100644 (file)
@@ -1808,13 +1808,17 @@ elf32_avr_adjust_diff_reloc_value (bfd *abfd,
 /* Delete some bytes from a section while changing the size of an instruction.
    The parameter "addr" denotes the section-relative offset pointing just
    behind the shrinked instruction. "addr+count" point at the first
-   byte just behind the original unshrinked instruction.  */
+   byte just behind the original unshrinked instruction. If delete_shrinks_insn
+   is FALSE, we are deleting redundant padding bytes from relax_info prop
+   record handling. In that case, addr is section-relative offset of start
+   of padding, and count is the number of padding bytes to delete. */
 
 static bfd_boolean
 elf32_avr_relax_delete_bytes (bfd *abfd,
                               asection *sec,
                               bfd_vma addr,
-                              int count)
+                              int count,
+                              bfd_boolean delete_shrinks_insn)
 {
   Elf_Internal_Shdr *symtab_hdr;
   unsigned int sec_shndx;
@@ -1829,6 +1833,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   struct avr_relax_info *relax_info;
   struct avr_property_record *prop_record = NULL;
   bfd_boolean did_shrink = FALSE;
+  bfd_boolean did_pad = FALSE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
@@ -1909,6 +1914,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
          to remember we didn't delete anything i.e. don't set did_shrink,
          so that we don't corrupt reloc offsets or symbol values.*/
       memset (contents + toaddr - count, fill, count);
+      did_pad = TRUE;
 
       /* Adjust the TOADDR to avoid moving symbols located at the address
          of the property record, which has not moved.  */
@@ -1965,7 +1971,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
         continue;
 
        shrinked_insn_address = (sec->output_section->vma
-                                + sec->output_offset + addr - count);
+                                + sec->output_offset + addr);
+       if (delete_shrinks_insn)
+         shrinked_insn_address -= count;
 
        irel = elf_section_data (isec)->relocs;
        /* PR 12161: Read in the relocs for this section if necessary.  */
@@ -2002,6 +2010,13 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
                   a symbol or section associated with it.  */
                if (sym_sec == sec)
                  {
+                   /* If there is an alignment boundary, we only need to
+                      adjust addends that end up below the boundary. */
+                   bfd_vma shrink_boundary = (reloc_toaddr
+                                              + sec->output_section->vma
+                                              + sec->output_offset);
+                   bfd_boolean addend_within_shrink_boundary = FALSE;
+
                    symval += sym_sec->output_section->vma
                              + sym_sec->output_offset;
 
@@ -2015,8 +2030,17 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
                              (unsigned int) (symval + irel->r_addend),
                              (unsigned int) shrinked_insn_address);
 
+                   /* If we padded bytes, then the boundary didn't change,
+                      so there's no need to adjust addends pointing at the boundary.
+                      If we didn't pad, then we actually shrank the boundary, so
+                      addends pointing at the boundary need to be adjusted too. */
+                    addend_within_shrink_boundary = did_pad
+                      ? ((symval + irel->r_addend) < shrink_boundary)
+                      : ((symval + irel->r_addend) <= shrink_boundary);
+
                    if (symval <= shrinked_insn_address
-                       && (symval + irel->r_addend) > shrinked_insn_address)
+                       && (symval + irel->r_addend) > shrinked_insn_address
+                       && addend_within_shrink_boundary)
                      {
                        if (elf32_avr_is_diff_reloc (irel))
                          {
@@ -2648,7 +2672,8 @@ elf32_avr_relax_section (bfd *abfd,
                   {
                     /* Delete two bytes of data.  */
                     if (!elf32_avr_relax_delete_bytes (abfd, sec,
-                                                       irel->r_offset + 2, 2))
+                                                       irel->r_offset + 2, 2,
+                                                       TRUE))
                       goto error_return;
 
                     /* That will change things, so, we should relax again.
@@ -2657,6 +2682,7 @@ elf32_avr_relax_section (bfd *abfd,
                   }
               }
           }
+         /* Fall through.  */
 
         default:
           {
@@ -2972,7 +2998,8 @@ elf32_avr_relax_section (bfd *abfd,
 
                            /* Delete two bytes of data.  */
                            if (!elf32_avr_relax_delete_bytes (abfd, sec,
-                                                              irel->r_offset + insn_size, 2))
+                                                              irel->r_offset + insn_size, 2,
+                                                              TRUE))
                              goto error_return;
 
                            /* That will change things, so, we should relax
@@ -3040,7 +3067,7 @@ elf32_avr_relax_section (bfd *abfd,
                         record->offset -= count;
                         elf32_avr_relax_delete_bytes (abfd, sec,
                                                       addr - count,
-                                                      count);
+                                                      count, FALSE);
                         *again = TRUE;
                       }
                   }
@@ -3230,8 +3257,8 @@ avr_add_stub (const char *stub_name,
 
   if (hsh == NULL)
     {
-      (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
-                             NULL, stub_name);
+      _bfd_error_handler (_("%B: cannot create stub entry %s"),
+                         NULL, stub_name);
       return NULL;
     }
 
This page took 0.04125 seconds and 4 git commands to generate.