public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] COFF/PE: insert local symbols from foreign input  objects into output executable
@ 2011-09-28 12:01 Jan Beulich
  2011-10-11  6:48 ` Ping: " Jan Beulich
  2011-10-25  9:02 ` Nick Clifton
  0 siblings, 2 replies; 4+ messages in thread
From: Jan Beulich @ 2011-09-28 12:01 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 8746 bytes --]

Building EFI binaries, particularly larger ones (like e.g. Xen does), on Linux
(where relocatable objects are in ELF format) so far led to all local (aka
static) symbols to be discarded, making debugging quite a bit more difficult
(like Linux, Xen builds an internal symbol lookup table from nm output
generated on the binary produced by an earlier linking pass). Therefore, this
patch arranges to insert all (relevant) local symbols from non-COFF objects
into the final executable's symbol table between those coming from COFF input
files and the global ones.

bfd/
2011-09-28  Jan Beulich  <jbeulich@suse.com>

	* coffgen.c (coff_write_alien_symbol): Make public. Add 'struct
	internal_syment *' parameter. Extend 'dummy' to an array with two
	elements. Set n_numaux early. Handle BSF_FILE.
	(coff_write_symbols): Pass NULL as new third argument to
	coff_write_alien_symbol().
	* cofflink.c (_bfd_coff_final_link): Don't use COFF-specific
	obj_raw_syment_count() on non-COFF input BFD. Insert local symbols
	from non-COFF input BFDs.
	* libcoff-in.h (coff_write_alien_symbol): Declare.
	* libcoff.h (coff_write_alien_symbol): Re-generate.

--- 2011-09-28/bfd/coffgen.c	2011-09-16 08:37:33.000000000 +0200
+++ 2011-09-28/bfd/coffgen.c	2011-09-28 12:01:54.000000000 +0200
@@ -983,23 +983,26 @@ coff_write_symbol (bfd *abfd,
    file originally.  This symbol may have been created by the linker,
    or we may be linking a non COFF file to a COFF file.  */
 
-static bfd_boolean
+bfd_boolean
 coff_write_alien_symbol (bfd *abfd,
 			 asymbol *symbol,
+			 struct internal_syment *isym,
 			 bfd_vma *written,
 			 bfd_size_type *string_size_p,
 			 asection **debug_string_section_p,
 			 bfd_size_type *debug_string_size_p)
 {
   combined_entry_type *native;
-  combined_entry_type dummy;
+  combined_entry_type dummy[2];
   asection *output_section = symbol->section->output_section
 			       ? symbol->section->output_section
 			       : symbol->section;
+  bfd_boolean ret;
 
-  native = &dummy;
+  native = dummy;
   native->u.syment.n_type = T_NULL;
   native->u.syment.n_flags = 0;
+  native->u.syment.n_numaux = 0;
   if (bfd_is_und_section (symbol->section))
     {
       native->u.syment.n_scnum = N_UNDEF;
@@ -1010,6 +1013,11 @@ coff_write_alien_symbol (bfd *abfd,
       native->u.syment.n_scnum = N_UNDEF;
       native->u.syment.n_value = symbol->value;
     }
+  else if (symbol->flags & BSF_FILE)
+    {
+      native->u.syment.n_scnum = N_DEBUG;
+      native->u.syment.n_numaux = 1;
+    }
   else if (symbol->flags & BSF_DEBUGGING)
     {
       /* There isn't much point to writing out a debugging symbol
@@ -1017,6 +1025,8 @@ coff_write_alien_symbol (bfd *abfd,
          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;
     }
   else
@@ -1037,16 +1047,20 @@ coff_write_alien_symbol (bfd *abfd,
     }
 
   native->u.syment.n_type = 0;
-  if (symbol->flags & BSF_LOCAL)
+  if (symbol->flags & BSF_FILE)
+    native->u.syment.n_sclass = C_FILE;
+  else if (symbol->flags & BSF_LOCAL)
     native->u.syment.n_sclass = C_STAT;
   else if (symbol->flags & BSF_WEAK)
     native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
   else
     native->u.syment.n_sclass = C_EXT;
-  native->u.syment.n_numaux = 0;
 
-  return coff_write_symbol (abfd, symbol, native, written, string_size_p,
-			    debug_string_section_p, debug_string_size_p);
+  ret = coff_write_symbol (abfd, symbol, native, written, string_size_p,
+			   debug_string_section_p, debug_string_size_p);
+  if (isym != NULL)
+    *isym = native->u.syment;
+  return ret;
 }
 
 /* Write a native symbol to a COFF file.  */
@@ -1153,8 +1167,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, &written, &string_size,
-					&debug_string_section,
+	  if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,
+					&string_size, &debug_string_section,
 					&debug_string_size))
 	    return FALSE;
 	}
--- 2011-09-28/bfd/cofflink.c	2011-09-16 08:37:33.000000000 +0200
+++ 2011-09-28/bfd/cofflink.c	2011-09-28 12:01:54.000000000 +0200
@@ -866,7 +866,7 @@ _bfd_coff_final_link (bfd *abfd,
       size_t sz;
 
       sub->output_has_begun = FALSE;
-      sz = obj_raw_syment_count (sub);
+      sz = bfd_family_coff (sub) ? obj_raw_syment_count (sub) : 2;
       if (sz > max_sym_count)
 	max_sym_count = sz;
     }
@@ -943,6 +943,92 @@ _bfd_coff_final_link (bfd *abfd,
 	}
     }
 
+  if (finfo.info->strip != strip_all && finfo.info->discard != discard_all)
+    {
+      /* Add local symbols from foreign inputs.  */
+      for(sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+	{
+	  unsigned int i;
+
+	  if (bfd_family_coff (sub) || ! bfd_get_outsymbols (sub))
+	    continue;
+	  for (i = 0; i < bfd_get_symcount (sub); ++i)
+	    {
+	      asymbol *sym = bfd_get_outsymbols (sub) [i];
+	      file_ptr pos;
+	      struct internal_syment isym;
+	      bfd_size_type string_size = 0;
+	      bfd_vma written = 0;
+	      bfd_boolean rewrite = FALSE;
+
+	      if (! (sym->flags & BSF_LOCAL)
+		  || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
+				    | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
+				    | BSF_SYNTHETIC))
+		  || ((sym->flags & BSF_DEBUGGING)
+		      && ! (sym->flags & BSF_FILE)))
+		continue;
+
+	      /* See if we are discarding symbols with this name.  */
+	      if ((finfo.info->strip == strip_some
+		   && (bfd_hash_lookup (finfo.info->keep_hash,
+					bfd_asymbol_name(sym), FALSE, FALSE)
+		       == NULL))
+		  || (((finfo.info->discard == discard_sec_merge
+			&& (bfd_get_section (sym)->flags & SEC_MERGE)
+			&& ! finfo.info->relocatable)
+		       || finfo.info->discard == discard_l)
+		      && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
+		continue;
+
+	      pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd)
+					     * symesz;
+	      if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+		goto error_return;
+	      if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
+					    &string_size, NULL, NULL))
+		goto error_return;
+
+	      if (string_size)
+		{
+		  bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT);
+		  bfd_size_type indx;
+
+		  indx = _bfd_stringtab_add (finfo.strtab,
+					     bfd_asymbol_name (sym), 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, finfo.outsyms);
+		  rewrite = TRUE;
+		}
+
+	      if (isym.n_sclass == C_FILE)
+		{
+		  if (finfo.last_file_index != -1)
+		    {
+		      finfo.last_file.n_value = obj_raw_syment_count (abfd);
+		      bfd_coff_swap_sym_out (abfd, &finfo.last_file,
+					     finfo.outsyms);
+		      pos = obj_sym_filepos (abfd) + finfo.last_file_index
+						     * symesz;
+		      rewrite = TRUE;
+		    }
+		  finfo.last_file_index = obj_raw_syment_count (abfd);
+		  finfo.last_file = isym;
+		}
+
+	      if (rewrite
+		  && (bfd_seek (abfd, pos, SEEK_SET) != 0
+		      || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz))
+		goto error_return;
+
+	      obj_raw_syment_count (abfd) += written;
+	    }
+	}
+    }
+
   if (! bfd_coff_final_link_postscript (abfd, & finfo))
     goto error_return;
 
--- 2011-09-28/bfd/libcoff-in.h	2011-09-16 08:37:39.000000000 +0200
+++ 2011-09-28/bfd/libcoff-in.h	2011-09-28 12:01:54.000000000 +0200
@@ -318,6 +318,9 @@ extern void coff_mangle_symbols
   (bfd *);
 extern bfd_boolean coff_write_symbols
   (bfd *);
+extern bfd_boolean coff_write_alien_symbol
+  (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+   bfd_size_type *, asection **, bfd_size_type *);
 extern bfd_boolean coff_write_linenumbers
   (bfd *);
 extern alent *coff_get_lineno
--- 2011-09-28/bfd/libcoff.h	2011-09-16 08:37:39.000000000 +0200
+++ 2011-09-28/bfd/libcoff.h	2011-09-28 12:01:54.000000000 +0200
@@ -322,6 +322,9 @@ extern void coff_mangle_symbols
   (bfd *);
 extern bfd_boolean coff_write_symbols
   (bfd *);
+extern bfd_boolean coff_write_alien_symbol
+  (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+   bfd_size_type *, asection **, bfd_size_type *);
 extern bfd_boolean coff_write_linenumbers
   (bfd *);
 extern alent *coff_get_lineno



[-- Attachment #2: binutils-mainline-COFF-foreign-symbols.patch --]
[-- Type: text/plain, Size: 8742 bytes --]

Building EFI binaries, particularly larger ones (like e.g. Xen does), on Linux
(where relocatable objects are in ELF format) so far led to all local (aka
static) symbols to be discarded, making debugging quite a bit more difficult
(like Linux, Xen builds an internal symbol lookup table from nm output
generated on the binary produced by an earlier linking pass). Therefore, this
patch arranges to insert all (relevant) local symbols from non-COFF objects
into the final executable's symbol table between those coming from COFF input
files and the global ones.

bfd/
2011-09-28  Jan Beulich  <jbeulich@suse.com>

	* coffgen.c (coff_write_alien_symbol): Make public. Add 'struct
	internal_syment *' parameter. Extend 'dummy' to an array with two
	elements. Set n_numaux early. Handle BSF_FILE.
	(coff_write_symbols): Pass NULL as new third argument to
	coff_write_alien_symbol().
	* cofflink.c (_bfd_coff_final_link): Don't use COFF-specific
	obj_raw_syment_count() on non-COFF input BFD. Insert local symbols
	from non-COFF input BFDs.
	* libcoff-in.h (coff_write_alien_symbol): Declare.
	* libcoff.h (coff_write_alien_symbol): Re-generate.

--- 2011-09-28/bfd/coffgen.c	2011-09-16 08:37:33.000000000 +0200
+++ 2011-09-28/bfd/coffgen.c	2011-09-28 12:01:54.000000000 +0200
@@ -983,23 +983,26 @@ coff_write_symbol (bfd *abfd,
    file originally.  This symbol may have been created by the linker,
    or we may be linking a non COFF file to a COFF file.  */
 
-static bfd_boolean
+bfd_boolean
 coff_write_alien_symbol (bfd *abfd,
 			 asymbol *symbol,
+			 struct internal_syment *isym,
 			 bfd_vma *written,
 			 bfd_size_type *string_size_p,
 			 asection **debug_string_section_p,
 			 bfd_size_type *debug_string_size_p)
 {
   combined_entry_type *native;
-  combined_entry_type dummy;
+  combined_entry_type dummy[2];
   asection *output_section = symbol->section->output_section
 			       ? symbol->section->output_section
 			       : symbol->section;
+  bfd_boolean ret;
 
-  native = &dummy;
+  native = dummy;
   native->u.syment.n_type = T_NULL;
   native->u.syment.n_flags = 0;
+  native->u.syment.n_numaux = 0;
   if (bfd_is_und_section (symbol->section))
     {
       native->u.syment.n_scnum = N_UNDEF;
@@ -1010,6 +1013,11 @@ coff_write_alien_symbol (bfd *abfd,
       native->u.syment.n_scnum = N_UNDEF;
       native->u.syment.n_value = symbol->value;
     }
+  else if (symbol->flags & BSF_FILE)
+    {
+      native->u.syment.n_scnum = N_DEBUG;
+      native->u.syment.n_numaux = 1;
+    }
   else if (symbol->flags & BSF_DEBUGGING)
     {
       /* There isn't much point to writing out a debugging symbol
@@ -1017,6 +1025,8 @@ coff_write_alien_symbol (bfd *abfd,
          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;
     }
   else
@@ -1037,16 +1047,20 @@ coff_write_alien_symbol (bfd *abfd,
     }
 
   native->u.syment.n_type = 0;
-  if (symbol->flags & BSF_LOCAL)
+  if (symbol->flags & BSF_FILE)
+    native->u.syment.n_sclass = C_FILE;
+  else if (symbol->flags & BSF_LOCAL)
     native->u.syment.n_sclass = C_STAT;
   else if (symbol->flags & BSF_WEAK)
     native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
   else
     native->u.syment.n_sclass = C_EXT;
-  native->u.syment.n_numaux = 0;
 
-  return coff_write_symbol (abfd, symbol, native, written, string_size_p,
-			    debug_string_section_p, debug_string_size_p);
+  ret = coff_write_symbol (abfd, symbol, native, written, string_size_p,
+			   debug_string_section_p, debug_string_size_p);
+  if (isym != NULL)
+    *isym = native->u.syment;
+  return ret;
 }
 
 /* Write a native symbol to a COFF file.  */
@@ -1153,8 +1167,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, &written, &string_size,
-					&debug_string_section,
+	  if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,
+					&string_size, &debug_string_section,
 					&debug_string_size))
 	    return FALSE;
 	}
--- 2011-09-28/bfd/cofflink.c	2011-09-16 08:37:33.000000000 +0200
+++ 2011-09-28/bfd/cofflink.c	2011-09-28 12:01:54.000000000 +0200
@@ -866,7 +866,7 @@ _bfd_coff_final_link (bfd *abfd,
       size_t sz;
 
       sub->output_has_begun = FALSE;
-      sz = obj_raw_syment_count (sub);
+      sz = bfd_family_coff (sub) ? obj_raw_syment_count (sub) : 2;
       if (sz > max_sym_count)
 	max_sym_count = sz;
     }
@@ -943,6 +943,92 @@ _bfd_coff_final_link (bfd *abfd,
 	}
     }
 
+  if (finfo.info->strip != strip_all && finfo.info->discard != discard_all)
+    {
+      /* Add local symbols from foreign inputs.  */
+      for(sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+	{
+	  unsigned int i;
+
+	  if (bfd_family_coff (sub) || ! bfd_get_outsymbols (sub))
+	    continue;
+	  for (i = 0; i < bfd_get_symcount (sub); ++i)
+	    {
+	      asymbol *sym = bfd_get_outsymbols (sub) [i];
+	      file_ptr pos;
+	      struct internal_syment isym;
+	      bfd_size_type string_size = 0;
+	      bfd_vma written = 0;
+	      bfd_boolean rewrite = FALSE;
+
+	      if (! (sym->flags & BSF_LOCAL)
+		  || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
+				    | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
+				    | BSF_SYNTHETIC))
+		  || ((sym->flags & BSF_DEBUGGING)
+		      && ! (sym->flags & BSF_FILE)))
+		continue;
+
+	      /* See if we are discarding symbols with this name.  */
+	      if ((finfo.info->strip == strip_some
+		   && (bfd_hash_lookup (finfo.info->keep_hash,
+					bfd_asymbol_name(sym), FALSE, FALSE)
+		       == NULL))
+		  || (((finfo.info->discard == discard_sec_merge
+			&& (bfd_get_section (sym)->flags & SEC_MERGE)
+			&& ! finfo.info->relocatable)
+		       || finfo.info->discard == discard_l)
+		      && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
+		continue;
+
+	      pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd)
+					     * symesz;
+	      if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+		goto error_return;
+	      if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
+					    &string_size, NULL, NULL))
+		goto error_return;
+
+	      if (string_size)
+		{
+		  bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT);
+		  bfd_size_type indx;
+
+		  indx = _bfd_stringtab_add (finfo.strtab,
+					     bfd_asymbol_name (sym), 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, finfo.outsyms);
+		  rewrite = TRUE;
+		}
+
+	      if (isym.n_sclass == C_FILE)
+		{
+		  if (finfo.last_file_index != -1)
+		    {
+		      finfo.last_file.n_value = obj_raw_syment_count (abfd);
+		      bfd_coff_swap_sym_out (abfd, &finfo.last_file,
+					     finfo.outsyms);
+		      pos = obj_sym_filepos (abfd) + finfo.last_file_index
+						     * symesz;
+		      rewrite = TRUE;
+		    }
+		  finfo.last_file_index = obj_raw_syment_count (abfd);
+		  finfo.last_file = isym;
+		}
+
+	      if (rewrite
+		  && (bfd_seek (abfd, pos, SEEK_SET) != 0
+		      || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz))
+		goto error_return;
+
+	      obj_raw_syment_count (abfd) += written;
+	    }
+	}
+    }
+
   if (! bfd_coff_final_link_postscript (abfd, & finfo))
     goto error_return;
 
--- 2011-09-28/bfd/libcoff-in.h	2011-09-16 08:37:39.000000000 +0200
+++ 2011-09-28/bfd/libcoff-in.h	2011-09-28 12:01:54.000000000 +0200
@@ -318,6 +318,9 @@ extern void coff_mangle_symbols
   (bfd *);
 extern bfd_boolean coff_write_symbols
   (bfd *);
+extern bfd_boolean coff_write_alien_symbol
+  (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+   bfd_size_type *, asection **, bfd_size_type *);
 extern bfd_boolean coff_write_linenumbers
   (bfd *);
 extern alent *coff_get_lineno
--- 2011-09-28/bfd/libcoff.h	2011-09-16 08:37:39.000000000 +0200
+++ 2011-09-28/bfd/libcoff.h	2011-09-28 12:01:54.000000000 +0200
@@ -322,6 +322,9 @@ extern void coff_mangle_symbols
   (bfd *);
 extern bfd_boolean coff_write_symbols
   (bfd *);
+extern bfd_boolean coff_write_alien_symbol
+  (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+   bfd_size_type *, asection **, bfd_size_type *);
 extern bfd_boolean coff_write_linenumbers
   (bfd *);
 extern alent *coff_get_lineno

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

* Ping: [PATCH] COFF/PE: insert local symbols from foreign input  objects into output executable
  2011-09-28 12:01 [PATCH] COFF/PE: insert local symbols from foreign input objects into output executable Jan Beulich
@ 2011-10-11  6:48 ` Jan Beulich
  2011-10-25  9:02 ` Nick Clifton
  1 sibling, 0 replies; 4+ messages in thread
From: Jan Beulich @ 2011-10-11  6:48 UTC (permalink / raw)
  To: dave.korn.cygwin, dj; +Cc: binutils

There are no arch-independent PE/COFF maintainers listed, so you being
the ix86 ones are getting closest.

Thanks, Jan

>>> On 28.09.11 at 14:00, "Jan Beulich" <JBeulich@suse.com> wrote:
> Building EFI binaries, particularly larger ones (like e.g. Xen does), on 
> Linux
> (where relocatable objects are in ELF format) so far led to all local (aka
> static) symbols to be discarded, making debugging quite a bit more difficult
> (like Linux, Xen builds an internal symbol lookup table from nm output
> generated on the binary produced by an earlier linking pass). Therefore, 
> this
> patch arranges to insert all (relevant) local symbols from non-COFF objects
> into the final executable's symbol table between those coming from COFF 
> input
> files and the global ones.
> 
> bfd/
> 2011-09-28  Jan Beulich  <jbeulich@suse.com>
> 
> 	* coffgen.c (coff_write_alien_symbol): Make public. Add 'struct
> 	internal_syment *' parameter. Extend 'dummy' to an array with two
> 	elements. Set n_numaux early. Handle BSF_FILE.
> 	(coff_write_symbols): Pass NULL as new third argument to
> 	coff_write_alien_symbol().
> 	* cofflink.c (_bfd_coff_final_link): Don't use COFF-specific
> 	obj_raw_syment_count() on non-COFF input BFD. Insert local symbols
> 	from non-COFF input BFDs.
> 	* libcoff-in.h (coff_write_alien_symbol): Declare.
> 	* libcoff.h (coff_write_alien_symbol): Re-generate.
> 
> --- 2011-09-28/bfd/coffgen.c	2011-09-16 08:37:33.000000000 +0200
> +++ 2011-09-28/bfd/coffgen.c	2011-09-28 12:01:54.000000000 +0200
> @@ -983,23 +983,26 @@ coff_write_symbol (bfd *abfd,
>     file originally.  This symbol may have been created by the linker,
>     or we may be linking a non COFF file to a COFF file.  */
>  
> -static bfd_boolean
> +bfd_boolean
>  coff_write_alien_symbol (bfd *abfd,
>  			 asymbol *symbol,
> +			 struct internal_syment *isym,
>  			 bfd_vma *written,
>  			 bfd_size_type *string_size_p,
>  			 asection **debug_string_section_p,
>  			 bfd_size_type *debug_string_size_p)
>  {
>    combined_entry_type *native;
> -  combined_entry_type dummy;
> +  combined_entry_type dummy[2];
>    asection *output_section = symbol->section->output_section
>  			       ? symbol->section->output_section
>  			       : symbol->section;
> +  bfd_boolean ret;
>  
> -  native = &dummy;
> +  native = dummy;
>    native->u.syment.n_type = T_NULL;
>    native->u.syment.n_flags = 0;
> +  native->u.syment.n_numaux = 0;
>    if (bfd_is_und_section (symbol->section))
>      {
>        native->u.syment.n_scnum = N_UNDEF;
> @@ -1010,6 +1013,11 @@ coff_write_alien_symbol (bfd *abfd,
>        native->u.syment.n_scnum = N_UNDEF;
>        native->u.syment.n_value = symbol->value;
>      }
> +  else if (symbol->flags & BSF_FILE)
> +    {
> +      native->u.syment.n_scnum = N_DEBUG;
> +      native->u.syment.n_numaux = 1;
> +    }
>    else if (symbol->flags & BSF_DEBUGGING)
>      {
>        /* There isn't much point to writing out a debugging symbol
> @@ -1017,6 +1025,8 @@ coff_write_alien_symbol (bfd *abfd,
>           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;
>      }
>    else
> @@ -1037,16 +1047,20 @@ coff_write_alien_symbol (bfd *abfd,
>      }
>  
>    native->u.syment.n_type = 0;
> -  if (symbol->flags & BSF_LOCAL)
> +  if (symbol->flags & BSF_FILE)
> +    native->u.syment.n_sclass = C_FILE;
> +  else if (symbol->flags & BSF_LOCAL)
>      native->u.syment.n_sclass = C_STAT;
>    else if (symbol->flags & BSF_WEAK)
>      native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
>    else
>      native->u.syment.n_sclass = C_EXT;
> -  native->u.syment.n_numaux = 0;
>  
> -  return coff_write_symbol (abfd, symbol, native, written, string_size_p,
> -			    debug_string_section_p, debug_string_size_p);
> +  ret = coff_write_symbol (abfd, symbol, native, written, string_size_p,
> +			   debug_string_section_p, debug_string_size_p);
> +  if (isym != NULL)
> +    *isym = native->u.syment;
> +  return ret;
>  }
>  
>  /* Write a native symbol to a COFF file.  */
> @@ -1153,8 +1167,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, &written, &string_size,
> -					&debug_string_section,
> +	  if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,
> +					&string_size, &debug_string_section,
>  					&debug_string_size))
>  	    return FALSE;
>  	}
> --- 2011-09-28/bfd/cofflink.c	2011-09-16 08:37:33.000000000 +0200
> +++ 2011-09-28/bfd/cofflink.c	2011-09-28 12:01:54.000000000 +0200
> @@ -866,7 +866,7 @@ _bfd_coff_final_link (bfd *abfd,
>        size_t sz;
>  
>        sub->output_has_begun = FALSE;
> -      sz = obj_raw_syment_count (sub);
> +      sz = bfd_family_coff (sub) ? obj_raw_syment_count (sub) : 2;
>        if (sz > max_sym_count)
>  	max_sym_count = sz;
>      }
> @@ -943,6 +943,92 @@ _bfd_coff_final_link (bfd *abfd,
>  	}
>      }
>  
> +  if (finfo.info->strip != strip_all && finfo.info->discard != discard_all)
> +    {
> +      /* Add local symbols from foreign inputs.  */
> +      for(sub = info->input_bfds; sub != NULL; sub = sub->link_next)
> +	{
> +	  unsigned int i;
> +
> +	  if (bfd_family_coff (sub) || ! bfd_get_outsymbols (sub))
> +	    continue;
> +	  for (i = 0; i < bfd_get_symcount (sub); ++i)
> +	    {
> +	      asymbol *sym = bfd_get_outsymbols (sub) [i];
> +	      file_ptr pos;
> +	      struct internal_syment isym;
> +	      bfd_size_type string_size = 0;
> +	      bfd_vma written = 0;
> +	      bfd_boolean rewrite = FALSE;
> +
> +	      if (! (sym->flags & BSF_LOCAL)
> +		  || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
> +				    | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
> +				    | BSF_SYNTHETIC))
> +		  || ((sym->flags & BSF_DEBUGGING)
> +		      && ! (sym->flags & BSF_FILE)))
> +		continue;
> +
> +	      /* See if we are discarding symbols with this name.  */
> +	      if ((finfo.info->strip == strip_some
> +		   && (bfd_hash_lookup (finfo.info->keep_hash,
> +					bfd_asymbol_name(sym), FALSE, FALSE)
> +		       == NULL))
> +		  || (((finfo.info->discard == discard_sec_merge
> +			&& (bfd_get_section (sym)->flags & SEC_MERGE)
> +			&& ! finfo.info->relocatable)
> +		       || finfo.info->discard == discard_l)
> +		      && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
> +		continue;
> +
> +	      pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd)
> +					     * symesz;
> +	      if (bfd_seek (abfd, pos, SEEK_SET) != 0)
> +		goto error_return;
> +	      if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
> +					    &string_size, NULL, NULL))
> +		goto error_return;
> +
> +	      if (string_size)
> +		{
> +		  bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT);
> +		  bfd_size_type indx;
> +
> +		  indx = _bfd_stringtab_add (finfo.strtab,
> +					     bfd_asymbol_name (sym), 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, finfo.outsyms);
> +		  rewrite = TRUE;
> +		}
> +
> +	      if (isym.n_sclass == C_FILE)
> +		{
> +		  if (finfo.last_file_index != -1)
> +		    {
> +		      finfo.last_file.n_value = obj_raw_syment_count (abfd);
> +		      bfd_coff_swap_sym_out (abfd, &finfo.last_file,
> +					     finfo.outsyms);
> +		      pos = obj_sym_filepos (abfd) + finfo.last_file_index
> +						     * symesz;
> +		      rewrite = TRUE;
> +		    }
> +		  finfo.last_file_index = obj_raw_syment_count (abfd);
> +		  finfo.last_file = isym;
> +		}
> +
> +	      if (rewrite
> +		  && (bfd_seek (abfd, pos, SEEK_SET) != 0
> +		      || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz))
> +		goto error_return;
> +
> +	      obj_raw_syment_count (abfd) += written;
> +	    }
> +	}
> +    }
> +
>    if (! bfd_coff_final_link_postscript (abfd, & finfo))
>      goto error_return;
>  
> --- 2011-09-28/bfd/libcoff-in.h	2011-09-16 08:37:39.000000000 +0200
> +++ 2011-09-28/bfd/libcoff-in.h	2011-09-28 12:01:54.000000000 +0200
> @@ -318,6 +318,9 @@ extern void coff_mangle_symbols
>    (bfd *);
>  extern bfd_boolean coff_write_symbols
>    (bfd *);
> +extern bfd_boolean coff_write_alien_symbol
> +  (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
> +   bfd_size_type *, asection **, bfd_size_type *);
>  extern bfd_boolean coff_write_linenumbers
>    (bfd *);
>  extern alent *coff_get_lineno
> --- 2011-09-28/bfd/libcoff.h	2011-09-16 08:37:39.000000000 +0200
> +++ 2011-09-28/bfd/libcoff.h	2011-09-28 12:01:54.000000000 +0200
> @@ -322,6 +322,9 @@ extern void coff_mangle_symbols
>    (bfd *);
>  extern bfd_boolean coff_write_symbols
>    (bfd *);
> +extern bfd_boolean coff_write_alien_symbol
> +  (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
> +   bfd_size_type *, asection **, bfd_size_type *);
>  extern bfd_boolean coff_write_linenumbers
>    (bfd *);
>  extern alent *coff_get_lineno


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

* Re: [PATCH] COFF/PE: insert local symbols from foreign input  objects into output executable
  2011-09-28 12:01 [PATCH] COFF/PE: insert local symbols from foreign input objects into output executable Jan Beulich
  2011-10-11  6:48 ` Ping: " Jan Beulich
@ 2011-10-25  9:02 ` Nick Clifton
  2011-11-02 14:55   ` Jan Beulich
  1 sibling, 1 reply; 4+ messages in thread
From: Nick Clifton @ 2011-10-25  9:02 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

Hi Jan,

> bfd/
> 2011-09-28  Jan Beulich<jbeulich@suse.com>
>
> 	* coffgen.c (coff_write_alien_symbol): Make public. Add 'struct
> 	internal_syment *' parameter. Extend 'dummy' to an array with two
> 	elements. Set n_numaux early. Handle BSF_FILE.
> 	(coff_write_symbols): Pass NULL as new third argument to
> 	coff_write_alien_symbol().
> 	* cofflink.c (_bfd_coff_final_link): Don't use COFF-specific
> 	obj_raw_syment_count() on non-COFF input BFD. Insert local symbols
> 	from non-COFF input BFDs.
> 	* libcoff-in.h (coff_write_alien_symbol): Declare.
> 	* libcoff.h (coff_write_alien_symbol): Re-generate.

Approved - please apply.

> +  if (finfo.info->strip != strip_all&&  finfo.info->discard != discard_all)
> +    {
> +      /* Add local symbols from foreign inputs.  */
> +      for(sub = info->input_bfds; sub != NULL; sub = sub->link_next)

I think that it would be worthwhile extending this comment to explain 
why the local symbols are being preserved.

Cheers
   Nick

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

* Re: [PATCH] COFF/PE: insert local symbols from foreign input   objects into output executable
  2011-10-25  9:02 ` Nick Clifton
@ 2011-11-02 14:55   ` Jan Beulich
  0 siblings, 0 replies; 4+ messages in thread
From: Jan Beulich @ 2011-11-02 14:55 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils

>>> On 25.10.11 at 11:03, Nick Clifton <nickc@redhat.com> wrote:
> Hi Jan,
> 
>> bfd/
>> 2011-09-28  Jan Beulich<jbeulich@suse.com>
>>
>> 	* coffgen.c (coff_write_alien_symbol): Make public. Add 'struct
>> 	internal_syment *' parameter. Extend 'dummy' to an array with two
>> 	elements. Set n_numaux early. Handle BSF_FILE.
>> 	(coff_write_symbols): Pass NULL as new third argument to
>> 	coff_write_alien_symbol().
>> 	* cofflink.c (_bfd_coff_final_link): Don't use COFF-specific
>> 	obj_raw_syment_count() on non-COFF input BFD. Insert local symbols
>> 	from non-COFF input BFDs.
>> 	* libcoff-in.h (coff_write_alien_symbol): Declare.
>> 	* libcoff.h (coff_write_alien_symbol): Re-generate.
> 
> Approved - please apply.
> 
>> +  if (finfo.info->strip != strip_all&&  finfo.info->discard != discard_all)
>> +    {
>> +      /* Add local symbols from foreign inputs.  */
>> +      for(sub = info->input_bfds; sub != NULL; sub = sub->link_next)
> 
> I think that it would be worthwhile extending this comment to explain 
> why the local symbols are being preserved.

As it wasn't clear to me in what way this could be reasonably
extended (given the context, which I think already makes
things pretty clear), I committed this without adjustment to
the comment.

Jan

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

end of thread, other threads:[~2011-11-02 14:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-28 12:01 [PATCH] COFF/PE: insert local symbols from foreign input objects into output executable Jan Beulich
2011-10-11  6:48 ` Ping: " Jan Beulich
2011-10-25  9:02 ` Nick Clifton
2011-11-02 14:55   ` 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).