]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/write.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / write.c
index 9b5ae6ff32a3b43453bdf03da62bbb12adda569c..ca14b3734bd3e17ba2dfbd942660c7e1408c5d85 100644 (file)
@@ -1,5 +1,5 @@
 /* write.c - emit .o file
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2021 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -443,7 +443,7 @@ cvt_frag_to_fill (segT sec ATTRIBUTE_UNUSED, fragS *fragP)
 #ifdef HANDLE_ALIGN
       HANDLE_ALIGN (fragP);
 #endif
-skip_align:
+    skip_align:
       know (fragP->fr_next != NULL);
       fragP->fr_offset = (fragP->fr_next->fr_address
                          - fragP->fr_address
@@ -1625,7 +1625,7 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
                                "to section %s of %s: '%s'",
                                (long) f->fr_fix),
                      (long) f->fr_fix,
-                     sec->name, stdoutput->filename,
+                     bfd_section_name (sec), bfd_get_filename (stdoutput),
                      bfd_errmsg (bfd_get_error ()));
          offset += f->fr_fix;
        }
@@ -1649,9 +1649,11 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
                                    "in section %s of %s: '%s'",
                                    "can't fill %ld bytes "
                                    "in section %s of %s: '%s'",
-                                   (long) count), (long) count,
-                                   sec->name, stdoutput->filename,
-                                   bfd_errmsg (bfd_get_error ()));
+                                   (long) count),
+                         (long) count,
+                         bfd_section_name (sec),
+                         bfd_get_filename (stdoutput),
+                         bfd_errmsg (bfd_get_error ()));
              offset += count;
              free (buf);
            }
@@ -1678,7 +1680,8 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
                                        "in section %s of %s: '%s'",
                                        (long) fill_size),
                              (long) fill_size,
-                             sec->name, stdoutput->filename,
+                             bfd_section_name (sec),
+                             bfd_get_filename (stdoutput),
                              bfd_errmsg (bfd_get_error ()));
                  offset += fill_size;
                }
@@ -1714,7 +1717,8 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
                                        "in section %s of %s: '%s'",
                                        (long) (n_per_buf * fill_size)),
                              (long) (n_per_buf * fill_size),
-                             sec->name, stdoutput->filename,
+                             bfd_section_name (sec),
+                             bfd_get_filename (stdoutput),
                              bfd_errmsg (bfd_get_error ()));
                  offset += n_per_buf * fill_size;
                }
@@ -1893,6 +1897,7 @@ create_note_reloc (segT           sec,
                   symbolS *      sym,
                   bfd_size_type  note_offset,
                   bfd_size_type  desc2_offset,
+                  offsetT        desc2_size,
                   int            reloc_type,
                   bfd_vma        addend,
                   char *         note)
@@ -1927,15 +1932,21 @@ create_note_reloc (segT           sec,
         but still stores the addend in the word being relocated.  */
       || strstr (bfd_get_target (stdoutput), "-sh") != NULL)
     {
+      offsetT i;
+
+      /* Zero out the addend, since it is now stored in the note.  */
+      reloc->u.b.r.addend = 0;
+
       if (target_big_endian)
        {
-         if (bfd_arch_bits_per_address (stdoutput) <= 32)
-           note[desc2_offset + 3] = addend;
-         else
-           note[desc2_offset + 7] = addend;
+         for (i = desc2_size; addend != 0 && i > 0; addend >>= 8, i--)
+           note[desc2_offset + i - 1] = (addend & 0xff);
        }
       else
-       note[desc2_offset] = addend;
+       {
+         for (i = 0; addend != 0 && i < desc2_size; addend >>= 8, i++)
+           note[desc2_offset + i] = (addend & 0xff);
+       }
     }
 }
 
@@ -1960,7 +1971,8 @@ maybe_generate_build_notes (void)
   /* Create a GNU Build Attribute section.  */
   sec = subseg_new (GNU_BUILD_ATTRS_SECTION_NAME, FALSE);
   elf_section_type (sec) = SHT_NOTE;
-  bfd_set_section_flags (sec, SEC_READONLY | SEC_HAS_CONTENTS | SEC_DATA);
+  bfd_set_section_flags (sec, (SEC_READONLY | SEC_HAS_CONTENTS | SEC_DATA
+                              | SEC_OCTETS));
   bfd_set_section_alignment (sec, 2);
 
   /* Work out the size of the notes that we will create,
@@ -2020,14 +2032,14 @@ maybe_generate_build_notes (void)
        if (target_big_endian)
          {
            note[3] = 8; /* strlen (name) + 1.  */
-           note[7] = desc_size; /* Two 8-byte offsets.  */
+           note[7] = desc_size; /* Two N-byte offsets.  */
            note[10] = NT_GNU_BUILD_ATTRIBUTE_OPEN >> 8;
            note[11] = NT_GNU_BUILD_ATTRIBUTE_OPEN & 0xff;
          }
        else
          {
            note[0] = 8; /* strlen (name) + 1.  */
-           note[4] = desc_size; /* Two 8-byte offsets.  */
+           note[4] = desc_size; /* Two N-byte offsets.  */
            note[8] = NT_GNU_BUILD_ATTRIBUTE_OPEN & 0xff;
            note[9] = NT_GNU_BUILD_ATTRIBUTE_OPEN >> 8;
          }
@@ -2037,10 +2049,12 @@ maybe_generate_build_notes (void)
        memcpy (note + 12, "GA$\ 13a1", 8);
 
        /* Create a relocation to install the start address of the note...  */
-       create_note_reloc (sec, sym, total_size, 20, desc_reloc, 0, note);
+       create_note_reloc (sec, sym, total_size, 20, desc_size / 2, desc_reloc, 0, note);
 
        /* ...and another one to install the end address.  */
-       create_note_reloc (sec, sym, total_size, desc2_offset, desc_reloc,
+       create_note_reloc (sec, sym, total_size, desc2_offset,
+                          desc_size / 2,
+                          desc_reloc,
                           bfd_section_size (bsym->section),
                           note);
 
@@ -2428,7 +2442,7 @@ write_object_file (void)
 #endif
 
   /* Stop if there is an error.  */
-  if (had_errors ())
+  if (!flag_always_generate_output && had_errors ())
     return;
 
   /* Now that all the sizes are known, and contents correct, we can
@@ -2480,6 +2494,10 @@ write_object_file (void)
 }
 
 #ifdef TC_GENERIC_RELAX_TABLE
+#ifndef md_generic_table_relax_frag
+#define md_generic_table_relax_frag relax_frag
+#endif
+
 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE.  */
 
 long
@@ -2497,7 +2515,7 @@ relax_frag (segT segment, fragS *fragP, long stretch)
   const relax_typeS *table;
 
   target = fragP->fr_offset;
-  address = fragP->fr_address;
+  address = fragP->fr_address + fragP->fr_fix;
   table = TC_GENERIC_RELAX_TABLE;
   this_state = fragP->fr_subtype;
   start_type = this_type = table + this_state;
@@ -2537,13 +2555,13 @@ relax_frag (segT segment, fragS *fragP, long stretch)
             negative.  Don't allow this in case the negative reach is
             large enough to require a larger branch instruction.  */
          else if (target < address)
-           target = fragP->fr_next->fr_address + stretch;
+           return 0;
        }
     }
 
-  aim = target - address - fragP->fr_fix;
+  aim = target - address;
 #ifdef TC_PCREL_ADJUST
-  /* Currently only the ns32k family needs this.  */
+  /* Currently only the ns32k and arc needs this.  */
   aim += TC_PCREL_ADJUST (fragP);
 #endif
 
@@ -2931,7 +2949,7 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
 
              case rs_org:
                {
-                 addressT target = offset;
+                 offsetT target = offset;
                  addressT after;
 
                  if (symbolP)
@@ -2951,7 +2969,7 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
                  /* Growth may be negative, but variable part of frag
                     cannot have fewer than 0 chars.  That is, we can't
                     .org backwards.  */
-                 if (address + fragP->fr_fix > target)
+                 if ((offsetT) (address + fragP->fr_fix) > target)
                    {
                      growth = 0;
 
@@ -2999,7 +3017,7 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
                        || ! S_IS_DEFINED (symbolP))
                      {
                        as_bad_where (fragP->fr_file, fragP->fr_line,
-                                     _(".space specifies non-absolute value"));
+                                     _(".space, .nops or .fill specifies non-absolute value"));
                        /* Prevent repeat of this error message.  */
                        fragP->fr_symbol = 0;
                      }
@@ -3030,7 +3048,8 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
 #ifdef TC_GENERIC_RELAX_TABLE
                /* The default way to relax a frag is to look through
                   TC_GENERIC_RELAX_TABLE.  */
-               growth = relax_frag (segment, fragP, stretch);
+               growth = md_generic_table_relax_frag (segment, fragP,
+                                                     stretch);
 #endif /* TC_GENERIC_RELAX_TABLE  */
 #endif
                break;