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
dca5e56b
Commit
dca5e56b
authored
Apr 16, 1999
by
Andreas Mohr
Committed by
Alexandre Julliard
Apr 16, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- Implemented proper ("real", compressed) Win16 entry tables.
- Fixed MyAlloc (AKA NE_AllocateSegment). - Implemented PatchCodeHandle16.
parent
0a997524
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
160 additions
and
143 deletions
+160
-143
builtin.c
if1632/builtin.c
+15
-35
module.h
include/module.h
+14
-0
module.c
loader/ne/module.c
+0
-0
segment.c
loader/ne/segment.c
+114
-93
build.c
tools/build.c
+17
-15
No files found.
if1632/builtin.c
View file @
dca5e56b
...
...
@@ -266,53 +266,33 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force )
LPCSTR
BUILTIN_GetEntryPoint16
(
WORD
cs
,
WORD
ip
,
WORD
*
pOrd
)
{
static
char
buffer
[
80
];
WORD
ordinal
,
i
,
max_offset
;
WORD
i
,
max_offset
;
register
BYTE
*
p
;
NE_MODULE
*
pModule
;
ET_BUNDLE
*
bundle
;
ET_ENTRY
*
entry
;
if
(
!
(
pModule
=
NE_GetPtr
(
FarGetOwner16
(
GlobalHandle16
(
cs
)
))))
return
NULL
;
/* Search for the ordinal */
p
=
(
BYTE
*
)
pModule
+
pModule
->
entry_table
;
max_offset
=
0
;
ordinal
=
1
;
*
pOrd
=
0
;
while
(
*
p
)
{
switch
(
p
[
1
])
{
case
0
:
/* unused */
ordinal
+=
*
p
;
p
+=
2
;
break
;
case
1
:
/* code segment */
i
=
*
p
;
p
+=
2
;
while
(
i
--
>
0
)
bundle
=
(
ET_BUNDLE
*
)((
BYTE
*
)
pModule
+
pModule
->
entry_table
);
entry
=
(
ET_ENTRY
*
)((
BYTE
*
)
bundle
+
6
);
do
{
for
(
i
=
bundle
->
first
+
1
;
i
<
bundle
->
last
;
i
++
)
{
p
++
;
if
((
*
(
WORD
*
)
p
<=
ip
)
&&
(
*
(
WORD
*
)
p
>=
max_offset
))
if
((
entry
->
offs
<=
ip
)
&&
(
entry
->
type
==
1
)
/* code segment ? */
&&
(
entry
->
offs
>=
max_offset
))
{
max_offset
=
*
(
WORD
*
)
p
;
*
pOrd
=
ordinal
;
}
p
+=
2
;
ordinal
++
;
}
break
;
case
0xff
:
/* moveable (should not happen in built-in modules) */
TRACE
(
relay
,
"Built-in module has moveable entry
\n
"
);
ordinal
+=
*
p
;
p
+=
2
+
*
p
*
6
;
break
;
default:
/* other segment */
ordinal
+=
*
p
;
p
+=
2
+
*
p
*
3
;
break
;
max_offset
=
entry
->
offs
;
*
pOrd
=
i
;
}
entry
++
;
}
}
while
(
(
bundle
->
next
)
&&
(
bundle
=
(
ET_BUNDLE
*
)((
BYTE
*
)
pModule
+
bundle
->
next
)));
/* Search for the name in the resident names table */
/* (built-in modules have no non-resident table) */
...
...
include/module.h
View file @
dca5e56b
...
...
@@ -56,6 +56,20 @@ typedef struct _NE_MODULE
}
NE_MODULE
;
typedef
struct
{
BYTE
type
;
BYTE
flags
;
BYTE
segnum
;
WORD
offs
WINE_PACKED
;
}
ET_ENTRY
;
typedef
struct
{
WORD
first
;
/* ordinal */
WORD
last
;
/* ordinal */
WORD
next
;
/* bundle */
}
ET_BUNDLE
;
/* In-memory segment table */
typedef
struct
{
...
...
loader/ne/module.c
View file @
dca5e56b
This diff is collapsed.
Click to expand it.
loader/ne/segment.c
View file @
dca5e56b
...
...
@@ -88,7 +88,7 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
mem
=
GlobalLock16
(
pSeg
->
hSeg
);
if
(
pModule
->
flags
&
NE_FFLAGS_SELFLOAD
&&
segnum
>
1
)
{
/* Implement self
loading segments */
/* Implement self
-
loading segments */
SELFLOADHEADER
*
selfloadheader
;
STACK16FRAME
*
stack16Top
;
DWORD
oldstack
;
...
...
@@ -396,7 +396,7 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
{
HFILE
hf
;
HFILE16
hFile16
;
/* Handle self
loading modules */
/* Handle self
-
loading modules */
SELFLOADHEADER
*
selfloadheader
;
STACK16FRAME
*
stack16Top
;
THDB
*
thdb
=
THREAD_Current
();
...
...
@@ -413,7 +413,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
=
GlobalHandleToSel16
(
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
0xFF00
,
pModule
->
self
,
FALSE
,
FALSE
,
FALSE
));
pModule
->
self_loading_sel
=
SEL
(
GLOBAL_Alloc
(
GMEM_ZEROINIT
,
0xFF00
,
pModule
->
self
,
FALSE
,
FALSE
,
FALSE
));
oldstack
=
thdb
->
cur_stack
;
thdb
->
cur_stack
=
PTR_SEG_OFF_TO_SEGPTR
(
pModule
->
self_loading_sel
,
0xff00
-
sizeof
(
*
stack16Top
)
);
...
...
@@ -453,111 +453,120 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
/***********************************************************************
*
PatchCodeHandle
*
NE_FixupSegmentPrologs
*
*
Needed for self-loading modules.
*
Fixup exported functions prologs of one segment
*/
/* It does nothing */
DWORD
WINAPI
PatchCodeHandle16
(
HANDLE16
hSel
)
void
NE_FixupSegmentPrologs
(
NE_MODULE
*
pModule
,
WORD
segnum
)
{
FIXME
(
module
,
"(%04x): stub.
\n
"
,
hSel
);
return
(
DWORD
)
NULL
;
}
SEGTABLEENTRY
*
pSegTable
=
NE_SEG_TABLE
(
pModule
);
ET_BUNDLE
*
bundle
;
ET_ENTRY
*
entry
;
WORD
dgroup
,
num_entries
,
sel
=
SEL
(
pSegTable
[
segnum
-
1
].
hSeg
);
BYTE
*
pSeg
,
*
pFunc
;
TRACE
(
module
,
"(%d);
\n
"
,
segnum
);
/***********************************************************************
* NE_FixupPrologs
*
* Fixup the exported functions prologs.
*/
void
NE_FixupPrologs
(
NE_MODULE
*
pModule
)
if
(
pSegTable
[
segnum
-
1
].
flags
&
NE_SEGFLAGS_DATA
)
{
SEGTABLEENTRY
*
pSegTable
;
WORD
dgroup
=
0
;
WORD
sel
;
BYTE
*
p
,
*
fixup_ptr
,
count
;
dbg_decl_str
(
module
,
512
)
;
pSegTable
[
segnum
-
1
].
flags
|=
NE_SEGFLAGS_LOADED
;
return
;
}
if
(
!
(
dgroup
=
SEL
(
pSegTable
[
pModule
->
dgroup
-
1
].
hSeg
)))
return
;
pSegTable
=
NE_SEG_TABLE
(
pModule
);
if
(
pModule
->
flags
&
NE_FFLAGS_SINGLEDATA
)
dgroup
=
SEL
(
pSegTable
[
pModule
->
dgroup
-
1
].
hSeg
);
pSeg
=
PTR_SEG_OFF_TO_LIN
(
sel
,
0
);
TRACE
(
module
,
"(%04x)
\n
"
,
pModule
->
self
);
p
=
(
BYTE
*
)
pModule
+
pModule
->
entry_table
;
while
(
*
p
)
bundle
=
(
ET_BUNDLE
*
)((
BYTE
*
)
pModule
+
pModule
->
entry_table
);
do
{
TRACE
(
module
,
"num_entries: %d, bundle: %p, next: %04x, pSeg: %p
\n
"
,
bundle
->
last
-
bundle
->
first
,
bundle
,
bundle
->
next
,
pSeg
);
if
(
!
(
num_entries
=
bundle
->
last
-
bundle
->
first
))
return
;
entry
=
(
ET_ENTRY
*
)((
BYTE
*
)
bundle
+
6
);
while
(
num_entries
--
)
{
if
(
p
[
1
]
==
0
)
/* Unused entry */
/*TRACE(module, "entry: %p, entry->segnum: %d, entry->offs: %04x\n", entry, entry->segnum, entry->offs);*/
if
(
entry
->
segnum
==
segnum
)
{
p
+=
2
;
/* Skip it */
continue
;
}
if
(
p
[
1
]
==
0xfe
)
/* Constant entry */
pFunc
=
((
BYTE
*
)
pSeg
+
entry
->
offs
);
TRACE
(
module
,
"pFunc: %p, *(DWORD *)pFunc: %08lx, num_entries: %d
\n
"
,
pFunc
,
*
(
DWORD
*
)
pFunc
,
num_entries
);
if
(
*
(
pFunc
+
2
)
==
0x90
)
{
p
+=
2
+
*
p
*
3
;
/* Skip it */
continue
;
if
(
*
(
WORD
*
)
pFunc
==
0x581e
)
/* push ds, pop ax */
{
TRACE
(
module
,
"patch %04x:%04x -> mov ax, ds
\n
"
,
sel
,
entry
->
offs
);
*
(
WORD
*
)
pFunc
=
0xd88c
;
/* mov ax, ds */
}
/* Now fixup the entries of this bundle */
count
=
*
p
;
sel
=
p
[
1
];
p
+=
2
;
while
(
count
--
>
0
)
{
dbg_reset_str
(
module
);
dsprintf
(
module
,
"Flags: %04x, sel %02x "
,
*
p
,
sel
);
/* According to the output generated by TDUMP, the flags mean:
* 0x0001 function is exported
* 0x0002 Single data (seems to occur only in DLLs)
*/
if
(
sel
==
0xff
)
{
/* moveable */
dsprintf
(
module
,
"(%02x) o %04x"
,
p
[
3
],
*
(
WORD
*
)(
p
+
4
)
);
fixup_ptr
=
(
char
*
)
GET_SEL_BASE
(
SEL
(
pSegTable
[
p
[
3
]
-
1
].
hSeg
))
+
*
(
WORD
*
)(
p
+
4
);
}
else
{
/* fixed */
dsprintf
(
module
,
"offset %04x"
,
*
(
WORD
*
)(
p
+
1
)
);
fixup_ptr
=
(
char
*
)
GET_SEL_BASE
(
SEL
(
pSegTable
[
sel
-
1
].
hSeg
))
+
*
(
WORD
*
)(
p
+
1
);
}
TRACE
(
module
,
"%s Signature: %02x %02x %02x,ff %x
\n
"
,
dbg_str
(
module
),
fixup_ptr
[
0
],
fixup_ptr
[
1
],
fixup_ptr
[
2
],
pModule
->
flags
);
if
(
*
p
&
0x0001
)
{
/* Verify the signature */
if
(((
fixup_ptr
[
0
]
==
0x1e
&&
fixup_ptr
[
1
]
==
0x58
)
||
(
fixup_ptr
[
0
]
==
0x8c
&&
fixup_ptr
[
1
]
==
0xd8
))
&&
fixup_ptr
[
2
]
==
0x90
)
{
if
(
*
p
&
0x0002
)
{
if
(
pModule
->
flags
&
NE_FFLAGS_MULTIPLEDATA
)
if
(
*
(
WORD
*
)
pFunc
==
0xd88c
)
{
/* can this happen? */
ERR
(
fixup
,
"FixupPrologs got confused
\n
"
);
}
else
if
(
pModule
->
flags
&
NE_FFLAGS_SINGLEDATA
)
if
((
entry
->
flags
&
2
))
/* public data ? */
{
*
fixup_ptr
=
0xb8
;
/* MOV AX, */
*
(
WORD
*
)(
fixup_ptr
+
1
)
=
dgroup
;
}
TRACE
(
module
,
"patch %04x:%04x -> mov ax, dgroup [%04x]
\n
"
,
sel
,
entry
->
offs
,
dgroup
);
*
pFunc
=
0xb8
;
/* mov ax, */
*
(
WORD
*
)(
pFunc
+
1
)
=
dgroup
;
}
else
if
((
pModule
->
flags
&
NE_FFLAGS_MULTIPLEDATA
)
&&
(
entry
->
flags
&
1
))
/* exported ? */
{
if
(
pModule
->
flags
&
NE_FFLAGS_MULTIPLEDATA
)
{
fixup_ptr
[
0
]
=
0x90
;
/* non-library: NOPs */
fixup_ptr
[
1
]
=
0x90
;
fixup_ptr
[
2
]
=
0x90
;
TRACE
(
module
,
"patch %04x:%04x -> nop, nop
\n
"
,
sel
,
entry
->
offs
);
*
(
WORD
*
)
pFunc
=
0x9090
;
/* nop, nop */
}
}
}
else
{
WARN
(
fixup
,
"Unknown signature
\n
"
);
}
}
else
TRACE
(
module
,
"
\n
"
);
p
+=
(
sel
==
0xff
)
?
6
:
3
;
entry
++
;
}
}
while
(
(
bundle
->
next
)
&&
(
bundle
=
((
ET_BUNDLE
*
)((
BYTE
*
)
pModule
+
bundle
->
next
)))
);
}
/***********************************************************************
* PatchCodeHandle
*
* Needed for self-loading modules.
*/
DWORD
WINAPI
PatchCodeHandle16
(
HANDLE16
hSeg
)
{
WORD
segnum
;
WORD
sel
=
SEL
(
hSeg
);
NE_MODULE
*
pModule
=
NE_GetPtr
(
FarGetOwner16
(
sel
));
SEGTABLEENTRY
*
pSegTable
=
NE_SEG_TABLE
(
pModule
);
TRACE
(
module
,
"(%04x);
\n
"
,
hSeg
);
/* find the segment number of the module that belongs to hSeg */
for
(
segnum
=
1
;
segnum
<=
pModule
->
seg_count
;
segnum
++
)
{
if
(
SEL
(
pSegTable
[
segnum
-
1
].
hSeg
)
==
sel
)
{
NE_FixupSegmentPrologs
(
pModule
,
segnum
);
break
;
}
}
return
MAKELONG
(
hSeg
,
sel
);
}
/***********************************************************************
* NE_FixupPrologs
*
* Fixup the exported functions prologs.
*/
void
NE_FixupPrologs
(
NE_MODULE
*
pModule
)
{
WORD
segnum
;
TRACE
(
module
,
"(%04x)
\n
"
,
pModule
->
self
);
if
(
pModule
->
flags
&
NE_FFLAGS_SELFLOAD
)
NE_FixupSegmentPrologs
(
pModule
,
1
);
else
for
(
segnum
=
1
;
segnum
<=
pModule
->
seg_count
;
segnum
++
)
NE_FixupSegmentPrologs
(
pModule
,
segnum
);
}
/***********************************************************************
...
...
@@ -797,23 +806,30 @@ static WORD NE_Ne2MemFlags(WORD flags)
/***********************************************************************
* NE_AllocateSegment (WPROCS.26)
*
* MyAlloc() function for self-loading apps.
*/
DWORD
WINAPI
NE_AllocateSegment
(
WORD
wFlags
,
WORD
wSize
,
WORD
wElem
)
{
WORD
size
=
wSize
<<
wElem
;
HANDLE16
hMem
=
GlobalAlloc16
(
NE_Ne2MemFlags
(
wFlags
),
size
);
HANDLE16
hMem
=
0
;
if
(
wSize
||
(
wFlags
&
NE_SEGFLAGS_MOVEABLE
))
hMem
=
GlobalAlloc16
(
NE_Ne2MemFlags
(
wFlags
),
size
);
/* not data == code */
if
(
(
wFlags
&
NE_SEGFLAGS_EXECUTEONLY
)
||
!
(
wFlags
&
NE_SEGFLAGS_DATA
)
)
{
WORD
hSel
=
GlobalHandleToSel16
(
hMem
);
if
(
((
wFlags
&
0x7
)
!=
0x1
)
&&
/* DATA */
((
wFlags
&
0x7
)
!=
0x7
)
)
/* DATA|ALLOCATED|LOADED */
{
WORD
hSel
=
SEL
(
hMem
);
WORD
access
=
SelectorAccessRights16
(
hSel
,
0
,
0
);
access
|=
2
<<
2
;
/* SEGMENT_CODE */
SelectorAccessRights16
(
hSel
,
1
,
access
);
}
return
MAKELONG
(
hMem
,
GlobalHandleToSel16
(
hMem
)
);
if
(
size
)
return
MAKELONG
(
hMem
,
SEL
(
hMem
)
);
else
return
MAKELONG
(
0
,
hMem
);
}
...
...
@@ -823,12 +839,17 @@ DWORD WINAPI NE_AllocateSegment( WORD wFlags, WORD wSize, WORD wElem )
BOOL
NE_CreateSegments
(
NE_MODULE
*
pModule
)
{
SEGTABLEENTRY
*
pSegment
;
int
i
,
minsize
;
int
i
,
minsize
,
seg_count
;
assert
(
!
(
pModule
->
flags
&
NE_FFLAGS_WIN32
)
);
pSegment
=
NE_SEG_TABLE
(
pModule
);
for
(
i
=
1
;
i
<=
pModule
->
seg_count
;
i
++
,
pSegment
++
)
if
(
pModule
->
flags
&
NE_FFLAGS_SELFLOAD
)
seg_count
=
1
;
else
seg_count
=
pModule
->
seg_count
;
for
(
i
=
1
;
i
<=
seg_count
;
i
++
,
pSegment
++
)
{
minsize
=
pSegment
->
minsize
?
pSegment
->
minsize
:
0x10000
;
if
(
i
==
pModule
->
ss
)
minsize
+=
pModule
->
stack_size
;
...
...
tools/build.c
View file @
dca5e56b
...
...
@@ -796,8 +796,10 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
NE_MODULE
*
pModule
;
SEGTABLEENTRY
*
pSegment
;
OFSTRUCT
*
pFileInfo
;
BYTE
*
pstr
,
*
bundle
;
BYTE
*
pstr
;
WORD
*
pword
;
ET_BUNDLE
*
bundle
=
0
;
ET_ENTRY
*
entry
=
0
;
/* Module layout:
* NE_MODULE Module
...
...
@@ -911,7 +913,6 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
/* Entry table */
pModule
->
entry_table
=
(
int
)
pstr
-
(
int
)
pModule
;
bundle
=
NULL
;
odp
=
OrdinalDefinitions
+
1
;
for
(
i
=
1
;
i
<=
Limit
;
i
++
,
odp
++
)
{
...
...
@@ -943,24 +944,25 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
break
;
}
/* create a new bundle if necessary */
if
(
!
bundle
||
(
bundle
[
0
]
>=
254
)
||
(
bundle
[
1
]
!=
selector
))
if
(
!
bundle
)
{
bundle
=
pstr
;
bundle
[
0
]
=
0
;
bundle
[
1
]
=
selector
;
pstr
+=
2
;
bundle
=
(
ET_BUNDLE
*
)
pstr
;
bundle
->
first
=
0
;
pstr
+=
sizeof
(
ET_BUNDLE
);
}
(
*
bundle
)
++
;
if
(
selector
!=
0
)
{
*
pstr
++
=
1
;
*
(
WORD
*
)
pstr
=
odp
->
offset
;
pstr
+=
sizeof
(
WORD
);
}
/* FIXME: is this really correct ?? */
entry
=
(
ET_ENTRY
*
)
pstr
;
entry
->
type
=
selector
;
entry
->
flags
=
3
;
/* exported & public data */
entry
->
segnum
=
selector
;
entry
->
offs
=
odp
->
offset
;
pstr
+=
sizeof
(
ET_ENTRY
);
}
*
pstr
++
=
0
;
bundle
->
last
=
i
;
bundle
->
next
=
0
;
/* Dump the module content */
...
...
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