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