Bug compiling Wine-980503 with i586-pc-linux-gnu/egcs-2.91.25 19980425

Jim Peterson jspeter@roanoke.infi.net
Mon May 4 22:32:00 GMT 1998


  I've found an obscure error in the egcs 4/25 snapshot which appears when
  compiling wine-980503.  The only instance of this bug that I'm aware of
  occurs in the windows/defwnd.c file in the procedure DefWindowProc16() for
  case WM_NCCREATE.  Most particularly, the following two code snippets
  demonstrate the problem:

 Good version (egcs-1.0.2):

0x4018b174 <DefWindowProc16+192>:       xorl   %eax,%eax
0x4018b176 <DefWindowProc16+194>:       movw   0x14(%ebp),%ax
0x4018b17a <DefWindowProc16+198>:       movl   0x2454(%ebx),%esi
0x4018b180 <DefWindowProc16+204>:       shrl   $0x13,0x14(%ebp)
0x4018b184 <DefWindowProc16+208>:       movl   0x14(%ebp),%ecx
0x4018b187 <DefWindowProc16+211>:       addl   (%esi,%ecx,8),%eax
0x4018b18a <DefWindowProc16+214>:       movl   0x16(%eax),%edx
0x4018b18d <DefWindowProc16+217>:       testl  %edx,%edx

 Buggy version (egcs-2.91.25):

0x4018b148 <DefWindowProc16+196>:       movl   0x2454(%ebx),%esi
0x4018b14e <DefWindowProc16+202>:       shrl   $0x13,0x14(%ebp)
0x4018b152 <DefWindowProc16+206>:       xorl   %eax,%eax
0x4018b154 <DefWindowProc16+208>:       movl   0x14(%ebp),%ecx
0x4018b157 <DefWindowProc16+211>:       movw   0x14(%ebp),%ax
0x4018b15b <DefWindowProc16+215>:       addl   (%esi,%ecx,8),%eax
0x4018b15e <DefWindowProc16+218>:       movl   0x16(%eax),%edx
0x4018b161 <DefWindowProc16+221>:       testl  %edx,%edx

  Aside from simple reordering of instructions, there is no real difference.
  The problem occurs when a passed-in parameter, which is not used at any point
  after this code ( 0x14(%ebp) = lParam ) is shifted with the statement
  'shrl $0x13,0x14(%ebp)' _before_ its original value is loaded into %ax with
  'movw 0x14(%ebp),%ax'.  The C code involved is buried in some macro
  definitions.

  The code must be compiled with both '-fPIC' and '-O2' in order for the bug
  to appear.

  Appended is the most reduced version of the function that I can devise which
  still miscompiles (as is shown by objdump).

  The many different cases in the switch statement and the call to function
  SPY_EnterMessage() are necessary to show the bug.

--Jim

==============================================================================

/* compile with "gcc -fPIC -O2 -c rce.c -o rce.o". */

typedef struct
{
  unsigned long base;    /* base address or 0 if entry is free   */
} ldt_copy_entry;

#define LDT_SIZE  8192

extern ldt_copy_entry ldt_copy[LDT_SIZE];

typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef int LRESULT;
typedef WORD HWND16;
typedef WORD UINT16;
typedef WORD WPARAM16;
typedef int LPARAM;
typedef char* LPSTR;

typedef struct
{
  char* lpszName;
} CREATESTRUCT16;

LRESULT DefWindowProc16( UINT16 msg, LPARAM lParam )
{
  void * wndPtr;
  LRESULT result = 0;

  SPY_EnterMessage( msg, lParam );

  switch(msg)
  {
  case 0x0081 :
  {
    CREATESTRUCT16 *cs = (CREATESTRUCT16 *)((void*)((ldt_copy[(((int)( (((WORD)((DWORD)(   lParam   ) >> 16)) )    ) & 0xffff) >> 3 ) ].base)  + (unsigned int)( (((WORD)(DWORD)(   lParam   )) )  )))  ;
    result = (LRESULT)cs;
  }
  break;

  case 0x0083 :
  {
    result = 2;
  }
  break;

  case 0x0046 :
    break;

  case 0x0047 :
  {
    result = 3;
  }
  break;

  case 0x000d :
  {
    result = 4;
  }
  break;

  case 0x000c :
    result = 5;
    break;

  default:
    result = 1;
    break;
  }
  return result;
} 



More information about the Gcc-bugs mailing list