Make bfd_byte an int8_t, flagword a uint32_t
[binutils-gdb.git] / bfd / cofflink.c
index 67d9c62b0b44fc2bb10c1ea3b11764b1f96faecc..9baec2fc712382a5267760dc3f18ad07c60762e0 100644 (file)
@@ -1,5 +1,5 @@
 /* COFF specific linker code.
-   Copyright (C) 1994-2021 Free Software Foundation, Inc.
+   Copyright (C) 1994-2023 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -896,10 +896,8 @@ _bfd_coff_final_link (bfd *abfd,
              asymbol *sym = bfd_get_outsymbols (sub) [i];
              file_ptr pos;
              struct internal_syment isym;
-             union internal_auxent iaux;
-             bfd_size_type string_size = 0, indx;
              bfd_vma written = 0;
-             bool rewrite = false, hash;
+             bool rewrite = false;
 
              if (! (sym->flags & BSF_LOCAL)
                  || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
@@ -925,54 +923,12 @@ _bfd_coff_final_link (bfd *abfd,
                                             * symesz;
              if (bfd_seek (abfd, pos, SEEK_SET) != 0)
                goto error_return;
-             if (! coff_write_alien_symbol(abfd, sym, &isym, &iaux, &written,
-                                           &string_size, NULL, NULL))
+             if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
+                                           flaginfo.strtab,
+                                           !flaginfo.info->traditional_format,
+                                           NULL, NULL))
                goto error_return;
 
-             hash = !flaginfo.info->traditional_format;
-
-             if (string_size >= 6 && isym.n_sclass == C_FILE
-                 && ! isym._n._n_n._n_zeroes && isym.n_numaux)
-               {
-                 indx = _bfd_stringtab_add (flaginfo.strtab, ".file", hash,
-                                            false);
-                 if (indx == (bfd_size_type) -1)
-                   goto error_return;
-                 isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
-                 bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms);
-                 if (bfd_seek (abfd, pos, SEEK_SET) != 0
-                     || bfd_bwrite (flaginfo.outsyms, symesz,
-                                    abfd) != symesz)
-                   goto error_return;
-                 string_size -= 6;
-               }
-
-             if (string_size)
-               {
-                 indx = _bfd_stringtab_add (flaginfo.strtab,
-                                            bfd_asymbol_name (sym), hash,
-                                            false);
-                 if (indx == (bfd_size_type) -1)
-                   goto error_return;
-                 if (isym.n_sclass != C_FILE)
-                   {
-                     isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
-                     bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms);
-                     rewrite = true;
-                   }
-                 else
-                   {
-                     BFD_ASSERT (isym.n_numaux == 1);
-                     iaux.x_file.x_n.x_n.x_offset = STRING_SIZE_SIZE + indx;
-                     bfd_coff_swap_aux_out (abfd, &iaux, isym.n_type, C_FILE,
-                                            0, 1, flaginfo.outsyms + symesz);
-                     if (bfd_seek (abfd, pos + symesz, SEEK_SET) != 0
-                         || bfd_bwrite (flaginfo.outsyms + symesz, symesz,
-                                        abfd) != symesz)
-                       goto error_return;
-                   }
-               }
-
              if (isym.n_sclass == C_FILE)
                {
                  if (flaginfo.last_file_index != -1)
@@ -1212,7 +1168,7 @@ _bfd_coff_final_link (bfd *abfd,
 static char *
 dores_com (char *ptr, bfd *output_bfd, int heap)
 {
-  if (coff_data(output_bfd)->pe)
+  if (obj_pe (output_bfd))
     {
       int val = strtoul (ptr, &ptr, 0);
 
@@ -1257,7 +1213,7 @@ process_embedded_commands (bfd *output_bfd,
   char *e;
   bfd_byte *copy;
 
-  if (!sec)
+  if (sec == NULL || (sec->flags & SEC_HAS_CONTENTS) == 0)
     return 1;
 
   if (!bfd_malloc_and_get_section (abfd, sec, &copy))
@@ -1444,7 +1400,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
   output_index = syment_base;
   outsym = flaginfo->outsyms;
 
-  if (coff_data (output_bfd)->pe
+  if (obj_pe (output_bfd)
       && ! process_embedded_commands (output_bfd, flaginfo->info, input_bfd))
     return false;
 
@@ -1661,7 +1617,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
          islp = isymp + 2;
          esl = esym + 2 * isymesz;
          eslend = ((bfd_byte *) obj_coff_external_syms (input_bfd)
-                   + aux.x_sym.x_fcnary.x_fcn.x_endndx.l * isymesz);
+                   + aux.x_sym.x_fcnary.x_fcn.x_endndx.u32 * isymesz);
          while (esl < eslend)
            {
              const char *elename;
@@ -1700,7 +1656,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
                  bfd_coff_swap_aux_in (input_bfd, (esl + isymesz),
                                        islp->n_type, islp->n_sclass, 0,
                                        islp->n_numaux, &eleaux);
-                 indx = eleaux.x_sym.x_tagndx.l;
+                 indx = eleaux.x_sym.x_tagndx.u32;
 
                  /* FIXME: If this tagndx entry refers to a symbol
                     defined later in this file, we just ignore it.
@@ -2041,7 +1997,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
                      || isymp->n_sclass == C_BLOCK
                      || isymp->n_sclass == C_FCN)
                    {
-                     indx = auxp->x_sym.x_fcnary.x_fcn.x_endndx.l;
+                     indx = auxp->x_sym.x_fcnary.x_fcn.x_endndx.u32;
                      if (indx > 0
                          && indx < obj_raw_syment_count (input_bfd))
                        {
@@ -2058,20 +2014,20 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
                            indx = output_index;
                          else
                            indx = flaginfo->sym_indices[indx];
-                         auxp->x_sym.x_fcnary.x_fcn.x_endndx.l = indx;
+                         auxp->x_sym.x_fcnary.x_fcn.x_endndx.u32 = indx;
                        }
                    }
 
-                 indx = auxp->x_sym.x_tagndx.l;
+                 indx = auxp->x_sym.x_tagndx.u32;
                  if (indx > 0 && indx < obj_raw_syment_count (input_bfd))
                    {
                      long symindx;
 
                      symindx = flaginfo->sym_indices[indx];
                      if (symindx < 0)
-                       auxp->x_sym.x_tagndx.l = 0;
+                       auxp->x_sym.x_tagndx.u32 = 0;
                      else
-                       auxp->x_sym.x_tagndx.l = symindx;
+                       auxp->x_sym.x_tagndx.u32 = symindx;
                    }
 
                  /* The .bf symbols are supposed to be linked through
@@ -2089,7 +2045,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
                    {
                      if (flaginfo->last_bf_index != -1)
                        {
-                         flaginfo->last_bf.x_sym.x_fcnary.x_fcn.x_endndx.l =
+                         flaginfo->last_bf.x_sym.x_fcnary.x_fcn.x_endndx.u32 =
                            *indexp;
 
                          if ((bfd_size_type) flaginfo->last_bf_index
@@ -2137,7 +2093,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
                            }
                        }
 
-                     if (auxp->x_sym.x_fcnary.x_fcn.x_endndx.l != 0)
+                     if (auxp->x_sym.x_fcnary.x_fcn.x_endndx.u32 != 0)
                        flaginfo->last_bf_index = -1;
                      else
                        {
@@ -2606,14 +2562,10 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data)
        if (isym.n_value > (bfd_vma) 0xffffffff)
          {
            if (! h->root.linker_def)
-             {
-               char value_buf[128];
-
-               sprintf_vma (value_buf, isym.n_value);
-               _bfd_error_handler
-                 (_("%pB: stripping non-representable symbol '%s' (value 0x%s)"),
-                  output_bfd, h->root.root.string, value_buf);
-             }
+             _bfd_error_handler
+               (_("%pB: stripping non-representable symbol '%s' "
+                  "(value 0x%" PRIx64 ")"),
+                output_bfd, h->root.root.string, isym.n_value);
            return true;
          }
 #endif
@@ -3009,8 +2961,10 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
              sec = sections[symndx];
 
              /* PR 19623: Relocations against symbols in
-                the absolute sections should ignored.  */
-             if (bfd_is_abs_section (sec))
+                the absolute sections should ignored.
+                PR 29807: Also ignore relocs against file symbols or
+                other such nonsense in fuzzed objects.  */
+             if (sec == NULL || bfd_is_abs_section (sec))
                continue;
 
              val = (sec->output_section->vma
@@ -3023,10 +2977,11 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
       else
        {
          if (h->root.type == bfd_link_hash_defined
+             /* Defined weak symbols are a GNU extension.  */
              || h->root.type == bfd_link_hash_defweak)
            {
-             /* Defined weak symbols are a GNU extension. */
              sec = h->root.u.def.section;
+             BFD_ASSERT (sec->output_section != NULL);
              val = (h->root.u.def.value
                     + sec->output_section->vma
                     + sec->output_offset);
@@ -3047,8 +3002,8 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
                     external causes the library member to be linked.
                     See also linker.c: generic_link_check_archive_element. */
                  struct coff_link_hash_entry *h2 =
-                   h->auxbfd->tdata.coff_obj_data->sym_hashes[
-                   h->aux->x_sym.x_tagndx.l];
+                   h->auxbfd->tdata.coff_obj_data->sym_hashes
+                   [h->aux->x_sym.x_tagndx.u32];
 
                  if (!h2 || h2->root.type == bfd_link_hash_undefined)
                    {
@@ -3103,7 +3058,7 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
                           - input_section->vma
                           + input_section->output_offset
                           + input_section->output_section->vma);
-             if (coff_data (output_bfd)->pe)
+             if (obj_pe (output_bfd))
                addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
              if (fwrite (&addr, 1, sizeof (bfd_vma), (FILE *) info->base_file)
                  != sizeof (bfd_vma))
@@ -3133,7 +3088,6 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
          return false;
        case bfd_reloc_overflow:
          {
-
            /* Ignore any weak undef symbols that may have overflowed.  Due to
               PR ld/19011 the base address is now in the upper 64-bit address
               range.  This means that when _bfd_final_link_relocate calculates
@@ -3169,5 +3123,6 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
          }
        }
     }
+
   return true;
 }