Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
914406f8
Commit
914406f8
authored
Nov 14, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved LDT handling to libwine.so. Changed the interface to use the
exported LDT_ENTRY structure.
parent
41d6e2fe
Hide whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
511 additions
and
705 deletions
+511
-705
kernel_main.c
dlls/kernel/kernel_main.c
+1
-1
thunk.c
dlls/kernel/thunk.c
+1
-1
mmsystem.c
dlls/winmm/mmsystem.c
+10
-14
dib.c
graphics/x11drv/dib.c
+3
-8
builtin.c
if1632/builtin.c
+4
-5
relay.c
if1632/relay.c
+1
-1
snoop.c
if1632/snoop.c
+3
-5
builtin16.h
include/builtin16.h
+0
-1
global.h
include/global.h
+2
-5
ldt.h
include/ldt.h
+6
-58
selectors.h
include/selectors.h
+2
-5
server.h
include/server.h
+1
-2
library.h
include/wine/library.h
+62
-0
Makefile.in
library/Makefile.in
+1
-0
ldt.c
library/ldt.c
+169
-0
module.c
loader/ne/module.c
+2
-2
resource.c
loader/ne/resource.c
+2
-2
segment.c
loader/ne/segment.c
+5
-6
task.c
loader/task.c
+4
-5
Makefile.in
memory/Makefile.in
+0
-1
environ.c
memory/environ.c
+3
-2
global.c
memory/global.c
+13
-24
heap.c
memory/heap.c
+11
-11
instr.c
memory/instr.c
+1
-1
ldt.c
memory/ldt.c
+0
-302
selector.c
memory/selector.c
+160
-194
dosmem.c
msdos/dosmem.c
+6
-7
dpmi.c
msdos/dpmi.c
+15
-20
vxd.c
msdos/vxd.c
+1
-2
metafile.c
objects/metafile.c
+1
-1
process.c
scheduler/process.c
+1
-2
thread.c
scheduler/thread.c
+2
-3
process.c
server/process.c
+0
-2
thread.c
server/thread.c
+4
-4
trace.c
server/trace.c
+0
-1
relay.c
tools/winebuild/relay.c
+7
-5
spec16.c
tools/winebuild/spec16.c
+7
-2
No files found.
dlls/kernel/kernel_main.c
View file @
914406f8
...
...
@@ -56,7 +56,7 @@ static BOOL process_attach(void)
#define SET_ENTRY_POINT( num, addr ) \
NE_SetEntryPoint( hModule, (num), GLOBAL_CreateBlock( GMEM_FIXED, \
DOSMEM_MapDosToLinear(addr), 0x10000, hModule, \
FALSE, FALSE, FALSE
))
WINE_LDT_FLAGS_DATA
))
SET_ENTRY_POINT
(
174
,
0xa0000
);
/* KERNEL.174: __A000H */
SET_ENTRY_POINT
(
181
,
0xb0000
);
/* KERNEL.181: __B000H */
...
...
dlls/kernel/thunk.c
View file @
914406f8
...
...
@@ -1012,7 +1012,7 @@ AllocSLCallback(
*
(
DWORD
*
)(
thunk
+
18
)
=
GetCurrentProcessId
();
sel
=
SELECTOR_AllocBlock
(
thunk
,
32
,
SEGMENT_CODE
,
FALSE
,
FALS
E
);
sel
=
SELECTOR_AllocBlock
(
thunk
,
32
,
WINE_LDT_FLAGS_COD
E
);
return
(
sel
<<
16
)
|
0
;
}
...
...
dlls/winmm/mmsystem.c
View file @
914406f8
...
...
@@ -4925,9 +4925,8 @@ LRESULT WINAPI DefDriverProc(DWORD dwDriverIdentifier, HDRVR hDrv,
*/
HINSTANCE16
WINAPI
mmTaskCreate16
(
SEGPTR
spProc
,
HINSTANCE16
*
lphMmTask
,
DWORD
dwPmt
)
{
DWORD
showCmd
=
0x40002
;
DWORD
*
pShowCmd
;
LPSTR
cmdline
;
WORD
sel1
,
sel2
;
LOADPARAMS16
*
lp
;
HINSTANCE16
ret
;
HINSTANCE16
handle
;
...
...
@@ -4942,20 +4941,19 @@ HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD d
*/
FIXME
(
"This is currently broken. It will fail
\n
"
);
cmdline
=
(
LPSTR
)
HeapAlloc
(
GetProcessHeap
(),
0
,
0x0d
);
cmdline
=
SEGPTR_ALLOC
(
0x0d
);
cmdline
[
0
]
=
0x0d
;
*
(
LPDWORD
)(
cmdline
+
1
)
=
(
DWORD
)
spProc
;
*
(
LPDWORD
)(
cmdline
+
5
)
=
dwPmt
;
*
(
LPDWORD
)(
cmdline
+
9
)
=
0
;
sel1
=
SELECTOR_AllocBlock
(
cmdline
,
0x0d
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
sel2
=
SELECTOR_AllocBlock
(
&
showCmd
,
sizeof
(
showCmd
),
SEGMENT_DATA
,
FALSE
,
FALSE
);
pShowCmd
=
SEGPTR_ALLOC
(
sizeof
(
DWORD
));
*
pShowCmd
=
0x40002
;
lp
=
(
LOADPARAMS16
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
LOADPARAMS16
));
lp
->
hEnvironment
=
0
;
lp
->
cmdLine
=
PTR_SEG_OFF_TO_SEGPTR
(
sel1
,
0
);
lp
->
showCmd
=
PTR_SEG_OFF_TO_SEGPTR
(
sel2
,
0
);
lp
->
cmdLine
=
SEGPTR_GET
(
cmdline
);
lp
->
showCmd
=
SEGPTR_GET
(
pShowCmd
);
lp
->
reserved
=
0
;
#ifndef USE_MM_TSK_WINE
...
...
@@ -4971,12 +4969,10 @@ HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD d
}
if
(
lphMmTask
)
*
lphMmTask
=
handle
;
UnMapLS
(
PTR_SEG_OFF_TO_SEGPTR
(
sel2
,
0
));
UnMapLS
(
PTR_SEG_OFF_TO_SEGPTR
(
sel1
,
0
));
HeapFree
(
GetProcessHeap
(),
0
,
lp
);
HeapFree
(
GetProcessHeap
(),
0
,
cmdline
);
SEGPTR_FREE
(
pShowCmd
);
SEGPTR_FREE
(
cmdline
);
TRACE
(
"=> 0x%04x/%d
\n
"
,
handle
,
ret
);
return
ret
;
...
...
graphics/x11drv/dib.c
View file @
914406f8
...
...
@@ -3324,8 +3324,7 @@ HBITMAP16 X11DRV_DIB_CreateDIBSection16(
if
(
dib
->
dsBm
.
bmBits
)
{
((
X11DRV_DIBSECTION
*
)
bmp
->
dib
)
->
selector
=
SELECTOR_AllocBlock
(
dib
->
dsBm
.
bmBits
,
size
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
SELECTOR_AllocBlock
(
dib
->
dsBm
.
bmBits
,
size
,
WINE_LDT_FLAGS_DATA
);
}
TRACE
(
"ptr = %p, size =%d, selector = %04x, segptr = %ld
\n
"
,
dib
->
dsBm
.
bmBits
,
size
,
((
X11DRV_DIBSECTION
*
)
bmp
->
dib
)
->
selector
,
...
...
@@ -3600,12 +3599,8 @@ void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
if
(
dib
->
colorMap
)
HeapFree
(
GetProcessHeap
(),
0
,
dib
->
colorMap
);
if
(
dib
->
selector
)
{
WORD
count
=
(
GetSelectorLimit16
(
dib
->
selector
)
>>
16
)
+
1
;
SELECTOR_FreeBlock
(
dib
->
selector
,
count
);
}
if
(
dib
->
selector
)
SELECTOR_FreeBlock
(
dib
->
selector
);
}
...
...
if1632/builtin.c
View file @
914406f8
...
...
@@ -60,8 +60,7 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
HMODULE16
hModule
;
hModule
=
GLOBAL_CreateBlock
(
GMEM_MOVEABLE
,
descr
->
module_start
,
descr
->
module_size
,
0
,
FALSE
,
FALSE
,
FALSE
);
descr
->
module_size
,
0
,
WINE_LDT_FLAGS_DATA
);
if
(
!
hModule
)
return
0
;
FarSetOwner16
(
hModule
,
hModule
);
...
...
@@ -76,7 +75,8 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
pSegTable
=
NE_SEG_TABLE
(
pModule
);
pSegTable
->
hSeg
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
descr
->
code_start
,
pSegTable
->
minsize
,
hModule
,
TRUE
,
TRUE
,
FALSE
);
pSegTable
->
minsize
,
hModule
,
WINE_LDT_FLAGS_CODE
|
WINE_LDT_FLAGS_32BIT
);
if
(
!
pSegTable
->
hSeg
)
return
0
;
patch_code_segment
(
descr
->
code_start
);
pSegTable
++
;
...
...
@@ -86,8 +86,7 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
minsize
=
pSegTable
->
minsize
?
pSegTable
->
minsize
:
0x10000
;
minsize
+=
pModule
->
heap_size
;
if
(
minsize
>
0x10000
)
minsize
=
0x10000
;
pSegTable
->
hSeg
=
GLOBAL_Alloc
(
GMEM_FIXED
,
minsize
,
hModule
,
FALSE
,
FALSE
,
FALSE
);
pSegTable
->
hSeg
=
GLOBAL_Alloc
(
GMEM_FIXED
,
minsize
,
hModule
,
WINE_LDT_FLAGS_DATA
);
if
(
!
pSegTable
->
hSeg
)
return
0
;
if
(
pSegTable
->
minsize
)
memcpy
(
GlobalLock16
(
pSegTable
->
hSeg
),
descr
->
data_start
,
pSegTable
->
minsize
);
...
...
if1632/relay.c
View file @
914406f8
...
...
@@ -42,7 +42,7 @@ BOOL RELAY_Init(void)
codesel
=
SELECTOR_AllocBlock
(
(
void
*
)
Call16_Ret_Start
,
(
char
*
)
Call16_Ret_End
-
(
char
*
)
Call16_Ret_Start
,
SEGMENT_CODE
,
TRUE
,
FALSE
);
WINE_LDT_FLAGS_CODE
|
WINE_LDT_FLAGS_32BIT
);
if
(
!
codesel
)
return
FALSE
;
/* Patch the return addresses for CallTo16 routines */
...
...
if1632/snoop.c
View file @
914406f8
...
...
@@ -91,7 +91,7 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) {
if
(
!
TRACE_ON
(
snoop
))
return
;
if
(
!
snr
)
{
xsnr
=
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
2
*
sizeof
(
*
snr
),
0
,
TRUE
,
TRUE
,
FALSE
);
xsnr
=
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
2
*
sizeof
(
*
snr
),
0
,
WINE_LDT_FLAGS_CODE
|
WINE_LDT_FLAGS_32BIT
);
snr
=
GlobalLock16
(
xsnr
);
snr
[
0
].
pushbp
=
0x5566
;
snr
[
0
].
pusheax
=
0x50
;
...
...
@@ -126,14 +126,13 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) {
(
*
dll
)
->
name
=
HEAP_strdupA
(
GetProcessHeap
(),
0
,
name
);
if
((
s
=
strrchr
((
*
dll
)
->
name
,
'.'
)))
*
s
=
'\0'
;
(
*
dll
)
->
funhandle
=
GlobalHandleToSel16
(
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
65535
,
0
,
TRUE
,
FALSE
,
FALS
E
));
(
*
dll
)
->
funhandle
=
GlobalHandleToSel16
(
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
65535
,
0
,
WINE_LDT_FLAGS_COD
E
));
(
*
dll
)
->
funs
=
GlobalLock16
((
*
dll
)
->
funhandle
);
if
(
!
(
*
dll
)
->
funs
)
{
HeapFree
(
GetProcessHeap
(),
0
,
*
dll
);
FIXME
(
"out of memory
\n
"
);
return
;
}
memset
((
*
dll
)
->
funs
,
0
,
65535
);
}
FARPROC16
...
...
@@ -240,9 +239,8 @@ void WINAPI SNOOP16_Entry(FARPROC proc, LPBYTE args, CONTEXT86 *context) {
rets
=
&
((
*
rets
)
->
next
);
}
if
(
!*
rets
)
{
HANDLE16
hand
=
GlobalHandleToSel16
(
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
65535
,
0
,
TRUE
,
FALSE
,
FALS
E
));
HANDLE16
hand
=
GlobalHandleToSel16
(
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
65535
,
0
,
WINE_LDT_FLAGS_COD
E
));
*
rets
=
GlobalLock16
(
hand
);
memset
(
*
rets
,
0
,
65535
);
(
*
rets
)
->
rethandle
=
hand
;
i
=
0
;
/* entry 0 is free */
}
...
...
include/builtin16.h
View file @
914406f8
...
...
@@ -9,7 +9,6 @@
#include "windef.h"
#include "wine/windef16.h"
#include "ldt.h"
struct
_CONTEXT86
;
struct
_STACK16FRAME
;
...
...
include/global.h
View file @
914406f8
...
...
@@ -12,13 +12,10 @@
/* memory/global.c */
extern
HGLOBAL16
GLOBAL_CreateBlock
(
UINT16
flags
,
const
void
*
ptr
,
DWORD
size
,
HGLOBAL16
hOwner
,
BOOL16
isCode
,
BOOL16
is32Bit
,
BOOL16
isReadOnly
);
HGLOBAL16
hOwner
,
unsigned
char
selflags
);
extern
BOOL16
GLOBAL_FreeBlock
(
HGLOBAL16
handle
);
extern
BOOL16
GLOBAL_MoveBlock
(
HGLOBAL16
handle
,
const
void
*
ptr
,
DWORD
size
);
extern
HGLOBAL16
GLOBAL_Alloc
(
WORD
flags
,
DWORD
size
,
HGLOBAL16
hOwner
,
BOOL16
isCode
,
BOOL16
is32Bit
,
BOOL16
isReadOnly
);
extern
HGLOBAL16
GLOBAL_Alloc
(
WORD
flags
,
DWORD
size
,
HGLOBAL16
hOwner
,
unsigned
char
selflags
);
/* memory/virtual.c */
extern
DWORD
VIRTUAL_GetPageSize
(
void
);
...
...
include/ldt.h
View file @
914406f8
...
...
@@ -8,58 +8,15 @@
#define __WINE_LDT_H
#include "windef.h"
enum
seg_type
{
SEGMENT_DATA
=
0
,
SEGMENT_STACK
=
1
,
SEGMENT_CODE
=
2
};
/* This structure represents a real LDT entry. */
/* It is used by get_ldt_entry() and set_ldt_entry(). */
typedef
struct
{
unsigned
long
base
;
/* base address */
unsigned
long
limit
;
/* segment limit (in pages or bytes) */
int
seg_32bit
;
/* is segment 32-bit? */
int
read_only
;
/* is segment read-only? */
int
limit_in_pages
;
/* is the limit in pages or bytes? */
enum
seg_type
type
;
/* segment type */
}
ldt_entry
;
extern
void
LDT_BytesToEntry
(
const
unsigned
long
*
buffer
,
ldt_entry
*
content
);
extern
void
LDT_EntryToBytes
(
unsigned
long
*
buffer
,
const
ldt_entry
*
content
);
extern
int
LDT_GetEntry
(
int
entry
,
ldt_entry
*
content
);
extern
int
LDT_SetEntry
(
int
entry
,
const
ldt_entry
*
content
);
extern
void
LDT_Print
(
int
start
,
int
length
);
/* This structure is used to build the local copy of the LDT. */
typedef
struct
{
unsigned
long
base
;
/* base address or 0 if entry is free */
unsigned
long
limit
;
/* limit in bytes or 0 if entry is free */
}
ldt_copy_entry
;
#define LDT_SIZE 8192
extern
ldt_copy_entry
ldt_copy
[
LDT_SIZE
];
#include "wine/library.h"
#define __AHSHIFT 3
/* don't change! */
#define __AHINCR (1 << __AHSHIFT)
#define SELECTOR_TO_ENTRY(sel) (((int)(sel) & 0xffff) >> __AHSHIFT)
#define ENTRY_TO_SELECTOR(i) ((i) ? (((int)(i) << __AHSHIFT) | 7) : 0)
#define IS_LDT_ENTRY_FREE(i) (!(ldt_flags_copy[(i)] & LDT_FLAGS_ALLOCATED))
#define IS_SELECTOR_FREE(sel) (IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel)))
#define GET_SEL_BASE(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].base)
#define GET_SEL_LIMIT(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit)
/* Convert a segmented ptr (16:16) to a linear (32) pointer */
#define PTR_SEG_OFF_TO_LIN(seg,off) \
((void*)(
GET_SEL_BASE(seg)
+ (unsigned int)(off)))
((void*)(
(char*)wine_ldt_copy.base[LOWORD(seg) >> __AHSHIFT]
+ (unsigned int)(off)))
#define PTR_REAL_TO_LIN(seg,off) \
((void*)(((unsigned int)(seg) << 4) + LOWORD(off)))
#define PTR_SEG_TO_LIN(ptr) \
...
...
@@ -74,23 +31,14 @@ extern ldt_copy_entry ldt_copy[LDT_SIZE];
#define W32S_APP2WINE(addr, offset) ((addr)? (DWORD)(addr) + (DWORD)(offset) : 0)
#define W32S_WINE2APP(addr, offset) ((addr)? (DWORD)(addr) - (DWORD)(offset) : 0)
extern
unsigned
char
ldt_flags_copy
[
LDT_SIZE
];
#define LDT_FLAGS_TYPE 0x03
/* Mask for segment type */
#define LDT_FLAGS_READONLY 0x04
/* Segment is read-only (data) */
#define LDT_FLAGS_EXECONLY 0x04
/* Segment is execute-only (code) */
#define LDT_FLAGS_32BIT 0x08
/* Segment is 32-bit (code or stack) */
#define LDT_FLAGS_BIG 0x10
/* Segment is big (limit is in pages) */
#define LDT_FLAGS_ALLOCATED 0x80
/* Segment is allocated (no longer free) */
#define GET_SEL_FLAGS(sel) (ldt_flags_copy[SELECTOR_TO_ENTRY(sel)])
#define FIRST_LDT_ENTRY_TO_ALLOC 17
#define IS_SELECTOR_FREE(sel) (!(wine_ldt_copy.flags[LOWORD(sel) >> __AHSHIFT] & WINE_LDT_FLAGS_ALLOCATED))
/* Determine if sel is a system selector (i.e. not managed by Wine) */
#define IS_SELECTOR_SYSTEM(sel) \
(!((sel) & 4) || (
SELECTOR_TO_ENTRY(sel
) < FIRST_LDT_ENTRY_TO_ALLOC))
(!((sel) & 4) || (
(LOWORD(sel) >> __AHSHIFT
) < FIRST_LDT_ENTRY_TO_ALLOC))
#define IS_SELECTOR_32BIT(sel) \
(IS_SELECTOR_SYSTEM(sel) || (
GET_SEL_FLAGS(sel) &
LDT_FLAGS_32BIT))
(IS_SELECTOR_SYSTEM(sel) || (
wine_ldt_copy.flags[LOWORD(sel) >> __AHSHIFT] & WINE_
LDT_FLAGS_32BIT))
#endif
/* __WINE_LDT_H */
include/selectors.h
View file @
914406f8
...
...
@@ -10,12 +10,9 @@
#include "windef.h"
#include "ldt.h"
extern
WORD
SELECTOR_AllocBlock
(
const
void
*
base
,
DWORD
size
,
enum
seg_type
type
,
BOOL
is32bit
,
BOOL
readonly
);
extern
WORD
SELECTOR_AllocBlock
(
const
void
*
base
,
DWORD
size
,
unsigned
char
flags
);
extern
WORD
SELECTOR_ReallocBlock
(
WORD
sel
,
const
void
*
base
,
DWORD
size
);
extern
void
SELECTOR_MoveBlock
(
WORD
sel
,
const
void
*
new_base
);
extern
void
SELECTOR_FreeBlock
(
WORD
sel
,
WORD
count
);
extern
void
SELECTOR_FreeBlock
(
WORD
sel
);
#ifdef __i386__
# ifdef __GNUC__
...
...
include/server.h
View file @
914406f8
...
...
@@ -178,7 +178,6 @@ struct init_process_request
{
REQUEST_HEADER
;
/* request header */
IN
void
*
ldt_copy
;
/* addr of LDT copy */
IN
void
*
ldt_flags
;
/* addr of LDT flags */
IN
int
ppid
;
/* parent Unix pid */
OUT
int
start_flags
;
/* flags from startup info */
OUT
unsigned
int
server_start
;
/* server start time (GetTickCount) */
...
...
@@ -1592,7 +1591,7 @@ union generic_request
struct
async_result_request
async_result
;
};
#define SERVER_PROTOCOL_VERSION 2
7
#define SERVER_PROTOCOL_VERSION 2
8
/* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */
...
...
include/wine/library.h
View file @
914406f8
...
...
@@ -8,6 +8,7 @@
#define __WINE_WINE_LIBRARY_H
#include <sys/types.h>
#include "winbase.h"
/* dll loading */
...
...
@@ -26,4 +27,65 @@ extern void wine_dbg_add_option( const char *name, unsigned char set, unsigned c
extern
void
*
wine_anon_mmap
(
void
*
start
,
size_t
size
,
int
prot
,
int
flags
);
/* LDT management */
extern
void
wine_ldt_get_entry
(
unsigned
short
sel
,
LDT_ENTRY
*
entry
);
extern
int
wine_ldt_set_entry
(
unsigned
short
sel
,
const
LDT_ENTRY
*
entry
);
/* the local copy of the LDT */
extern
struct
__wine_ldt_copy
{
void
*
base
[
8192
];
/* base address or 0 if entry is free */
unsigned
long
limit
[
8192
];
/* limit in bytes or 0 if entry is free */
unsigned
char
flags
[
8192
];
/* flags (defined below) */
}
wine_ldt_copy
;
#define WINE_LDT_FLAGS_DATA 0x13
/* Data segment */
#define WINE_LDT_FLAGS_STACK 0x17
/* Stack segment */
#define WINE_LDT_FLAGS_CODE 0x1b
/* Code segment */
#define WINE_LDT_FLAGS_TYPE_MASK 0x1f
/* Mask for segment type */
#define WINE_LDT_FLAGS_32BIT 0x40
/* Segment is 32-bit (code or stack) */
#define WINE_LDT_FLAGS_ALLOCATED 0x80
/* Segment is allocated (no longer free) */
/* helper functions to manipulate the LDT_ENTRY structure */
inline
static
void
wine_ldt_set_base
(
LDT_ENTRY
*
ent
,
const
void
*
base
)
{
ent
->
BaseLow
=
(
WORD
)(
unsigned
long
)
base
;
ent
->
HighWord
.
Bits
.
BaseMid
=
(
BYTE
)((
unsigned
long
)
base
>>
16
);
ent
->
HighWord
.
Bits
.
BaseHi
=
(
BYTE
)((
unsigned
long
)
base
>>
24
);
}
inline
static
void
wine_ldt_set_limit
(
LDT_ENTRY
*
ent
,
unsigned
int
limit
)
{
if
((
ent
->
HighWord
.
Bits
.
Granularity
=
(
limit
>=
0x100000
)))
limit
>>=
12
;
ent
->
LimitLow
=
(
WORD
)
limit
;
ent
->
HighWord
.
Bits
.
LimitHi
=
(
limit
>>
16
);
}
inline
static
void
*
wine_ldt_get_base
(
const
LDT_ENTRY
*
ent
)
{
return
(
void
*
)(
ent
->
BaseLow
|
(
unsigned
long
)
ent
->
HighWord
.
Bits
.
BaseMid
<<
16
|
(
unsigned
long
)
ent
->
HighWord
.
Bits
.
BaseHi
<<
24
);
}
inline
static
unsigned
int
wine_ldt_get_limit
(
const
LDT_ENTRY
*
ent
)
{
unsigned
int
limit
=
ent
->
LimitLow
|
(
ent
->
HighWord
.
Bits
.
LimitHi
<<
16
);
if
(
ent
->
HighWord
.
Bits
.
Granularity
)
limit
=
(
limit
<<
12
)
|
0xfff
;
return
limit
;
}
inline
static
void
wine_ldt_set_flags
(
LDT_ENTRY
*
ent
,
unsigned
char
flags
)
{
ent
->
HighWord
.
Bits
.
Dpl
=
3
;
ent
->
HighWord
.
Bits
.
Pres
=
1
;
ent
->
HighWord
.
Bits
.
Type
=
flags
;
ent
->
HighWord
.
Bits
.
Sys
=
0
;
ent
->
HighWord
.
Bits
.
Reserved_0
=
0
;
ent
->
HighWord
.
Bits
.
Default_Big
=
(
flags
&
WINE_LDT_FLAGS_32BIT
)
!=
0
;
}
inline
static
unsigned
char
wine_ldt_get_flags
(
const
LDT_ENTRY
*
ent
)
{
unsigned
char
ret
=
ent
->
HighWord
.
Bits
.
Type
;
if
(
ent
->
HighWord
.
Bits
.
Default_Big
)
ret
|=
WINE_LDT_FLAGS_32BIT
;
return
ret
;
}
#endif
/* __WINE_WINE_LIBRARY_H */
library/Makefile.in
View file @
914406f8
...
...
@@ -10,6 +10,7 @@ SONAME = libwine.so
C_SRCS
=
\
debug.c
\
ldt.c
\
loader.c
\
port.c
...
...
library/ldt.c
0 → 100644
View file @
914406f8
/*
* LDT manipulation functions
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "winbase.h"
#include "wine/library.h"
#ifdef __i386__
#ifdef linux
#ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
#endif
struct
modify_ldt_s
{
unsigned
int
entry_number
;
unsigned
long
base_addr
;
unsigned
int
limit
;
unsigned
int
seg_32bit
:
1
;
unsigned
int
contents
:
2
;
unsigned
int
read_exec_only
:
1
;
unsigned
int
limit_in_pages
:
1
;
unsigned
int
seg_not_present
:
1
;
};
static
inline
int
modify_ldt
(
int
func
,
struct
modify_ldt_s
*
ptr
,
unsigned
long
count
)
{
int
res
;
#ifdef __PIC__
__asm__
__volatile__
(
"pushl %%ebx
\n\t
"
"movl %2,%%ebx
\n\t
"
"int $0x80
\n\t
"
"popl %%ebx"
:
"=a"
(
res
)
:
"0"
(
SYS_modify_ldt
),
"r"
(
func
),
"c"
(
ptr
),
"d"
(
count
)
);
#else
__asm__
__volatile__
(
"int $0x80"
:
"=a"
(
res
)
:
"0"
(
SYS_modify_ldt
),
"b"
(
func
),
"c"
(
ptr
),
"d"
(
count
)
);
#endif
/* __PIC__ */
if
(
res
>=
0
)
return
res
;
errno
=
-
res
;
return
-
1
;
}
#endif
/* linux */
#if defined(__svr4__) || defined(_SCO_DS)
#include <sys/sysi86.h>
extern
int
sysi86
(
int
,
void
*
);
#ifndef __sun__
#include <sys/seg.h>
#endif
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <machine/segments.h>
extern
int
i386_get_ldt
(
int
,
union
descriptor
*
,
int
);
extern
int
i386_set_ldt
(
int
,
union
descriptor
*
,
int
);
#endif
/* __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
#endif
/* __i386__ */
/* local copy of the LDT */
struct
__wine_ldt_copy
wine_ldt_copy
;
/***********************************************************************
* ldt_get_entry
*
* Retrieve an LDT entry.
*/
void
wine_ldt_get_entry
(
unsigned
short
sel
,
LDT_ENTRY
*
entry
)
{
int
index
=
sel
>>
3
;
wine_ldt_set_base
(
entry
,
wine_ldt_copy
.
base
[
index
]
);
wine_ldt_set_limit
(
entry
,
wine_ldt_copy
.
limit
[
index
]
);
wine_ldt_set_flags
(
entry
,
wine_ldt_copy
.
flags
[
index
]
);
}
/***********************************************************************
* ldt_set_entry
*
* Set an LDT entry.
*/
int
wine_ldt_set_entry
(
unsigned
short
sel
,
const
LDT_ENTRY
*
entry
)
{
int
ret
=
0
,
index
=
sel
>>
3
;
/* Entry 0 must not be modified; its base and limit are always 0 */
if
(
!
index
)
return
0
;
#ifdef __i386__
#ifdef linux
{
struct
modify_ldt_s
ldt_info
;
ldt_info
.
entry_number
=
index
;
ldt_info
.
base_addr
=
(
unsigned
long
)
wine_ldt_get_base
(
entry
);
ldt_info
.
limit
=
entry
->
LimitLow
|
(
entry
->
HighWord
.
Bits
.
LimitHi
<<
16
);
ldt_info
.
seg_32bit
=
entry
->
HighWord
.
Bits
.
Default_Big
;
ldt_info
.
contents
=
(
entry
->
HighWord
.
Bits
.
Type
>>
2
)
&
3
;
ldt_info
.
read_exec_only
=
!
(
entry
->
HighWord
.
Bits
.
Type
&
2
);
ldt_info
.
limit_in_pages
=
entry
->
HighWord
.
Bits
.
Granularity
;
ldt_info
.
seg_not_present
=
!
entry
->
HighWord
.
Bits
.
Pres
;
if
((
ret
=
modify_ldt
(
1
,
&
ldt_info
,
sizeof
(
ldt_info
)))
<
0
)
perror
(
"modify_ldt"
);
}
#endif
/* linux */
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
{
ret
=
i386_set_ldt
(
index
,
(
union
descriptor
*
)
entry
,
1
);
if
(
ret
<
0
)
{
perror
(
"i386_set_ldt"
);
fprintf
(
stderr
,
"Did you reconfigure the kernel with
\"
options USER_LDT
\"
?
\n
"
);
exit
(
1
);
}
}
#endif
/* __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
#if defined(__svr4__) || defined(_SCO_DS)
{
struct
ssd
ldt_mod
;
ldt_mod
.
sel
=
sel
;
ldt_mod
.
bo
=
(
unsigned
long
)
wine_ldt_get_base
(
entry
);
ldt_mod
.
ls
=
entry
->
LimitLow
|
(
entry
->
HighWord
.
Bits
.
LimitHi
<<
16
);
ldt_mod
.
acc1
=
entry
->
HighWord
.
Bytes
.
Flags1
;
ldt_mod
.
acc2
=
entry
->
HighWord
.
Bytes
.
Flags2
>>
4
;
if
((
ret
=
sysi86
(
SI86DSCR
,
&
ldt_mod
))
==
-
1
)
perror
(
"sysi86"
);
}
#endif
#endif
/* __i386__ */
if
(
ret
>=
0
)
{
wine_ldt_copy
.
base
[
index
]
=
wine_ldt_get_base
(
entry
);
wine_ldt_copy
.
limit
[
index
]
=
wine_ldt_get_limit
(
entry
);
wine_ldt_copy
.
flags
[
index
]
=
(
entry
->
HighWord
.
Bits
.
Type
|
(
entry
->
HighWord
.
Bits
.
Default_Big
?
WINE_LDT_FLAGS_32BIT
:
0
)
|
(
wine_ldt_copy
.
flags
[
index
]
&
WINE_LDT_FLAGS_ALLOCATED
));
}
return
ret
;
}
loader/ne/module.c
View file @
914406f8
...
...
@@ -737,7 +737,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
if
(
ne_header
.
ne_cbnrestab
)
{
pModule
->
nrname_handle
=
GLOBAL_Alloc
(
0
,
ne_header
.
ne_cbnrestab
,
hModule
,
FALSE
,
FALSE
,
FALSE
);
hModule
,
WINE_LDT_FLAGS_DATA
);
if
(
!
pModule
->
nrname_handle
)
{
GlobalFree16
(
hModule
);
...
...
@@ -763,7 +763,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
{
pModule
->
dlls_to_init
=
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
(
pModule
->
modref_count
+
1
)
*
sizeof
(
HMODULE16
),
hModule
,
FALSE
,
FALSE
,
FALSE
);
hModule
,
WINE_LDT_FLAGS_DATA
);
if
(
!
pModule
->
dlls_to_init
)
{
if
(
pModule
->
nrname_handle
)
GlobalFree16
(
pModule
->
nrname_handle
);
...
...
loader/ne/resource.c
View file @
914406f8
...
...
@@ -380,7 +380,7 @@ HGLOBAL16 WINAPI AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size)
pNameInfo
=
(
NE_NAMEINFO
*
)((
char
*
)
pModule
+
hRsrc
);
if
(
size
<
(
DWORD
)
pNameInfo
->
length
<<
sizeShift
)
size
=
(
DWORD
)
pNameInfo
->
length
<<
sizeShift
;
return
GLOBAL_Alloc
(
GMEM_FIXED
,
size
,
hModule
,
FALSE
,
FALSE
,
FALSE
);
return
GLOBAL_Alloc
(
GMEM_FIXED
,
size
,
hModule
,
WINE_LDT_FLAGS_DATA
);
}
...
...
@@ -398,7 +398,7 @@ HGLOBAL16 WINAPI DirectResAlloc16( HINSTANCE16 hInstance, WORD wType,
if
(
wType
!=
0x10
)
/* 0x10 is the only observed value, passed from
CreateCursorIndirect. */
TRACE
(
"(wType=%x)
\n
"
,
wType
);
return
GLOBAL_Alloc
(
GMEM_MOVEABLE
,
wSize
,
hInstance
,
FALSE
,
FALSE
,
FALSE
);
return
GLOBAL_Alloc
(
GMEM_MOVEABLE
,
wSize
,
hInstance
,
WINE_LDT_FLAGS_DATA
);
}
...
...
loader/ne/segment.c
View file @
914406f8
...
...
@@ -410,7 +410,7 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
selfloadheader
->
EntryAddrProc
=
NE_GetEntryPoint
(
hselfload
,
27
);
selfloadheader
->
MyAlloc
=
NE_GetEntryPoint
(
hselfload
,
28
);
selfloadheader
->
SetOwner
=
NE_GetEntryPoint
(
GetModuleHandle16
(
"KERNEL"
),
403
);
pModule
->
self_loading_sel
=
SEL
(
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
0xFF00
,
pModule
->
self
,
FALSE
,
FALSE
,
FALSE
));
pModule
->
self_loading_sel
=
SEL
(
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
0xFF00
,
pModule
->
self
,
WINE_LDT_FLAGS_DATA
));
oldstack
=
NtCurrentTeb
()
->
cur_stack
;
NtCurrentTeb
()
->
cur_stack
=
PTR_SEG_OFF_TO_SEGPTR
(
pModule
->
self_loading_sel
,
0xff00
-
sizeof
(
STACK16FRAME
)
);
...
...
@@ -845,6 +845,7 @@ BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum )
{
SEGTABLEENTRY
*
pSeg
=
NE_SEG_TABLE
(
pModule
)
+
segnum
-
1
;
int
minsize
;
unsigned
char
selflags
;
assert
(
!
(
pModule
->
flags
&
NE_FFLAGS_WIN32
)
);
...
...
@@ -861,11 +862,9 @@ BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum )
if
(
segnum
==
pModule
->
ss
)
minsize
+=
pModule
->
stack_size
;
if
(
segnum
==
pModule
->
dgroup
)
minsize
+=
pModule
->
heap_size
;
pSeg
->
hSeg
=
GLOBAL_Alloc
(
NE_Ne2MemFlags
(
pSeg
->
flags
),
minsize
,
pModule
->
self
,
!
(
pSeg
->
flags
&
NE_SEGFLAGS_DATA
),
(
pSeg
->
flags
&
NE_SEGFLAGS_32BIT
)
!=
0
,
FALSE
/*pSeg->flags & NE_SEGFLAGS_READONLY*/
);
selflags
=
(
pSeg
->
flags
&
NE_SEGFLAGS_DATA
)
?
WINE_LDT_FLAGS_DATA
:
WINE_LDT_FLAGS_CODE
;
if
(
pSeg
->
flags
&
NE_SEGFLAGS_32BIT
)
selflags
|=
WINE_LDT_FLAGS_32BIT
;
pSeg
->
hSeg
=
GLOBAL_Alloc
(
NE_Ne2MemFlags
(
pSeg
->
flags
),
minsize
,
pModule
->
self
,
selflags
);
if
(
!
pSeg
->
hSeg
)
return
FALSE
;
pSeg
->
flags
|=
NE_SEGFLAGS_ALLOCATED
;
...
...
loader/task.c
View file @
914406f8
...
...
@@ -169,7 +169,7 @@ static SEGPTR TASK_AllocThunk( HTASK16 hTask )
if
(
!
sel
)
/* Allocate a new segment */
{
sel
=
GLOBAL_Alloc
(
GMEM_FIXED
,
sizeof
(
THUNKS
)
+
(
MIN_THUNKS
-
1
)
*
8
,
pTask
->
hPDB
,
TRUE
,
FALSE
,
FALS
E
);
pTask
->
hPDB
,
WINE_LDT_FLAGS_COD
E
);
if
(
!
sel
)
return
(
SEGPTR
)
0
;
TASK_CreateThunks
(
sel
,
0
,
MIN_THUNKS
);
pThunk
->
next
=
sel
;
...
...
@@ -228,7 +228,7 @@ BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline,
/* Allocate the task structure */
hTask
=
GLOBAL_Alloc
(
GMEM_FIXED
|
GMEM_ZEROINIT
,
sizeof
(
TDB
),
pModule
->
self
,
FALSE
,
FALSE
,
FALSE
);
pModule
->
self
,
WINE_LDT_FLAGS_DATA
);
if
(
!
hTask
)
return
FALSE
;
pTask
=
(
TDB
*
)
GlobalLock16
(
hTask
);
...
...
@@ -268,7 +268,7 @@ BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline,
/* Allocate a selector for the PDB */
pTask
->
hPDB
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
&
pTask
->
pdb
,
sizeof
(
PDB16
),
pModule
->
self
,
FALSE
,
FALSE
,
FALSE
);
pModule
->
self
,
WINE_LDT_FLAGS_DATA
);
/* Fill the PDB */
...
...
@@ -313,8 +313,7 @@ BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline,
/* Allocate a code segment alias for the TDB */
pTask
->
hCSAlias
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
(
void
*
)
pTask
,
sizeof
(
TDB
),
pTask
->
hPDB
,
TRUE
,
FALSE
,
FALSE
);
sizeof
(
TDB
),
pTask
->
hPDB
,
WINE_LDT_FLAGS_CODE
);
/* Set the owner of the environment block */
...
...
memory/Makefile.in
View file @
914406f8
...
...
@@ -12,7 +12,6 @@ C_SRCS = \
global.c
\
heap.c
\
instr.c
\
ldt.c
\
local.c
\
registry.c
\
selector.c
\
...
...
memory/environ.c
View file @
914406f8
...
...
@@ -123,7 +123,7 @@ BOOL ENV_BuildEnvironment(void)
if
(
!
(
p
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
)))
return
FALSE
;
current_envdb
.
environ
=
p
;
current_envdb
.
env_sel
=
SELECTOR_AllocBlock
(
p
,
0x10000
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
current_envdb
.
env_sel
=
SELECTOR_AllocBlock
(
p
,
0x10000
,
WINE_LDT_FLAGS_DATA
);
/* And fill it with the Unix environment */
...
...
@@ -302,7 +302,8 @@ BOOL WINAPI SetEnvironmentVariableA( LPCSTR name, LPCSTR value )
if
(
!
(
new_env
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
env
,
old_size
+
len
)))
goto
done
;
if
(
current_envdb
.
env_sel
)
SELECTOR_MoveBlock
(
current_envdb
.
env_sel
,
new_env
);
current_envdb
.
env_sel
=
SELECTOR_ReallocBlock
(
current_envdb
.
env_sel
,
new_env
,
old_size
+
len
);
p
=
new_env
+
(
p
-
env
);
if
(
len
>
0
)
memmove
(
p
+
len
,
p
,
old_size
-
(
p
-
new_env
)
);
...
...
memory/global.c
View file @
914406f8
...
...
@@ -112,24 +112,20 @@ void debug_handles(void)
* Create a global heap block for a fixed range of linear memory.
*/
HGLOBAL16
GLOBAL_CreateBlock
(
WORD
flags
,
const
void
*
ptr
,
DWORD
size
,
HGLOBAL16
hOwner
,
BOOL16
isCode
,
BOOL16
is32Bit
,
BOOL16
isReadOnly
)
HGLOBAL16
hOwner
,
unsigned
char
selflags
)
{
WORD
sel
,
selcount
;
GLOBALARENA
*
pArena
;
/* Allocate the selector(s) */
sel
=
SELECTOR_AllocBlock
(
ptr
,
size
,
isCode
?
SEGMENT_CODE
:
SEGMENT_DATA
,
is32Bit
,
isReadOnly
);
sel
=
SELECTOR_AllocBlock
(
ptr
,
size
,
selflags
);
if
(
!
sel
)
return
0
;
selcount
=
(
size
+
0xffff
)
/
0x10000
;
if
(
!
(
pArena
=
GLOBAL_GetArena
(
sel
,
selcount
)))
{
SELECTOR_FreeBlock
(
sel
,
selcount
);
SELECTOR_FreeBlock
(
sel
);
return
0
;
}
...
...
@@ -144,7 +140,7 @@ HGLOBAL16 GLOBAL_CreateBlock( WORD flags, const void *ptr, DWORD size,
pArena
->
flags
=
flags
&
GA_MOVEABLE
;
if
(
flags
&
GMEM_DISCARDABLE
)
pArena
->
flags
|=
GA_DISCARDABLE
;
if
(
flags
&
GMEM_DDESHARE
)
pArena
->
flags
|=
GA_IPCSHARE
;
if
(
!
isCode
)
pArena
->
flags
|=
GA_DGROUP
;
if
(
!
(
selflags
&
(
WINE_LDT_FLAGS_CODE
^
WINE_LDT_FLAGS_DATA
))
)
pArena
->
flags
|=
GA_DGROUP
;
pArena
->
selCount
=
selcount
;
if
(
selcount
>
1
)
/* clear the next arena blocks */
memset
(
pArena
+
1
,
0
,
(
selcount
-
1
)
*
sizeof
(
GLOBALARENA
)
);
...
...
@@ -169,7 +165,7 @@ BOOL16 GLOBAL_FreeBlock( HGLOBAL16 handle )
if
(
!
VALID_HANDLE
(
sel
))
return
FALSE
;
pArena
=
GET_ARENA_PTR
(
sel
);
SELECTOR_FreeBlock
(
sel
,
(
pArena
->
size
+
0xffff
)
/
0x10000
);
SELECTOR_FreeBlock
(
sel
);
memset
(
pArena
,
0
,
sizeof
(
GLOBALARENA
)
);
return
TRUE
;
}
...
...
@@ -192,10 +188,7 @@ BOOL16 GLOBAL_MoveBlock( HGLOBAL16 handle, const void *ptr, DWORD size )
pArena
->
base
=
(
DWORD
)
ptr
;
pArena
->
size
=
size
;
SELECTOR_MoveBlock
(
sel
,
ptr
);
SetSelectorLimit16
(
sel
,
size
-
1
);
SELECTOR_ReallocBlock
(
sel
,
ptr
,
size
);
return
TRUE
;
}
...
...
@@ -204,8 +197,7 @@ BOOL16 GLOBAL_MoveBlock( HGLOBAL16 handle, const void *ptr, DWORD size )
*
* Implementation of GlobalAlloc16()
*/
HGLOBAL16
GLOBAL_Alloc
(
UINT16
flags
,
DWORD
size
,
HGLOBAL16
hOwner
,
BOOL16
isCode
,
BOOL16
is32Bit
,
BOOL16
isReadOnly
)
HGLOBAL16
GLOBAL_Alloc
(
UINT16
flags
,
DWORD
size
,
HGLOBAL16
hOwner
,
unsigned
char
selflags
)
{
void
*
ptr
;
HGLOBAL16
handle
;
...
...
@@ -214,8 +206,7 @@ HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner,
/* If size is 0, create a discarded block */
if
(
size
==
0
)
return
GLOBAL_CreateBlock
(
flags
,
NULL
,
1
,
hOwner
,
isCode
,
is32Bit
,
isReadOnly
);
if
(
size
==
0
)
return
GLOBAL_CreateBlock
(
flags
,
NULL
,
1
,
hOwner
,
selflags
);
/* Fixup the size */
...
...
@@ -229,8 +220,7 @@ HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner,
/* Allocate the selector(s) */
handle
=
GLOBAL_CreateBlock
(
flags
,
ptr
,
size
,
hOwner
,
isCode
,
is32Bit
,
isReadOnly
);
handle
=
GLOBAL_CreateBlock
(
flags
,
ptr
,
size
,
hOwner
,
selflags
);
if
(
!
handle
)
{
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
...
...
@@ -255,7 +245,7 @@ HGLOBAL16 WINAPI GlobalAlloc16(
if
(
flags
&
GMEM_DDESHARE
)
owner
=
GetExePtr
(
owner
);
/* Make it a module handle */
return
GLOBAL_Alloc
(
flags
,
size
,
owner
,
FALSE
,
FALSE
,
FALSE
);
return
GLOBAL_Alloc
(
flags
,
size
,
owner
,
WINE_LDT_FLAGS_DATA
);
}
...
...
@@ -333,7 +323,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
ptr
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
ptr
,
size
);
if
(
!
ptr
)
{
SELECTOR_FreeBlock
(
sel
,
(
oldsize
+
0xffff
)
/
0x10000
);
SELECTOR_FreeBlock
(
sel
);
memset
(
pArena
,
0
,
sizeof
(
GLOBALARENA
)
);
return
0
;
}
...
...
@@ -352,7 +342,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
if
(
!
(
pNewArena
=
GLOBAL_GetArena
(
sel
,
selcount
)))
{
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
SELECTOR_FreeBlock
(
sel
,
selcount
);
SELECTOR_FreeBlock
(
sel
);
return
0
;
}
...
...
@@ -699,8 +689,7 @@ DWORD WINAPI GlobalDOSAlloc16(
WORD
wSelector
;
GLOBALARENA
*
pArena
;
wSelector
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
lpBlock
,
size
,
hModule
,
0
,
0
,
0
);
wSelector
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
lpBlock
,
size
,
hModule
,
WINE_LDT_FLAGS_DATA
);
pArena
=
GET_ARENA_PTR
(
wSelector
);
pArena
->
flags
|=
GA_DOSMEM
;
return
MAKELONG
(
wSelector
,
uParagraph
);
...
...
memory/heap.c
View file @
914406f8
...
...
@@ -484,10 +484,13 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
if
(
flags
&
HEAP_WINE_SEGPTR
)
{
selector
=
SELECTOR_AllocBlock
(
address
,
totalSize
,
(
flags
&
(
HEAP_WINE_CODESEG
|
HEAP_WINE_CODE16SEG
))
?
SEGMENT_CODE
:
SEGMENT_DATA
,
(
flags
&
HEAP_WINE_CODESEG
)
!=
0
,
FALSE
);
unsigned
char
selflags
=
WINE_LDT_FLAGS_DATA
;
if
(
flags
&
(
HEAP_WINE_CODESEG
|
HEAP_WINE_CODE16SEG
))
selflags
=
WINE_LDT_FLAGS_CODE
;
if
(
flags
&
HEAP_WINE_CODESEG
)
selflags
|=
WINE_LDT_FLAGS_32BIT
;
selector
=
SELECTOR_AllocBlock
(
address
,
totalSize
,
selflags
);
if
(
!
selector
)
{
ERR
(
"Could not allocate selector
\n
"
);
...
...
@@ -1835,16 +1838,13 @@ HANDLE WINAPI Local32Init16( WORD segment, DWORD tableSize,
nrBlocks
=
(
totSize
+
0x7fff
)
>>
15
;
selectorTable
=
(
LPWORD
)
HeapAlloc
(
header
->
heap
,
0
,
nrBlocks
*
2
);
selectorEven
=
SELECTOR_AllocBlock
(
base
,
totSize
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
selectorOdd
=
SELECTOR_AllocBlock
(
base
+
0x8000
,
totSize
-
0x8000
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
selectorEven
=
SELECTOR_AllocBlock
(
base
,
totSize
,
WINE_LDT_FLAGS_DATA
);
selectorOdd
=
SELECTOR_AllocBlock
(
base
+
0x8000
,
totSize
-
0x8000
,
WINE_LDT_FLAGS_DATA
);
if
(
!
selectorTable
||
!
selectorEven
||
!
selectorOdd
)
{
if
(
selectorTable
)
HeapFree
(
header
->
heap
,
0
,
selectorTable
);
if
(
selectorEven
)
SELECTOR_FreeBlock
(
selectorEven
,
totSize
>>
16
);
if
(
selectorOdd
)
SELECTOR_FreeBlock
(
selectorOdd
,
(
totSize
-
0x8000
)
>>
16
);
if
(
selectorEven
)
SELECTOR_FreeBlock
(
selectorEven
);
if
(
selectorOdd
)
SELECTOR_FreeBlock
(
selectorOdd
);
HeapDestroy
(
header
->
heap
);
VirtualFree
(
base
,
0
,
MEM_RELEASE
);
return
0
;
...
...
memory/instr.c
View file @
914406f8
...
...
@@ -236,7 +236,7 @@ static BYTE *INSTR_GetOperandAddr( CONTEXT86 *context, BYTE *instr,
/* Make sure the segment and offset are valid */
if
(
IS_SELECTOR_SYSTEM
(
seg
))
return
(
BYTE
*
)(
base
+
(
index
<<
ss
));
if
(((
seg
&
7
)
!=
7
)
||
IS_SELECTOR_FREE
(
seg
))
return
NULL
;
if
(
GET_SEL_LIMIT
(
seg
)
<
(
base
+
(
index
<<
ss
)))
return
NULL
;
if
(
wine_ldt_copy
.
limit
[
seg
>>
3
]
<
(
base
+
(
index
<<
ss
)))
return
NULL
;
return
(
BYTE
*
)
PTR_SEG_OFF_TO_LIN
(
seg
,
(
base
+
(
index
<<
ss
))
);
#undef GET_VAL
}
...
...
memory/ldt.c
deleted
100644 → 0
View file @
41d6e2fe
/*
* LDT manipulation functions
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "ldt.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL
(
ldt
);
#ifdef __i386__
#ifdef linux
#ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
#endif
struct
modify_ldt_s
{
unsigned
int
entry_number
;
unsigned
long
base_addr
;
unsigned
int
limit
;
unsigned
int
seg_32bit
:
1
;
unsigned
int
contents
:
2
;
unsigned
int
read_exec_only
:
1
;
unsigned
int
limit_in_pages
:
1
;
unsigned
int
seg_not_present
:
1
;
};
static
inline
int
modify_ldt
(
int
func
,
struct
modify_ldt_s
*
ptr
,
unsigned
long
count
)
{
int
res
;
#ifdef __PIC__
__asm__
__volatile__
(
"pushl %%ebx
\n\t
"
"movl %2,%%ebx
\n\t
"
"int $0x80
\n\t
"
"popl %%ebx"
:
"=a"
(
res
)
:
"0"
(
SYS_modify_ldt
),
"r"
(
func
),
"c"
(
ptr
),
"d"
(
count
)
);
#else
__asm__
__volatile__
(
"int $0x80"
:
"=a"
(
res
)
:
"0"
(
SYS_modify_ldt
),
"b"
(
func
),
"c"
(
ptr
),
"d"
(
count
)
);
#endif
/* __PIC__ */
if
(
res
>=
0
)
return
res
;
errno
=
-
res
;
return
-
1
;
}
#endif
/* linux */
#if defined(__svr4__) || defined(_SCO_DS)
#include <sys/sysi86.h>
extern
int
sysi86
(
int
,
void
*
);
#ifndef __sun__
#include <sys/seg.h>
#endif
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <machine/segments.h>
extern
int
i386_get_ldt
(
int
,
union
descriptor
*
,
int
);
extern
int
i386_set_ldt
(
int
,
union
descriptor
*
,
int
);
#endif
/* __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
#endif
/* __i386__ */
ldt_copy_entry
ldt_copy
[
LDT_SIZE
];
unsigned
char
ldt_flags_copy
[
LDT_SIZE
];
/***********************************************************************
* LDT_BytesToEntry
*
* Convert the raw bytes of the descriptor to an ldt_entry structure.
*/
void
LDT_BytesToEntry
(
const
unsigned
long
*
buffer
,
ldt_entry
*
content
)
{
content
->
base
=
(
*
buffer
>>
16
)
&
0x0000ffff
;
content
->
limit
=
*
buffer
&
0x0000ffff
;
buffer
++
;
content
->
base
|=
(
*
buffer
&
0xff000000
)
|
((
*
buffer
<<
16
)
&
0x00ff0000
);
content
->
limit
|=
(
*
buffer
&
0x000f0000
);
content
->
type
=
(
*
buffer
>>
10
)
&
3
;
content
->
seg_32bit
=
(
*
buffer
&
0x00400000
)
!=
0
;
content
->
read_only
=
(
*
buffer
&
0x00000200
)
==
0
;
content
->
limit_in_pages
=
(
*
buffer
&
0x00800000
)
!=
0
;
}
/***********************************************************************
* LDT_EntryToBytes
*
* Convert an ldt_entry structure to the raw bytes of the descriptor.
*/
void
LDT_EntryToBytes
(
unsigned
long
*
buffer
,
const
ldt_entry
*
content
)
{
*
buffer
++
=
((
content
->
base
&
0x0000ffff
)
<<
16
)
|
(
content
->
limit
&
0x0ffff
);
*
buffer
=
(
content
->
base
&
0xff000000
)
|
((
content
->
base
&
0x00ff0000
)
>>
16
)
|
(
content
->
limit
&
0xf0000
)
|
(
content
->
type
<<
10
)
|
((
content
->
read_only
==
0
)
<<
9
)
|
((
content
->
seg_32bit
!=
0
)
<<
22
)
|
((
content
->
limit_in_pages
!=
0
)
<<
23
)
|
0xf000
;
}
/***********************************************************************
* LDT_GetEntry
*
* Retrieve an LDT entry.
*/
int
LDT_GetEntry
(
int
entry
,
ldt_entry
*
content
)
{
int
ret
=
0
;
content
->
base
=
ldt_copy
[
entry
].
base
;
content
->
limit
=
ldt_copy
[
entry
].
limit
;
content
->
type
=
(
ldt_flags_copy
[
entry
]
&
LDT_FLAGS_TYPE
);
content
->
seg_32bit
=
(
ldt_flags_copy
[
entry
]
&
LDT_FLAGS_32BIT
)
!=
0
;
content
->
read_only
=
(
ldt_flags_copy
[
entry
]
&
LDT_FLAGS_READONLY
)
!=
0
;
content
->
limit_in_pages
=
(
ldt_flags_copy
[
entry
]
&
LDT_FLAGS_BIG
)
!=
0
;
if
(
content
->
limit_in_pages
)
content
->
limit
>>=
12
;
return
ret
;
}
/***********************************************************************
* LDT_SetEntry
*
* Set an LDT entry.
*/
int
LDT_SetEntry
(
int
entry
,
const
ldt_entry
*
content
)
{
int
ret
=
0
;
TRACE
(
"entry=%04x base=%08lx limit=%05lx %s %d-bit "
"flags=%c%c%c
\n
"
,
entry
,
content
->
base
,
content
->
limit
,
content
->
limit_in_pages
?
"pages"
:
"bytes"
,
content
->
seg_32bit
?
32
:
16
,
content
->
read_only
&&
(
content
->
type
&
SEGMENT_CODE
)
?
'-'
:
'r'
,
content
->
read_only
||
(
content
->
type
&
SEGMENT_CODE
)
?
'-'
:
'w'
,
(
content
->
type
&
SEGMENT_CODE
)
?
'x'
:
'-'
);
/* Entry 0 must not be modified; its base and limit are always 0 */
if
(
!
entry
)
return
0
;
#ifdef __i386__
#ifdef linux
{
struct
modify_ldt_s
ldt_info
;
ldt_info
.
entry_number
=
entry
;
ldt_info
.
base_addr
=
content
->
base
;
ldt_info
.
limit
=
content
->
limit
;
ldt_info
.
seg_32bit
=
content
->
seg_32bit
!=
0
;
ldt_info
.
contents
=
content
->
type
;
ldt_info
.
read_exec_only
=
content
->
read_only
!=
0
;
ldt_info
.
limit_in_pages
=
content
->
limit_in_pages
!=
0
;
ldt_info
.
seg_not_present
=
0
;
/* Make sure the info will be accepted by the kernel */
/* This is ugly, but what can I do? */
if
(
content
->
type
==
SEGMENT_STACK
)
{
/* FIXME */
}
else
{
if
(
ldt_info
.
base_addr
>=
0xc0000000
)
{
WARN
(
"Invalid base addr %08lx
\n
"
,
ldt_info
.
base_addr
);
return
-
1
;
}
if
(
content
->
limit_in_pages
)
{
if
((
ldt_info
.
limit
<<
12
)
+
0xfff
>
0xc0000000
-
ldt_info
.
base_addr
)
ldt_info
.
limit
=
(
0xc0000000
-
0xfff
-
ldt_info
.
base_addr
)
>>
12
;
}
else
{
if
(
ldt_info
.
limit
>
0xc0000000
-
ldt_info
.
base_addr
)
ldt_info
.
limit
=
0xc0000000
-
ldt_info
.
base_addr
;
}
}
if
((
ret
=
modify_ldt
(
1
,
&
ldt_info
,
sizeof
(
ldt_info
)))
<
0
)
perror
(
"modify_ldt"
);
}
#endif
/* linux */
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
{
long
d
[
2
];
LDT_EntryToBytes
(
d
,
content
);
ret
=
i386_set_ldt
(
entry
,
(
union
descriptor
*
)
d
,
1
);
if
(
ret
<
0
)
{
perror
(
"i386_set_ldt"
);
MESSAGE
(
"Did you reconfigure the kernel with
\"
options USER_LDT
\"
?
\n
"
);
exit
(
1
);
}
}
#endif
/* __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
#if defined(__svr4__) || defined(_SCO_DS)
{
struct
ssd
ldt_mod
;
int
i
;
ldt_mod
.
sel
=
ENTRY_TO_SELECTOR
(
entry
)
|
4
;
ldt_mod
.
bo
=
content
->
base
;
ldt_mod
.
ls
=
content
->
limit
;
i
=
((
content
->
limit
&
0xf0000
)
|
(
content
->
type
<<
10
)
|
(((
content
->
read_only
!=
0
)
^
1
)
<<
9
)
|
((
content
->
seg_32bit
!=
0
)
<<
22
)
|
((
content
->
limit_in_pages
!=
0
)
<<
23
)
|
(
1
<<
15
)
|
0x7000
);
ldt_mod
.
acc1
=
(
i
&
0xff00
)
>>
8
;
ldt_mod
.
acc2
=
(
i
&
0xf00000
)
>>
20
;
if
(
content
->
base
==
0
)
{
ldt_mod
.
acc1
=
0
;
ldt_mod
.
acc2
=
0
;
}
if
((
ret
=
sysi86
(
SI86DSCR
,
&
ldt_mod
))
==
-
1
)
perror
(
"sysi86"
);
}
#endif
#endif
/* __i386__ */
if
(
ret
<
0
)
return
ret
;
ldt_copy
[
entry
].
base
=
content
->
base
;
if
(
!
content
->
limit_in_pages
)
ldt_copy
[
entry
].
limit
=
content
->
limit
;
else
ldt_copy
[
entry
].
limit
=
(
content
->
limit
<<
12
)
|
0x0fff
;
ldt_flags_copy
[
entry
]
=
(
content
->
type
&
LDT_FLAGS_TYPE
)
|
(
content
->
read_only
?
LDT_FLAGS_READONLY
:
0
)
|
(
content
->
seg_32bit
?
LDT_FLAGS_32BIT
:
0
)
|
(
content
->
limit_in_pages
?
LDT_FLAGS_BIG
:
0
)
|
(
ldt_flags_copy
[
entry
]
&
LDT_FLAGS_ALLOCATED
);
return
ret
;
}
/***********************************************************************
* LDT_Print
*
* Print the content of the LDT on stdout.
*/
void
LDT_Print
(
int
start
,
int
length
)
{
int
i
;
char
flags
[
3
];
if
(
length
==
-
1
)
length
=
LDT_SIZE
-
start
;
for
(
i
=
start
;
i
<
start
+
length
;
i
++
)
{
if
(
!
ldt_copy
[
i
].
base
&&
!
ldt_copy
[
i
].
limit
)
continue
;
/* Free entry */
if
((
ldt_flags_copy
[
i
]
&
LDT_FLAGS_TYPE
)
==
SEGMENT_CODE
)
{
flags
[
0
]
=
(
ldt_flags_copy
[
i
]
&
LDT_FLAGS_EXECONLY
)
?
'-'
:
'r'
;
flags
[
1
]
=
'-'
;
flags
[
2
]
=
'x'
;
}
else
{
flags
[
0
]
=
'r'
;
flags
[
1
]
=
(
ldt_flags_copy
[
i
]
&
LDT_FLAGS_READONLY
)
?
'-'
:
'w'
;
flags
[
2
]
=
'-'
;
}
MESSAGE
(
"%04x: sel=%04x base=%08lx limit=%08lx %d-bit %c%c%c
\n
"
,
i
,
ENTRY_TO_SELECTOR
(
i
),
ldt_copy
[
i
].
base
,
ldt_copy
[
i
].
limit
,
ldt_flags_copy
[
i
]
&
LDT_FLAGS_32BIT
?
32
:
16
,
flags
[
0
],
flags
[
1
],
flags
[
2
]
);
}
}
memory/selector.c
View file @
914406f8
...
...
@@ -18,38 +18,55 @@
DEFAULT_DEBUG_CHANNEL
(
selector
);
#define LDT_SIZE 8192
/* get the number of selectors needed to cover up to the selector limit */
inline
static
WORD
get_sel_count
(
WORD
sel
)
{
return
(
wine_ldt_copy
.
limit
[
sel
>>
__AHSHIFT
]
>>
16
)
+
1
;
}
/***********************************************************************
* AllocSelectorArray (KERNEL.206)
* SELECTOR_AllocArray
*
* Allocate a selector array without setting the LDT entries
*/
WORD
WINAPI
AllocSelectorArray16
(
WORD
count
)
static
WORD
SELECTOR_AllocArray
(
WORD
count
)
{
WORD
i
,
sel
,
size
=
0
;
ldt_entry
entry
;
if
(
!
count
)
return
0
;
for
(
i
=
FIRST_LDT_ENTRY_TO_ALLOC
;
i
<
LDT_SIZE
;
i
++
)
{
if
(
!
IS_LDT_ENTRY_FREE
(
i
)
)
size
=
0
;
if
(
wine_ldt_copy
.
flags
[
i
]
&
WINE_LDT_FLAGS_ALLOCATED
)
size
=
0
;
else
if
(
++
size
>=
count
)
break
;
}
if
(
i
==
LDT_SIZE
)
return
0
;
sel
=
i
-
size
+
1
;
entry
.
base
=
0
;
entry
.
type
=
SEGMENT_DATA
;
entry
.
seg_32bit
=
FALSE
;
entry
.
read_only
=
FALSE
;
entry
.
limit_in_pages
=
FALSE
;
entry
.
limit
=
1
;
/* avoid 0 base and limit */
/* mark selectors as allocated */
for
(
i
=
0
;
i
<
count
;
i
++
)
wine_ldt_copy
.
flags
[
sel
+
i
]
|=
WINE_LDT_FLAGS_ALLOCATED
;
for
(
i
=
0
;
i
<
count
;
i
++
)
return
(
sel
<<
__AHSHIFT
)
|
7
;
}
/***********************************************************************
* AllocSelectorArray (KERNEL.206)
*/
WORD
WINAPI
AllocSelectorArray16
(
WORD
count
)
{
WORD
i
,
sel
=
SELECTOR_AllocArray
(
count
);
if
(
sel
)
{
/* Mark selector as allocated */
ldt_flags_copy
[
sel
+
i
]
|=
LDT_FLAGS_ALLOCATED
;
LDT_SetEntry
(
sel
+
i
,
&
entry
);
LDT_ENTRY
entry
;
wine_ldt_set_base
(
&
entry
,
0
);
wine_ldt_set_limit
(
&
entry
,
1
);
/* avoid 0 base and limit */
wine_ldt_set_flags
(
&
entry
,
WINE_LDT_FLAGS_DATA
);
for
(
i
=
0
;
i
<
count
;
i
++
)
wine_ldt_set_entry
(
sel
+
(
i
<<
__AHSHIFT
),
&
entry
);
}
return
ENTRY_TO_SELECTOR
(
sel
)
;
return
sel
;
}
...
...
@@ -60,17 +77,16 @@ WORD WINAPI AllocSelector16( WORD sel )
{
WORD
newsel
,
count
,
i
;
count
=
sel
?
((
GET_SEL_LIMIT
(
sel
)
>>
16
)
+
1
)
:
1
;
newsel
=
AllocSelectorArray16
(
count
);
TRACE
(
"(%04x): returning %04x
\n
"
,
sel
,
newsel
);
count
=
sel
?
get_sel_count
(
sel
)
:
1
;
newsel
=
SELECTOR_AllocArray
(
count
);
TRACE
(
"(%04x): returning %04x
\n
"
,
sel
,
newsel
);
if
(
!
newsel
)
return
0
;
if
(
!
sel
)
return
newsel
;
/* nothing to copy */
for
(
i
=
0
;
i
<
count
;
i
++
)
{
ldt_entry
entry
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
)
+
i
,
&
entry
);
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
newsel
)
+
i
,
&
entry
);
LDT_ENTRY
entry
;
wine_ldt_get_entry
(
sel
+
(
i
<<
__AHSHIFT
)
,
&
entry
);
wine_ldt_set_entry
(
newsel
+
(
i
<<
__AHSHIFT
)
,
&
entry
);
}
return
newsel
;
}
...
...
@@ -81,8 +97,23 @@ WORD WINAPI AllocSelector16( WORD sel )
*/
WORD
WINAPI
FreeSelector16
(
WORD
sel
)
{
LDT_ENTRY
entry
;
if
(
IS_SELECTOR_FREE
(
sel
))
return
sel
;
/* error */
SELECTOR_FreeBlock
(
sel
,
1
);
#ifdef __i386__
/* Check if we are freeing current %fs or %gs selector */
if
(
!
((
__get_fs
()
^
sel
)
&
~
7
))
{
WARN
(
"Freeing %%fs selector (%04x), not good.
\n
"
,
__get_fs
()
);
__set_fs
(
0
);
}
if
(
!
((
__get_gs
()
^
sel
)
&
~
7
))
__set_gs
(
0
);
#endif
/* __i386__ */
memset
(
&
entry
,
0
,
sizeof
(
entry
)
);
/* clear the LDT entries */
wine_ldt_set_entry
(
sel
,
&
entry
);
wine_ldt_copy
.
flags
[
sel
>>
__AHSHIFT
]
&=
~
WINE_LDT_FLAGS_ALLOCATED
;
return
0
;
}
...
...
@@ -92,32 +123,22 @@ WORD WINAPI FreeSelector16( WORD sel )
*
* Set the LDT entries for an array of selectors.
*/
static
void
SELECTOR_SetEntries
(
WORD
sel
,
const
void
*
base
,
DWORD
size
,
enum
seg_type
type
,
BOOL
is32bit
,
BOOL
readonly
)
static
void
SELECTOR_SetEntries
(
WORD
sel
,
const
void
*
base
,
DWORD
size
,
unsigned
char
flags
)
{
ldt_entry
entry
;
LDT_ENTRY
entry
;
WORD
i
,
count
;
/* The limit for the first selector is the whole */
/* block. The next selectors get a 64k limit. */
entry
.
base
=
(
unsigned
long
)
base
;
entry
.
type
=
type
;
entry
.
seg_32bit
=
is32bit
;
entry
.
read_only
=
readonly
;
entry
.
limit_in_pages
=
(
size
>
0x100000
);
if
(
entry
.
limit_in_pages
)
entry
.
limit
=
((
size
+
0xfff
)
>>
12
)
-
1
;
else
entry
.
limit
=
size
-
1
;
wine_ldt_set_base
(
&
entry
,
base
);
wine_ldt_set_limit
(
&
entry
,
size
-
1
);
wine_ldt_set_flags
(
&
entry
,
flags
);
/* Make sure base and limit are not 0 together if the size is not 0 */
if
(
!
base
&&
!
entry
.
limit
&&
size
)
entry
.
limit
=
1
;
if
(
!
base
&&
size
==
1
)
wine_ldt_set_limit
(
&
entry
,
1
)
;
count
=
(
size
+
0xffff
)
/
0x10000
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
sel
)
+
i
,
&
entry
);
entry
.
base
+=
0x10000
;
/* Apparently the next selectors should *not* get a 64k limit. */
/* Can't remember where I read they should... --AJ */
entry
.
limit
-=
entry
.
limit_in_pages
?
0x10
:
0x10000
;
wine_ldt_set_entry
(
sel
+
(
i
<<
__AHSHIFT
),
&
entry
);
wine_ldt_set_base
(
&
entry
,
wine_ldt_get_base
(
&
entry
)
+
0x10000
);
wine_ldt_set_limit
(
&
entry
,
wine_ldt_get_limit
(
&
entry
)
-
0x10000
);
}
}
...
...
@@ -127,70 +148,29 @@ static void SELECTOR_SetEntries( WORD sel, const void *base, DWORD size,
*
* Allocate selectors for a block of linear memory.
*/
WORD
SELECTOR_AllocBlock
(
const
void
*
base
,
DWORD
size
,
enum
seg_type
type
,
BOOL
is32bit
,
BOOL
readonly
)
WORD
SELECTOR_AllocBlock
(
const
void
*
base
,
DWORD
size
,
unsigned
char
flags
)
{
WORD
sel
,
count
;
if
(
!
size
)
return
0
;
count
=
(
size
+
0xffff
)
/
0x10000
;
sel
=
AllocSelectorArray16
(
count
);
if
(
sel
)
SELECTOR_SetEntries
(
sel
,
base
,
size
,
type
,
is32bit
,
readonly
);
sel
=
SELECTOR_AllocArray
(
count
);
if
(
sel
)
SELECTOR_SetEntries
(
sel
,
base
,
size
,
flags
);
return
sel
;
}
/***********************************************************************
* SELECTOR_MoveBlock
*
* Move a block of selectors in linear memory.
*/
void
SELECTOR_MoveBlock
(
WORD
sel
,
const
void
*
new_base
)
{
WORD
i
,
count
=
(
GET_SEL_LIMIT
(
sel
)
>>
16
)
+
1
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
ldt_entry
entry
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
)
+
i
,
&
entry
);
entry
.
base
=
(
unsigned
long
)
new_base
;
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
sel
)
+
i
,
&
entry
);
}
}
/***********************************************************************
* SELECTOR_FreeBlock
*
* Free a block of selectors.
*/
void
SELECTOR_FreeBlock
(
WORD
sel
,
WORD
count
)
void
SELECTOR_FreeBlock
(
WORD
sel
)
{
WORD
i
,
nextsel
;
ldt_entry
entry
;
WORD
i
,
count
=
get_sel_count
(
sel
);
TRACE
(
"(%04x,%d)
\n
"
,
sel
,
count
);
sel
&=
~
(
__AHINCR
-
1
);
/* clear bottom bits of selector */
nextsel
=
sel
+
(
count
<<
__AHSHIFT
);
#ifdef __i386__
{
/* Check if we are freeing current %fs or %gs selector */
if
((
__get_fs
()
>=
sel
)
&&
(
__get_fs
()
<
nextsel
))
{
WARN
(
"Freeing %%fs selector (%04x), not good.
\n
"
,
__get_fs
()
);
__set_fs
(
0
);
}
if
((
__get_gs
()
>=
sel
)
&&
(
__get_gs
()
<
nextsel
))
__set_gs
(
0
);
}
#endif
/* __i386__ */
memset
(
&
entry
,
0
,
sizeof
(
entry
)
);
/* clear the LDT entries */
for
(
i
=
SELECTOR_TO_ENTRY
(
sel
);
count
;
i
++
,
count
--
)
{
LDT_SetEntry
(
i
,
&
entry
);
ldt_flags_copy
[
i
]
&=
~
LDT_FLAGS_ALLOCATED
;
}
for
(
i
=
0
;
i
<
count
;
i
++
)
FreeSelector16
(
sel
+
(
i
<<
__AHSHIFT
)
);
}
...
...
@@ -201,40 +181,39 @@ void SELECTOR_FreeBlock( WORD sel, WORD count )
*/
WORD
SELECTOR_ReallocBlock
(
WORD
sel
,
const
void
*
base
,
DWORD
size
)
{
ldt_entry
entry
;
LDT_ENTRY
entry
;
WORD
i
,
oldcount
,
newcount
;
if
(
!
size
)
size
=
1
;
oldcount
=
(
GET_SEL_LIMIT
(
sel
)
>>
16
)
+
1
;
oldcount
=
get_sel_count
(
sel
)
;
newcount
=
(
size
+
0xffff
)
>>
16
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
)
,
&
entry
);
wine_ldt_get_entry
(
sel
,
&
entry
);
if
(
oldcount
<
newcount
)
/* We need to add selectors */
{
WORD
index
=
sel
>>
__AHSHIFT
;
/* Check if the next selectors are free */
if
(
SELECTOR_TO_ENTRY
(
sel
)
+
newcount
>
LDT_SIZE
)
i
=
oldcount
;
if
(
index
+
newcount
>
LDT_SIZE
)
i
=
oldcount
;
else
for
(
i
=
oldcount
;
i
<
newcount
;
i
++
)
if
(
!
IS_LDT_ENTRY_FREE
(
SELECTOR_TO_ENTRY
(
sel
)
+
i
)
)
break
;
if
(
wine_ldt_copy
.
flags
[
index
+
i
]
&
WINE_LDT_FLAGS_ALLOCATED
)
break
;
if
(
i
<
newcount
)
/* they are not free */
{
SELECTOR_FreeBlock
(
sel
,
oldcount
);
sel
=
AllocSelectorArray16
(
newcount
);
SELECTOR_FreeBlock
(
sel
);
sel
=
SELECTOR_AllocArray
(
newcount
);
}
else
/* mark the selectors as allocated */
{
for
(
i
=
oldcount
;
i
<
newcount
;
i
++
)
ldt_flags_copy
[
SELECTOR_TO_ENTRY
(
sel
)
+
i
]
|=
LDT_FLAGS_ALLOCATED
;
wine_ldt_copy
.
flags
[
index
+
i
]
|=
WINE_
LDT_FLAGS_ALLOCATED
;
}
}
else
if
(
oldcount
>
newcount
)
/* We need to remove selectors */
{
SELECTOR_FreeBlock
(
ENTRY_TO_SELECTOR
(
SELECTOR_TO_ENTRY
(
sel
)
+
newcount
),
oldcount
-
newcount
);
SELECTOR_FreeBlock
(
sel
+
(
newcount
<<
__AHSHIFT
)
);
}
if
(
sel
)
SELECTOR_SetEntries
(
sel
,
base
,
size
,
entry
.
type
,
entry
.
seg_32bit
,
entry
.
read_only
);
if
(
sel
)
SELECTOR_SetEntries
(
sel
,
base
,
size
,
wine_ldt_get_flags
(
&
entry
)
);
return
sel
;
}
...
...
@@ -244,10 +223,11 @@ WORD SELECTOR_ReallocBlock( WORD sel, const void *base, DWORD size )
*/
WORD
WINAPI
PrestoChangoSelector16
(
WORD
selSrc
,
WORD
selDst
)
{
ldt_entry
entry
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
selSrc
),
&
entry
);
entry
.
type
^=
SEGMENT_CODE
;
/* toggle the executable bit */
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
selDst
),
&
entry
);
LDT_ENTRY
entry
;
wine_ldt_get_entry
(
selSrc
,
&
entry
);
/* toggle the executable bit */
entry
.
HighWord
.
Bits
.
Type
^=
(
WINE_LDT_FLAGS_CODE
^
WINE_LDT_FLAGS_DATA
);
wine_ldt_set_entry
(
selDst
,
&
entry
);
return
selDst
;
}
...
...
@@ -258,15 +238,15 @@ WORD WINAPI PrestoChangoSelector16( WORD selSrc, WORD selDst )
WORD
WINAPI
AllocCStoDSAlias16
(
WORD
sel
)
{
WORD
newsel
;
ldt_entry
entry
;
LDT_ENTRY
entry
;
newsel
=
AllocSelectorArray16
(
1
);
newsel
=
SELECTOR_AllocArray
(
1
);
TRACE
(
"(%04x): returning %04x
\n
"
,
sel
,
newsel
);
if
(
!
newsel
)
return
0
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
)
,
&
entry
);
entry
.
type
=
SEGMENT
_DATA
;
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
newsel
)
,
&
entry
);
wine_ldt_get_entry
(
sel
,
&
entry
);
entry
.
HighWord
.
Bits
.
Type
=
WINE_LDT_FLAGS
_DATA
;
wine_ldt_set_entry
(
newsel
,
&
entry
);
return
newsel
;
}
...
...
@@ -277,15 +257,15 @@ WORD WINAPI AllocCStoDSAlias16( WORD sel )
WORD
WINAPI
AllocDStoCSAlias16
(
WORD
sel
)
{
WORD
newsel
;
ldt_entry
entry
;
LDT_ENTRY
entry
;
newsel
=
AllocSelectorArray16
(
1
);
newsel
=
SELECTOR_AllocArray
(
1
);
TRACE
(
"(%04x): returning %04x
\n
"
,
sel
,
newsel
);
if
(
!
newsel
)
return
0
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
)
,
&
entry
);
entry
.
type
=
SEGMENT
_CODE
;
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
newsel
)
,
&
entry
);
wine_ldt_get_entry
(
sel
,
&
entry
);
entry
.
HighWord
.
Bits
.
Type
=
WINE_LDT_FLAGS
_CODE
;
wine_ldt_set_entry
(
newsel
,
&
entry
);
return
newsel
;
}
...
...
@@ -295,10 +275,10 @@ WORD WINAPI AllocDStoCSAlias16( WORD sel )
*/
void
WINAPI
LongPtrAdd16
(
DWORD
ptr
,
DWORD
add
)
{
ldt_entry
entry
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
SELECTOROF
(
ptr
)
),
&
entry
);
entry
.
base
+=
add
;
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
SELECTOROF
(
ptr
)
),
&
entry
);
LDT_ENTRY
entry
;
wine_ldt_get_entry
(
SELECTOROF
(
ptr
),
&
entry
);
wine_ldt_set_base
(
&
entry
,
(
char
*
)
wine_ldt_get_base
(
&
entry
)
+
add
)
;
wine_ldt_set_entry
(
SELECTOROF
(
ptr
),
&
entry
);
}
...
...
@@ -318,12 +298,12 @@ DWORD WINAPI WIN16_GetSelectorBase( WORD sel )
}
DWORD
WINAPI
GetSelectorBase
(
WORD
sel
)
{
DWORD
base
=
GET_SEL_BASE
(
sel
)
;
void
*
base
=
wine_ldt_copy
.
base
[
sel
>>
__AHSHIFT
]
;
/* if base points into DOSMEM, assume we have to
* return pointer into physical lower 1MB */
return
DOSMEM_MapLinearToDos
(
(
LPVOID
)
base
);
return
DOSMEM_MapLinearToDos
(
base
);
}
...
...
@@ -344,13 +324,10 @@ DWORD WINAPI WIN16_SetSelectorBase( WORD sel, DWORD base )
}
WORD
WINAPI
SetSelectorBase
(
WORD
sel
,
DWORD
base
)
{
ldt_entry
entry
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
entry
.
base
=
(
DWORD
)
DOSMEM_MapDosToLinear
(
base
);
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
LDT_ENTRY
entry
;
wine_ldt_get_entry
(
sel
,
&
entry
);
wine_ldt_set_base
(
&
entry
,
DOSMEM_MapDosToLinear
(
base
)
);
wine_ldt_set_entry
(
sel
,
&
entry
);
return
sel
;
}
...
...
@@ -360,7 +337,7 @@ WORD WINAPI SetSelectorBase( WORD sel, DWORD base )
*/
DWORD
WINAPI
GetSelectorLimit16
(
WORD
sel
)
{
return
GET_SEL_LIMIT
(
sel
)
;
return
wine_ldt_copy
.
limit
[
sel
>>
__AHSHIFT
]
;
}
...
...
@@ -369,12 +346,10 @@ DWORD WINAPI GetSelectorLimit16( WORD sel )
*/
WORD
WINAPI
SetSelectorLimit16
(
WORD
sel
,
DWORD
limit
)
{
ldt_entry
entry
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
entry
.
limit_in_pages
=
(
limit
>=
0x100000
);
if
(
entry
.
limit_in_pages
)
entry
.
limit
=
limit
>>
12
;
else
entry
.
limit
=
limit
;
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
LDT_ENTRY
entry
;
wine_ldt_get_entry
(
sel
,
&
entry
);
wine_ldt_set_limit
(
&
entry
,
limit
);
wine_ldt_set_entry
(
sel
,
&
entry
);
return
sel
;
}
...
...
@@ -384,26 +359,18 @@ WORD WINAPI SetSelectorLimit16( WORD sel, DWORD limit )
*/
WORD
WINAPI
SelectorAccessRights16
(
WORD
sel
,
WORD
op
,
WORD
val
)
{
ldt_entry
entry
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
LDT_ENTRY
entry
;
wine_ldt_get_entry
(
sel
,
&
entry
);
if
(
op
==
0
)
/* get */
{
return
0x01
|
/* accessed */
0x10
|
/* not system */
0x60
|
/* DPL 3 */
0x80
|
/* present */
((
entry
.
read_only
==
0
)
<<
1
)
|
(
entry
.
type
<<
2
)
|
(
entry
.
seg_32bit
<<
14
)
|
(
entry
.
limit_in_pages
<<
15
);
return
entry
.
HighWord
.
Bytes
.
Flags1
|
((
entry
.
HighWord
.
Bytes
.
Flags2
<<
8
)
&
0xf0
);
}
else
/* set */
{
entry
.
read_only
=
((
val
&
2
)
==
0
);
entry
.
type
=
(
val
>>
2
)
&
3
;
entry
.
seg_32bit
=
val
&
0x4000
;
entry
.
limit_in_pages
=
val
&
0x8000
;
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
entry
.
HighWord
.
Bytes
.
Flags1
=
LOBYTE
(
val
)
|
0xf0
;
entry
.
HighWord
.
Bytes
.
Flags2
=
(
entry
.
HighWord
.
Bytes
.
Flags2
&
0x0f
)
|
(
HIBYTE
(
val
)
&
0xf0
);
wine_ldt_set_entry
(
sel
,
&
entry
);
return
0
;
}
}
...
...
@@ -415,14 +382,15 @@ WORD WINAPI SelectorAccessRights16( WORD sel, WORD op, WORD val )
BOOL16
WINAPI
IsBadCodePtr16
(
SEGPTR
lpfn
)
{
WORD
sel
;
ldt_entry
entry
;
LDT_ENTRY
entry
;
sel
=
SELECTOROF
(
lpfn
);
if
(
!
sel
)
return
TRUE
;
if
(
IS_SELECTOR_FREE
(
sel
))
return
TRUE
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
if
(
entry
.
type
!=
SEGMENT_CODE
)
return
TRUE
;
if
(
OFFSETOF
(
lpfn
)
>
GET_SEL_LIMIT
(
sel
))
return
TRUE
;
wine_ldt_get_entry
(
sel
,
&
entry
);
/* check for code segment, ignoring conforming, read-only and accessed bits */
if
((
entry
.
HighWord
.
Bits
.
Type
^
WINE_LDT_FLAGS_CODE
)
&
0x18
)
return
TRUE
;
if
(
OFFSETOF
(
lpfn
)
>
wine_ldt_get_limit
(
&
entry
))
return
TRUE
;
return
FALSE
;
}
...
...
@@ -433,15 +401,17 @@ BOOL16 WINAPI IsBadCodePtr16( SEGPTR lpfn )
BOOL16
WINAPI
IsBadStringPtr16
(
SEGPTR
ptr
,
UINT16
size
)
{
WORD
sel
;
ldt_entry
entry
;
LDT_ENTRY
entry
;
sel
=
SELECTOROF
(
ptr
);
if
(
!
sel
)
return
TRUE
;
if
(
IS_SELECTOR_FREE
(
sel
))
return
TRUE
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
if
((
entry
.
type
==
SEGMENT_CODE
)
&&
entry
.
read_only
)
return
TRUE
;
wine_ldt_get_entry
(
sel
,
&
entry
);
/* check for data or readable code segment */
if
(
!
(
entry
.
HighWord
.
Bits
.
Type
&
0x10
))
return
TRUE
;
/* system descriptor */
if
((
entry
.
HighWord
.
Bits
.
Type
&
0x0a
)
==
0x08
)
return
TRUE
;
/* non-readable code segment */
if
(
strlen
(
PTR_SEG_TO_LIN
(
ptr
))
<
size
)
size
=
strlen
(
PTR_SEG_TO_LIN
(
ptr
))
+
1
;
if
(
size
&&
(
OFFSETOF
(
ptr
)
+
size
-
1
>
GET_SEL_LIMIT
(
sel
)))
return
TRUE
;
if
(
size
&&
(
OFFSETOF
(
ptr
)
+
size
-
1
>
wine_ldt_get_limit
(
&
entry
)))
return
TRUE
;
return
FALSE
;
}
...
...
@@ -452,14 +422,16 @@ BOOL16 WINAPI IsBadStringPtr16( SEGPTR ptr, UINT16 size )
BOOL16
WINAPI
IsBadHugeReadPtr16
(
SEGPTR
ptr
,
DWORD
size
)
{
WORD
sel
;
ldt_entry
entry
;
LDT_ENTRY
entry
;
sel
=
SELECTOROF
(
ptr
);
if
(
!
sel
)
return
TRUE
;
if
(
IS_SELECTOR_FREE
(
sel
))
return
TRUE
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
if
((
entry
.
type
==
SEGMENT_CODE
)
&&
entry
.
read_only
)
return
TRUE
;
if
(
size
&&
(
OFFSETOF
(
ptr
)
+
size
-
1
>
GET_SEL_LIMIT
(
sel
)))
return
TRUE
;
wine_ldt_get_entry
(
sel
,
&
entry
);
/* check for data or readable code segment */
if
(
!
(
entry
.
HighWord
.
Bits
.
Type
&
0x10
))
return
TRUE
;
/* system descriptor */
if
((
entry
.
HighWord
.
Bits
.
Type
&
0x0a
)
==
0x08
)
return
TRUE
;
/* non-readable code segment */
if
(
size
&&
(
OFFSETOF
(
ptr
)
+
size
-
1
>
wine_ldt_get_limit
(
&
entry
)))
return
TRUE
;
return
FALSE
;
}
...
...
@@ -470,14 +442,15 @@ BOOL16 WINAPI IsBadHugeReadPtr16( SEGPTR ptr, DWORD size )
BOOL16
WINAPI
IsBadHugeWritePtr16
(
SEGPTR
ptr
,
DWORD
size
)
{
WORD
sel
;
ldt_entry
entry
;
LDT_ENTRY
entry
;
sel
=
SELECTOROF
(
ptr
);
if
(
!
sel
)
return
TRUE
;
if
(
IS_SELECTOR_FREE
(
sel
))
return
TRUE
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
sel
),
&
entry
);
if
((
entry
.
type
==
SEGMENT_CODE
)
||
entry
.
read_only
)
return
TRUE
;
if
(
size
&&
(
OFFSETOF
(
ptr
)
+
size
-
1
>
GET_SEL_LIMIT
(
sel
)))
return
TRUE
;
wine_ldt_get_entry
(
sel
,
&
entry
);
/* check for writeable data segment, ignoring expand-down and accessed flags */
if
((
entry
.
HighWord
.
Bits
.
Type
^
WINE_LDT_FLAGS_DATA
)
&
~
5
)
return
TRUE
;
if
(
size
&&
(
OFFSETOF
(
ptr
)
+
size
-
1
>
wine_ldt_get_limit
(
&
entry
)))
return
TRUE
;
return
FALSE
;
}
...
...
@@ -514,11 +487,13 @@ BOOL16 WINAPI IsBadFlatReadWritePtr16( SEGPTR ptr, DWORD size, BOOL16 bWrite )
*/
DWORD
WINAPI
MemoryRead16
(
WORD
sel
,
DWORD
offset
,
void
*
buffer
,
DWORD
count
)
{
if
(
IS_SELECTOR_FREE
(
sel
))
return
0
;
if
(
offset
>
GET_SEL_LIMIT
(
sel
))
return
0
;
if
(
offset
+
count
>
GET_SEL_LIMIT
(
sel
)
+
1
)
count
=
GET_SEL_LIMIT
(
sel
)
+
1
-
offset
;
memcpy
(
buffer
,
((
char
*
)
GET_SEL_BASE
(
sel
))
+
offset
,
count
);
WORD
index
=
sel
>>
__AHSHIFT
;
if
(
!
(
wine_ldt_copy
.
flags
[
index
]
&
WINE_LDT_FLAGS_ALLOCATED
))
return
0
;
if
(
offset
>
wine_ldt_copy
.
limit
[
index
])
return
0
;
if
(
offset
+
count
>
wine_ldt_copy
.
limit
[
index
]
+
1
)
count
=
wine_ldt_copy
.
limit
[
index
]
+
1
-
offset
;
memcpy
(
buffer
,
(
char
*
)
wine_ldt_copy
.
base
[
index
]
+
offset
,
count
);
return
count
;
}
...
...
@@ -528,11 +503,13 @@ DWORD WINAPI MemoryRead16( WORD sel, DWORD offset, void *buffer, DWORD count )
*/
DWORD
WINAPI
MemoryWrite16
(
WORD
sel
,
DWORD
offset
,
void
*
buffer
,
DWORD
count
)
{
if
(
IS_SELECTOR_FREE
(
sel
))
return
0
;
if
(
offset
>
GET_SEL_LIMIT
(
sel
))
return
0
;
if
(
offset
+
count
>
GET_SEL_LIMIT
(
sel
)
+
1
)
count
=
GET_SEL_LIMIT
(
sel
)
+
1
-
offset
;
memcpy
(
((
char
*
)
GET_SEL_BASE
(
sel
))
+
offset
,
buffer
,
count
);
WORD
index
=
sel
>>
__AHSHIFT
;
if
(
!
(
wine_ldt_copy
.
flags
[
index
]
&
WINE_LDT_FLAGS_ALLOCATED
))
return
0
;
if
(
offset
>
wine_ldt_copy
.
limit
[
index
])
return
0
;
if
(
offset
+
count
>
wine_ldt_copy
.
limit
[
index
]
+
1
)
count
=
wine_ldt_copy
.
limit
[
index
]
+
1
-
offset
;
memcpy
(
(
char
*
)
wine_ldt_copy
.
base
[
index
]
+
offset
,
buffer
,
count
);
return
count
;
}
...
...
@@ -547,7 +524,7 @@ DWORD WINAPI MemoryWrite16( WORD sel, DWORD offset, void *buffer, DWORD count )
*/
LPVOID
WINAPI
MapSL
(
SEGPTR
sptr
)
{
return
(
LPVOID
)
PTR_SEG_TO_LIN
(
sptr
);
return
(
char
*
)
wine_ldt_copy
.
base
[
SELECTOROF
(
sptr
)
>>
__AHSHIFT
]
+
OFFSETOF
(
sptr
);
}
/***********************************************************************
...
...
@@ -583,7 +560,7 @@ SEGPTR WINAPI MapLS( LPVOID ptr )
return
(
SEGPTR
)
ptr
;
else
{
WORD
sel
=
SELECTOR_AllocBlock
(
ptr
,
0x10000
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
WORD
sel
=
SELECTOR_AllocBlock
(
ptr
,
0x10000
,
WINE_LDT_FLAGS_DATA
);
return
PTR_SEG_OFF_TO_SEGPTR
(
sel
,
0
);
}
}
...
...
@@ -596,8 +573,7 @@ SEGPTR WINAPI MapLS( LPVOID ptr )
*/
void
WINAPI
UnMapLS
(
SEGPTR
sptr
)
{
if
(
SELECTOROF
(
sptr
))
SELECTOR_FreeBlock
(
SELECTOROF
(
sptr
),
1
);
if
(
SELECTOROF
(
sptr
))
FreeSelector16
(
SELECTOROF
(
sptr
)
);
}
/***********************************************************************
...
...
@@ -647,26 +623,16 @@ BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldten
req
->
entry
=
sel
>>
__AHSHIFT
;
if
((
ret
=
!
server_call
(
REQ_GET_SELECTOR_ENTRY
)))
{
if
(
!
(
req
->
flags
&
LDT_FLAGS_ALLOCATED
))
if
(
!
(
req
->
flags
&
WINE_
LDT_FLAGS_ALLOCATED
))
{
SetLastError
(
ERROR_MR_MID_NOT_FOUND
);
/* sic */
ret
=
FALSE
;
}
else
{
if
(
req
->
flags
&
LDT_FLAGS_BIG
)
req
->
limit
>>=
12
;
ldtent
->
BaseLow
=
req
->
base
&
0x0000ffff
;
ldtent
->
HighWord
.
Bits
.
BaseMid
=
(
req
->
base
&
0x00ff0000
)
>>
16
;
ldtent
->
HighWord
.
Bits
.
BaseHi
=
(
req
->
base
&
0xff000000
)
>>
24
;
ldtent
->
LimitLow
=
req
->
limit
&
0x0000ffff
;
ldtent
->
HighWord
.
Bits
.
LimitHi
=
(
req
->
limit
&
0x000f0000
)
>>
16
;
ldtent
->
HighWord
.
Bits
.
Dpl
=
3
;
ldtent
->
HighWord
.
Bits
.
Sys
=
0
;
ldtent
->
HighWord
.
Bits
.
Pres
=
1
;
ldtent
->
HighWord
.
Bits
.
Granularity
=
(
req
->
flags
&
LDT_FLAGS_BIG
)
!=
0
;
ldtent
->
HighWord
.
Bits
.
Default_Big
=
(
req
->
flags
&
LDT_FLAGS_32BIT
)
!=
0
;
ldtent
->
HighWord
.
Bits
.
Type
=
((
req
->
flags
&
LDT_FLAGS_TYPE
)
<<
2
)
|
0x10
;
if
(
!
(
req
->
flags
&
LDT_FLAGS_READONLY
))
ldtent
->
HighWord
.
Bits
.
Type
|=
0x2
;
wine_ldt_set_base
(
ldtent
,
(
void
*
)
req
->
base
);
wine_ldt_set_limit
(
ldtent
,
req
->
limit
);
wine_ldt_set_flags
(
ldtent
,
req
->
flags
);
}
}
}
...
...
msdos/dosmem.c
View file @
914406f8
...
...
@@ -212,7 +212,7 @@ static void DOSMEM_InitDPMI(void)
memcpy
(
ptr
,
enter_xms
,
sizeof
(
enter_xms
)
);
ptr
=
DOSMEM_GetBlock
(
sizeof
(
enter_pm
),
&
DOSMEM_dpmi_seg
);
memcpy
(
ptr
,
enter_pm
,
sizeof
(
enter_pm
)
);
DOSMEM_dpmi_sel
=
SELECTOR_AllocBlock
(
ptr
,
sizeof
(
enter_pm
),
SEGMENT_CODE
,
FALSE
,
FALS
E
);
DOSMEM_dpmi_sel
=
SELECTOR_AllocBlock
(
ptr
,
sizeof
(
enter_pm
),
WINE_LDT_FLAGS_COD
E
);
}
BIOSDATA
*
DOSMEM_BiosData
()
...
...
@@ -506,11 +506,11 @@ BOOL DOSMEM_Init(BOOL dos_init)
setup_dos_mem
(
dos_init
);
DOSMEM_0000H
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
DOSMEM_sysmem
,
0x10000
,
0
,
FALSE
,
FALSE
,
FALSE
);
0x10000
,
0
,
WINE_LDT_FLAGS_DATA
);
DOSMEM_BiosDataSeg
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
DOSMEM_sysmem
+
0x400
,
0x100
,
0
,
FALSE
,
FALSE
,
FALSE
);
0x100
,
0
,
WINE_LDT_FLAGS_DATA
);
DOSMEM_BiosSysSeg
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
DOSMEM_dosmem
+
0xf0000
,
0x10000
,
0
,
FALSE
,
FALSE
,
FALSE
);
0x10000
,
0
,
WINE_LDT_FLAGS_DATA
);
DOSMEM_FillBiosSegments
();
DOSMEM_FillIsrTable
();
DOSMEM_InitMemory
();
...
...
@@ -836,9 +836,8 @@ WORD DOSMEM_AllocSelector(WORD realsel)
HMODULE16
hModule
=
GetModuleHandle16
(
"KERNEL"
);
WORD
sel
;
sel
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
DOSMEM_dosmem
+
realsel
*
16
,
0x10000
,
hModule
,
FALSE
,
FALSE
,
FALSE
);
sel
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
DOSMEM_dosmem
+
realsel
*
16
,
0x10000
,
hModule
,
WINE_LDT_FLAGS_DATA
);
TRACE_
(
selector
)(
"(0x%04x) returns 0x%04x.
\n
"
,
realsel
,
sel
);
return
sel
;
}
...
...
msdos/dpmi.c
View file @
914406f8
...
...
@@ -260,7 +260,7 @@ static void DPMI_CallRMCBProc( CONTEXT86 *context, RMCB *rmcb, WORD flag )
DWORD
esp
,
edi
;
INT_SetRealModeContext
((
REALMODECALL
*
)
PTR_SEG_OFF_TO_LIN
(
rmcb
->
regs_sel
,
rmcb
->
regs_ofs
),
context
);
ss
=
SELECTOR_AllocBlock
(
(
void
*
)(
context
->
SegSs
<<
4
),
0x10000
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
ss
=
SELECTOR_AllocBlock
(
(
void
*
)(
context
->
SegSs
<<
4
),
0x10000
,
WINE_LDT_FLAGS_DATA
);
esp
=
context
->
Esp
;
FIXME
(
"untested!
\n
"
);
...
...
@@ -583,25 +583,24 @@ static void StartPM( CONTEXT86 *context, LPDOSTASK lpDosTask )
DWORD
psp_ofs
=
(
DWORD
)(
lpDosTask
->
psp_seg
<<
4
);
PDB16
*
psp
=
(
PDB16
*
)
psp_ofs
;
HANDLE16
env_seg
=
psp
->
environment
;
int
is32
;
unsigned
char
selflags
=
WINE_LDT_FLAGS_DATA
;
RESET_CFLAG
(
context
);
lpDosTask
->
dpmi_flag
=
AX_reg
(
context
);
is32
=
lpDosTask
->
dpmi_flag
&
1
;
/* our mode switch wrapper have placed the desired CS into DX */
cs
=
SELECTOR_AllocBlock
(
(
void
*
)(
DX_reg
(
context
)
<<
4
),
0x10000
,
SEGMENT_CODE
,
FALSE
,
FALS
E
);
cs
=
SELECTOR_AllocBlock
(
(
void
*
)(
DX_reg
(
context
)
<<
4
),
0x10000
,
WINE_LDT_FLAGS_COD
E
);
/* due to a flaw in some CPUs (at least mine), it is best to mark stack segments as 32-bit if they
can be used in 32-bit code. Otherwise, these CPUs may not set the high word of esp during a
ring transition (from kernel code) to the 16-bit stack, and this causes trouble if executing
32-bit code using this stack. */
ss
=
SELECTOR_AllocBlock
(
(
void
*
)(
context
->
SegSs
<<
4
),
0x10000
,
SEGMENT_DATA
,
is32
,
FALSE
);
if
(
lpDosTask
->
dpmi_flag
&
1
)
selflags
|=
WINE_LDT_FLAGS_32BIT
;
ss
=
SELECTOR_AllocBlock
(
(
void
*
)(
context
->
SegSs
<<
4
),
0x10000
,
selflags
);
/* do the same for the data segments, just in case */
if
(
context
->
SegDs
==
context
->
SegSs
)
ds
=
ss
;
else
ds
=
SELECTOR_AllocBlock
(
(
void
*
)(
context
->
SegDs
<<
4
),
0x10000
,
SEGMENT_DATA
,
is32
,
FALSE
);
es
=
SELECTOR_AllocBlock
(
psp
,
0x100
,
SEGMENT_DATA
,
is32
,
FALSE
);
else
ds
=
SELECTOR_AllocBlock
(
(
void
*
)(
context
->
SegDs
<<
4
),
0x10000
,
selflags
);
es
=
SELECTOR_AllocBlock
(
psp
,
0x100
,
selflags
);
/* convert environment pointer, as the spec says, but we're a bit lazy about the size here... */
psp
->
environment
=
SELECTOR_AllocBlock
(
(
void
*
)(
env_seg
<<
4
),
0x10000
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
psp
->
environment
=
SELECTOR_AllocBlock
(
(
void
*
)(
env_seg
<<
4
),
0x10000
,
WINE_LDT_FLAGS_DATA
);
pm_ctx
=
*
context
;
pm_ctx
.
SegCs
=
DOSMEM_dpmi_sel
;
...
...
@@ -852,24 +851,20 @@ void WINAPI INT_Int31Handler( CONTEXT86 *context )
case
0x000b
:
/* Get descriptor */
TRACE
(
"get descriptor (0x%04x)
\n
"
,
BX_reg
(
context
));
{
ldt_entry
entry
;
LDT_GetEntry
(
SELECTOR_TO_ENTRY
(
BX_reg
(
context
)
),
&
entry
);
entry
.
base
=
W32S_WINE2APP
(
entry
.
base
,
offset
);
LDT_ENTRY
entry
;
wine_ldt_set_base
(
&
entry
,
(
void
*
)
W32S_WINE2APP
(
wine_ldt_get_base
(
&
entry
),
offset
)
);
/* FIXME: should use ES:EDI for 32-bit clients */
LDT_EntryToBytes
(
PTR_SEG_OFF_TO_LIN
(
context
->
SegEs
,
DI_reg
(
context
)
),
&
entry
);
*
(
LDT_ENTRY
*
)
PTR_SEG_OFF_TO_LIN
(
context
->
SegEs
,
LOWORD
(
context
->
Edi
)
)
=
entry
;
}
break
;
case
0x000c
:
/* Set descriptor */
TRACE
(
"set descriptor (0x%04x)
\n
"
,
BX_reg
(
context
));
{
ldt_entry
entry
;
LDT_BytesToEntry
(
PTR_SEG_OFF_TO_LIN
(
context
->
SegEs
,
DI_reg
(
context
)
),
&
entry
);
entry
.
base
=
W32S_APP2WINE
(
entry
.
base
,
offset
);
LDT_SetEntry
(
SELECTOR_TO_ENTRY
(
BX_reg
(
context
)
),
&
entry
);
LDT_ENTRY
entry
=
*
(
LDT_ENTRY
*
)
PTR_SEG_OFF_TO_LIN
(
context
->
SegEs
,
LOWORD
(
context
->
Edi
)
);
wine_ldt_set_base
(
&
entry
,
(
void
*
)
W32S_APP2WINE
(
wine_ldt_get_base
(
&
entry
),
offset
)
);
wine_ldt_set_entry
(
LOWORD
(
context
->
Ebx
),
&
entry
);
}
break
;
...
...
msdos/vxd.c
View file @
914406f8
...
...
@@ -392,8 +392,7 @@ void WINAPI VXD_TimerAPI ( CONTEXT86 *context )
case
0x0009
:
/* get system time selector */
if
(
!
System_Time_Selector
)
{
System_Time_Selector
=
SELECTOR_AllocBlock
(
&
System_Time
,
sizeof
(
DWORD
),
SEGMENT_DATA
,
FALSE
,
TRUE
);
System_Time_Selector
=
SELECTOR_AllocBlock
(
&
System_Time
,
sizeof
(
DWORD
),
WINE_LDT_FLAGS_DATA
);
CreateSystemTimer
(
55
,
System_Time_Tick
);
}
...
...
objects/metafile.c
View file @
914406f8
...
...
@@ -101,7 +101,7 @@ HMETAFILE16 MF_Create_HMETAFILE16(METAHEADER *mh)
size
=
sizeof
(
METAHEADER
)
+
sizeof
(
METAHEADERDISK
);
hmf
=
GLOBAL_CreateBlock
(
GMEM_MOVEABLE
,
mh
,
mh
->
mtSize
*
sizeof
(
WORD
),
GetCurrentPDB16
(),
FALSE
,
FALSE
,
FALSE
);
GetCurrentPDB16
(),
WINE_LDT_FLAGS_DATA
);
return
hmf
;
}
...
...
scheduler/process.c
View file @
914406f8
...
...
@@ -192,8 +192,7 @@ static BOOL process_init( char *argv[] )
struct
init_process_request
*
req
=
server_alloc_req
(
sizeof
(
*
req
),
sizeof
(
main_exe_name
)
-
1
);
req
->
ldt_copy
=
ldt_copy
;
req
->
ldt_flags
=
ldt_flags_copy
;
req
->
ldt_copy
=
&
wine_ldt_copy
;
req
->
ppid
=
getppid
();
if
((
ret
=
!
server_call
(
REQ_INIT_PROCESS
)))
{
...
...
scheduler/thread.c
View file @
914406f8
...
...
@@ -93,7 +93,7 @@ static BOOL THREAD_InitTEB( TEB *teb )
teb
->
stack_top
=
(
void
*
)
~
0UL
;
teb
->
StaticUnicodeString
.
MaximumLength
=
sizeof
(
teb
->
StaticUnicodeBuffer
);
teb
->
StaticUnicodeString
.
Buffer
=
(
PWSTR
)
teb
->
StaticUnicodeBuffer
;
teb
->
teb_sel
=
SELECTOR_AllocBlock
(
teb
,
0x1000
,
SEGMENT_DATA
,
TRUE
,
FALSE
);
teb
->
teb_sel
=
SELECTOR_AllocBlock
(
teb
,
0x1000
,
WINE_LDT_FLAGS_DATA
|
WINE_LDT_FLAGS_32BIT
);
return
(
teb
->
teb_sel
!=
0
);
}
...
...
@@ -196,8 +196,7 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 )
if
(
alloc_stack16
)
{
teb
->
stack_sel
=
SELECTOR_AllocBlock
(
teb
->
stack_top
,
0x10000
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
teb
->
stack_sel
=
SELECTOR_AllocBlock
(
teb
->
stack_top
,
0x10000
,
WINE_LDT_FLAGS_DATA
);
if
(
!
teb
->
stack_sel
)
goto
error
;
teb
->
cur_stack
=
PTR_SEG_OFF_TO_SEGPTR
(
teb
->
stack_sel
,
0x10000
-
sizeof
(
STACK16FRAME
)
);
...
...
server/process.c
View file @
914406f8
...
...
@@ -171,7 +171,6 @@ struct thread *create_process( int fd )
process
->
queue
=
NULL
;
process
->
atom_table
=
NULL
;
process
->
ldt_copy
=
NULL
;
process
->
ldt_flags
=
NULL
;
process
->
exe
.
next
=
NULL
;
process
->
exe
.
prev
=
NULL
;
process
->
exe
.
file
=
NULL
;
...
...
@@ -808,7 +807,6 @@ DECL_HANDLER(init_process)
return
;
}
current
->
process
->
ldt_copy
=
req
->
ldt_copy
;
current
->
process
->
ldt_flags
=
req
->
ldt_flags
;
init_process
(
req
->
ppid
,
req
);
}
...
...
server/thread.c
View file @
914406f8
...
...
@@ -574,7 +574,7 @@ static void get_selector_entry( struct thread *thread, int entry,
unsigned
int
*
base
,
unsigned
int
*
limit
,
unsigned
char
*
flags
)
{
if
(
!
thread
->
process
->
ldt_copy
||
!
thread
->
process
->
ldt_flags
)
if
(
!
thread
->
process
->
ldt_copy
)
{
set_error
(
STATUS_ACCESS_DENIED
);
return
;
...
...
@@ -587,10 +587,10 @@ static void get_selector_entry( struct thread *thread, int entry,
if
(
suspend_for_ptrace
(
thread
))
{
unsigned
char
flags_buf
[
4
];
int
*
addr
=
(
int
*
)
thread
->
process
->
ldt_copy
+
2
*
entry
;
int
*
addr
=
(
int
*
)
thread
->
process
->
ldt_copy
+
entry
;
if
(
read_thread_int
(
thread
,
addr
,
base
)
==
-
1
)
goto
done
;
if
(
read_thread_int
(
thread
,
addr
+
1
,
limit
)
==
-
1
)
goto
done
;
addr
=
(
int
*
)
thread
->
process
->
ldt_
flags
+
(
entry
>>
2
);
if
(
read_thread_int
(
thread
,
addr
+
8192
,
limit
)
==
-
1
)
goto
done
;
addr
=
(
int
*
)
thread
->
process
->
ldt_
copy
+
2
*
8192
+
(
entry
>>
2
);
if
(
read_thread_int
(
thread
,
addr
,
(
int
*
)
flags_buf
)
==
-
1
)
goto
done
;
*
flags
=
flags_buf
[
entry
&
3
];
done:
...
...
server/trace.c
View file @
914406f8
...
...
@@ -324,7 +324,6 @@ static void dump_boot_done_request( const struct boot_done_request *req )
static
void
dump_init_process_request
(
const
struct
init_process_request
*
req
)
{
fprintf
(
stderr
,
" ldt_copy=%p,"
,
req
->
ldt_copy
);
fprintf
(
stderr
,
" ldt_flags=%p,"
,
req
->
ldt_flags
);
fprintf
(
stderr
,
" ppid=%d"
,
req
->
ppid
);
}
...
...
tools/winebuild/relay.c
View file @
914406f8
...
...
@@ -145,18 +145,19 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
else
fprintf
(
outfile
,
"
\t
movw "
PREFIX
"SYSLEVEL_Win16CurrentTeb, %%fs
\n
"
);
/* Get address of ldt_copy array into %ecx */
/* Get address of
wine_
ldt_copy array into %ecx */
if
(
UsePIC
)
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"ldt_copy@GOT(%%ecx), %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"
wine_
ldt_copy@GOT(%%ecx), %%ecx
\n
"
);
else
fprintf
(
outfile
,
"
\t
movl $"
PREFIX
"ldt_copy, %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
movl $"
PREFIX
"
wine_
ldt_copy, %%ecx
\n
"
);
/* Translate STACK16FRAME base to flat offset in %edx */
fprintf
(
outfile
,
"
\t
movw %%ss, %%dx
\n
"
);
fprintf
(
outfile
,
"
\t
andl $0xfff8, %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
shrl $1, %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
movl (%%ecx,%%edx), %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
movzwl %%sp, %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
leal (%%ebp,%%edx), %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
leal (%%ebp,%%edx), %%edx
\n
"
);
/* Get saved flags into %ecx */
fprintf
(
outfile
,
"
\t
popl %%ecx
\n
"
);
...
...
@@ -852,7 +853,8 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
fprintf
(
outfile
,
"
\t
shldl $16,%%ebx,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
andl $0xfff8,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"ldt_copy(%%eax),%%esi
\n
"
);
fprintf
(
outfile
,
"
\t
shrl $1,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"wine_ldt_copy(%%eax),%%esi
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%bx,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
addl %%eax,%%esi
\n
"
);
...
...
tools/winebuild/spec16.c
View file @
914406f8
...
...
@@ -388,7 +388,8 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile, char *prefix, int
case
'p'
:
/* linear pointer */
case
't'
:
/* linear pointer to null-terminated string */
if
(
!
usecdecl
)
pos
-=
4
;
fprintf
(
outfile
,
"PTR_SEG_TO_LIN( *(SEGPTR *)(args+%d) )"
,
pos
);
fprintf
(
outfile
,
"((char*)wine_ldt_copy.base[*(WORD*)(args+%d) >> 3] + *(WORD*)(args+%d))"
,
pos
+
2
,
pos
);
if
(
usecdecl
)
pos
+=
4
;
break
;
...
...
@@ -565,7 +566,11 @@ void BuildSpec16File( FILE *outfile )
input_file_name
);
fprintf
(
outfile
,
"#include
\"
builtin16.h
\"\n\n
"
);
fprintf
(
outfile
,
"extern void RELAY_Unimplemented16(void);
\n\n
"
);
fprintf
(
outfile
,
"extern struct
\n
{
\n
"
);
fprintf
(
outfile
,
" void *base[8192];
\n
"
);
fprintf
(
outfile
,
" unsigned long limit[8192];
\n
"
);
fprintf
(
outfile
,
" unsigned char flags[8192];
\n
"
);
fprintf
(
outfile
,
"} wine_ldt_copy;
\n\n
"
);
data
=
(
unsigned
char
*
)
xmalloc
(
0x10000
);
memset
(
data
,
0
,
16
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment