This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Ping: [PATCH] COFF/PE: insert local symbols from foreign input objects into output executable


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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]