gdb: fix vfork with multiple threads
[deliverable/binutils-gdb.git] / bfd / coffgen.c
index e208ceee6690da22ce0fbd555019bcf70dc9204a..b13e7732962bcdc52b6e66d1291b5da46d11a5e1 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of COFF, for BFD.
-   Copyright (C) 1990-2016 Free Software Foundation, Inc.
+   Copyright (C) 1990-2021 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -37,6 +37,7 @@
    coff_data (abfd).  */
 
 #include "sysdep.h"
+#include <limits.h>
 #include "bfd.h"
 #include "libbfd.h"
 #include "coff/internal.h"
 /* Take a section header read from a coff file (in HOST byte order),
    and make a BFD "section" out of it.  This is used by ECOFF.  */
 
-static bfd_boolean
+static bool
 make_a_section_from_file (bfd *abfd,
                          struct internal_scnhdr *hdr,
                          unsigned int target_index)
 {
   asection *return_section;
   char *name;
-  bfd_boolean result = TRUE;
+  bool result = true;
   flagword flags;
 
   name = NULL;
@@ -72,10 +73,10 @@ make_a_section_from_file (bfd *abfd,
       const char *strings;
 
       /* Flag that this BFD uses long names, even though the format might
-         expect them to be off by default.  This won't directly affect the
-         format of any output BFD created from this one, but the information
-         can be used to decide what to do.  */
-      bfd_coff_set_long_section_names (abfd, TRUE);
+        expect them to be off by default.  This won't directly affect the
+        format of any output BFD created from this one, but the information
+        can be used to decide what to do.  */
+      bfd_coff_set_long_section_names (abfd, true);
       memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1);
       buf[SCNNMLEN - 1] = '\0';
       strindex = strtol (buf, &p, 10);
@@ -83,14 +84,14 @@ make_a_section_from_file (bfd *abfd,
        {
          strings = _bfd_coff_read_string_table (abfd);
          if (strings == NULL)
-           return FALSE;
+           return false;
          if ((bfd_size_type)(strindex + 2) >= obj_coff_strings_len (abfd))
-           return FALSE;
+           return false;
          strings += strindex;
          name = (char *) bfd_alloc (abfd,
-                                     (bfd_size_type) strlen (strings) + 1 + 1);
+                                    (bfd_size_type) strlen (strings) + 1 + 1);
          if (name == NULL)
-           return FALSE;
+           return false;
          strcpy (name, strings);
        }
     }
@@ -99,16 +100,16 @@ make_a_section_from_file (bfd *abfd,
     {
       /* Assorted wastage to null-terminate the name, thanks AT&T! */
       name = (char *) bfd_alloc (abfd,
-                                 (bfd_size_type) sizeof (hdr->s_name) + 1 + 1);
+                                (bfd_size_type) sizeof (hdr->s_name) + 1 + 1);
       if (name == NULL)
-       return FALSE;
+       return false;
       strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
       name[sizeof (hdr->s_name)] = 0;
     }
 
   return_section = bfd_make_section_anyway (abfd, name);
   if (return_section == NULL)
-    return FALSE;
+    return false;
 
   return_section->vma = hdr->s_vaddr;
   return_section->lma = hdr->s_paddr;
@@ -128,7 +129,7 @@ make_a_section_from_file (bfd *abfd,
 
   if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section,
                                         & flags))
-    result = FALSE;
+    result = false;
 
   return_section->flags = flags;
 
@@ -175,9 +176,9 @@ make_a_section_from_file (bfd *abfd,
            {
              _bfd_error_handler
                /* xgettext: c-format */
-               (_("%B: unable to initialize compress status for section %s"),
+               (_("%pB: unable to initialize compress status for section %s"),
                 abfd, name);
-             return FALSE;
+             return false;
            }
          if (return_section->compress_status == COMPRESS_SECTION_DONE)
            {
@@ -187,21 +188,21 @@ make_a_section_from_file (bfd *abfd,
 
                  new_name = bfd_alloc (abfd, len + 2);
                  if (new_name == NULL)
-                   return FALSE;
+                   return false;
                  new_name[0] = '.';
                  new_name[1] = 'z';
                  memcpy (new_name + 2, name + 1, len);
                }
            }
-         break;
+        break;
        case decompress:
          if (!bfd_init_section_decompress_status (abfd, return_section))
            {
              _bfd_error_handler
                /* xgettext: c-format */
-               (_("%B: unable to initialize decompress status for section %s"),
+               (_("%pB: unable to initialize decompress status for section %s"),
                 abfd, name);
-             return FALSE;
+             return false;
            }
          if (name[1] == 'z')
            {
@@ -209,14 +210,14 @@ make_a_section_from_file (bfd *abfd,
 
              new_name = bfd_alloc (abfd, len);
              if (new_name == NULL)
-               return FALSE;
+               return false;
              new_name[0] = '.';
              memcpy (new_name + 1, name + 2, len - 1);
            }
          break;
        }
       if (new_name != NULL)
-       bfd_rename_section (abfd, return_section, new_name);
+       bfd_rename_section (return_section, new_name);
     }
 
   return result;
@@ -224,12 +225,12 @@ make_a_section_from_file (bfd *abfd,
 
 /* Read in a COFF object and make it into a BFD.  This is used by
    ECOFF as well.  */
-const bfd_target *
+bfd_cleanup
 coff_real_object_p (bfd *,
-                    unsigned,
-                    struct internal_filehdr *,
-                    struct internal_aouthdr *);
-const bfd_target *
+                   unsigned,
+                   struct internal_filehdr *,
+                   struct internal_aouthdr *);
+bfd_cleanup
 coff_real_object_p (bfd *abfd,
                    unsigned nscns,
                    struct internal_filehdr *internal_f,
@@ -256,14 +257,14 @@ coff_real_object_p (bfd *abfd,
   if ((internal_f->f_flags & F_EXEC) != 0)
     abfd->flags |= D_PAGED;
 
-  bfd_get_symcount (abfd) = internal_f->f_nsyms;
+  abfd->symcount = internal_f->f_nsyms;
   if (internal_f->f_nsyms)
     abfd->flags |= HAS_SYMS;
 
   if (internal_a != (struct internal_aouthdr *) NULL)
-    bfd_get_start_address (abfd) = internal_a->entry;
+    abfd->start_address = internal_a->entry;
   else
-    bfd_get_start_address (abfd) = 0;
+    abfd->start_address = 0;
 
   /* Set up the tdata area.  ECOFF uses its own routine, and overrides
      abfd->flags.  */
@@ -274,13 +275,10 @@ coff_real_object_p (bfd *abfd,
 
   scnhsz = bfd_coff_scnhsz (abfd);
   readsize = (bfd_size_type) nscns * scnhsz;
-  external_sections = (char *) bfd_alloc (abfd, readsize);
+  external_sections = (char *) _bfd_alloc_and_read (abfd, readsize, readsize);
   if (!external_sections)
     goto fail;
 
-  if (bfd_bread ((void *) external_sections, readsize, abfd) != readsize)
-    goto fail;
-
   /* Set the arch/mach *before* swapping in sections; section header swapping
      may depend on arch/mach info.  */
   if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f))
@@ -301,21 +299,23 @@ coff_real_object_p (bfd *abfd,
        }
     }
 
-  return abfd->xvec;
+  _bfd_coff_free_symbols (abfd);
+  return _bfd_no_cleanup;
 
  fail:
+  _bfd_coff_free_symbols (abfd);
   bfd_release (abfd, tdata);
  fail2:
   abfd->tdata.any = tdata_save;
   abfd->flags = oflags;
-  bfd_get_start_address (abfd) = ostart;
-  return (const bfd_target *) NULL;
+  abfd->start_address = ostart;
+  return NULL;
 }
 
 /* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is
    not a COFF file.  This is also used by ECOFF.  */
 
-const bfd_target *
+bfd_cleanup
 coff_object_p (bfd *abfd)
 {
   bfd_size_type filhsz;
@@ -329,14 +329,11 @@ coff_object_p (bfd *abfd)
   filhsz = bfd_coff_filhsz (abfd);
   aoutsz = bfd_coff_aoutsz (abfd);
 
-  filehdr = bfd_alloc (abfd, filhsz);
+  filehdr = _bfd_alloc_and_read (abfd, filhsz, filhsz);
   if (filehdr == NULL)
-    return NULL;
-  if (bfd_bread (filehdr, filhsz, abfd) != filhsz)
     {
       if (bfd_get_error () != bfd_error_system_call)
        bfd_set_error (bfd_error_wrong_format);
-      bfd_release (abfd, filehdr);
       return NULL;
     }
   bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f);
@@ -362,18 +359,13 @@ coff_object_p (bfd *abfd)
     {
       void * opthdr;
 
-      opthdr = bfd_alloc (abfd, aoutsz);
+      opthdr = _bfd_alloc_and_read (abfd, aoutsz, internal_f.f_opthdr);
       if (opthdr == NULL)
        return NULL;
-      if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd)
-         != internal_f.f_opthdr)
-       {
-         bfd_release (abfd, opthdr);
-         return NULL;
-       }
       /* PR 17512: file: 11056-1136-0.004.  */
       if (internal_f.f_opthdr < aoutsz)
-       memset (((char *) opthdr) + internal_f.f_opthdr, 0, aoutsz - internal_f.f_opthdr);
+       memset (((char *) opthdr) + internal_f.f_opthdr, 0,
+               aoutsz - internal_f.f_opthdr);
 
       bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a);
       bfd_release (abfd, opthdr);
@@ -494,9 +486,9 @@ _bfd_coff_internal_syment_name (bfd *abfd,
 struct internal_reloc *
 _bfd_coff_read_internal_relocs (bfd *abfd,
                                asection *sec,
-                               bfd_boolean cache,
+                               bool cache,
                                bfd_byte *external_relocs,
-                               bfd_boolean require_internal,
+                               bool require_internal,
                                struct internal_reloc *internal_relocs)
 {
   bfd_size_type relsz;
@@ -552,11 +544,8 @@ _bfd_coff_read_internal_relocs (bfd *abfd,
   for (; erel < erel_end; erel += relsz, irel++)
     bfd_coff_swap_reloc_in (abfd, (void *) erel, (void *) irel);
 
-  if (free_external != NULL)
-    {
-      free (free_external);
-      free_external = NULL;
-    }
+  free (free_external);
+  free_external = NULL;
 
   if (cache && free_internal != NULL)
     {
@@ -574,10 +563,8 @@ _bfd_coff_read_internal_relocs (bfd *abfd,
   return internal_relocs;
 
  error_return:
-  if (free_external != NULL)
-    free (free_external);
-  if (free_internal != NULL)
-    free (free_internal);
+  free (free_external);
+  free (free_internal);
   return NULL;
 }
 
@@ -595,7 +582,7 @@ coff_count_linenumbers (bfd *abfd)
   if (limit == 0)
     {
       /* This may be from the backend linker, in which case the
-         lineno_count in the sections is correct.  */
+        lineno_count in the sections is correct.  */
       for (s = abfd->sections; s != NULL; s = s->next)
        total += s->lineno_count;
       return total;
@@ -613,13 +600,13 @@ coff_count_linenumbers (bfd *abfd)
          coff_symbol_type *q = coffsymbol (q_maybe);
 
          /* The AIX 4.1 compiler can sometimes generate line numbers
-             attached to debugging symbols.  We try to simply ignore
-             those here.  */
+            attached to debugging symbols.  We try to simply ignore
+            those here.  */
          if (q->lineno != NULL
              && q->symbol.section->owner != NULL)
            {
              /* This symbol has line numbers.  Increment the owning
-                section's linenumber count.  */
+                section's linenumber count.  */
              alent *l = q->lineno;
 
              do
@@ -675,11 +662,11 @@ fixup_symbol_value (bfd *abfd,
          syment->n_value = (coff_symbol_ptr->symbol.value
                             + coff_symbol_ptr->symbol.section->output_offset);
          if (! obj_pe (abfd))
-            {
-              syment->n_value += (syment->n_sclass == C_STATLAB)
-                ? coff_symbol_ptr->symbol.section->output_section->lma
-                : coff_symbol_ptr->symbol.section->output_section->vma;
-            }
+           {
+             syment->n_value += (syment->n_sclass == C_STATLAB)
+               ? coff_symbol_ptr->symbol.section->output_section->lma
+               : coff_symbol_ptr->symbol.section->output_section->vma;
+           }
        }
       else
        {
@@ -698,7 +685,7 @@ fixup_symbol_value (bfd *abfd,
    chain, and that the last one points to the first external symbol. We
    do that here too.  */
 
-bfd_boolean
+bool
 coff_renumber_symbols (bfd *bfd_ptr, int *first_undef)
 {
   unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
@@ -725,7 +712,7 @@ coff_renumber_symbols (bfd *bfd_ptr, int *first_undef)
     amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1);
     newsyms = (asymbol **) bfd_alloc (bfd_ptr, amt);
     if (!newsyms)
-      return FALSE;
+      return false;
     bfd_ptr->outsymbols = newsyms;
     for (i = 0; i < symbol_count; i++)
       if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0
@@ -787,7 +774,7 @@ coff_renumber_symbols (bfd *bfd_ptr, int *first_undef)
 
   obj_conv_table_size (bfd_ptr) = native_index;
 
-  return TRUE;
+  return true;
 }
 
 /* Run thorough the symbol table again, and fix it so that all
@@ -823,8 +810,8 @@ coff_mangle_symbols (bfd *bfd_ptr)
          if (s->fix_line)
            {
              /* The value is the offset into the line number entries
-                 for the symbol's section.  On output, the symbol's
-                 section should be N_DEBUG.  */
+                for the symbol's section.  On output, the symbol's
+                section should be N_DEBUG.  */
              s->u.syment.n_value =
                (coff_symbol_ptr->symbol.section->output_section->line_filepos
                 + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr));
@@ -888,13 +875,13 @@ coff_fix_symbol_name (bfd *abfd,
 
       if (bfd_coff_force_symnames_in_strings (abfd))
        {
-          native->u.syment._n._n_n._n_offset =
+         native->u.syment._n._n_n._n_offset =
              (*string_size_p + STRING_SIZE_SIZE);
          native->u.syment._n._n_n._n_zeroes = 0;
          *string_size_p += 6;  /* strlen(".file") + 1 */
        }
       else
-       strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
+       strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
 
       BFD_ASSERT (! (native + 1)->is_sym);
       auxent = &(native + 1)->u.auxent;
@@ -981,7 +968,7 @@ coff_fix_symbol_name (bfd *abfd,
 
 /* Write a symbol out to a COFF file.  */
 
-static bfd_boolean
+static bool
 coff_write_symbol (bfd *abfd,
                   asymbol *symbol,
                   combined_entry_type *native,
@@ -1024,10 +1011,10 @@ coff_write_symbol (bfd *abfd,
   symesz = bfd_coff_symesz (abfd);
   buf = bfd_alloc (abfd, symesz);
   if (!buf)
-    return FALSE;
+    return false;
   bfd_coff_swap_sym_out (abfd, &native->u.syment, buf);
   if (bfd_bwrite (buf, symesz, abfd) != symesz)
-    return FALSE;
+    return false;
   bfd_release (abfd, buf);
 
   if (native->u.syment.n_numaux > 0)
@@ -1038,7 +1025,7 @@ coff_write_symbol (bfd *abfd,
       auxesz = bfd_coff_auxesz (abfd);
       buf = bfd_alloc (abfd, auxesz);
       if (!buf)
-       return FALSE;
+       return false;
       for (j = 0; j < native->u.syment.n_numaux; j++)
        {
          BFD_ASSERT (! (native + j + 1)->is_sym);
@@ -1048,7 +1035,7 @@ coff_write_symbol (bfd *abfd,
                                 native->u.syment.n_numaux,
                                 buf);
          if (bfd_bwrite (buf, auxesz, abfd) != auxesz)
-           return FALSE;
+           return false;
        }
       bfd_release (abfd, buf);
     }
@@ -1057,14 +1044,14 @@ coff_write_symbol (bfd *abfd,
   set_index (symbol, *written);
 
   *written += numaux + 1;
-  return TRUE;
+  return true;
 }
 
 /* Write out a symbol to a COFF file that does not come from a COFF
    file originally.  This symbol may have been created by the linker,
    or we may be linking a non COFF file to a COFF file.  */
 
-bfd_boolean
+bool
 coff_write_alien_symbol (bfd *abfd,
                         asymbol *symbol,
                         struct internal_syment *isym,
@@ -1080,7 +1067,7 @@ coff_write_alien_symbol (bfd *abfd,
                               ? symbol->section->output_section
                               : symbol->section;
   struct bfd_link_info *link_info = coff_data (abfd)->link_info;
-  bfd_boolean ret;
+  bool ret;
 
   if ((!link_info || link_info->strip_discarded)
       && !bfd_is_abs_section (symbol->section)
@@ -1088,12 +1075,12 @@ coff_write_alien_symbol (bfd *abfd,
     {
       symbol->name = "";
       if (isym != NULL)
-        memset (isym, 0, sizeof (*isym));
-      return TRUE;
+       memset (isym, 0, sizeof (*isym));
+      return true;
     }
   native = dummy;
-  native->is_sym = TRUE;
-  native[1].is_sym = FALSE;
+  native->is_sym = true;
+  native[1].is_sym = false;
   native->u.syment.n_type = T_NULL;
   native->u.syment.n_flags = 0;
   native->u.syment.n_numaux = 0;
@@ -1115,13 +1102,13 @@ coff_write_alien_symbol (bfd *abfd,
   else if (symbol->flags & BSF_DEBUGGING)
     {
       /* There isn't much point to writing out a debugging symbol
-         unless we are prepared to convert it into COFF debugging
-         format.  So, we just ignore them.  We must clobber the symbol
-         name to keep it from being put in the string table.  */
+        unless we are prepared to convert it into COFF debugging
+        format.  So, we just ignore them.  We must clobber the symbol
+        name to keep it from being put in the string table.  */
       symbol->name = "";
       if (isym != NULL)
-        memset (isym, 0, sizeof (*isym));
-      return TRUE;
+       memset (isym, 0, sizeof (*isym));
+      return true;
     }
   else
     {
@@ -1132,7 +1119,7 @@ coff_write_alien_symbol (bfd *abfd,
        native->u.syment.n_value += output_section->vma;
 
       /* Copy the any flags from the file header into the symbol.
-         FIXME: Why?  */
+        FIXME: Why?  */
       {
        coff_symbol_type *c = coff_symbol_from (symbol);
        if (c != (coff_symbol_type *) NULL)
@@ -1161,7 +1148,7 @@ coff_write_alien_symbol (bfd *abfd,
 
 /* Write a native symbol to a COFF file.  */
 
-static bfd_boolean
+static bool
 coff_write_native_symbol (bfd *abfd,
                          coff_symbol_type *symbol,
                          bfd_vma *written,
@@ -1178,7 +1165,7 @@ coff_write_native_symbol (bfd *abfd,
       && symbol->symbol.section->output_section == bfd_abs_section_ptr)
     {
       symbol->symbol.name = "";
-      return TRUE;
+      return true;
     }
 
   BFD_ASSERT (native->is_sym);
@@ -1207,7 +1194,7 @@ coff_write_native_symbol (bfd *abfd,
             + symbol->symbol.section->output_offset);
          count++;
        }
-      symbol->done_lineno = TRUE;
+      symbol->done_lineno = true;
 
       if (! bfd_is_const_section (symbol->symbol.section->output_section))
        symbol->symbol.section->output_section->moving_line_filepos +=
@@ -1227,7 +1214,7 @@ null_error_handler (const char *fmt ATTRIBUTE_UNUSED,
 
 /* Write out the COFF symbols.  */
 
-bfd_boolean
+bool
 coff_write_symbols (bfd *abfd)
 {
   bfd_size_type string_size;
@@ -1262,7 +1249,7 @@ coff_write_symbols (bfd *abfd)
 
   /* Seek to the right place.  */
   if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
-    return FALSE;
+    return false;
 
   /* Output all the symbols we have.  */
   written = 0;
@@ -1277,7 +1264,7 @@ coff_write_symbols (bfd *abfd)
          if (!coff_write_alien_symbol (abfd, symbol, NULL, NULL, &written,
                                        &string_size, &debug_string_section,
                                        &debug_string_size))
-           return FALSE;
+           return false;
        }
       else
        {
@@ -1322,7 +1309,7 @@ coff_write_symbols (bfd *abfd)
          if (!coff_write_native_symbol (abfd, c_symbol, &written,
                                         &string_size, &debug_string_section,
                                         &debug_string_size))
-           return FALSE;
+           return false;
        }
     }
 
@@ -1341,7 +1328,7 @@ coff_write_symbols (bfd *abfd)
 #endif
       if (bfd_bwrite ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd)
          != sizeof (buffer))
-       return FALSE;
+       return false;
 
       /* Handle long section names.  This code must handle section
         names just as they are handled in coff_write_object_contents.  */
@@ -1358,7 +1345,7 @@ coff_write_symbols (bfd *abfd)
                {
                  if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd)
                      != len + 1)
-                   return FALSE;
+                   return false;
                }
            }
        }
@@ -1400,7 +1387,7 @@ coff_write_symbols (bfd *abfd)
              if (bfd_coff_force_symnames_in_strings (abfd))
                {
                  if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
-                   return FALSE;
+                   return false;
                }
              maxlen = bfd_coff_filnmlen (abfd);
            }
@@ -1411,15 +1398,15 @@ coff_write_symbols (bfd *abfd)
            {
              if (bfd_bwrite ((void *) (q->name), (bfd_size_type) name_length + 1,
                             abfd) != name_length + 1)
-               return FALSE;
+               return false;
            }
        }
     }
   else
     {
       /* We would normally not write anything here, but we'll write
-         out 4 so that any stupid coff reader which tries to read the
-         string table even when there isn't one won't croak.  */
+        out 4 so that any stupid coff reader which tries to read the
+        string table even when there isn't one won't croak.  */
       unsigned int size = STRING_SIZE_SIZE;
       bfd_byte buffer[STRING_SIZE_SIZE];
 
@@ -1430,7 +1417,7 @@ coff_write_symbols (bfd *abfd)
 #endif
       if (bfd_bwrite ((void *) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd)
          != STRING_SIZE_SIZE)
-       return FALSE;
+       return false;
     }
 
   /* Make sure the .debug section was created to be the correct size.
@@ -1444,10 +1431,10 @@ coff_write_symbols (bfd *abfd)
                                 1 << debug_string_section->alignment_power)
                      == debug_string_section->size)));
 
-  return TRUE;
+  return true;
 }
 
-bfd_boolean
+bool
 coff_write_linenumbers (bfd *abfd)
 {
   asection *s;
@@ -1457,14 +1444,14 @@ coff_write_linenumbers (bfd *abfd)
   linesz = bfd_coff_linesz (abfd);
   buff = bfd_alloc (abfd, linesz);
   if (!buff)
-    return FALSE;
+    return false;
   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
     {
       if (s->lineno_count)
        {
          asymbol **q = abfd->outsymbols;
          if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0)
-           return FALSE;
+           return false;
          /* Find all the linenumbers in this section.  */
          while (*q)
            {
@@ -1485,7 +1472,7 @@ coff_write_linenumbers (bfd *abfd)
                      bfd_coff_swap_lineno_out (abfd, &out, buff);
                      if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd)
                          != linesz)
-                       return FALSE;
+                       return false;
                      l++;
                      while (l->line_number)
                        {
@@ -1494,7 +1481,7 @@ coff_write_linenumbers (bfd *abfd)
                          bfd_coff_swap_lineno_out (abfd, &out, buff);
                          if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd)
                              != linesz)
-                           return FALSE;
+                           return false;
                          l++;
                        }
                    }
@@ -1504,7 +1491,7 @@ coff_write_linenumbers (bfd *abfd)
        }
     }
   bfd_release (abfd, buff);
-  return TRUE;
+  return true;
 }
 
 alent *
@@ -1521,7 +1508,8 @@ coff_pointerize_aux (bfd *abfd,
                     combined_entry_type *table_base,
                     combined_entry_type *symbol,
                     unsigned int indaux,
-                    combined_entry_type *auxent)
+                    combined_entry_type *auxent,
+                    combined_entry_type *table_end)
 {
   unsigned int type = symbol->u.syment.n_type;
   unsigned int n_sclass = symbol->u.syment.n_sclass;
@@ -1539,6 +1527,8 @@ coff_pointerize_aux (bfd *abfd,
     return;
   if (n_sclass == C_FILE)
     return;
+  if (n_sclass == C_DWARF)
+    return;
 
   BFD_ASSERT (! auxent->is_sym);
   /* Otherwise patch up.  */
@@ -1547,15 +1537,22 @@ coff_pointerize_aux (bfd *abfd,
 
   if ((ISFCN (type) || ISTAG (n_sclass) || n_sclass == C_BLOCK
        || n_sclass == C_FCN)
-      && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0)
+      && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0
+      && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l
+      < (long) obj_raw_syment_count (abfd)
+      && table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l
+      < table_end)
     {
       auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p =
        table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
       auxent->fix_end = 1;
     }
+
   /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can
      generate one, so we must be careful to ignore it.  */
-  if (auxent->u.auxent.x_sym.x_tagndx.l > 0)
+  if ((unsigned long) auxent->u.auxent.x_sym.x_tagndx.l
+      < obj_raw_syment_count (abfd)
+      && table_base + auxent->u.auxent.x_sym.x_tagndx.l < table_end)
     {
       auxent->u.auxent.x_sym.x_tagndx.p =
        table_base + auxent->u.auxent.x_sym.x_tagndx.l;
@@ -1582,19 +1579,20 @@ build_debug_section (bfd *abfd, asection ** sect_return)
       return NULL;
     }
 
-  sec_size = sect->size;
-  debug_section = (char *) bfd_alloc (abfd, sec_size);
-  if (debug_section == NULL)
-    return NULL;
-
   /* Seek to the beginning of the `.debug' section and read it.
      Save the current position first; it is needed by our caller.
      Then read debug section and reset the file pointer.  */
 
   position = bfd_tell (abfd);
-  if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0
-      || bfd_bread (debug_section, sec_size, abfd) != sec_size
-      || bfd_seek (abfd, position, SEEK_SET) != 0)
+  if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0)
+    return NULL;
+
+  sec_size = sect->size;
+  debug_section = (char *) _bfd_alloc_and_read (abfd, sec_size, sec_size);
+  if (debug_section == NULL)
+    return NULL;
+
+  if (bfd_seek (abfd, position, SEEK_SET) != 0)
     return NULL;
 
   * sect_return = sect;
@@ -1625,37 +1623,31 @@ copy_name (bfd *abfd, char *name, size_t maxlen)
 
 /* Read in the external symbols.  */
 
-bfd_boolean
+bool
 _bfd_coff_get_external_symbols (bfd *abfd)
 {
-  bfd_size_type symesz;
-  bfd_size_type size;
+  size_t symesz;
+  size_t size;
   void * syms;
 
   if (obj_coff_external_syms (abfd) != NULL)
-    return TRUE;
+    return true;
 
   symesz = bfd_coff_symesz (abfd);
-
-  size = obj_raw_syment_count (abfd) * symesz;
-  if (size == 0)
-    return TRUE;
-
-  syms = bfd_malloc (size);
-  if (syms == NULL)
-    return FALSE;
-
-  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
-      || bfd_bread (syms, size, abfd) != size)
+  if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size))
     {
-      if (syms != NULL)
-       free (syms);
-      return FALSE;
+      bfd_set_error (bfd_error_file_truncated);
+      return false;
     }
 
-  obj_coff_external_syms (abfd) = syms;
+  if (size == 0)
+    return true;
 
-  return TRUE;
+  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
+    return false;
+  syms = _bfd_malloc_and_read (abfd, size, size);
+  obj_coff_external_syms (abfd) = syms;
+  return syms != NULL;
 }
 
 /* Read in the external strings.  The strings are not loaded until
@@ -1671,6 +1663,7 @@ _bfd_coff_read_string_table (bfd *abfd)
   bfd_size_type strsize;
   char *strings;
   file_ptr pos;
+  ufile_ptr filesize;
 
   if (obj_coff_strings (abfd) != NULL)
     return obj_coff_strings (abfd);
@@ -1704,11 +1697,13 @@ _bfd_coff_read_string_table (bfd *abfd)
 #endif
     }
 
-  if (strsize < STRING_SIZE_SIZE)
+  filesize = bfd_get_file_size (abfd);
+  if (strsize < STRING_SIZE_SIZE
+      || (filesize != 0 && strsize > filesize))
     {
       _bfd_error_handler
        /* xgettext: c-format */
-       (_("%B: bad string table size %lu"), abfd, (unsigned long) strsize);
+       (_("%pB: bad string table size %" PRIu64), abfd, (uint64_t) strsize);
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     }
@@ -1739,15 +1734,19 @@ _bfd_coff_read_string_table (bfd *abfd)
 
 /* Free up the external symbols and strings read from a COFF file.  */
 
-bfd_boolean
+bool
 _bfd_coff_free_symbols (bfd *abfd)
 {
+  if (! bfd_family_coff (abfd))
+    return false;
+
   if (obj_coff_external_syms (abfd) != NULL
       && ! obj_coff_keep_syms (abfd))
     {
       free (obj_coff_external_syms (abfd));
       obj_coff_external_syms (abfd) = NULL;
     }
+
   if (obj_coff_strings (abfd) != NULL
       && ! obj_coff_keep_strings (abfd))
     {
@@ -1755,7 +1754,8 @@ _bfd_coff_free_symbols (bfd *abfd)
       obj_coff_strings (abfd) = NULL;
       obj_coff_strings_len (abfd) = 0;
     }
-  return TRUE;
+
+  return true;
 }
 
 /* Read a symbol table into freshly bfd_allocated memory, swap it, and
@@ -1784,7 +1784,11 @@ coff_get_normalized_symtab (bfd *abfd)
   if (! _bfd_coff_get_external_symbols (abfd))
     return NULL;
 
-  size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type);
+  size = obj_raw_syment_count (abfd);
+  /* Check for integer overflow.  */
+  if (size > (bfd_size_type) -1 / sizeof (combined_entry_type))
+    return NULL;
+  size *= sizeof (combined_entry_type);
   internal = (combined_entry_type *) bfd_zalloc (abfd, size);
   if (internal == NULL && size != 0)
     return NULL;
@@ -1809,13 +1813,10 @@ coff_get_normalized_symtab (bfd *abfd)
       bfd_coff_swap_sym_in (abfd, (void *) raw_src,
                            (void *) & internal_ptr->u.syment);
       symbol_ptr = internal_ptr;
-      internal_ptr->is_sym = TRUE;
+      internal_ptr->is_sym = true;
 
-      /* PR 17512: file: 1353-1166-0.004.  */
-      if (symbol_ptr->u.syment.n_sclass == C_FILE
-         && symbol_ptr->u.syment.n_numaux > 0
-         && raw_src + symesz + symbol_ptr->u.syment.n_numaux
-         * symesz > raw_end)
+      /* PR 17512: Prevent buffer overrun.  */
+      if (symbol_ptr->u.syment.n_numaux > ((raw_end - 1) - raw_src) / symesz)
        {
          bfd_release (abfd, internal);
          return NULL;
@@ -1826,30 +1827,27 @@ coff_get_normalized_symtab (bfd *abfd)
           i++)
        {
          internal_ptr++;
-         /* PR 17512: Prevent buffer overrun.  */
-         if (internal_ptr >= internal_end)
-           {
-             bfd_release (abfd, internal);
-             return NULL;
-           }
-
          raw_src += symesz;
+
          bfd_coff_swap_aux_in (abfd, (void *) raw_src,
                                symbol_ptr->u.syment.n_type,
                                symbol_ptr->u.syment.n_sclass,
                                (int) i, symbol_ptr->u.syment.n_numaux,
                                &(internal_ptr->u.auxent));
 
-         internal_ptr->is_sym = FALSE;
+         internal_ptr->is_sym = false;
          coff_pointerize_aux (abfd, internal, symbol_ptr, i,
-                              internal_ptr);
+                              internal_ptr, internal_end);
        }
     }
 
-  /* Free the raw symbols, but not the strings (if we have them).  */
-  obj_coff_keep_strings (abfd) = TRUE;
-  if (! _bfd_coff_free_symbols (abfd))
-    return NULL;
+  /* Free the raw symbols.  */
+  if (obj_coff_external_syms (abfd) != NULL
+      && ! obj_coff_keep_syms (abfd))
+    {
+      free (obj_coff_external_syms (abfd));
+      obj_coff_external_syms (abfd) = NULL;
+    }
 
   for (internal_ptr = internal; internal_ptr < internal_end;
        internal_ptr++)
@@ -1885,8 +1883,8 @@ coff_get_normalized_symtab (bfd *abfd)
          else
            {
              /* Ordinary short filename, put into memory anyway.  The
-                 Microsoft PE tools sometimes store a filename in
-                 multiple AUX entries.  */
+                Microsoft PE tools sometimes store a filename in
+                multiple AUX entries.  */
              if (internal_ptr->u.syment.n_numaux > 1
                  && coff_data (abfd)->pe)
                internal_ptr->u.syment._n._n_n._n_offset =
@@ -1911,7 +1909,7 @@ coff_get_normalized_symtab (bfd *abfd)
              char *newstring;
 
              /* Find the length of this string without walking into memory
-                that isn't ours.  */
+                that isn't ours.  */
              for (i = 0; i < 8; ++i)
                if (internal_ptr->u.syment._n._n_name[i] == '\0')
                  break;
@@ -1928,7 +1926,7 @@ coff_get_normalized_symtab (bfd *abfd)
          else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment))
            {
              /* Long name already.  Point symbol at the string in the
-                 table.  */
+                table.  */
              if (string_table == NULL)
                {
                  string_table = _bfd_coff_read_string_table (abfd);
@@ -1982,13 +1980,20 @@ coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
       bfd_set_error (bfd_error_invalid_operation);
       return -1;
     }
+#if SIZEOF_LONG == SIZEOF_INT
+  if (asect->reloc_count >= LONG_MAX / sizeof (arelent *))
+    {
+      bfd_set_error (bfd_error_file_too_big);
+      return -1;
+    }
+#endif
   return (asect->reloc_count + 1) * sizeof (arelent *);
 }
 
 asymbol *
 coff_make_empty_symbol (bfd *abfd)
 {
-  bfd_size_type amt = sizeof (coff_symbol_type);
+  size_t amt = sizeof (coff_symbol_type);
   coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_zalloc (abfd, amt);
 
   if (new_symbol == NULL)
@@ -1996,7 +2001,7 @@ coff_make_empty_symbol (bfd *abfd)
   new_symbol->symbol.section = 0;
   new_symbol->native = NULL;
   new_symbol->lineno = NULL;
-  new_symbol->done_lineno = FALSE;
+  new_symbol->done_lineno = false;
   new_symbol->symbol.the_bfd = abfd;
 
   return & new_symbol->symbol;
@@ -2009,7 +2014,7 @@ coff_bfd_make_debug_symbol (bfd *abfd,
                            void * ptr ATTRIBUTE_UNUSED,
                            unsigned long sz ATTRIBUTE_UNUSED)
 {
-  bfd_size_type amt = sizeof (coff_symbol_type);
+  size_t amt = sizeof (coff_symbol_type);
   coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_alloc (abfd, amt);
 
   if (new_symbol == NULL)
@@ -2020,11 +2025,11 @@ coff_bfd_make_debug_symbol (bfd *abfd,
   new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt);
   if (!new_symbol->native)
     return NULL;
-  new_symbol->native->is_sym = TRUE;
+  new_symbol->native->is_sym = true;
   new_symbol->symbol.section = bfd_abs_section_ptr;
   new_symbol->symbol.flags = BSF_DEBUGGING;
   new_symbol->lineno = NULL;
-  new_symbol->done_lineno = FALSE;
+  new_symbol->done_lineno = false;
   new_symbol->symbol.the_bfd = abfd;
 
   return & new_symbol->symbol;
@@ -2120,6 +2125,12 @@ coff_print_symbol (bfd *abfd,
                  fprintf (file, "File ");
                  break;
 
+               case C_DWARF:
+                 fprintf (file, "AUX scnlen 0x%lx nreloc %ld",
+                          (unsigned long) auxp->u.auxent.x_sect.x_scnlen,
+                          auxp->u.auxent.x_sect.x_nreloc);
+                 break;
+
                case C_STAT:
                  if (combined->u.syment.n_type == T_NULL)
                    /* Probably a section symbol ?  */
@@ -2204,7 +2215,7 @@ coff_print_symbol (bfd *abfd,
    function for the is_local_label_name entry point, but some may
    override it.  */
 
-bfd_boolean
+bool
 _bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
                               const char *name)
 {
@@ -2215,17 +2226,17 @@ _bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
    section, calculate and return the name of the source file and the line
    nearest to the wanted location.  */
 
-bfd_boolean
+bool
 coff_find_nearest_line_with_names (bfd *abfd,
-                                   asymbol **symbols,
-                                   asection *section,
-                                   bfd_vma offset,
-                                   const char **filename_ptr,
-                                   const char **functionname_ptr,
-                                   unsigned int *line_ptr,
-                                   const struct dwarf_debug_section *debug_sections)
+                                  asymbol **symbols,
+                                  asection *section,
+                                  bfd_vma offset,
+                                  const char **filename_ptr,
+                                  const char **functionname_ptr,
+                                  unsigned int *line_ptr,
+                                  const struct dwarf_debug_section *debug_sections)
 {
-  bfd_boolean found;
+  bool found;
   unsigned int i;
   unsigned int line_base;
   coff_data_type *cof = coff_data (abfd);
@@ -2234,7 +2245,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
   combined_entry_type *pend;
   alent *l;
   struct coff_section_tdata *sec_data;
-  bfd_size_type amt;
+  size_t amt;
 
   /* Before looking through the symbol table, try to use a .stab
      section to find the information.  */
@@ -2242,17 +2253,19 @@ coff_find_nearest_line_with_names (bfd *abfd,
                                             &found, filename_ptr,
                                             functionname_ptr, line_ptr,
                                             &coff_data(abfd)->line_info))
-    return FALSE;
+    return false;
 
   if (found)
-    return TRUE;
+    return true;
 
   /* Also try examining DWARF2 debugging information.  */
   if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
                                     filename_ptr, functionname_ptr,
-                                    line_ptr, NULL, debug_sections, 0,
+                                    line_ptr, NULL, debug_sections,
                                     &coff_data(abfd)->dwarf2_find_line_info))
-    return TRUE;
+    return true;
+
+  sec_data = coff_section_data (abfd, section);
 
   /* If the DWARF lookup failed, but there is DWARF information available
      then the problem might be that the file has been rebased.  This tool
@@ -2260,18 +2273,37 @@ coff_find_nearest_line_with_names (bfd *abfd,
      information.  So try again, using a bias against the address sought.  */
   if (coff_data (abfd)->dwarf2_find_line_info != NULL)
     {
-      bfd_signed_vma bias;
+      bfd_signed_vma bias = 0;
+
+      /* Create a cache of the result for the next call.  */
+      if (sec_data == NULL && section->owner == abfd)
+       {
+         amt = sizeof (struct coff_section_tdata);
+         section->used_by_bfd = bfd_zalloc (abfd, amt);
+         sec_data = (struct coff_section_tdata *) section->used_by_bfd;
+       }
 
-      bias = _bfd_dwarf2_find_symbol_bias (symbols,
-                                          & coff_data (abfd)->dwarf2_find_line_info);
+      if (sec_data != NULL && sec_data->saved_bias)
+       bias = sec_data->saved_bias;
+      else if (symbols)
+       {
+         bias = _bfd_dwarf2_find_symbol_bias (symbols,
+                                              & coff_data (abfd)->dwarf2_find_line_info);
+
+         if (sec_data)
+           {
+             sec_data->saved_bias = true;
+             sec_data->bias = bias;
+           }
+       }
 
       if (bias
          && _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section,
                                            offset + bias,
                                            filename_ptr, functionname_ptr,
-                                           line_ptr, NULL, debug_sections, 0,
+                                           line_ptr, NULL, debug_sections,
                                            &coff_data(abfd)->dwarf2_find_line_info))
-       return TRUE;
+       return true;
     }
 
   *filename_ptr = 0;
@@ -2280,15 +2312,15 @@ coff_find_nearest_line_with_names (bfd *abfd,
 
   /* Don't try and find line numbers in a non coff file.  */
   if (!bfd_family_coff (abfd))
-    return FALSE;
+    return false;
 
   if (cof == NULL)
-    return FALSE;
+    return false;
 
   /* Find the first C_FILE symbol.  */
   p = cof->raw_syments;
   if (!p)
-    return FALSE;
+    return false;
 
   pend = p + cof->raw_syment_count;
   while (p < pend)
@@ -2305,7 +2337,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
       bfd_vma maxdiff;
 
       /* Look through the C_FILE symbols to find the best one.  */
-      sec_vma = bfd_get_section_vma (abfd, section);
+      sec_vma = bfd_section_vma (section);
       *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
       maxdiff = (bfd_vma) 0 - (bfd_vma) 1;
       while (1)
@@ -2338,7 +2370,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
            file_addr += coff_section_from_bfd_index (abfd,
                                                      p2->u.syment.n_scnum)->vma;
          /* We use <= MAXDIFF here so that if we get a zero length
-             file, we actually use the next file entry.  */
+            file, we actually use the next file entry.  */
          if (p2 < pend
              && offset + sec_vma >= file_addr
              && offset + sec_vma - file_addr <= maxdiff)
@@ -2347,21 +2379,30 @@ coff_find_nearest_line_with_names (bfd *abfd,
              maxdiff = offset + sec_vma - p2->u.syment.n_value;
            }
 
+         if (p->u.syment.n_value >= cof->raw_syment_count)
+           break;
+
          /* Avoid endless loops on erroneous files by ensuring that
             we always move forward in the file.  */
          if (p >= cof->raw_syments + p->u.syment.n_value)
            break;
 
          p = cof->raw_syments + p->u.syment.n_value;
-         if (p > pend || p->u.syment.n_sclass != C_FILE)
+         if (!p->is_sym || p->u.syment.n_sclass != C_FILE)
            break;
        }
     }
 
-  /* Now wander though the raw linenumbers of the section.  */
-  /* If we have been called on this section before, and the offset we
-     want is further down then we can prime the lookup loop.  */
-  sec_data = coff_section_data (abfd, section);
+  if (section->lineno_count == 0)
+    {
+      *functionname_ptr = NULL;
+      *line_ptr = 0;
+      return true;
+    }
+
+  /* Now wander though the raw linenumbers of the section.
+     If we have been called on this section before, and the offset
+     we want is further down then we can prime the lookup loop.  */
   if (sec_data != NULL
       && sec_data->i > 0
       && offset >= sec_data->offset)
@@ -2390,6 +2431,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
              coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
              if (coff->symbol.value > offset)
                break;
+
              *functionname_ptr = coff->symbol.name;
              last_value = coff->symbol.value;
              if (coff->native)
@@ -2401,11 +2443,15 @@ coff_find_nearest_line_with_names (bfd *abfd,
 
                  /* In XCOFF a debugging symbol can follow the
                     function symbol.  */
-                 if (s->u.syment.n_scnum == N_DEBUG)
+                 if (((size_t) ((char *) s - (char *) obj_raw_syments (abfd))
+                      < obj_raw_syment_count (abfd) * sizeof (*s))
+                     && s->u.syment.n_scnum == N_DEBUG)
                    s = s + 1 + s->u.syment.n_numaux;
 
                  /* S should now point to the .bf of the function.  */
-                 if (s->u.syment.n_numaux)
+                 if (((size_t) ((char *) s - (char *) obj_raw_syments (abfd))
+                      < obj_raw_syment_count (abfd) * sizeof (*s))
+                     && s->u.syment.n_numaux)
                    {
                      /* The linenumber is stored in the auxent.  */
                      union internal_auxent *a = &((s + 1)->u.auxent);
@@ -2446,6 +2492,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
       section->used_by_bfd = bfd_zalloc (abfd, amt);
       sec_data = (struct coff_section_tdata *) section->used_by_bfd;
     }
+
   if (sec_data != NULL)
     {
       sec_data->offset = offset;
@@ -2454,10 +2501,10 @@ coff_find_nearest_line_with_names (bfd *abfd,
       sec_data->line_base = line_base;
     }
 
-  return TRUE;
+  return true;
 }
 
-bfd_boolean
+bool
 coff_find_nearest_line (bfd *abfd,
                        asymbol **symbols,
                        asection *section,
@@ -2470,17 +2517,17 @@ coff_find_nearest_line (bfd *abfd,
   if (discriminator_ptr)
     *discriminator_ptr = 0;
   return coff_find_nearest_line_with_names (abfd, symbols, section, offset,
-                                            filename_ptr, functionname_ptr,
-                                            line_ptr, dwarf_debug_sections);
+                                           filename_ptr, functionname_ptr,
+                                           line_ptr, dwarf_debug_sections);
 }
 
-bfd_boolean
+bool
 coff_find_inliner_info (bfd *abfd,
                        const char **filename_ptr,
                        const char **functionname_ptr,
                        unsigned int *line_ptr)
 {
-  bfd_boolean found;
+  bool found;
 
   found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
                                         functionname_ptr, line_ptr,
@@ -2504,10 +2551,10 @@ coff_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
 
 /* Change the class of a coff symbol held by BFD.  */
 
-bfd_boolean
-bfd_coff_set_symbol_class (bfd *         abfd,
-                          asymbol *     symbol,
-                          unsigned int  symbol_class)
+bool
+bfd_coff_set_symbol_class (bfd *        abfd,
+                          asymbol *     symbol,
+                          unsigned int  symbol_class)
 {
   coff_symbol_type * csym;
 
@@ -2515,7 +2562,7 @@ bfd_coff_set_symbol_class (bfd *         abfd,
   if (csym == NULL)
     {
       bfd_set_error (bfd_error_invalid_operation);
-      return FALSE;
+      return false;
     }
   else if (csym->native == NULL)
     {
@@ -2525,13 +2572,13 @@ bfd_coff_set_symbol_class (bfd *         abfd,
         coff_write_alien_symbol().  */
 
       combined_entry_type * native;
-      bfd_size_type amt = sizeof (* native);
+      size_t amt = sizeof (* native);
 
       native = (combined_entry_type *) bfd_zalloc (abfd, amt);
       if (native == NULL)
-       return FALSE;
+       return false;
 
-      native->is_sym = TRUE;
+      native->is_sym = true;
       native->u.syment.n_type   = T_NULL;
       native->u.syment.n_sclass = symbol_class;
 
@@ -2564,10 +2611,10 @@ bfd_coff_set_symbol_class (bfd *         abfd,
   else
     csym->native->u.syment.n_sclass = symbol_class;
 
-  return TRUE;
+  return true;
 }
 
-bfd_boolean
+bool
 _bfd_coff_section_already_linked (bfd *abfd,
                                  asection *sec,
                                  struct bfd_link_info *info)
@@ -2578,22 +2625,25 @@ _bfd_coff_section_already_linked (bfd *abfd,
   struct bfd_section_already_linked_hash_entry *already_linked_list;
   struct coff_comdat_info *s_comdat;
 
+  if (sec->output_section == bfd_abs_section_ptr)
+    return false;
+
   flags = sec->flags;
   if ((flags & SEC_LINK_ONCE) == 0)
-    return FALSE;
+    return false;
 
   /* The COFF backend linker doesn't support group sections.  */
   if ((flags & SEC_GROUP) != 0)
-    return FALSE;
+    return false;
 
-  name = bfd_get_section_name (abfd, sec);
+  name = bfd_section_name (sec);
   s_comdat = bfd_coff_get_comdat_section (abfd, sec);
 
   if (s_comdat != NULL)
     key = s_comdat->name;
   else
     {
-      if (CONST_STRNEQ (name, ".gnu.linkonce.")
+      if (startswith (name, ".gnu.linkonce.")
          && (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
        key++;
       else
@@ -2620,7 +2670,8 @@ _bfd_coff_section_already_linked (bfd *abfd,
         .gnu.linkonce.*.<key>.  */
       if (((s_comdat != NULL) == (l_comdat != NULL)
           && strcmp (name, l->sec->name) == 0)
-         || (l->sec->owner->flags & BFD_PLUGIN) != 0)
+         || (l->sec->owner->flags & BFD_PLUGIN) != 0
+         || (sec->owner->flags & BFD_PLUGIN) != 0)
        {
          /* The section has already been linked.  See if we should
             issue a warning.  */
@@ -2631,12 +2682,12 @@ _bfd_coff_section_already_linked (bfd *abfd,
   /* This is the first section with this name.  Record it.  */
   if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
     info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
-  return FALSE;
+  return false;
 }
 
 /* Initialize COOKIE for input bfd ABFD. */
 
-static bfd_boolean
+static bool
 init_reloc_cookie (struct coff_reloc_cookie *cookie,
                   struct bfd_link_info *info ATTRIBUTE_UNUSED,
                   bfd *abfd)
@@ -2649,7 +2700,7 @@ init_reloc_cookie (struct coff_reloc_cookie *cookie,
 
   cookie->symbols = obj_symbols (abfd);
 
-  return TRUE;
+  return true;
 }
 
 /* Free the memory allocated by init_reloc_cookie, if appropriate.  */
@@ -2664,7 +2715,7 @@ fini_reloc_cookie (struct coff_reloc_cookie *cookie ATTRIBUTE_UNUSED,
 /* Initialize the relocation information in COOKIE for input section SEC
    of input bfd ABFD.  */
 
-static bfd_boolean
+static bool
 init_reloc_cookie_rels (struct coff_reloc_cookie *cookie,
                        struct bfd_link_info *info ATTRIBUTE_UNUSED,
                        bfd *abfd,
@@ -2675,17 +2726,18 @@ init_reloc_cookie_rels (struct coff_reloc_cookie *cookie,
       cookie->rels = NULL;
       cookie->relend = NULL;
       cookie->rel = NULL;
-      return TRUE;
+      return true;
     }
 
-  cookie->rels = _bfd_coff_read_internal_relocs (abfd, sec, FALSE, NULL, 0, NULL);
+  cookie->rels = _bfd_coff_read_internal_relocs (abfd, sec, false, NULL,
+                                                0, NULL);
 
   if (cookie->rels == NULL)
-    return FALSE;
+    return false;
 
   cookie->rel = cookie->rels;
   cookie->relend = (cookie->rels + sec->reloc_count);
-  return TRUE;
+  return true;
 }
 
 /* Free the memory allocated by init_reloc_cookie_rels,
@@ -2707,20 +2759,20 @@ fini_reloc_cookie_rels (struct coff_reloc_cookie *cookie,
 
 /* Initialize the whole of COOKIE for input section SEC.  */
 
-static bfd_boolean
+static bool
 init_reloc_cookie_for_section (struct coff_reloc_cookie *cookie,
                               struct bfd_link_info *info,
                               asection *sec)
 {
   if (!init_reloc_cookie (cookie, info, sec->owner))
-    return FALSE;
+    return false;
 
   if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec))
     {
       fini_reloc_cookie (cookie, sec->owner);
-      return FALSE;
+      return false;
     }
-  return TRUE;
+  return true;
 }
 
 /* Free the memory allocated by init_reloc_cookie_for_section,
@@ -2744,19 +2796,33 @@ _bfd_coff_gc_mark_hook (asection *sec,
   if (h != NULL)
     {
       switch (h->root.type)
-        {
-        case bfd_link_hash_defined:
-        case bfd_link_hash_defweak:
-          return h->root.u.def.section;
+       {
+       case bfd_link_hash_defined:
+       case bfd_link_hash_defweak:
+         return h->root.u.def.section;
 
-        case bfd_link_hash_common:
-          return h->root.u.c.p->section;
+       case bfd_link_hash_common:
+         return h->root.u.c.p->section;
 
-       case bfd_link_hash_undefined:
        case bfd_link_hash_undefweak:
-        default:
-          break;
-        }
+         if (h->symbol_class == C_NT_WEAK && h->numaux == 1)
+           {
+             /* PE weak externals.  A weak symbol may include an auxiliary
+                record indicating that if the weak symbol is not resolved,
+                another external symbol is used instead.  */
+             struct coff_link_hash_entry *h2 =
+               h->auxbfd->tdata.coff_obj_data->sym_hashes[
+                   h->aux->x_sym.x_tagndx.l];
+
+             if (h2 && h2->root.type != bfd_link_hash_undefined)
+               return  h2->root.u.def.section;
+           }
+         break;
+
+       case bfd_link_hash_undefined:
+       default:
+         break;
+       }
       return NULL;
     }
 
@@ -2789,14 +2855,14 @@ _bfd_coff_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
                            + obj_convert (sec->owner)[cookie->rel->r_symndx])->native->u.syment);
 }
 
-static bfd_boolean _bfd_coff_gc_mark
+static bool _bfd_coff_gc_mark
   (struct bfd_link_info *, asection *, coff_gc_mark_hook_fn);
 
 /* COOKIE->rel describes a relocation against section SEC, which is
    a section we've decided to keep.  Mark the section that contains
    the relocation symbol.  */
 
-static bfd_boolean
+static bool
 _bfd_coff_gc_mark_reloc (struct bfd_link_info *info,
                         asection *sec,
                         coff_gc_mark_hook_fn gc_mark_hook,
@@ -2810,21 +2876,21 @@ _bfd_coff_gc_mark_reloc (struct bfd_link_info *info,
       if (bfd_get_flavour (rsec->owner) != bfd_target_coff_flavour)
        rsec->gc_mark = 1;
       else if (!_bfd_coff_gc_mark (info, rsec, gc_mark_hook))
-       return FALSE;
+       return false;
     }
-  return TRUE;
+  return true;
 }
 
 /* The mark phase of garbage collection.  For a given section, mark
    it and any sections in this section's group, and all the sections
    which define symbols to which it refers.  */
 
-static bfd_boolean
+static bool
 _bfd_coff_gc_mark (struct bfd_link_info *info,
                   asection *sec,
                   coff_gc_mark_hook_fn gc_mark_hook)
 {
-  bfd_boolean ret = TRUE;
+  bool ret = true;
 
   sec->gc_mark = 1;
 
@@ -2835,25 +2901,25 @@ _bfd_coff_gc_mark (struct bfd_link_info *info,
       struct coff_reloc_cookie cookie;
 
       if (!init_reloc_cookie_for_section (&cookie, info, sec))
-        ret = FALSE;
+       ret = false;
       else
-        {
-          for (; cookie.rel < cookie.relend; cookie.rel++)
-            {
+       {
+         for (; cookie.rel < cookie.relend; cookie.rel++)
+           {
              if (!_bfd_coff_gc_mark_reloc (info, sec, gc_mark_hook, &cookie))
                {
-                 ret = FALSE;
+                 ret = false;
                  break;
                }
            }
-          fini_reloc_cookie_for_section (&cookie, sec);
-        }
+         fini_reloc_cookie_for_section (&cookie, sec);
+       }
     }
 
   return ret;
 }
 
-static bfd_boolean
+static bool
 _bfd_coff_gc_mark_extra_sections (struct bfd_link_info *info,
                                  coff_gc_mark_hook_fn mark_hook ATTRIBUTE_UNUSED)
 {
@@ -2862,20 +2928,20 @@ _bfd_coff_gc_mark_extra_sections (struct bfd_link_info *info,
   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       asection *isec;
-      bfd_boolean some_kept;
+      bool some_kept;
 
-      if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+      if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour)
        continue;
 
       /* Ensure all linker created sections are kept, and see whether
         any other section is already marked.  */
-      some_kept = FALSE;
+      some_kept = false;
       for (isec = ibfd->sections; isec != NULL; isec = isec->next)
        {
          if ((isec->flags & SEC_LINKER_CREATED) != 0)
            isec->gc_mark = 1;
          else if (isec->gc_mark)
-           some_kept = TRUE;
+           some_kept = true;
        }
 
       /* If no section in this file will be kept, then we can
@@ -2890,12 +2956,12 @@ _bfd_coff_gc_mark_extra_sections (struct bfd_link_info *info,
            || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
          isec->gc_mark = 1;
     }
-  return TRUE;
+  return true;
 }
 
 /* Sweep symbols in swept sections.  Called via coff_link_hash_traverse.  */
 
-static bfd_boolean
+static bool
 coff_gc_sweep_symbol (struct coff_link_hash_entry *h,
                      void *data ATTRIBUTE_UNUSED)
 {
@@ -2912,15 +2978,15 @@ coff_gc_sweep_symbol (struct coff_link_hash_entry *h,
       h->symbol_class = C_HIDDEN;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* The sweep phase of garbage collection.  Remove all garbage sections.  */
 
-typedef bfd_boolean (*gc_sweep_hook_fn)
+typedef bool (*gc_sweep_hook_fn)
   (bfd *, struct bfd_link_info *, asection *, const struct internal_reloc *);
 
-static bfd_boolean
+static bool
 coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
 {
   bfd *sub;
@@ -2935,13 +3001,13 @@ coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
       for (o = sub->sections; o != NULL; o = o->next)
        {
            /* Keep debug and special sections.  */
-          if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
+         if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
              || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
            o->gc_mark = 1;
-          else if (CONST_STRNEQ (o->name, ".idata")
-                  || CONST_STRNEQ (o->name, ".pdata")
-                  || CONST_STRNEQ (o->name, ".xdata")
-                  || CONST_STRNEQ (o->name, ".rsrc"))
+         else if (startswith (o->name, ".idata")
+                  || startswith (o->name, ".pdata")
+                  || startswith (o->name, ".xdata")
+                  || startswith (o->name, ".rsrc"))
            o->gc_mark = 1;
 
          if (o->gc_mark)
@@ -2957,7 +3023,8 @@ coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
 
          if (info->print_gc_sections && o->size != 0)
            /* xgettext: c-format */
-            _bfd_error_handler (_("Removing unused section '%s' in file '%B'"), sub, o->name);
+           _bfd_error_handler (_("removing unused section '%pA' in file '%pB'"),
+                               o, sub);
 
 #if 0
          /* But we also have to update some of the relocation
@@ -2968,13 +3035,13 @@ coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
              && !bfd_is_abs_section (o->output_section))
            {
              struct internal_reloc *internal_relocs;
-             bfd_boolean r;
+             bool r;
 
              internal_relocs
                = _bfd_coff_link_read_relocs (o->owner, o, NULL, NULL,
                                             info->keep_memory);
              if (internal_relocs == NULL)
-               return FALSE;
+               return false;
 
              r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs);
 
@@ -2982,7 +3049,7 @@ coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
                free (internal_relocs);
 
              if (!r)
-               return FALSE;
+               return false;
            }
 #endif
        }
@@ -2993,7 +3060,7 @@ coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
   coff_link_hash_traverse (coff_hash_table (info), coff_gc_sweep_symbol,
                           NULL);
 
-  return TRUE;
+  return true;
 }
 
 /* Keep all sections containing symbols undefined on the command-line,
@@ -3009,7 +3076,7 @@ _bfd_coff_gc_keep (struct bfd_link_info *info)
       struct coff_link_hash_entry *h;
 
       h = coff_link_hash_lookup (coff_hash_table (info), sym->name,
-                               FALSE, FALSE, FALSE);
+                               false, false, false);
 
       if (h != NULL
          && (h->root.type == bfd_link_hash_defined
@@ -3021,7 +3088,7 @@ _bfd_coff_gc_keep (struct bfd_link_info *info)
 
 /* Do mark and sweep of unused sections.  */
 
-bfd_boolean
+bool
 bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
 {
   bfd *sub;
@@ -3033,8 +3100,8 @@ bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
   if (!bed->can_gc_sections
       || !is_coff_hash_table (info->hash))
     {
-      _bfd_error_handler(_("Warning: gc-sections option ignored"));
-      return TRUE;
+      _bfd_error_handler(_("warning: gc-sections option ignored"));
+      return true;
     }
 #endif
 
@@ -3046,20 +3113,20 @@ bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
       asection *o;
 
       if (bfd_get_flavour (sub) != bfd_target_coff_flavour)
-        continue;
+       continue;
 
       for (o = sub->sections; o != NULL; o = o->next)
-        {
+       {
          if (((o->flags & (SEC_EXCLUDE | SEC_KEEP)) == SEC_KEEP
-              || CONST_STRNEQ (o->name, ".vectors")
-              || CONST_STRNEQ (o->name, ".ctors")
-              || CONST_STRNEQ (o->name, ".dtors"))
+              || startswith (o->name, ".vectors")
+              || startswith (o->name, ".ctors")
+              || startswith (o->name, ".dtors"))
              && !o->gc_mark)
            {
              if (!_bfd_coff_gc_mark (info, o, _bfd_coff_gc_mark_hook))
-               return FALSE;
+               return false;
            }
-        }
+       }
     }
 
   /* Allow the backend to mark additional target specific sections.  */
@@ -3068,3 +3135,37 @@ bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
   /* ... and mark SEC_EXCLUDE for those that go.  */
   return coff_gc_sweep (abfd, info);
 }
+
+/* Return name used to identify a comdat group.  */
+
+const char *
+bfd_coff_group_name (bfd *abfd, const asection *sec)
+{
+  struct coff_comdat_info *ci = bfd_coff_get_comdat_section (abfd, sec);
+  if (ci != NULL)
+    return ci->name;
+  return NULL;
+}
+
+bool
+_bfd_coff_close_and_cleanup (bfd *abfd)
+{
+  struct coff_tdata *tdata = coff_data (abfd);
+
+  if (tdata != NULL)
+    {
+      /* PR 25447:
+        Do not clear the keep_syms and keep_strings flags.
+        These may have been set by pe_ILF_build_a_bfd() indicating
+        that the syms and strings pointers are not to be freed.  */
+      if (bfd_get_format (abfd) == bfd_object
+         && bfd_family_coff (abfd)
+         && !_bfd_coff_free_symbols (abfd))
+       return false;
+
+      if (bfd_get_format (abfd) == bfd_object
+         || bfd_get_format (abfd) == bfd_core)
+       _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
+    }
+  return _bfd_generic_close_and_cleanup (abfd);
+}
This page took 0.056549 seconds and 4 git commands to generate.