Commit cc195924 authored by Ulrich Weigand's avatar Ulrich Weigand Committed by Alexandre Julliard

Added check whether unaligned memory access is allowed.

Added macros to access unaligned WORDs / DWORDs.
parent a6d83eba
...@@ -782,6 +782,21 @@ then ...@@ -782,6 +782,21 @@ then
AC_DEFINE(BITFIELDS_BIGENDIAN) AC_DEFINE(BITFIELDS_BIGENDIAN)
fi fi
AC_CACHE_CHECK( "whether unaligned memory access is allowed", wine_cv_allow_unaligned_access,
[AC_TRY_RUN([
long volatile test[2];
main()
{
long volatile *ua = (long volatile *)((char *)test + 1);
*ua = 0;
exit(0);
} ], wine_cv_allow_unaligned_access=yes, wine_cv_allow_unaligned_access=no,
wine_cv_allow_unaligned_access=no ) ])
if test "$wine_allow_unaligned_access" = "yes"
then
AC_DEFINE(ALLOW_UNALIGNED_ACCESS)
fi
dnl **** Check for functions **** dnl **** Check for functions ****
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* <presently under construction - contact hunnise@nortelnetworks.com> * <presently under construction - contact hunnise@nortelnetworks.com>
* *
*/ */
#include "wine/port.h"
#include "windef.h" #include "windef.h"
#include "winerror.h" #include "winerror.h"
#include "winbase.h" #include "winbase.h"
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <stdlib.h> /* abs() */ #include <stdlib.h> /* abs() */
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "config.h"
#include "winbase.h" #include "winbase.h"
#include "windef.h" #include "windef.h"
#include "winerror.h" #include "winerror.h"
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "config.h"
#include "winbase.h" #include "winbase.h"
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "winnls.h" #include "winnls.h"
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
/* Define if bitfields are bigendian */ /* Define if bitfields are bigendian */
#undef BITFIELDS_BIGENDIAN #undef BITFIELDS_BIGENDIAN
/* Define if unaligned memory access is allowed */
#undef ALLOW_UNALIGNED_ACCESS
/* Define if .type asm directive must be inside a .def directive */ /* Define if .type asm directive must be inside a .def directive */
#undef NEED_TYPE_IN_DEF #undef NEED_TYPE_IN_DEF
......
...@@ -50,6 +50,9 @@ ...@@ -50,6 +50,9 @@
/* Define if bitfields are bigendian */ /* Define if bitfields are bigendian */
#undef BITFIELDS_BIGENDIAN #undef BITFIELDS_BIGENDIAN
/* Define if unaligned memory access is allowed */
#undef ALLOW_UNALIGNED_ACCESS
/* Define if .type asm directive must be inside a .def directive */ /* Define if .type asm directive must be inside a .def directive */
#undef NEED_TYPE_IN_DEF #undef NEED_TYPE_IN_DEF
......
...@@ -166,33 +166,6 @@ typedef LRESULT CALLBACK (*WNDPROC)(HWND,UINT,WPARAM,LPARAM); ...@@ -166,33 +166,6 @@ typedef LRESULT CALLBACK (*WNDPROC)(HWND,UINT,WPARAM,LPARAM);
#define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val))) #define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val)))
#endif #endif
/* Macros to access unaligned or wrong-endian WORDs and DWORDs. */
/* Note: These macros are semantically broken, at least for wrc. wrc
spits out data in the platform's current binary format, *not* in
little-endian format. These macros are used throughout the resource
code to load and store data to the resources. Since it is unlikely
that we'll ever be dealing with little-endian resource data, the
byte-swapping nature of these macros has been disabled. Rather than
remove the use of these macros from the resource loading code, the
macros have simply been disabled. In the future, someone may want
to reactivate these macros for other purposes. In that case, the
resource code will have to be modified to use different macros. */
#if 1
#define PUT_WORD(ptr,w) (*(WORD *)(ptr) = (w))
#define GET_WORD(ptr) (*(WORD *)(ptr))
#define PUT_DWORD(ptr,dw) (*(DWORD *)(ptr) = (dw))
#define GET_DWORD(ptr) (*(DWORD *)(ptr))
#else
#define PUT_WORD(ptr,w) (*(BYTE *)(ptr) = LOBYTE(w), \
*((BYTE *)(ptr) + 1) = HIBYTE(w))
#define GET_WORD(ptr) ((WORD)(*(BYTE *)(ptr) | \
(WORD)(*((BYTE *)(ptr)+1) << 8)))
#define PUT_DWORD(ptr,dw) (PUT_WORD((ptr),LOWORD(dw)), \
PUT_WORD((WORD *)(ptr)+1,HIWORD(dw)))
#define GET_DWORD(ptr) ((DWORD)(GET_WORD(ptr) | \
((DWORD)GET_WORD((WORD *)(ptr)+1) << 16)))
#endif /* 1 */
/* min and max macros */ /* min and max macros */
#define __max(a,b) (((a) > (b)) ? (a) : (b)) #define __max(a,b) (((a) > (b)) ? (a) : (b))
......
...@@ -142,4 +142,55 @@ extern int wine_dlclose( void *handle, char *error, int errorsize ); ...@@ -142,4 +142,55 @@ extern int wine_dlclose( void *handle, char *error, int errorsize );
#define RTLD_GLOBAL 0x100 #define RTLD_GLOBAL 0x100
#endif #endif
/* Macros to access unaligned or wrong-endian WORDs and DWORDs. */
#define PUT_WORD(ptr, w) (*(WORD *)(ptr) = (w))
#define GET_WORD(ptr) (*(WORD *)(ptr))
#define PUT_DWORD(ptr, d) (*(DWORD *)(ptr) = (d))
#define GET_DWORD(ptr) (*(DWORD *)(ptr))
#define PUT_LE_WORD(ptr, w) \
do { ((BYTE *)(ptr))[0] = LOBYTE(w); \
((BYTE *)(ptr))[1] = HIBYTE(w); } while (0)
#define GET_LE_WORD(ptr) \
MAKEWORD( ((BYTE *)(ptr))[0], \
((BYTE *)(ptr))[1] )
#define PUT_LE_DWORD(ptr, d) \
do { PUT_LE_WORD(&((WORD *)(ptr))[0], LOWORD(d)); \
PUT_LE_WORD(&((WORD *)(ptr))[1], HIBYTE(d)); } while (0)
#define GET_LE_DWORD(ptr) \
((DWORD)MAKELONG( GET_LE_WORD(&((WORD *)(ptr))[0]), \
GET_LE_WORD(&((WORD *)(ptr))[1]) ))
#define PUT_BE_WORD(ptr, w) \
do { ((BYTE *)(ptr))[1] = LOBYTE(w); \
((BYTE *)(ptr))[0] = HIBYTE(w); } while (0)
#define GET_BE_WORD(ptr) \
MAKEWORD( ((BYTE *)(ptr))[1], \
((BYTE *)(ptr))[0] )
#define PUT_BE_DWORD(ptr, d) \
do { PUT_BE_WORD(&((WORD *)(ptr))[1], LOWORD(d)); \
PUT_BE_WORD(&((WORD *)(ptr))[0], HIBYTE(d)); } while (0)
#define GET_BE_DWORD(ptr) \
((DWORD)MAKELONG( GET_BE_WORD(&((WORD *)(ptr))[1]), \
GET_BE_WORD(&((WORD *)(ptr))[0]) ))
#if defined(ALLOW_UNALIGNED_ACCESS)
#define PUT_UA_WORD(ptr, w) PUT_WORD(ptr, w)
#define GET_UA_WORD(ptr) GET_WORD(ptr)
#define PUT_UA_DWORD(ptr, d) PUT_DWORD(ptr, d)
#define GET_UA_DWORD(ptr) GET_DWORD(ptr)
#elif defined(WORDS_BIGENDIAN)
#define PUT_UA_WORD(ptr, w) PUT_BE_WORD(ptr, w)
#define GET_UA_WORD(ptr) GET_BE_WORD(ptr)
#define PUT_UA_DWORD(ptr, d) PUT_BE_DWORD(ptr, d)
#define GET_UA_DWORD(ptr) GET_BE_DWORD(ptr)
#else
#define PUT_UA_WORD(ptr, w) PUT_LE_WORD(ptr, w)
#define GET_UA_WORD(ptr) GET_LE_WORD(ptr)
#define PUT_UA_DWORD(ptr, d) PUT_LE_DWORD(ptr, d)
#define GET_UA_DWORD(ptr) GET_LE_DWORD(ptr)
#endif
#endif /* !defined(__WINE_WINE_PORT_H) */ #endif /* !defined(__WINE_WINE_PORT_H) */
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include "config.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "windef.h" #include "windef.h"
#include "winnls.h" #include "winnls.h"
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <assert.h> #include <assert.h>
#include <unistd.h> #include <unistd.h>
#include "wine/port.h"
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "ntddk.h" #include "ntddk.h"
#include "callback.h" #include "callback.h"
...@@ -272,8 +273,8 @@ BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline, ...@@ -272,8 +273,8 @@ BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline,
pTask->pdb.int20 = 0x20cd; pTask->pdb.int20 = 0x20cd;
pTask->pdb.dispatcher[0] = 0x9a; /* ljmp */ pTask->pdb.dispatcher[0] = 0x9a; /* ljmp */
PUT_DWORD(&pTask->pdb.dispatcher[1], (DWORD)GetProcAddress16( GetModuleHandle16("KERNEL"), PUT_UA_DWORD(&pTask->pdb.dispatcher[1],
"DOS3Call" )); (DWORD)GetProcAddress16( GetModuleHandle16("KERNEL"), "DOS3Call" ));
pTask->pdb.savedint22 = INT_GetPMHandler( 0x22 ); pTask->pdb.savedint22 = INT_GetPMHandler( 0x22 );
pTask->pdb.savedint23 = INT_GetPMHandler( 0x23 ); pTask->pdb.savedint23 = INT_GetPMHandler( 0x23 );
pTask->pdb.savedint24 = INT_GetPMHandler( 0x24 ); pTask->pdb.savedint24 = INT_GetPMHandler( 0x24 );
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "wine/port.h"
#include "windef.h" #include "windef.h"
#include "winnls.h" #include "winnls.h"
#include "winerror.h" #include "winerror.h"
...@@ -59,7 +60,7 @@ static const char ENV_program_name[] = "C:\\WINDOWS\\SYSTEM\\KRNL386.EXE"; ...@@ -59,7 +60,7 @@ static const char ENV_program_name[] = "C:\\WINDOWS\\SYSTEM\\KRNL386.EXE";
/* Fill the extra bytes with the program name and stuff */ /* Fill the extra bytes with the program name and stuff */
#define FILL_EXTRA_ENV(p) \ #define FILL_EXTRA_ENV(p) \
*(p) = '\0'; \ *(p) = '\0'; \
PUT_WORD( (p) + 1, 1 ); \ PUT_UA_WORD( (p) + 1, 1 ); \
strcpy( (p) + 3, ENV_program_name ); strcpy( (p) + 3, ENV_program_name );
STARTUPINFOA current_startupinfo = STARTUPINFOA current_startupinfo =
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "config.h"
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "selectors.h" #include "selectors.h"
...@@ -682,6 +683,16 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena ) ...@@ -682,6 +683,16 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
{ {
char *heapEnd = (char *)subheap + subheap->size; char *heapEnd = (char *)subheap + subheap->size;
#if !defined(ALLOW_UNALIGNED_ACCESS)
/* Check for unaligned pointers */
if ( (long)pArena % sizeof(void *) != 0 )
{
ERR( "Heap %08lx: unaligned arena pointer %08lx\n",
(DWORD)subheap->heap, (DWORD)pArena );
return FALSE;
}
#endif
/* Check magic number */ /* Check magic number */
if (pArena->magic != ARENA_FREE_MAGIC) if (pArena->magic != ARENA_FREE_MAGIC)
{ {
...@@ -766,6 +777,28 @@ static BOOL HEAP_ValidateInUseArena( SUBHEAP *subheap, ARENA_INUSE *pArena, BOOL ...@@ -766,6 +777,28 @@ static BOOL HEAP_ValidateInUseArena( SUBHEAP *subheap, ARENA_INUSE *pArena, BOOL
{ {
char *heapEnd = (char *)subheap + subheap->size; char *heapEnd = (char *)subheap + subheap->size;
#if !defined(ALLOW_UNALIGNED_ACCESS)
/* Check for unaligned pointers */
if ( (long)pArena % sizeof(void *) != 0 )
{
if ( quiet == NOISY )
{
ERR( "Heap %08lx: unaligned arena pointer %08lx\n",
(DWORD)subheap->heap, (DWORD)pArena );
if ( TRACE_ON(heap) )
HEAP_Dump( subheap->heap );
}
else if ( WARN_ON(heap) )
{
WARN( "Heap %08lx: unaligned arena pointer %08lx\n",
(DWORD)subheap->heap, (DWORD)pArena );
if ( TRACE_ON(heap) )
HEAP_Dump( subheap->heap );
}
return FALSE;
}
#endif
/* Check magic number */ /* Check magic number */
if (pArena->magic != ARENA_INUSE_MAGIC) if (pArena->magic != ARENA_INUSE_MAGIC)
{ {
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "wingdi.h" #include "wingdi.h"
#include "wine/winuser16.h" #include "wine/winuser16.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/port.h"
#include "heap.h" #include "heap.h"
#include "win.h" #include "win.h"
#include "controls.h" #include "controls.h"
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "wine/winuser16.h" #include "wine/winuser16.h"
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/port.h"
#include "controls.h" #include "controls.h"
#include "heap.h" #include "heap.h"
#include "win.h" #include "win.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment