3 static char RCSId[] = "$Id: selector.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
4 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
16 #include <linux/unistd.h>
17 #include <linux/head.h>
18 #include <linux/mman.h>
19 #include <linux/a.out.h>
20 #include <linux/ldt.h>
22 #if defined(__NetBSD__) || defined(__FreeBSD__)
24 #include <machine/segments.h>
32 #include "prototypes.h"
34 /* #define DEBUG_SELECTORS */
47 #if defined(__NetBSD__) || defined(__FreeBSD__)
48 #define PAGE_SIZE getpagesize()
49 #define MODIFY_LDT_CONTENTS_DATA 0
50 #define MODIFY_LDT_CONTENTS_STACK 1
51 #define MODIFY_LDT_CONTENTS_CODE 2
55 static SEGDESC
* EnvironmentSelector
= NULL
;
56 static SEGDESC
* PSP_Selector
= NULL
;
57 SEGDESC
* MakeProcThunks
= NULL
;
58 unsigned short PSPSelector
;
59 unsigned char ran_out
= 0;
60 int LastUsedSelector
= FIRST_SELECTOR
- 1;
62 unsigned short SelectorMap
[MAX_SELECTORS
];
63 SEGDESC Segments
[MAX_SELECTORS
];
66 static FILE *zfile
= NULL
;
69 extern void KERNEL_Ordinal_102();
70 extern void UNIXLIB_Ordinal_0();
71 extern char WindowsPath
[256];
75 extern char **environ
;
78 GetEntryPointFromOrdinal(struct w_files
* wpnt
, int ordinal
);
81 /**********************************************************************
87 for (i
= 0; i
< MAX_SELECTORS
; i
++) {
88 if (i
< FIRST_SELECTOR
) {
89 SelectorMap
[i
] = SELECTOR_IS32BIT
;
91 /* quick hack, just reserves 4 meg for wine. */
92 } else if ((i
<< 19) >= 0x8000000 &&
93 (i
<< 19) <= 0x8400000) {
94 SelectorMap
[i
]= SELECTOR_IS32BIT
;
102 if (set_ldt_entry(1, 0x8000000, 65535, 1,0x1a ,1,0)) {
103 perror ("set_ldt_entry");
109 /**********************************************************************
110 * FindUnusedSelectors
113 FindUnusedSelectors(int n_selectors
)
119 for (i
= LastUsedSelector
+ 1; i
!= LastUsedSelector
; i
++)
121 if (i
>= MAX_SELECTORS
)
127 if (SelectorMap
[i
] && n_found
) n_found
=0;
129 if (!SelectorMap
[i
] && ++n_found
== n_selectors
)
133 if (i
== LastUsedSelector
)
136 LastUsedSelector
= i
;
137 return i
- n_selectors
+ 1;
141 /**********************************************************************
144 * Created a shared memory copy of a segment:
146 * - at a new selector location (if "new" is a 16-bit value)
147 * - at an arbitrary memory location (if "new" is a 32-bit value)
150 IPCCopySelector(int i_old
, unsigned long new, int swap_type
)
152 SEGDESC
*s_new
, *s_old
;
156 s_old
= &Segments
[i_old
];
158 if (new & 0xffff0000)
160 /**************************************************************
161 * Let's set the address parameter for no segment.
165 base_addr
= (void *) new;
169 /***************************************************************
170 * We need to fill in the segment descriptor for segment "new".
173 s_new
= &Segments
[i_new
];
175 SelectorMap
[i_new
] = i_new
;
177 s_new
->selector
= (i_new
<< 3) | 0x0007;
178 s_new
->base_addr
= (void *) ((long) s_new
->selector
<< 16);
179 s_new
->length
= s_old
->length
;
180 s_new
->flags
= s_old
->flags
;
181 s_new
->owner
= s_old
->owner
;
184 if (s_old
->type
== MODIFY_LDT_CONTENTS_DATA
)
185 s_new
->type
= MODIFY_LDT_CONTENTS_CODE
;
187 s_new
->type
= MODIFY_LDT_CONTENTS_DATA
;
190 s_new
->type
= s_old
->type
;
192 base_addr
= s_new
->base_addr
;
195 /******************************************************************
196 * If we don't have a shared memory key for s_old, then we need
197 * to get one. In this case, we'll also have to copy the data
200 if (s_old
->shm_key
== -1)
202 s_old
->shm_key
= shmget(IPC_PRIVATE
, s_old
->length
, IPC_CREAT
| 0600);
203 if (s_old
->shm_key
== -1)
206 memset(s_new
, 0, sizeof(*s_new
));
211 if (shmat(s_old
->shm_key
, base_addr
, 0) == (char *) -1)
214 memset(s_new
, 0, sizeof(*s_new
));
217 shmctl(s_old
->shm_key
, IPC_RMID
, NULL
);
220 memcpy(base_addr
, s_old
->base_addr
, s_old
->length
);
221 munmap(s_old
->base_addr
,
222 ((s_old
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1)));
223 shmat(s_old
->shm_key
, s_old
->base_addr
, 0);
225 /******************************************************************
226 * If have shared memory key s_old, then just attach the new
231 if (shmat(s_old
->shm_key
, base_addr
, 0) == (char *) -1)
234 memset(s_new
, 0, sizeof(*s_new
));
241 /******************************************************************
242 * If we are creating a new segment, then we also need to update
243 * the LDT to include the new selector. In this return the
248 s_new
->shm_key
= s_old
->shm_key
;
250 if (set_ldt_entry(i_new
, (unsigned long) base_addr
,
251 s_old
->length
- 1, 0, s_new
->type
, 0, 0) < 0)
256 return s_new
->selector
;
258 /******************************************************************
259 * No new segment. So, just return the shared memory key.
262 return s_old
->shm_key
;
266 /**********************************************************************
269 * This is very bad!!! This function is implemented for Windows
270 * compatibility only. Do not call this from the emulation library.
272 WORD
AllocSelector(WORD old_selector
)
278 i_new
= FindUnusedSelectors(1);
279 s_new
= &Segments
[i_new
];
283 i_old
= (old_selector
>> 3);
285 selector
= IPCCopySelector(i_old
, i_new
, 0);
291 s_old
= &Segments
[i_old
];
292 s_new
->selector
= (i_new
<< 3) | 0x0007;
294 SelectorMap
[i_new
] = SelectorMap
[i_old
];
296 if (set_ldt_entry(i_new
, s_new
->base_addr
,
297 s_new
->length
- 1, 0,
298 s_new
->type
, 0, 0) < 0)
306 memset(s_new
, 0, sizeof(*s_new
));
310 SelectorMap
[i_new
] = i_new
;
313 return (i_new
<< 3) | 0x0007;
316 /**********************************************************************
317 * PrestoChangoSelector
319 * This is very bad!!! This function is implemented for Windows
320 * compatibility only. Do not call this from the emulation library.
322 unsigned int PrestoChangoSelector(unsigned src_selector
, unsigned dst_selector
)
326 int src_idx
, dst_idx
;
328 src_idx
= src_selector
>> 3;
329 dst_idx
= dst_selector
>> 3;
331 if (src_idx
== dst_idx
)
333 src_s
= &Segments
[src_idx
];
335 if (src_s
->type
== MODIFY_LDT_CONTENTS_DATA
)
336 src_s
->type
= MODIFY_LDT_CONTENTS_CODE
;
338 src_s
->type
= MODIFY_LDT_CONTENTS_DATA
;
340 if (set_ldt_entry(src_idx
, (long) src_s
->base_addr
,
341 src_s
->length
- 1, 0, src_s
->type
, 0, 0) < 0)
346 return src_s
->selector
;
350 return IPCCopySelector(src_idx
, dst_idx
, 1);
353 SEGDESC
*src_s
, *dst_s
;
355 int src_idx
, dst_idx
;
359 src_idx
= (SelectorMap
[src_selector
>> 3]);
360 dst_idx
= dst_selector
>> 3;
361 src_s
= &Segments
[src_idx
];
362 dst_s
= &Segments
[dst_idx
];
365 for (i
= FIRST_SELECTOR
; i
< MAX_SELECTORS
; i
++)
366 if (SelectorMap
[i
] == src_idx
)
369 if (src_s
->type
== MODIFY_LDT_CONTENTS_DATA
370 || alias_count
> 1 || src_idx
== dst_idx
)
374 if (src_s
->type
== MODIFY_LDT_CONTENTS_DATA
)
375 dst_s
->type
= MODIFY_LDT_CONTENTS_CODE
;
377 dst_s
->type
= MODIFY_LDT_CONTENTS_DATA
;
379 SelectorMap
[dst_idx
] = SelectorMap
[src_idx
];
380 if (set_ldt_entry(dst_idx
, (long) dst_s
->base_addr
,
381 dst_s
->length
- 1, 0, dst_s
->type
, 0, 0) < 0)
389 * We're changing an unaliased code segment into a data
390 * segment. The SAFEST (but ugliest) way to deal with
391 * this is to map the new segment and copy all the contents.
393 SelectorMap
[dst_idx
] = dst_idx
;
395 dst_s
->selector
= (dst_idx
<< 3) | 0x0007;
396 dst_s
->base_addr
= (void *) ((unsigned int) dst_s
->selector
<< 16);
397 dst_s
->type
= MODIFY_LDT_CONTENTS_DATA
;
400 zfile
= fopen("/dev/zero","r");
401 p
= (void *) mmap((char *) dst_s
->base_addr
,
402 ((dst_s
->length
+ PAGE_SIZE
-1)
404 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
405 MAP_FIXED
| MAP_PRIVATE
, fileno(zfile
), 0);
407 p
= (void *) mmap((char *) dst_s
->base_addr
,
408 ((dst_s
->length
+ PAGE_SIZE
-1)
410 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
411 MAP_FIXED
| MAP_PRIVATE
| MAP_ANON
, -1, 0);
416 memcpy((void *) dst_s
->base_addr
, (void *) src_s
->base_addr
,
418 if (set_ldt_entry(src_idx
, dst_s
->base_addr
,
419 dst_s
->length
- 1, 0, dst_s
->type
, 0, 0) < 0)
423 if (set_ldt_entry(dst_idx
, dst_s
->base_addr
,
424 dst_s
->length
- 1, 0, dst_s
->type
, 0, 0) < 0)
429 munmap(src_s
->base_addr
,
430 (src_s
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1));
431 SelectorMap
[src_idx
] = dst_idx
;
432 src_s
->base_addr
= dst_s
->base_addr
;
435 return dst_s
->selector
;
436 #endif /* HAVE_IPC */
439 /**********************************************************************
442 WORD
AllocDStoCSAlias(WORD ds_selector
)
444 unsigned int cs_selector
;
446 if (ds_selector
== 0)
449 cs_selector
= AllocSelector(0);
450 return PrestoChangoSelector(ds_selector
, cs_selector
);
453 /**********************************************************************
457 void CleanupSelectors(void)
461 for (sel_idx
= FIRST_SELECTOR
; sel_idx
< MAX_SELECTORS
; sel_idx
++)
462 if (SelectorMap
[sel_idx
])
463 FreeSelector((sel_idx
<< 3) | 7);
466 /**********************************************************************
469 WORD
FreeSelector(WORD sel
)
479 if (sel_idx
< FIRST_SELECTOR
|| sel_idx
>= MAX_SELECTORS
)
482 s
= &Segments
[sel_idx
];
483 if (s
->shm_key
== -1)
485 munmap(s
->base_addr
, ((s
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1)));
486 memset(s
, 0, sizeof(*s
));
488 SelectorMap
[sel_idx
] = 0;
495 for (i
= FIRST_SELECTOR
; i
< MAX_SELECTORS
; i
++)
496 if (SelectorMap
[i
] && Segments
[i
].shm_key
== s
->shm_key
)
499 if (alias_count
== 1)
500 shmctl(s
->shm_key
, IPC_RMID
, NULL
);
502 memset(s
, 0, sizeof(*s
));
504 SelectorMap
[sel_idx
] = 0;
508 sel_idx
= SelectorMap
[sel
>> 3];
510 if (sel_idx
< FIRST_SELECTOR
|| sel_idx
>= MAX_SELECTORS
)
513 if (sel_idx
!= (sel
>> 3))
515 SelectorMap
[sel
>> 3] = 0;
520 for (i
= FIRST_SELECTOR
; i
< MAX_SELECTORS
; i
++)
521 if (SelectorMap
[i
] == sel_idx
)
524 if (alias_count
== 1)
526 s
= &Segments
[sel_idx
];
527 munmap(s
->base_addr
, ((s
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1)));
528 memset(s
, 0, sizeof(*s
));
529 SelectorMap
[sel
>> 3] = 0;
531 #endif /* HAVE_IPC */
536 /**********************************************************************
540 CreateNewSegments(int code_flag
, int read_only
, int length
, int n_segments
)
542 SEGDESC
*s
, *first_segment
;
546 i
= FindUnusedSelectors(n_segments
);
548 dprintf_selectors(stddeb
, "Using %d segments starting at index %d.\n",
552 * Fill in selector info.
554 first_segment
= s
= &Segments
[i
];
555 for (last_i
= i
+ n_segments
; i
< last_i
; i
++, s
++)
559 contents
= MODIFY_LDT_CONTENTS_CODE
;
564 contents
= MODIFY_LDT_CONTENTS_DATA
;
565 s
->flags
= NE_SEGFLAGS_DATA
;
568 s
->selector
= (i
<< 3) | 0x0007;
572 zfile
= fopen("/dev/zero","r");
573 s
->base_addr
= (void *) mmap((char *) (s
->selector
<< 16),
574 ((s
->length
+ PAGE_SIZE
- 1) &
576 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
577 MAP_FIXED
| MAP_PRIVATE
,
580 s
->base_addr
= (void *) mmap((char *) (s
->selector
<< 16),
581 ((s
->length
+ PAGE_SIZE
- 1) &
583 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
584 MAP_FIXED
| MAP_PRIVATE
| MAP_ANON
,
590 if (set_ldt_entry(i
, (unsigned long) s
->base_addr
,
591 (s
->length
- 1) & 0xffff, 0,
592 contents
, read_only
, 0) < 0)
594 memset(s
, 0, sizeof(*s
));
601 SelectorMap
[i
] = (unsigned short) i
;
605 return first_segment
;
608 /**********************************************************************
612 GetNextSegment(unsigned int flags
, unsigned int limit
)
614 return CreateNewSegments(0, 0, limit
, 1);
617 /**********************************************************************
618 * GetEntryPointFromOrdinal
621 struct entry_tab_header_s
*eth
;
622 struct entry_tab_movable_s
*etm
;
623 struct entry_tab_fixed_s
*etf
;
627 unsigned int GetEntryDLLName(char * dll_name
, char * function
, int * sel
,
630 struct dll_table_entry_s
*dll_table
;
631 struct w_files
* wpnt
;
635 dll_table
= FindDLLTable(dll_name
);
638 ordinal
= FindOrdinalFromName(dll_table
, function
);
639 *sel
= dll_table
[ordinal
].selector
;
640 *addr
= (unsigned int) dll_table
[ordinal
].address
;
642 dll_table
[ordinal
].used
++;
647 /* We need a means of determining the ordinal for the function. */
648 /* Not a builtin symbol, look to see what the file has for us */
649 for(wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
){
650 if(strcasecmp(wpnt
->name
, dll_name
)) continue;
651 cpnt
= wpnt
->ne
->nrname_table
;
653 if( ((int) cpnt
) - ((int)wpnt
->ne
->nrname_table
) >
654 wpnt
->ne
->ne_header
->nrname_tab_length
) return 1;
656 if(strncmp(cpnt
, function
, len
) == 0) break;
659 ordinal
= *((unsigned short *) (cpnt
+ len
));
660 j
= GetEntryPointFromOrdinal(wpnt
, ordinal
);
669 unsigned int GetEntryDLLOrdinal(char * dll_name
, int ordinal
, int * sel
,
672 struct dll_table_entry_s
*dll_table
;
673 struct w_files
* wpnt
;
676 dll_table
= FindDLLTable(dll_name
);
679 *sel
= dll_table
[ordinal
].selector
;
680 *addr
= (unsigned int) dll_table
[ordinal
].address
;
682 dll_table
[ordinal
].used
++;
687 /* Not a builtin symbol, look to see what the file has for us */
688 for(wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
){
689 if(strcasecmp(wpnt
->name
, dll_name
)) continue;
690 j
= GetEntryPointFromOrdinal(wpnt
, ordinal
);
700 GetEntryPointFromOrdinal(struct w_files
* wpnt
, int ordinal
)
702 union lookup entry_tab_pointer
;
703 struct entry_tab_header_s
*eth
;
704 struct entry_tab_movable_s
*etm
;
705 struct entry_tab_fixed_s
*etf
;
709 entry_tab_pointer
.cpnt
= wpnt
->ne
->lookup_table
;
711 * Let's walk through the table until we get to our entry.
717 * Read header for this bundle.
719 eth
= entry_tab_pointer
.eth
++;
721 if (eth
->n_entries
== 0)
722 return 0xffffffff; /* Yikes - we went off the end of the table */
724 if (eth
->seg_number
== 0)
726 current_ordinal
+= eth
->n_entries
;
727 if(current_ordinal
> ordinal
) return 0;
732 * Read each of the bundle entries.
734 for (i
= 0; i
< eth
->n_entries
; i
++, current_ordinal
++)
736 if (eth
->seg_number
>= 0xfe)
738 etm
= entry_tab_pointer
.etm
++;
740 if (current_ordinal
== ordinal
)
742 return ((unsigned int)
743 (wpnt
->ne
->selector_table
[etm
->seg_number
- 1].base_addr
+
749 etf
= entry_tab_pointer
.etf
++;
751 if (current_ordinal
== ordinal
)
753 return ((unsigned int)
754 (wpnt
->ne
->selector_table
[eth
->seg_number
- 1].base_addr
+
755 (int) etf
->offset
[0] +
756 ((int) etf
->offset
[1] << 8)));
763 /**********************************************************************
766 LPSTR
GetDOSEnvironment(void)
768 return (LPSTR
) EnvironmentSelector
->base_addr
;
771 /**********************************************************************
775 CreateEnvironment(void)
781 s
= CreateNewSegments(0, 0, PAGE_SIZE
, 1);
786 * Fill environment with Windows path, the Unix environment,
789 p
= (char *) s
->base_addr
;
791 strcat(p
, WindowsPath
);
794 for (e
= environ
; *e
; e
++)
796 if (strncasecmp(*e
, "path", 4))
806 * Display environment
808 dprintf_selectors(stddeb
, "Environment at %p\n", s
->base_addr
);
809 for (p
= s
->base_addr
; *p
; p
+= strlen(p
) + 1)
810 dprintf_selectors(stddeb
, " %s\n", p
);
815 /**********************************************************************
822 /**********************************************************************
828 struct dos_psp_s
*psp
;
834 s
= CreateNewSegments(0, 0, PAGE_SIZE
, 1);
839 PSPSelector
= s
->selector
;
840 psp
= (struct dos_psp_s
*) s
->base_addr
;
841 psp
->pspInt20
= 0x20cd;
842 psp
->pspDispatcher
[0] = 0x9a;
843 usp
= (unsigned short *) &psp
->pspDispatcher
[1];
844 *usp
= (unsigned short) KERNEL_Ordinal_102
;
845 *(usp
+ 1) = UTEXTSEL
;
846 psp
->pspTerminateVector
[0] = (unsigned short) UNIXLIB_Ordinal_0
;
847 psp
->pspTerminateVector
[1] = UTEXTSEL
;
848 psp
->pspControlCVector
[0] = (unsigned short) UNIXLIB_Ordinal_0
;
849 psp
->pspControlCVector
[1] = UTEXTSEL
;
850 psp
->pspCritErrorVector
[0] = (unsigned short) UNIXLIB_Ordinal_0
;
851 psp
->pspCritErrorVector
[1] = UTEXTSEL
;
852 psp
->pspEnvironment
= EnvironmentSelector
->selector
;
854 p1
= psp
->pspCommandTail
;
855 for (i
= 1; i
< Argc
; i
++)
857 if ((int) ((int) p1
- (int) psp
->pspCommandTail
) +
858 strlen(Argv
[i
]) > 124)
864 for (p2
= Argv
[i
]; *p2
!= '\0'; )
869 psp
->pspCommandTailCount
= strlen(psp
->pspCommandTail
);
874 /**********************************************************************
878 CreateSelectors(struct w_files
* wpnt
)
881 struct ne_segment_table_entry_s
*seg_table
= wpnt
->ne
->seg_table
;
882 struct ne_header_s
*ne_header
= wpnt
->ne
->ne_header
;
883 SEGDESC
*selectors
, *s
;
884 unsigned short auto_data_sel
;
885 int contents
, read_only
;
886 int SelectorTableLength
;
889 int old_length
, file_image_length
;
890 int saved_old_length
;
894 * Allocate memory for the table to keep track of all selectors.
896 SelectorTableLength
= ne_header
->n_segment_tab
;
897 selectors
= malloc(SelectorTableLength
* sizeof(*selectors
));
898 if (selectors
== NULL
)
902 * Step through the segment table in the exe header.
905 for (i
= 0; i
< ne_header
->n_segment_tab
; i
++, s
++)
908 * Store the flags in our table.
910 s
->flags
= seg_table
[i
].seg_flags
;
913 * Is there an image for this segment in the file?
915 if (seg_table
[i
].seg_data_offset
== 0)
918 * No image in exe file, let's allocate some memory for it.
920 s
->length
= seg_table
[i
].min_alloc
;
925 * Image in file, let's just point to the image in memory.
927 s
->length
= seg_table
[i
].min_alloc
;
928 file_image_length
= seg_table
[i
].seg_data_length
;
929 if (file_image_length
== 0) file_image_length
= 0x10000;
934 old_length
= s
->length
;
937 * If this is the automatic data segment, its size must be adjusted.
938 * First we need to check for local heap. Second we nee to see if
939 * this is also the stack segment.
941 if (i
+ 1 == ne_header
->auto_data_seg
|| i
+ 1 == ne_header
->ss
)
944 ne_header
->sp
= s
->length
- 2;
948 * Is this a DATA or CODE segment?
951 if (s
->flags
& NE_SEGFLAGS_DATA
)
953 contents
= MODIFY_LDT_CONTENTS_DATA
;
954 if (s
->flags
& NE_SEGFLAGS_READONLY
)
959 contents
= MODIFY_LDT_CONTENTS_CODE
;
960 if (s
->flags
& NE_SEGFLAGS_EXECUTEONLY
)
965 stmp
= CreateNewSegments(!(s
->flags
& NE_SEGFLAGS_DATA
), read_only
,
967 s
->base_addr
= stmp
->base_addr
;
968 s
->selector
= stmp
->selector
;
970 s
->selector
= GlobalAlloc(GMEM_FIXED
, s
->length
);
971 if (s
->selector
== 0)
972 myerror("CreateSelectors: GlobalAlloc() failed");
974 s
->base_addr
= (void *) ((LONG
) s
->selector
<< 16);
978 if (!(s
->flags
& NE_SEGFLAGS_DATA
))
979 PrestoChangoSelector(s
->selector
, s
->selector
);
981 memset(s
->base_addr
, 0, s
->length
);
983 if (seg_table
[i
].seg_data_offset
!= 0)
988 status
= lseek(fd
, seg_table
[i
].seg_data_offset
*
989 (1 << ne_header
->align_shift_count
), SEEK_SET
);
990 if(read(fd
, s
->base_addr
, file_image_length
) != file_image_length
)
991 myerror("Unable to read segment from file");
995 * If this is the automatic data segment, then we must initialize
998 if (i
+ 1 == ne_header
->auto_data_seg
)
1000 auto_data_sel
= s
->selector
;
1001 saved_old_length
= old_length
;
1005 if(!auto_data_sel
)dprintf_selectors(stddeb
,"Warning: No auto_data_sel\n");
1007 for (i
= 0; i
< ne_header
->n_segment_tab
; i
++, s
++)
1009 Segments
[s
->selector
>> 3].owner
= auto_data_sel
;
1010 if (s
->selector
== auto_data_sel
)
1011 HEAP_LocalInit(auto_data_sel
, s
->base_addr
+ saved_old_length
,
1012 0x10000 - 2 - saved_old_length
1013 - ne_header
->stack_length
);
1016 if(!EnvironmentSelector
) {
1017 EnvironmentSelector
= CreateEnvironment();
1018 PSP_Selector
= CreatePSP();
1019 MakeProcThunks
= CreateNewSegments(1, 0, 0x10000, 1);
1024 /**********************************************************************
1027 FixupFunctionPrologs(struct w_files
* wpnt
)
1029 struct ne_header_s
*ne_header
= wpnt
->ne
->ne_header
;
1030 union lookup entry_tab_pointer
;
1031 struct entry_tab_header_s
*eth
;
1032 struct entry_tab_movable_s
*etm
;
1033 struct entry_tab_fixed_s
*etf
;
1034 unsigned char *fixup_ptr
;
1037 if (!(ne_header
->format_flags
& 0x0001))
1040 entry_tab_pointer
.cpnt
= wpnt
->ne
->lookup_table
;
1042 * Let's walk through the table and fixup prologs as we go.
1046 /* Get bundle header */
1047 eth
= entry_tab_pointer
.eth
++;
1049 /* Check for end of table */
1050 if (eth
->n_entries
== 0)
1053 /* Check for empty bundle */
1054 if (eth
->seg_number
== 0)
1057 /* Examine each bundle */
1058 for (i
= 0; i
< eth
->n_entries
; i
++)
1060 /* Moveable segment */
1061 if (eth
->seg_number
>= 0xfe)
1063 etm
= entry_tab_pointer
.etm
++;
1064 fixup_ptr
= (wpnt
->ne
->selector_table
[etm
->seg_number
-1].base_addr
1069 etf
= entry_tab_pointer
.etf
++;
1070 fixup_ptr
= (wpnt
->ne
->selector_table
[eth
->seg_number
-1].base_addr
1071 + (int) etf
->offset
[0]
1072 + ((int) etf
->offset
[1] << 8));
1076 /* Verify the signature */
1077 if (((fixup_ptr
[0] == 0x1e && fixup_ptr
[1] == 0x58)
1078 || (fixup_ptr
[0] == 0x8c && fixup_ptr
[1] == 0xd8))
1079 && fixup_ptr
[2] == 0x90)
1081 fixup_ptr
[0] = 0xb8; /* MOV AX, */
1082 fixup_ptr
[1] = wpnt
->hinstance
;
1083 fixup_ptr
[2] = (wpnt
->hinstance
>> 8);
1089 /***********************************************************************
1090 * GetSelectorBase (KERNEL.186)
1092 DWORD
GetSelectorBase(WORD wSelector
)
1094 fprintf(stdnimp
, "GetSelectorBase(selector %4X) stub!\n", wSelector
);
1098 /***********************************************************************
1099 * SetSelectorBase (KERNEL.187)
1101 void SetSelectorBase(WORD wSelector
, DWORD dwBase
)
1103 fprintf(stdnimp
, "SetSelectorBase(selector %4X, base %8lX) stub!\n",
1107 /***********************************************************************
1108 * GetSelectorLimit (KERNEL.188)
1110 DWORD
GetSelectorLimit(WORD wSelector
)
1112 fprintf(stdnimp
, "GetSelectorLimit(selector %4X) stub!\n", wSelector
);
1117 /***********************************************************************
1118 * SetSelectorLimit (KERNEL.189)
1120 void SetSelectorLimit(WORD wSelector
, DWORD dwLimit
)
1122 fprintf(stdnimp
, "SetSelectorLimit(selector %4X, base %8lX) stub!\n",
1123 wSelector
, dwLimit
);
1126 #endif /* ifndef WINELIB */