public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] PE/COFF: assorted adjustments
@ 2022-05-06  6:53 Jan Beulich
  2022-05-06  6:54 ` [PATCH 1/5] don't over-align file positions of PE executable sections Jan Beulich
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Jan Beulich @ 2022-05-06  6:53 UTC (permalink / raw)
  To: Binutils; +Cc: Dave Korn

In the Xen Project we link the hypervisor both an an ELF binary and
as a native EFI one, all from largely the same (ELF) objects. On
top of earlier changes to make certain variants thereof (like
including debug in the EFI binary) a few more issues were noticed,
most related to the stripping of such binaries.

1: don't over-align file positions of PE executable sections
2: COFF: make objcopy / strip honor --keep-file-symbols
3: COFF/PE: don't leave zero timestamp after objcopy / strip
4: COFF/PE: keep linker version during objcopy / strip
5: COFF: use hash for string table also when copying / stripping

Jan


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] don't over-align file positions of PE executable sections
  2022-05-06  6:53 [PATCH 0/5] PE/COFF: assorted adjustments Jan Beulich
@ 2022-05-06  6:54 ` Jan Beulich
  2022-05-06  6:54 ` [PATCH 2/5] COFF: make objcopy / strip honor --keep-file-symbols Jan Beulich
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Jan Beulich @ 2022-05-06  6:54 UTC (permalink / raw)
  To: Binutils; +Cc: Dave Korn

When a sufficiently small alignment was specified via --file-alignment,
individual section alignment shouldn't affect placement within the file.
This involves first of all clearing D_PAGED for images when section and
file alignment together don't permit paging of the image. The involved
comparison against COFF_PAGE_SIZE in turn helped point out (through a
compiler warning) that 'page_size' should be of unsigned type (as in
particular FileAlignment is). This yet in turn pointed out a dubious
error condition (which is being deleted).

For the D_PAGED case I think the enforced file alignment may still be
too high, but I'm wary of changing that logic without knowing of
possible corner cases.

Furthermore file positions in PE should be independent of the alignment
recorded in section headers anyway. Otherwise there are e.g. anomalies
following commit 6f8f6017a0c4 ("PR27567, Linking PE files adds alignment
section flags to executables") in that linking would use information a
subsequent processing step (e.g. stripping) wouldn't have available
anymore, and hence a binary could change in that 2nd step for no actual
reason. (Similarly stripping a binary linked with a linker pre-dating
that commit would change the binary again when stripping it a 2nd time.)
---
The new condition for clearing D_PAGED may be a little too strict now;
the alternative would be to check all section RVAs and file positions
to match modulo COFF_PAGE_SIZE. One could think that it should be the
other way around (file positions _only_ be assigned to satisfy that
condition), but then there would be no way to request sections to be
arranged in this more space saving manner. (Note that if that
condition was adjusted, other changes made later in the function then
would also need further refinement.)

Quite likely the referenced commit should be follow by another change
suppressing also the reading of the section alignment bits when
processing a PE binary. This would similarly eliminate the oddity of
stripping a previously stripped binary altering that binary again.

--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -2962,7 +2962,7 @@ coff_compute_section_file_positions (bfd
 #endif
 
 #ifdef COFF_IMAGE_WITH_PE
-  int page_size;
+  unsigned int page_size;
 
   if (coff_data (abfd)->link_info
       || (pe_data (abfd) && pe_data (abfd)->pe_opthdr.FileAlignment))
@@ -2973,22 +2973,12 @@ coff_compute_section_file_positions (bfd
 	 This repairs 'ld -r' for arm-wince-pe target.  */
       if (page_size == 0)
 	page_size = 1;
-
-      /* PR 17512: file: 0ac816d3.  */
-      if (page_size < 0)
-	{
-	  bfd_set_error (bfd_error_file_too_big);
-	  _bfd_error_handler
-	    /* xgettext:c-format */
-	    (_("%pB: page size is too large (0x%x)"), abfd, page_size);
-	  return false;
-	}
     }
   else
     page_size = PE_DEF_FILE_ALIGNMENT;
 #else
 #ifdef COFF_PAGE_SIZE
-  int page_size = COFF_PAGE_SIZE;
+  unsigned int page_size = COFF_PAGE_SIZE;
 #endif
 #endif
 
@@ -3070,9 +3060,10 @@ coff_compute_section_file_positions (bfd
     bfd_size_type amt;
 
 #ifdef COFF_PAGE_SIZE
-    /* Clear D_PAGED if section alignment is smaller than
-       COFF_PAGE_SIZE.  */
-   if (pe_data (abfd)->pe_opthdr.SectionAlignment < COFF_PAGE_SIZE)
+    /* Clear D_PAGED if section / file alignment aren't suitable for
+       paging at COFF_PAGE_SIZE granularity.  */
+   if (pe_data (abfd)->pe_opthdr.SectionAlignment < COFF_PAGE_SIZE
+       || page_size < COFF_PAGE_SIZE)
      abfd->flags &= ~D_PAGED;
 #endif
 
@@ -3193,7 +3184,11 @@ coff_compute_section_file_positions (bfd
 	     padding the previous section up if necessary.  */
 	  old_sofar = sofar;
 
+#ifdef COFF_IMAGE_WITH_PE
+	  sofar = BFD_ALIGN (sofar, page_size);
+#else
 	  sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+#endif
 
 #ifdef RS6000COFF_C
 	  /* Make sure the file offset and the vma of .text/.data are at the
@@ -3269,7 +3264,11 @@ coff_compute_section_file_positions (bfd
       else
 	{
 	  old_sofar = sofar;
+#ifdef COFF_IMAGE_WITH_PE
+	  sofar = BFD_ALIGN (sofar, page_size);
+#else
 	  sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+#endif
 	  align_adjust = sofar != old_sofar;
 	  current->size += sofar - old_sofar;
 	}


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/5] COFF: make objcopy / strip honor --keep-file-symbols
  2022-05-06  6:53 [PATCH 0/5] PE/COFF: assorted adjustments Jan Beulich
  2022-05-06  6:54 ` [PATCH 1/5] don't over-align file positions of PE executable sections Jan Beulich
@ 2022-05-06  6:54 ` Jan Beulich
  2022-05-06  6:54 ` [PATCH 3/5] COFF/PE: don't leave zero timestamp after objcopy / strip Jan Beulich
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Jan Beulich @ 2022-05-06  6:54 UTC (permalink / raw)
  To: Binutils; +Cc: Dave Korn

So far this option had no effect when used together with e.g.
--strip-debug. Set BSF_FILE on these symbols to change that.

While altering this also join two adjacent blocks of case labeled
statements with identical code.

--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -4755,6 +4755,9 @@ coff_slurp_symbol_table (bfd * abfd)
 		dst->symbol.value = src->u.syment.n_value;
 	      break;
 
+	    case C_FILE:	/* File name.  */
+	      dst->symbol.flags = BSF_FILE;
+	      /* Fall through.  */
 	    case C_MOS:		/* Member of structure.  */
 	    case C_EOS:		/* End of structure.  */
 	    case C_REGPARM:	/* Register parameter.  */
@@ -4768,11 +4771,6 @@ coff_slurp_symbol_table (bfd * abfd)
 	    case C_MOE:		/* Member of enumeration.  */
 	    case C_MOU:		/* Member of union.  */
 	    case C_UNTAG:	/* Union tag.  */
-	      dst->symbol.flags = BSF_DEBUGGING;
-	      dst->symbol.value = (src->u.syment.n_value);
-	      break;
-
-	    case C_FILE:	/* File name.  */
 	    case C_STRTAG:	/* Structure tag.  */
 #ifdef RS6000COFF_C
 	    case C_GSYM:
@@ -4790,7 +4788,7 @@ coff_slurp_symbol_table (bfd * abfd)
 	    case C_FUN:
 	    case C_ESTAT:
 #endif
-	      dst->symbol.flags = BSF_DEBUGGING;
+	      dst->symbol.flags |= BSF_DEBUGGING;
 	      dst->symbol.value = (src->u.syment.n_value);
 	      break;
 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/5] COFF/PE: don't leave zero timestamp after objcopy / strip
  2022-05-06  6:53 [PATCH 0/5] PE/COFF: assorted adjustments Jan Beulich
  2022-05-06  6:54 ` [PATCH 1/5] don't over-align file positions of PE executable sections Jan Beulich
  2022-05-06  6:54 ` [PATCH 2/5] COFF: make objcopy / strip honor --keep-file-symbols Jan Beulich
@ 2022-05-06  6:54 ` Jan Beulich
  2022-05-06  6:55 ` [PATCH 4/5] COFF/PE: keep linker version during " Jan Beulich
  2022-05-06  6:55 ` [PATCH 5/5] COFF: use hash for string table also when copying / stripping Jan Beulich
  4 siblings, 0 replies; 6+ messages in thread
From: Jan Beulich @ 2022-05-06  6:54 UTC (permalink / raw)
  To: Binutils; +Cc: Dave Korn

Fill the timestamp field suitably for _bfd_XXi_only_swap_filehdr_out().
Instead of re-arranging the present if(), fold this logic with that of
copying the optional header.

--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -2747,7 +2747,14 @@ copy_object (bfd *ibfd, bfd *obfd, const
       /* Copy PE parameters before changing them.  */
       if (bfd_get_flavour (ibfd) == bfd_target_coff_flavour
 	  && bfd_pei_p (ibfd))
-	pe->pe_opthdr = pe_data (ibfd)->pe_opthdr;
+	{
+	  pe->pe_opthdr = pe_data (ibfd)->pe_opthdr;
+
+ 	  if (preserve_dates)
+	    pe->timestamp = pe_data (ibfd)->coff.timestamp;
+	  else
+	    pe->timestamp = -1;
+	}
 
       if (pe_file_alignment != (bfd_vma) -1)
 	pe->pe_opthdr.FileAlignment = pe_file_alignment;
@@ -2793,11 +2800,6 @@ copy_object (bfd *ibfd, bfd *obfd, const
 
 		     file_alignment, section_alignment);
 	}
-
-      if (preserve_dates
-	  && bfd_get_flavour (ibfd) == bfd_target_coff_flavour
-	  && bfd_pei_p (ibfd))
-	pe->timestamp = pe_data (ibfd)->coff.timestamp;
     }
 
   free (isympp);


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/5] COFF/PE: keep linker version during objcopy / strip
  2022-05-06  6:53 [PATCH 0/5] PE/COFF: assorted adjustments Jan Beulich
                   ` (2 preceding siblings ...)
  2022-05-06  6:54 ` [PATCH 3/5] COFF/PE: don't leave zero timestamp after objcopy / strip Jan Beulich
@ 2022-05-06  6:55 ` Jan Beulich
  2022-05-06  6:55 ` [PATCH 5/5] COFF: use hash for string table also when copying / stripping Jan Beulich
  4 siblings, 0 replies; 6+ messages in thread
From: Jan Beulich @ 2022-05-06  6:55 UTC (permalink / raw)
  To: Binutils; +Cc: Dave Korn

Neither of the tools is really a linker, so whatever was originally
recorded should be retained rather than being overwritten by these
tools' versions.

--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -736,13 +736,23 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, v
 
   H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
 
+  if (extra->MajorLinkerVersion || extra->MinorLinkerVersion)
+    {
+      H_PUT_8 (abfd, extra->MajorLinkerVersion,
+	       aouthdr_out->standard.vstamp);
+      H_PUT_8 (abfd, extra->MinorLinkerVersion,
+	       aouthdr_out->standard.vstamp + 1);
+    }
+  else
+    {
 /* e.g. 219510000 is linker version 2.19  */
 #define LINKER_VERSION ((short) (BFD_VERSION / 1000000))
 
-  /* This piece of magic sets the "linker version" field to
-     LINKER_VERSION.  */
-  H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
-	    aouthdr_out->standard.vstamp);
+      /* This piece of magic sets the "linker version" field to
+	 LINKER_VERSION.  */
+      H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
+		aouthdr_out->standard.vstamp);
+    }
 
   PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->standard.tsize);
   PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->standard.dsize);


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 5/5] COFF: use hash for string table also when copying / stripping
  2022-05-06  6:53 [PATCH 0/5] PE/COFF: assorted adjustments Jan Beulich
                   ` (3 preceding siblings ...)
  2022-05-06  6:55 ` [PATCH 4/5] COFF/PE: keep linker version during " Jan Beulich
@ 2022-05-06  6:55 ` Jan Beulich
  4 siblings, 0 replies; 6+ messages in thread
From: Jan Beulich @ 2022-05-06  6:55 UTC (permalink / raw)
  To: Binutils; +Cc: Dave Korn

Otherwise the string table may grow and hence e.g. change a final binary
(observed with PE/COFF ones) even if really there's no change. Doing so
in fact reduces the overall amount of code, and in particular the number
of places which need to remain in sync.

Afaics there's no real equivalent to the "traditional_format" field used
when linking, so hashing is always enabled when copying / stripping.

--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -847,11 +847,12 @@ coff_mangle_symbols (bfd *bfd_ptr)
     }
 }
 
-static void
+static bool
 coff_write_auxent_fname (bfd *abfd,
 			 char *str,
 			 union internal_auxent *auxent,
-			 bfd_size_type *string_size_p)
+			 struct bfd_strtab_hash *strtab,
+			 bool hash)
 {
   unsigned int str_length = strlen (str);
   unsigned int filnmlen = bfd_coff_filnmlen (abfd);
@@ -862,9 +863,13 @@ coff_write_auxent_fname (bfd *abfd,
 	strncpy (auxent->x_file.x_n.x_fname, str, filnmlen);
       else
 	{
-	  auxent->x_file.x_n.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE;
+	  bfd_size_type indx = _bfd_stringtab_add (strtab, str, hash, false);
+
+	  if (indx == (bfd_size_type) -1)
+	    return false;
+
+	  auxent->x_file.x_n.x_n.x_offset = STRING_SIZE_SIZE + indx;
 	  auxent->x_file.x_n.x_n.x_zeroes = 0;
-	  *string_size_p += str_length + 1;
 	}
     }
   else
@@ -873,18 +878,22 @@ coff_write_auxent_fname (bfd *abfd,
       if (str_length > filnmlen)
 	str[filnmlen] = '\0';
     }
+
+  return true;
 }
 
-static void
+static bool
 coff_fix_symbol_name (bfd *abfd,
 		      asymbol *symbol,
 		      combined_entry_type *native,
-		      bfd_size_type *string_size_p,
+		      struct bfd_strtab_hash *strtab,
+		      bool hash,
 		      asection **debug_string_section_p,
 		      bfd_size_type *debug_string_size_p)
 {
   unsigned int name_length;
   char *name = (char *) (symbol->name);
+  bfd_size_type indx;
 
   if (name == NULL)
     {
@@ -900,17 +909,20 @@ coff_fix_symbol_name (bfd *abfd,
     {
       if (bfd_coff_force_symnames_in_strings (abfd))
 	{
-	  native->u.syment._n._n_n._n_offset =
-	      (*string_size_p + STRING_SIZE_SIZE);
+	  indx = _bfd_stringtab_add (strtab, ".file", hash, false);
+	  if (indx == (bfd_size_type) -1)
+	    return false;
+
+	  native->u.syment._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
 	  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);
 
       BFD_ASSERT (! (native + 1)->is_sym);
-      coff_write_auxent_fname (abfd, name, &(native + 1)->u.auxent,
-			       string_size_p);
+      if (!coff_write_auxent_fname (abfd, name, &(native + 1)->u.auxent,
+			       strtab, hash))
+	return false;
     }
   else
     {
@@ -920,10 +932,12 @@ coff_fix_symbol_name (bfd *abfd,
 
       else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment))
 	{
-	  native->u.syment._n._n_n._n_offset = (*string_size_p
-						+ STRING_SIZE_SIZE);
+	  indx = _bfd_stringtab_add (strtab, name, hash, false);
+	  if (indx == (bfd_size_type) -1)
+	    return false;
+
+	  native->u.syment._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
 	  native->u.syment._n._n_n._n_zeroes = 0;
-	  *string_size_p += name_length + 1;
 	}
       else
 	{
@@ -964,6 +978,8 @@ coff_fix_symbol_name (bfd *abfd,
 	  *debug_string_size_p += name_length + 1 + prefix_len;
 	}
     }
+
+  return true;
 }
 
 /* We need to keep track of the symbol index so that when we write out
@@ -979,7 +995,8 @@ coff_write_symbol (bfd *abfd,
 		   asymbol *symbol,
 		   combined_entry_type *native,
 		   bfd_vma *written,
-		   bfd_size_type *string_size_p,
+		   struct bfd_strtab_hash *strtab,
+		   bool hash,
 		   asection **debug_string_section_p,
 		   bfd_size_type *debug_string_size_p)
 {
@@ -1011,8 +1028,9 @@ coff_write_symbol (bfd *abfd,
     native->u.syment.n_scnum =
       output_section->target_index;
 
-  coff_fix_symbol_name (abfd, symbol, native, string_size_p,
-			debug_string_section_p, debug_string_size_p);
+  if (!coff_fix_symbol_name (abfd, symbol, native, strtab, hash,
+			     debug_string_section_p, debug_string_size_p))
+    return false;
 
   symesz = bfd_coff_symesz (abfd);
   buf = bfd_alloc (abfd, symesz);
@@ -1041,7 +1059,7 @@ coff_write_symbol (bfd *abfd,
 	  if (native->u.syment.n_sclass == C_FILE
 	      && (native + j + 1)->u.auxent.x_file.x_ftype)
 	    coff_write_auxent_fname (abfd, (char *) (native + j + 1)->extrap,
-				     &(native + j + 1)->u.auxent, string_size_p);
+				     &(native + j + 1)->u.auxent, strtab, hash);
 
 	  bfd_coff_swap_aux_out (abfd,
 				 &((native + j + 1)->u.auxent),
@@ -1069,9 +1087,9 @@ bool
 coff_write_alien_symbol (bfd *abfd,
 			 asymbol *symbol,
 			 struct internal_syment *isym,
-			 union internal_auxent *iaux,
 			 bfd_vma *written,
-			 bfd_size_type *string_size_p,
+			 struct bfd_strtab_hash *strtab,
+			 bool hash,
 			 asection **debug_string_section_p,
 			 bfd_size_type *debug_string_size_p)
 {
@@ -1152,12 +1170,10 @@ coff_write_alien_symbol (bfd *abfd,
   else
     native->u.syment.n_sclass = C_EXT;
 
-  ret = coff_write_symbol (abfd, symbol, native, written, string_size_p,
+  ret = coff_write_symbol (abfd, symbol, native, written, strtab, hash,
 			   debug_string_section_p, debug_string_size_p);
   if (isym != NULL)
     *isym = native->u.syment;
-  if (iaux != NULL && native->u.syment.n_numaux)
-    *iaux = native[1].u.auxent;
   return ret;
 }
 
@@ -1167,7 +1183,7 @@ static bool
 coff_write_native_symbol (bfd *abfd,
 			  coff_symbol_type *symbol,
 			  bfd_vma *written,
-			  bfd_size_type *string_size_p,
+			  struct bfd_strtab_hash *strtab,
 			  asection **debug_string_section_p,
 			  bfd_size_type *debug_string_size_p)
 {
@@ -1217,7 +1233,7 @@ coff_write_native_symbol (bfd *abfd,
     }
 
   return coff_write_symbol (abfd, &(symbol->symbol), native, written,
-			    string_size_p, debug_string_section_p,
+			    strtab, true, debug_string_section_p,
 			    debug_string_size_p);
 }
 
@@ -1232,7 +1248,7 @@ null_error_handler (const char *fmt ATTR
 bool
 coff_write_symbols (bfd *abfd)
 {
-  bfd_size_type string_size;
+  struct bfd_strtab_hash *strtab;
   asection *debug_string_section;
   bfd_size_type debug_string_size;
   unsigned int i;
@@ -1240,26 +1256,26 @@ coff_write_symbols (bfd *abfd)
   bfd_vma written = 0;
   asymbol **p;
 
-  string_size = 0;
   debug_string_section = NULL;
   debug_string_size = 0;
 
+  strtab = _bfd_stringtab_init ();
+  if (strtab == NULL)
+    return false;
+
   /* If this target supports long section names, they must be put into
      the string table.  This is supported by PE.  This code must
      handle section names just as they are handled in
-     coff_write_object_contents.  */
+     coff_write_object_contents.  This is why we pass hash as FALSE below.  */
   if (bfd_coff_long_section_names (abfd))
     {
       asection *o;
 
       for (o = abfd->sections; o != NULL; o = o->next)
-	{
-	  size_t len;
-
-	  len = strlen (o->name);
-	  if (len > SCNNMLEN)
-	    string_size += len + 1;
-	}
+	if (strlen (o->name) > SCNNMLEN
+	    && _bfd_stringtab_add (strtab, o->name, false, false)
+	       == (bfd_size_type) -1)
+	  return false;
     }
 
   /* Seek to the right place.  */
@@ -1276,8 +1292,8 @@ coff_write_symbols (bfd *abfd)
       if (c_symbol == (coff_symbol_type *) NULL
 	  || c_symbol->native == (combined_entry_type *) NULL)
 	{
-	  if (!coff_write_alien_symbol (abfd, symbol, NULL, NULL, &written,
-					&string_size, &debug_string_section,
+	  if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,
+					strtab, true, &debug_string_section,
 					&debug_string_size))
 	    return false;
 	}
@@ -1322,7 +1338,7 @@ coff_write_symbols (bfd *abfd)
 	    }
 
 	  if (!coff_write_native_symbol (abfd, c_symbol, &written,
-					 &string_size, &debug_string_section,
+					 strtab, &debug_string_section,
 					 &debug_string_size))
 	    return false;
 	}
@@ -1330,141 +1346,28 @@ coff_write_symbols (bfd *abfd)
 
   obj_raw_syment_count (abfd) = written;
 
-  /* Now write out strings.  */
-  if (string_size != 0)
-    {
-      unsigned int size = string_size + STRING_SIZE_SIZE;
-      bfd_byte buffer[STRING_SIZE_SIZE];
+  /* Now write out strings.
+
+     We would normally not write anything here if there are no strings, 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.  */
+  {
+    bfd_byte buffer[STRING_SIZE_SIZE];
 
 #if STRING_SIZE_SIZE == 4
-      H_PUT_32 (abfd, size, buffer);
+    H_PUT_32 (abfd, _bfd_stringtab_size (strtab) + STRING_SIZE_SIZE, buffer);
 #else
  #error Change H_PUT_32
 #endif
-      if (bfd_bwrite ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd)
-	  != sizeof (buffer))
-	return false;
-
-      /* Handle long section names.  This code must handle section
-	 names just as they are handled in coff_write_object_contents.  */
-      if (bfd_coff_long_section_names (abfd))
-	{
-	  asection *o;
-
-	  for (o = abfd->sections; o != NULL; o = o->next)
-	    {
-	      size_t len;
-
-	      len = strlen (o->name);
-	      if (len > SCNNMLEN)
-		{
-		  if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd)
-		      != len + 1)
-		    return false;
-		}
-	    }
-	}
-
-      for (p = abfd->outsymbols, i = 0;
-	   i < limit;
-	   i++, p++)
-	{
-	  asymbol *q = *p;
-	  size_t name_length = strlen (q->name);
-	  coff_symbol_type *c_symbol = coff_symbol_from (q);
-	  size_t maxlen;
-	  bool is_c_file = false;
-
-	  /* Figure out whether the symbol name should go in the string
-	     table.  Symbol names that are short enough are stored
-	     directly in the syment structure.  File names permit a
-	     different, longer, length in the syment structure.  On
-	     XCOFF, some symbol names are stored in the .debug section
-	     rather than in the string table.  */
-
-	  if (c_symbol == NULL
-	      || c_symbol->native == NULL)
-	    /* This is not a COFF symbol, so it certainly is not a
-	       file name, nor does it go in the .debug section.  */
-	    maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
-
-	  else if (! c_symbol->native->is_sym)
-	    maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
-
-	  else if (bfd_coff_symname_in_debug (abfd,
-					      &c_symbol->native->u.syment))
-	    /* This symbol name is in the XCOFF .debug section.
-	       Don't write it into the string table.  */
-	    maxlen = name_length;
-
-	  else if (c_symbol->native->u.syment.n_sclass == C_FILE
-		   && c_symbol->native->u.syment.n_numaux > 0)
-	    {
-	      is_c_file=true;
-	      if (bfd_coff_force_symnames_in_strings (abfd))
-		{
-		  if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
-		    return false;
-		}
-	      maxlen = bfd_coff_filnmlen (abfd);
-	    }
-	  else
-	    maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
-
-	  if (name_length > maxlen)
-	    {
-	      if (bfd_bwrite ((void *) (q->name), (bfd_size_type) name_length + 1,
-			     abfd) != name_length + 1)
-		return false;
-	    }
-
-	  /* Add strings for C_FILE aux entries. */
-	  if (is_c_file
-	      && c_symbol->native->u.syment.n_numaux > 1)
-	    {
-	      for (int j = 1; j < c_symbol->native->u.syment.n_numaux; j++)
-		{
-		  char *str;
-		  size_t str_length;
-
-		  /* Add strings from aux entries only if this isn't the
-		     filename auxiliary entry.  */
-		  if (!c_symbol->native[j + 1].u.auxent.x_file.x_ftype)
-		    continue;
-
-		  if (c_symbol->native[j + 1].u.auxent.x_file.x_n.x_fname[0] != 0)
-		    continue;
-
-		  str = (char *) c_symbol->native[j + 1].extrap;
-		  str_length = strlen (str);
-		  if (str_length > maxlen)
-		    {
-		      if (bfd_bwrite ((void *) (str), (bfd_size_type) str_length + 1,
-				      abfd) != str_length + 1)
-			return false;
-		    }
+    if (bfd_bwrite ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd)
+	!= sizeof (buffer))
+      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.  */
-      unsigned int size = STRING_SIZE_SIZE;
-      bfd_byte buffer[STRING_SIZE_SIZE];
+    if (! _bfd_stringtab_emit (abfd, strtab))
+      return false;
+  }
 
-#if STRING_SIZE_SIZE == 4
-      H_PUT_32 (abfd, size, buffer);
-#else
- #error Change H_PUT_32
-#endif
-      if (bfd_bwrite ((void *) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd)
-	  != STRING_SIZE_SIZE)
-	return false;
-    }
+  _bfd_stringtab_free (strtab);
 
   /* Make sure the .debug section was created to be the correct size.
      We should create it ourselves on the fly, but we don't because
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -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)
--- a/bfd/libcoff-in.h
+++ b/bfd/libcoff-in.h
@@ -329,8 +329,8 @@ extern void coff_mangle_symbols
 extern bool coff_write_symbols
   (bfd *);
 extern bool coff_write_alien_symbol
-  (bfd *, asymbol *, struct internal_syment *, union internal_auxent *,
-   bfd_vma *, bfd_size_type *, asection **, bfd_size_type *);
+  (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+   struct bfd_strtab_hash *, bool, asection **, bfd_size_type *);
 extern bool coff_write_linenumbers
   (bfd *);
 extern alent *coff_get_lineno
--- a/bfd/libcoff.h
+++ b/bfd/libcoff.h
@@ -329,8 +329,8 @@ extern void coff_mangle_symbols
 extern bool coff_write_symbols
   (bfd *);
 extern bool coff_write_alien_symbol
-  (bfd *, asymbol *, struct internal_syment *, union internal_auxent *,
-   bfd_vma *, bfd_size_type *, asection **, bfd_size_type *);
+  (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+   struct bfd_strtab_hash *, bool, asection **, bfd_size_type *);
 extern bool coff_write_linenumbers
   (bfd *);
 extern alent *coff_get_lineno


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-05-06  6:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-06  6:53 [PATCH 0/5] PE/COFF: assorted adjustments Jan Beulich
2022-05-06  6:54 ` [PATCH 1/5] don't over-align file positions of PE executable sections Jan Beulich
2022-05-06  6:54 ` [PATCH 2/5] COFF: make objcopy / strip honor --keep-file-symbols Jan Beulich
2022-05-06  6:54 ` [PATCH 3/5] COFF/PE: don't leave zero timestamp after objcopy / strip Jan Beulich
2022-05-06  6:55 ` [PATCH 4/5] COFF/PE: keep linker version during " Jan Beulich
2022-05-06  6:55 ` [PATCH 5/5] COFF: use hash for string table also when copying / stripping Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).