2 static char RCSId
[] = "$Id: selector.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
3 static char Copyright
[] = "Copyright Robert J. Amstadt, 1993";
15 #include <linux/unistd.h>
16 #include <linux/head.h>
17 #include <linux/mman.h>
18 #include <linux/a.out.h>
19 #include <linux/ldt.h>
21 #if defined(__NetBSD__) || defined(__FreeBSD__)
23 #include <machine/segments.h>
30 #include "prototypes.h"
32 /* #define DEBUG_SELECTORS /* */
39 #if defined(__NetBSD__) || defined(__FreeBSD__)
40 #define PAGE_SIZE getpagesize()
41 #define MODIFY_LDT_CONTENTS_DATA 0
42 #define MODIFY_LDT_CONTENTS_STACK 1
43 #define MODIFY_LDT_CONTENTS_CODE 2
47 static SEGDESC
* EnvironmentSelector
= NULL
;
48 static SEGDESC
* PSP_Selector
= NULL
;
49 SEGDESC
* MakeProcThunks
= NULL
;
50 unsigned short PSPSelector
;
51 unsigned char ran_out
= 0;
52 int LastUsedSelector
= FIRST_SELECTOR
- 1;
54 unsigned short SelectorMap
[MAX_SELECTORS
];
55 SEGDESC Segments
[MAX_SELECTORS
];
58 static FILE *zfile
= NULL
;
61 extern void KERNEL_Ordinal_102();
62 extern void UNIXLIB_Ordinal_0();
63 extern char *WIN_ProgramName
;
64 extern char WindowsPath
[256];
68 extern char **environ
;
70 /**********************************************************************
74 FindUnusedSelectors(int n_selectors
)
80 for (i
= LastUsedSelector
+ 1; i
!= LastUsedSelector
; i
++)
82 if (i
>= MAX_SELECTORS
)
88 if (!SelectorMap
[i
] && ++n_found
== n_selectors
)
92 if (i
== LastUsedSelector
)
96 return i
- n_selectors
+ 1;
100 /**********************************************************************
103 * Created a shared memory copy of a segment:
105 * - at a new selector location (if "new" is a 16-bit value)
106 * - at an arbitrary memory location (if "new" is a 32-bit value)
109 IPCCopySelector(int i_old
, unsigned long new, int swap_type
)
111 SEGDESC
*s_new
, *s_old
;
115 s_old
= &Segments
[i_old
];
117 if (new & 0xffff0000)
119 /**************************************************************
120 * Let's set the address parameter for no segment.
124 base_addr
= (void *) new;
128 /***************************************************************
129 * We need to fill in the segment descriptor for segment "new".
132 s_new
= &Segments
[i_new
];
134 SelectorMap
[i_new
] = i_new
;
136 s_new
->selector
= (i_new
<< 3) | 0x0007;
137 s_new
->base_addr
= (void *) ((long) s_new
->selector
<< 16);
138 s_new
->length
= s_old
->length
;
139 s_new
->flags
= s_old
->flags
;
140 s_new
->owner
= s_old
->owner
;
143 if (s_old
->type
== MODIFY_LDT_CONTENTS_DATA
)
144 s_new
->type
= MODIFY_LDT_CONTENTS_CODE
;
146 s_new
->type
= MODIFY_LDT_CONTENTS_DATA
;
149 s_new
->type
= s_old
->type
;
151 base_addr
= s_new
->base_addr
;
154 /******************************************************************
155 * If we don't have a shared memory key for s_old, then we need
156 * to get one. In this case, we'll also have to copy the data
159 if (s_old
->shm_key
== 0)
161 s_old
->shm_key
= shmget(IPC_PRIVATE
, s_old
->length
, 0600);
162 if (s_old
->shm_key
== 0)
165 memset(s_new
, 0, sizeof(*s_new
));
168 if (shmat(s_old
->shm_key
, base_addr
, 0) == NULL
)
171 memset(s_new
, 0, sizeof(*s_new
));
172 shmctl(s_old
->shm_key
, IPC_RMID
, NULL
);
175 memcpy(base_addr
, s_old
->base_addr
, s_old
->length
);
176 munmap(s_old
->base_addr
,
177 ((s_old
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1)));
178 shmat(s_old
->shm_key
, s_old
->base_addr
, 0);
180 /******************************************************************
181 * If have shared memory key s_old, then just attach the new
186 if (shmat(s_old
->shm_key
, base_addr
, 0) == NULL
)
189 memset(s_new
, 0, sizeof(*s_new
));
194 /******************************************************************
195 * If we are creating a new segment, then we also need to update
196 * the LDT to include the new selector. In this return the
201 s_new
->shm_key
= s_old
->shm_key
;
203 if (set_ldt_entry(i_new
, (unsigned long) base_addr
,
204 s_old
->length
- 1, 0, s_new
->type
, 0, 0) < 0)
209 return s_new
->selector
;
211 /******************************************************************
212 * No new segment. So, just return the shared memory key.
215 return s_old
->shm_key
;
219 /**********************************************************************
222 * This is very bad!!! This function is implemented for Windows
223 * compatibility only. Do not call this from the emulation library.
225 WORD
AllocSelector(WORD old_selector
)
227 SEGDESC
*s_new
, *s_old
;
231 i_new
= FindUnusedSelectors(1);
232 s_new
= &Segments
[i_new
];
236 i_old
= (old_selector
>> 3);
238 selector
= IPCCopySelector(i_old
, i_new
, 0);
244 s_old
= &Segments
[i_old
];
245 s_new
->selector
= (i_new
<< 3) | 0x0007;
247 SelectorMap
[i_new
] = SelectorMap
[i_old
];
249 if (set_ldt_entry(i_new
, s_new
->base_addr
,
250 s_new
->length
- 1, 0,
251 s_new
->type
, 0, 0) < 0)
259 memset(s_new
, 0, sizeof(*s_new
));
260 SelectorMap
[i_new
] = i_new
;
263 return (i_new
<< 3) | 0x0007;
266 /**********************************************************************
267 * PrestoChangoSelector
269 * This is very bad!!! This function is implemented for Windows
270 * compatibility only. Do not call this from the emulation library.
272 unsigned int PrestoChangoSelector(unsigned src_selector
, unsigned dst_selector
)
276 int src_idx
, dst_idx
;
278 src_idx
= src_selector
>> 3;
279 dst_idx
= dst_selector
>> 3;
281 if (src_idx
== dst_idx
)
283 src_s
= &Segments
[src_idx
];
285 if (src_s
->type
== MODIFY_LDT_CONTENTS_DATA
)
286 src_s
->type
= MODIFY_LDT_CONTENTS_CODE
;
288 src_s
->type
= MODIFY_LDT_CONTENTS_DATA
;
290 if (set_ldt_entry(src_idx
, (long) src_s
->base_addr
,
291 src_s
->length
- 1, 0, src_s
->type
, 0, 0) < 0)
296 return src_s
->selector
;
300 return IPCCopySelector(src_idx
, dst_idx
, 1);
303 SEGDESC
*src_s
, *dst_s
;
305 int src_idx
, dst_idx
;
309 src_idx
= (SelectorMap
[src_selector
>> 3]);
310 dst_idx
= dst_selector
>> 3;
311 src_s
= &Segments
[src_idx
];
312 dst_s
= &Segments
[dst_idx
];
315 for (i
= FIRST_SELECTOR
; i
< MAX_SELECTORS
; i
++)
316 if (SelectorMap
[i
] == src_idx
)
319 if (src_s
->type
== MODIFY_LDT_CONTENTS_DATA
320 || alias_count
> 1 || src_idx
== dst_idx
)
324 if (src_s
->type
== MODIFY_LDT_CONTENTS_DATA
)
325 dst_s
->type
= MODIFY_LDT_CONTENTS_CODE
;
327 dst_s
->type
= MODIFY_LDT_CONTENTS_DATA
;
329 SelectorMap
[dst_idx
] = SelectorMap
[src_idx
];
330 if (set_ldt_entry(dst_idx
, (long) dst_s
->base_addr
,
331 dst_s
->length
- 1, 0, dst_s
->type
, 0, 0) < 0)
339 * We're changing an unaliased code segment into a data
340 * segment. The SAFEST (but ugliest) way to deal with
341 * this is to map the new segment and copy all the contents.
343 SelectorMap
[dst_idx
] = dst_idx
;
345 dst_s
->selector
= (dst_idx
<< 3) | 0x0007;
346 dst_s
->base_addr
= (void *) ((unsigned int) dst_s
->selector
<< 16);
347 dst_s
->type
= MODIFY_LDT_CONTENTS_DATA
;
350 zfile
= fopen("/dev/zero","r");
351 p
= (void *) mmap((char *) dst_s
->base_addr
,
352 ((dst_s
->length
+ PAGE_SIZE
)
354 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
355 MAP_FIXED
| MAP_PRIVATE
, fileno(zfile
), 0);
357 p
= (void *) mmap((char *) dst_s
->base_addr
,
358 ((dst_s
->length
+ PAGE_SIZE
)
360 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
361 MAP_FIXED
| MAP_PRIVATE
| MAP_ANON
, -1, 0);
366 memcpy((void *) dst_s
->base_addr
, (void *) src_s
->base_addr
,
368 if (set_ldt_entry(src_idx
, dst_s
->base_addr
,
369 dst_s
->length
- 1, 0, dst_s
->type
, 0, 0) < 0)
373 if (set_ldt_entry(dst_idx
, dst_s
->base_addr
,
374 dst_s
->length
- 1, 0, dst_s
->type
, 0, 0) < 0)
379 munmap(src_s
->base_addr
,
380 (src_s
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1));
381 SelectorMap
[src_idx
] = dst_idx
;
382 src_s
->base_addr
= dst_s
->base_addr
;
385 return dst_s
->selector
;
386 #endif /* HAVE_IPC */
389 /**********************************************************************
392 WORD
AllocDStoCSAlias(WORD ds_selector
)
394 unsigned int cs_selector
;
396 if (ds_selector
== 0)
399 cs_selector
= AllocSelector(0);
400 return PrestoChangoSelector(ds_selector
, cs_selector
);
403 /**********************************************************************
406 WORD
FreeSelector(WORD sel
)
416 if (sel_idx
< FIRST_SELECTOR
|| sel_idx
>= MAX_SELECTORS
)
419 s
= &Segments
[sel_idx
];
422 munmap(s
->base_addr
, ((s
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1)));
423 memset(s
, 0, sizeof(*s
));
424 SelectorMap
[sel_idx
] = 0;
431 for (i
= FIRST_SELECTOR
; i
< MAX_SELECTORS
; i
++)
432 if (SelectorMap
[i
] && Segments
[i
].shm_key
== s
->shm_key
)
435 if (alias_count
== 1)
436 shmctl(s
->shm_key
, IPC_RMID
, NULL
);
438 memset(s
, 0, sizeof(*s
));
439 SelectorMap
[sel_idx
] = 0;
443 sel_idx
= SelectorMap
[sel
>> 3];
445 if (sel_idx
< FIRST_SELECTOR
|| sel_idx
>= MAX_SELECTORS
)
448 if (sel_idx
!= (sel
>> 3))
450 SelectorMap
[sel
>> 3] = 0;
455 for (i
= FIRST_SELECTOR
; i
< MAX_SELECTORS
; i
++)
456 if (SelectorMap
[i
] == sel_idx
)
459 if (alias_count
== 1)
461 s
= &Segments
[sel_idx
];
462 munmap(s
->base_addr
, ((s
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1)));
463 memset(s
, 0, sizeof(*s
));
464 SelectorMap
[sel
>> 3] = 0;
466 #endif /* HAVE_IPC */
471 /**********************************************************************
475 CreateNewSegments(int code_flag
, int read_only
, int length
, int n_segments
)
477 SEGDESC
*s
, *first_segment
;
481 i
= FindUnusedSelectors(n_segments
);
483 #ifdef DEBUG_SELECTORS
485 "Using %d segments starting at index %d.\n", n_segments
, i
);
489 * Fill in selector info.
491 first_segment
= s
= &Segments
[i
];
492 for (last_i
= i
+ n_segments
; i
< last_i
; i
++, s
++)
496 contents
= MODIFY_LDT_CONTENTS_CODE
;
501 contents
= MODIFY_LDT_CONTENTS_DATA
;
502 s
->flags
= NE_SEGFLAGS_DATA
;
505 s
->selector
= (i
<< 3) | 0x0007;
509 zfile
= fopen("/dev/zero","r");
510 s
->base_addr
= (void *) mmap((char *) (s
->selector
<< 16),
511 ((s
->length
+ PAGE_SIZE
- 1) &
513 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
514 MAP_FIXED
| MAP_PRIVATE
,
517 s
->base_addr
= (void *) mmap((char *) (s
->selector
<< 16),
518 ((s
->length
+ PAGE_SIZE
- 1) &
520 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
521 MAP_FIXED
| MAP_PRIVATE
| MAP_ANON
,
525 if (set_ldt_entry(i
, (unsigned long) s
->base_addr
,
526 (s
->length
- 1) & 0xffff, 0,
527 contents
, read_only
, 0) < 0)
529 memset(s
, 0, sizeof(*s
));
533 SelectorMap
[i
] = (unsigned short) i
;
537 return first_segment
;
540 /**********************************************************************
544 GetNextSegment(unsigned int flags
, unsigned int limit
)
546 return CreateNewSegments(0, 0, limit
, 1);
549 /**********************************************************************
550 * GetEntryPointFromOrdinal
553 struct entry_tab_header_s
*eth
;
554 struct entry_tab_movable_s
*etm
;
555 struct entry_tab_fixed_s
*etf
;
559 unsigned int GetEntryDLLName(char * dll_name
, char * function
, int * sel
,
562 struct dll_table_entry_s
*dll_table
;
563 struct w_files
* wpnt
;
567 dll_table
= FindDLLTable(dll_name
);
570 ordinal
= FindOrdinalFromName(dll_table
, function
);
571 *sel
= dll_table
[ordinal
].selector
;
572 *addr
= (unsigned int) dll_table
[ordinal
].address
;
574 dll_table
[ordinal
].used
++;
579 /* We need a means of determining the ordinal for the function. */
580 /* Not a builtin symbol, look to see what the file has for us */
581 for(wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
){
582 if(strcasecmp(wpnt
->name
, dll_name
)) continue;
583 cpnt
= wpnt
->nrname_table
;
585 if( ((int) cpnt
) - ((int)wpnt
->nrname_table
) >
586 wpnt
->ne_header
->nrname_tab_length
) return 1;
588 if(strncmp(cpnt
, function
, len
) == 0) break;
591 ordinal
= *((unsigned short *) (cpnt
+ len
));
592 j
= GetEntryPointFromOrdinal(wpnt
, ordinal
);
601 unsigned int GetEntryDLLOrdinal(char * dll_name
, int ordinal
, int * sel
,
604 struct dll_table_entry_s
*dll_table
;
605 struct w_files
* wpnt
;
608 dll_table
= FindDLLTable(dll_name
);
611 *sel
= dll_table
[ordinal
].selector
;
612 *addr
= (unsigned int) dll_table
[ordinal
].address
;
614 dll_table
[ordinal
].used
++;
619 /* Not a builtin symbol, look to see what the file has for us */
620 for(wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
){
621 if(strcasecmp(wpnt
->name
, dll_name
)) continue;
622 j
= GetEntryPointFromOrdinal(wpnt
, ordinal
);
632 GetEntryPointFromOrdinal(struct w_files
* wpnt
, int ordinal
)
635 struct mz_header_s
*mz_header
= wpnt
->mz_header
;
636 struct ne_header_s
*ne_header
= wpnt
->ne_header
;
639 union lookup entry_tab_pointer
;
640 struct entry_tab_header_s
*eth
;
641 struct entry_tab_movable_s
*etm
;
642 struct entry_tab_fixed_s
*etf
;
647 entry_tab_pointer
.cpnt
= wpnt
->lookup_table
;
649 * Let's walk through the table until we get to our entry.
655 * Read header for this bundle.
657 eth
= entry_tab_pointer
.eth
++;
659 if (eth
->n_entries
== 0)
660 return 0xffffffff; /* Yikes - we went off the end of the table */
662 if (eth
->seg_number
== 0)
664 current_ordinal
+= eth
->n_entries
;
665 if(current_ordinal
> ordinal
) return 0;
670 * Read each of the bundle entries.
672 for (i
= 0; i
< eth
->n_entries
; i
++, current_ordinal
++)
674 if (eth
->seg_number
>= 0xfe)
676 etm
= entry_tab_pointer
.etm
++;
678 if (current_ordinal
== ordinal
)
680 return ((unsigned int)
681 (wpnt
->selector_table
[etm
->seg_number
- 1].base_addr
+
687 etf
= entry_tab_pointer
.etf
++;
689 if (current_ordinal
== ordinal
)
691 return ((unsigned int)
692 (wpnt
->selector_table
[eth
->seg_number
- 1].base_addr
+
693 (int) etf
->offset
[0] +
694 ((int) etf
->offset
[1] << 8)));
701 /**********************************************************************
704 FixupFunctionPrologs(struct w_files
* wpnt
)
706 struct mz_header_s
*mz_header
= wpnt
->mz_header
;
707 struct ne_header_s
*ne_header
= wpnt
->ne_header
;
708 union lookup entry_tab_pointer
;
709 struct entry_tab_header_s
*eth
;
710 struct entry_tab_movable_s
*etm
;
711 struct entry_tab_fixed_s
*etf
;
712 unsigned char *fixup_ptr
;
715 if (!(ne_header
->format_flags
& 0x0001))
718 entry_tab_pointer
.cpnt
= wpnt
->lookup_table
;
720 * Let's walk through the table and fixup prologs as we go.
724 /* Get bundle header */
725 eth
= entry_tab_pointer
.eth
++;
727 /* Check for end of table */
728 if (eth
->n_entries
== 0)
731 /* Check for empty bundle */
732 if (eth
->seg_number
== 0)
735 /* Examine each bundle */
736 for (i
= 0; i
< eth
->n_entries
; i
++)
738 /* Moveable segment */
739 if (eth
->seg_number
>= 0xfe)
741 etm
= entry_tab_pointer
.etm
++;
742 fixup_ptr
= (wpnt
->selector_table
[etm
->seg_number
-1].base_addr
747 etf
= entry_tab_pointer
.etf
++;
748 fixup_ptr
= (wpnt
->selector_table
[eth
->seg_number
-1].base_addr
749 + (int) etf
->offset
[0]
750 + ((int) etf
->offset
[1] << 8));
754 /* Verify the signature */
755 if (((fixup_ptr
[0] == 0x1e && fixup_ptr
[1] == 0x58)
756 || (fixup_ptr
[0] == 0x8c && fixup_ptr
[1] == 0xd8))
757 && fixup_ptr
[2] == 0x90)
759 fixup_ptr
[0] = 0xb8; /* MOV AX, */
760 fixup_ptr
[1] = wpnt
->hinstance
;
761 fixup_ptr
[2] = (wpnt
->hinstance
>> 8);
768 /**********************************************************************
771 LPSTR
GetDOSEnvironment(void)
773 return (LPSTR
) EnvironmentSelector
->base_addr
;
776 /**********************************************************************
780 CreateEnvironment(void)
787 s
= CreateNewSegments(0, 0, PAGE_SIZE
, 1);
792 * Fill environment with Windows path, the Unix environment,
795 p
= (char *) s
->base_addr
;
797 strcat(p
, WindowsPath
);
800 for (e
= environ
; *e
; e
++)
802 if (strncasecmp(*e
, "path", 4))
810 w
= (unsigned short *) p
;
811 *w
= strlen(WIN_ProgramName
);
812 strcpy(p
+ 2, WIN_ProgramName
);
815 * Display environment
817 fprintf(stderr
, "Environment at %08.8x\n", s
->base_addr
);
818 for (p
= s
->base_addr
; *p
; p
+= strlen(p
) + 1)
819 fprintf(stderr
, " %s\n", p
);
821 fprintf(stderr
, " Program: %s\n", p
);
826 /**********************************************************************
833 /**********************************************************************
839 struct dos_psp_s
*psp
;
845 s
= CreateNewSegments(0, 0, PAGE_SIZE
, 1);
850 PSPSelector
= s
->selector
;
851 psp
= (struct dos_psp_s
*) s
->base_addr
;
852 psp
->pspInt20
= 0x20cd;
853 psp
->pspDispatcher
[0] = 0x9a;
854 usp
= (unsigned short *) &psp
->pspDispatcher
[1];
855 *usp
= (unsigned short) KERNEL_Ordinal_102
;
856 *(usp
+ 1) = UTEXTSEL
;
857 psp
->pspTerminateVector
[0] = (unsigned short) UNIXLIB_Ordinal_0
;
858 psp
->pspTerminateVector
[1] = UTEXTSEL
;
859 psp
->pspControlCVector
[0] = (unsigned short) UNIXLIB_Ordinal_0
;
860 psp
->pspControlCVector
[1] = UTEXTSEL
;
861 psp
->pspCritErrorVector
[0] = (unsigned short) UNIXLIB_Ordinal_0
;
862 psp
->pspCritErrorVector
[1] = UTEXTSEL
;
863 psp
->pspEnvironment
= EnvironmentSelector
->selector
;
865 p1
= psp
->pspCommandTail
;
866 for (i
= 1; i
< Argc
; i
++)
868 if ((int) ((int) p1
- (int) psp
->pspCommandTail
) +
869 strlen(Argv
[i
]) > 124)
875 for (p2
= Argv
[i
]; *p2
!= '\0'; )
880 psp
->pspCommandTailCount
= strlen(psp
->pspCommandTail
);
885 /**********************************************************************
889 CreateSelectors(struct w_files
* wpnt
)
892 struct ne_segment_table_entry_s
*seg_table
= wpnt
->seg_table
;
893 struct ne_header_s
*ne_header
= wpnt
->ne_header
;
894 SEGDESC
*selectors
, *s
, *stmp
;
895 unsigned short auto_data_sel
;
896 int contents
, read_only
;
897 int SelectorTableLength
;
900 int old_length
, file_image_length
;
901 int saved_old_length
;
904 * Allocate memory for the table to keep track of all selectors.
906 SelectorTableLength
= ne_header
->n_segment_tab
;
907 selectors
= malloc(SelectorTableLength
* sizeof(*selectors
));
908 if (selectors
== NULL
)
912 * Step through the segment table in the exe header.
915 for (i
= 0; i
< ne_header
->n_segment_tab
; i
++, s
++)
918 * Store the flags in our table.
920 s
->flags
= seg_table
[i
].seg_flags
;
923 * Is there an image for this segment in the file?
925 if (seg_table
[i
].seg_data_offset
== 0)
928 * No image in exe file, let's allocate some memory for it.
930 s
->length
= seg_table
[i
].min_alloc
;
935 * Image in file, let's just point to the image in memory.
937 s
->length
= seg_table
[i
].min_alloc
;
938 file_image_length
= seg_table
[i
].seg_data_length
;
939 if (file_image_length
== 0) file_image_length
= 0x10000;
944 old_length
= s
->length
;
947 * If this is the automatic data segment, its size must be adjusted.
948 * First we need to check for local heap. Second we nee to see if
949 * this is also the stack segment.
951 if (i
+ 1 == ne_header
->auto_data_seg
|| i
+ 1 == ne_header
->ss
)
954 ne_header
->sp
= s
->length
- 2;
958 * Is this a DATA or CODE segment?
961 if (s
->flags
& NE_SEGFLAGS_DATA
)
963 contents
= MODIFY_LDT_CONTENTS_DATA
;
964 if (s
->flags
& NE_SEGFLAGS_READONLY
)
969 contents
= MODIFY_LDT_CONTENTS_CODE
;
970 if (s
->flags
& NE_SEGFLAGS_EXECUTEONLY
)
975 stmp
= CreateNewSegments(!(s
->flags
& NE_SEGFLAGS_DATA
), read_only
,
977 s
->base_addr
= stmp
->base_addr
;
978 s
->selector
= stmp
->selector
;
980 s
->selector
= GlobalAlloc(GMEM_FIXED
, s
->length
);
981 if (s
->selector
== 0)
982 myerror("CreateSelectors: GlobalAlloc() failed");
984 s
->base_addr
= (void *) ((LONG
) s
->selector
<< 16);
985 if (!(s
->flags
& NE_SEGFLAGS_DATA
))
986 PrestoChangoSelector(s
->selector
, s
->selector
);
988 memset(s
->base_addr
, 0, s
->length
);
990 if (seg_table
[i
].seg_data_offset
!= 0)
995 status
= lseek(fd
, seg_table
[i
].seg_data_offset
*
996 (1 << ne_header
->align_shift_count
), SEEK_SET
);
997 if(read(fd
, s
->base_addr
, file_image_length
) != file_image_length
)
998 myerror("Unable to read segment from file");
1002 * If this is the automatic data segment, then we must initialize
1005 if (i
+ 1 == ne_header
->auto_data_seg
)
1007 auto_data_sel
= s
->selector
;
1008 saved_old_length
= old_length
;
1013 for (i
= 0; i
< ne_header
->n_segment_tab
; i
++, s
++)
1015 Segments
[s
->selector
>> 3].owner
= auto_data_sel
;
1016 if (s
->selector
== auto_data_sel
)
1017 HEAP_LocalInit(auto_data_sel
, s
->base_addr
+ saved_old_length
,
1018 0x10000 - 2 - saved_old_length
1019 - ne_header
->stack_length
);
1022 if(!EnvironmentSelector
) {
1023 EnvironmentSelector
= CreateEnvironment();
1024 PSP_Selector
= CreatePSP();
1025 MakeProcThunks
= CreateNewSegments(1, 0, 0x10000, 1);
1031 /***********************************************************************
1032 * GetSelectorBase (KERNEL.186)
1034 DWORD
GetSelectorBase(WORD wSelector
)
1036 fprintf(stderr
, "GetSelectorBase(selector %4X) stub!\n", wSelector
);
1039 /***********************************************************************
1040 * SetSelectorBase (KERNEL.187)
1042 void SetSelectorBase(WORD wSelector
, DWORD dwBase
)
1044 fprintf(stderr
, "SetSelectorBase(selector %4X, base %8X) stub!\n",
1048 /***********************************************************************
1049 * GetSelectorLimit (KERNEL.188)
1051 DWORD
GetSelectorLimit(WORD wSelector
)
1053 fprintf(stderr
, "GetSelectorLimit(selector %4X) stub!\n", wSelector
);
1058 /***********************************************************************
1059 * SetSelectorLimit (KERNEL.189)
1061 void SetSelectorLimit(WORD wSelector
, DWORD dwLimit
)
1063 fprintf(stderr
, "SetSelectorLimit(selector %4X, base %8X) stub!\n",
1064 wSelector
, dwLimit
);
1067 #endif /* ifndef WINELIB */