[Patch] bfd/peicode.h: Fix an ILF symbol undecoration bug

Danny Smith danny_smith_0000@yahoo.co.nz
Tue Mar 15 01:48:00 GMT 2005


The code in peicode.h (pe_ILF_build_a_bfd) at line 877ff
that strips prefix in IMPORT_NAME_NOPREFIX and
IMPORT_NAME_UNDECORATE cases, strips too much.  The
check_again logic is wrong.

As I undestand MS name decoration '_', '@', and '?' are
alternative forms of USER_LABEL_PREFIX, with '@' used for
fastcall, '?' for c++ mangled names, '_' everywhere else,
Only one of these is used for a symbol.

This if from PECOFF spec:

IMPORT_NAME_NOPREFIX:
"The import name is the public symbol name, but
skipping the leading ?, @, or optionally _."

IMPORT_NAME_UNDECORATE
"The import name is the public symbol name, but
skipping the leading ?, @, or optionally _, and
truncating at the first @."

Consider this fastcall symbol: 

/* fastcall.c */
void  __fastcall  _foo () {};

Copiling this with MS compiler:
cl /c fastcall.c
nm fastcall.obj
gives:
       T @_foo@0

Stripping both the '@' and '_' as done now, will leave an
unresolved reference. Only the '@' should be stripped.

Likewise compling the code as C++ the decorated name becomes:
       T ?_foo@@YIXXZ

Here only the leading '?' should be stripped. If we do that
and strip suffix at first '@' we would get the extern "C" name
_foo.  (This C++ undecoration only works for ordinary file level
functions that can translate to extern "C". It doesn't make
sense, to me, to fully undecorate mangled class member names)

After that long-winded reason, here is the simplification:

ChangeLog

2005-03-16  Danny Smith <dannysmith@users.sourceforge.net>
	    Ross Ridge  <rridge@csclub.uwaterloo.ca>

	* peicode.h (pe_ILF_build_a_bfd): Strip only one prefix
	character in IMPORT_NAME_UNDECORATE and IMPORT_NAME_NOPREFIX
	cases.


Index: peicode.h
===================================================================
RCS file: /cvs/src/src/bfd/peicode.h,v
retrieving revision 1.45
diff -c -3 -p -r1.45 peicode.h
*** peicode.h	28 Feb 2005 16:07:33 -0000	1.45
--- peicode.h	12 Mar 2005 22:24:05 -0000
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 877,913 ****
  
        if (import_name_type != IMPORT_NAME)
  	{
! 	  bfd_boolean skipped_leading_underscore = FALSE;
! 	  bfd_boolean skipped_leading_at = FALSE;
! 	  bfd_boolean skipped_leading_question_mark = FALSE;
! 	  bfd_boolean check_again;
! 	  
! 	  /* Skip any prefix in symbol_name.  */
! 	  -- symbol;
! 	  do
! 	    {
! 	      check_again = FALSE;
! 	      ++ symbol;
! 
! 	      switch (*symbol)
! 		{
! 		case '@':
! 		  if (! skipped_leading_at)
! 		    check_again = skipped_leading_at = TRUE;
! 		  break;
! 		case '?':
! 		  if (! skipped_leading_question_mark)
! 		    check_again = skipped_leading_question_mark = TRUE;
! 		  break;
! 		case '_':
! 		  if (! skipped_leading_underscore)
! 		    check_again = skipped_leading_underscore = TRUE;
! 		  break;
! 		default:
! 		  break;
! 		}
! 	    }
! 	  while (check_again);
  	}
        
        len = strlen (symbol);
--- 877,885 ----
  
        if (import_name_type != IMPORT_NAME)
  	{
! 	  char c = symbol[0];
! 	  if (c == '_' || c == '@' || c == '?')
! 	    symbol++;
  	}
        
        len = strlen (symbol);,"binutils" <binutils@sources.redhat.com>

Find local movie times and trailers on Yahoo! Movies.
http://au.movies.yahoo.com



More information about the Binutils mailing list