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
== -1)
161 s_old
->shm_key
= shmget(IPC_PRIVATE
, s_old
->length
, IPC_CREAT
);
162 if (s_old
->shm_key
== -1)
165 memset(s_new
, 0, sizeof(*s_new
));
170 if (shmat(s_old
->shm_key
, base_addr
, 0) == (char *) -1)
173 memset(s_new
, 0, sizeof(*s_new
));
176 shmctl(s_old
->shm_key
, IPC_RMID
, NULL
);
179 memcpy(base_addr
, s_old
->base_addr
, s_old
->length
);
180 munmap(s_old
->base_addr
,
181 ((s_old
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1)));
182 shmat(s_old
->shm_key
, s_old
->base_addr
, 0);
184 /******************************************************************
185 * If have shared memory key s_old, then just attach the new
190 if (shmat(s_old
->shm_key
, base_addr
, 0) == (char *) -1)
193 memset(s_new
, 0, sizeof(*s_new
));
200 /******************************************************************
201 * If we are creating a new segment, then we also need to update
202 * the LDT to include the new selector. In this return the
207 s_new
->shm_key
= s_old
->shm_key
;
209 if (set_ldt_entry(i_new
, (unsigned long) base_addr
,
210 s_old
->length
- 1, 0, s_new
->type
, 0, 0) < 0)
215 return s_new
->selector
;
217 /******************************************************************
218 * No new segment. So, just return the shared memory key.
221 return s_old
->shm_key
;
225 /**********************************************************************
228 * This is very bad!!! This function is implemented for Windows
229 * compatibility only. Do not call this from the emulation library.
231 WORD
AllocSelector(WORD old_selector
)
233 SEGDESC
*s_new
, *s_old
;
237 i_new
= FindUnusedSelectors(1);
238 s_new
= &Segments
[i_new
];
242 i_old
= (old_selector
>> 3);
244 selector
= IPCCopySelector(i_old
, i_new
, 0);
250 s_old
= &Segments
[i_old
];
251 s_new
->selector
= (i_new
<< 3) | 0x0007;
253 SelectorMap
[i_new
] = SelectorMap
[i_old
];
255 if (set_ldt_entry(i_new
, s_new
->base_addr
,
256 s_new
->length
- 1, 0,
257 s_new
->type
, 0, 0) < 0)
265 memset(s_new
, 0, sizeof(*s_new
));
269 SelectorMap
[i_new
] = i_new
;
272 return (i_new
<< 3) | 0x0007;
275 /**********************************************************************
276 * PrestoChangoSelector
278 * This is very bad!!! This function is implemented for Windows
279 * compatibility only. Do not call this from the emulation library.
281 unsigned int PrestoChangoSelector(unsigned src_selector
, unsigned dst_selector
)
285 int src_idx
, dst_idx
;
287 src_idx
= src_selector
>> 3;
288 dst_idx
= dst_selector
>> 3;
290 if (src_idx
== dst_idx
)
292 src_s
= &Segments
[src_idx
];
294 if (src_s
->type
== MODIFY_LDT_CONTENTS_DATA
)
295 src_s
->type
= MODIFY_LDT_CONTENTS_CODE
;
297 src_s
->type
= MODIFY_LDT_CONTENTS_DATA
;
299 if (set_ldt_entry(src_idx
, (long) src_s
->base_addr
,
300 src_s
->length
- 1, 0, src_s
->type
, 0, 0) < 0)
305 return src_s
->selector
;
309 return IPCCopySelector(src_idx
, dst_idx
, 1);
312 SEGDESC
*src_s
, *dst_s
;
314 int src_idx
, dst_idx
;
318 src_idx
= (SelectorMap
[src_selector
>> 3]);
319 dst_idx
= dst_selector
>> 3;
320 src_s
= &Segments
[src_idx
];
321 dst_s
= &Segments
[dst_idx
];
324 for (i
= FIRST_SELECTOR
; i
< MAX_SELECTORS
; i
++)
325 if (SelectorMap
[i
] == src_idx
)
328 if (src_s
->type
== MODIFY_LDT_CONTENTS_DATA
329 || alias_count
> 1 || src_idx
== dst_idx
)
333 if (src_s
->type
== MODIFY_LDT_CONTENTS_DATA
)
334 dst_s
->type
= MODIFY_LDT_CONTENTS_CODE
;
336 dst_s
->type
= MODIFY_LDT_CONTENTS_DATA
;
338 SelectorMap
[dst_idx
] = SelectorMap
[src_idx
];
339 if (set_ldt_entry(dst_idx
, (long) dst_s
->base_addr
,
340 dst_s
->length
- 1, 0, dst_s
->type
, 0, 0) < 0)
348 * We're changing an unaliased code segment into a data
349 * segment. The SAFEST (but ugliest) way to deal with
350 * this is to map the new segment and copy all the contents.
352 SelectorMap
[dst_idx
] = dst_idx
;
354 dst_s
->selector
= (dst_idx
<< 3) | 0x0007;
355 dst_s
->base_addr
= (void *) ((unsigned int) dst_s
->selector
<< 16);
356 dst_s
->type
= MODIFY_LDT_CONTENTS_DATA
;
359 zfile
= fopen("/dev/zero","r");
360 p
= (void *) mmap((char *) dst_s
->base_addr
,
361 ((dst_s
->length
+ PAGE_SIZE
)
363 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
364 MAP_FIXED
| MAP_PRIVATE
, fileno(zfile
), 0);
366 p
= (void *) mmap((char *) dst_s
->base_addr
,
367 ((dst_s
->length
+ PAGE_SIZE
)
369 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
370 MAP_FIXED
| MAP_PRIVATE
| MAP_ANON
, -1, 0);
375 memcpy((void *) dst_s
->base_addr
, (void *) src_s
->base_addr
,
377 if (set_ldt_entry(src_idx
, dst_s
->base_addr
,
378 dst_s
->length
- 1, 0, dst_s
->type
, 0, 0) < 0)
382 if (set_ldt_entry(dst_idx
, dst_s
->base_addr
,
383 dst_s
->length
- 1, 0, dst_s
->type
, 0, 0) < 0)
388 munmap(src_s
->base_addr
,
389 (src_s
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1));
390 SelectorMap
[src_idx
] = dst_idx
;
391 src_s
->base_addr
= dst_s
->base_addr
;
394 return dst_s
->selector
;
395 #endif /* HAVE_IPC */
398 /**********************************************************************
401 WORD
AllocDStoCSAlias(WORD ds_selector
)
403 unsigned int cs_selector
;
405 if (ds_selector
== 0)
408 cs_selector
= AllocSelector(0);
409 return PrestoChangoSelector(ds_selector
, cs_selector
);
412 /**********************************************************************
416 void CleanupSelectors(void)
420 for (sel_idx
= FIRST_SELECTOR
; sel_idx
< MAX_SELECTORS
; sel_idx
++)
421 if (SelectorMap
[sel_idx
])
422 FreeSelector((sel_idx
<< 3) | 7);
425 /**********************************************************************
428 WORD
FreeSelector(WORD sel
)
438 if (sel_idx
< FIRST_SELECTOR
|| sel_idx
>= MAX_SELECTORS
)
441 s
= &Segments
[sel_idx
];
442 if (s
->shm_key
== -1)
444 munmap(s
->base_addr
, ((s
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1)));
445 memset(s
, 0, sizeof(*s
));
447 SelectorMap
[sel_idx
] = 0;
454 for (i
= FIRST_SELECTOR
; i
< MAX_SELECTORS
; i
++)
455 if (SelectorMap
[i
] && Segments
[i
].shm_key
== s
->shm_key
)
458 if (alias_count
== 1)
459 shmctl(s
->shm_key
, IPC_RMID
, NULL
);
461 memset(s
, 0, sizeof(*s
));
463 SelectorMap
[sel_idx
] = 0;
467 sel_idx
= SelectorMap
[sel
>> 3];
469 if (sel_idx
< FIRST_SELECTOR
|| sel_idx
>= MAX_SELECTORS
)
472 if (sel_idx
!= (sel
>> 3))
474 SelectorMap
[sel
>> 3] = 0;
479 for (i
= FIRST_SELECTOR
; i
< MAX_SELECTORS
; i
++)
480 if (SelectorMap
[i
] == sel_idx
)
483 if (alias_count
== 1)
485 s
= &Segments
[sel_idx
];
486 munmap(s
->base_addr
, ((s
->length
+ PAGE_SIZE
) & ~(PAGE_SIZE
- 1)));
487 memset(s
, 0, sizeof(*s
));
488 SelectorMap
[sel
>> 3] = 0;
490 #endif /* HAVE_IPC */
495 /**********************************************************************
499 CreateNewSegments(int code_flag
, int read_only
, int length
, int n_segments
)
501 SEGDESC
*s
, *first_segment
;
505 i
= FindUnusedSelectors(n_segments
);
507 #ifdef DEBUG_SELECTORS
509 "Using %d segments starting at index %d.\n", n_segments
, i
);
513 * Fill in selector info.
515 first_segment
= s
= &Segments
[i
];
516 for (last_i
= i
+ n_segments
; i
< last_i
; i
++, s
++)
520 contents
= MODIFY_LDT_CONTENTS_CODE
;
525 contents
= MODIFY_LDT_CONTENTS_DATA
;
526 s
->flags
= NE_SEGFLAGS_DATA
;
529 s
->selector
= (i
<< 3) | 0x0007;
533 zfile
= fopen("/dev/zero","r");
534 s
->base_addr
= (void *) mmap((char *) (s
->selector
<< 16),
535 ((s
->length
+ PAGE_SIZE
- 1) &
537 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
538 MAP_FIXED
| MAP_PRIVATE
,
541 s
->base_addr
= (void *) mmap((char *) (s
->selector
<< 16),
542 ((s
->length
+ PAGE_SIZE
- 1) &
544 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
545 MAP_FIXED
| MAP_PRIVATE
| MAP_ANON
,
551 if (set_ldt_entry(i
, (unsigned long) s
->base_addr
,
552 (s
->length
- 1) & 0xffff, 0,
553 contents
, read_only
, 0) < 0)
555 memset(s
, 0, sizeof(*s
));
562 SelectorMap
[i
] = (unsigned short) i
;
566 return first_segment
;
569 /**********************************************************************
573 GetNextSegment(unsigned int flags
, unsigned int limit
)
575 return CreateNewSegments(0, 0, limit
, 1);
578 /**********************************************************************
579 * GetEntryPointFromOrdinal
582 struct entry_tab_header_s
*eth
;
583 struct entry_tab_movable_s
*etm
;
584 struct entry_tab_fixed_s
*etf
;
588 unsigned int GetEntryDLLName(char * dll_name
, char * function
, int * sel
,
591 struct dll_table_entry_s
*dll_table
;
592 struct w_files
* wpnt
;
596 dll_table
= FindDLLTable(dll_name
);
599 ordinal
= FindOrdinalFromName(dll_table
, function
);
600 *sel
= dll_table
[ordinal
].selector
;
601 *addr
= (unsigned int) dll_table
[ordinal
].address
;
603 dll_table
[ordinal
].used
++;
608 /* We need a means of determining the ordinal for the function. */
609 /* Not a builtin symbol, look to see what the file has for us */
610 for(wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
){
611 if(strcasecmp(wpnt
->name
, dll_name
)) continue;
612 cpnt
= wpnt
->nrname_table
;
614 if( ((int) cpnt
) - ((int)wpnt
->nrname_table
) >
615 wpnt
->ne_header
->nrname_tab_length
) return 1;
617 if(strncmp(cpnt
, function
, len
) == 0) break;
620 ordinal
= *((unsigned short *) (cpnt
+ len
));
621 j
= GetEntryPointFromOrdinal(wpnt
, ordinal
);
630 unsigned int GetEntryDLLOrdinal(char * dll_name
, int ordinal
, int * sel
,
633 struct dll_table_entry_s
*dll_table
;
634 struct w_files
* wpnt
;
637 dll_table
= FindDLLTable(dll_name
);
640 *sel
= dll_table
[ordinal
].selector
;
641 *addr
= (unsigned int) dll_table
[ordinal
].address
;
643 dll_table
[ordinal
].used
++;
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 j
= GetEntryPointFromOrdinal(wpnt
, ordinal
);
661 GetEntryPointFromOrdinal(struct w_files
* wpnt
, int ordinal
)
664 struct mz_header_s
*mz_header
= wpnt
->mz_header
;
665 struct ne_header_s
*ne_header
= wpnt
->ne_header
;
668 union lookup entry_tab_pointer
;
669 struct entry_tab_header_s
*eth
;
670 struct entry_tab_movable_s
*etm
;
671 struct entry_tab_fixed_s
*etf
;
676 entry_tab_pointer
.cpnt
= wpnt
->lookup_table
;
678 * Let's walk through the table until we get to our entry.
684 * Read header for this bundle.
686 eth
= entry_tab_pointer
.eth
++;
688 if (eth
->n_entries
== 0)
689 return 0xffffffff; /* Yikes - we went off the end of the table */
691 if (eth
->seg_number
== 0)
693 current_ordinal
+= eth
->n_entries
;
694 if(current_ordinal
> ordinal
) return 0;
699 * Read each of the bundle entries.
701 for (i
= 0; i
< eth
->n_entries
; i
++, current_ordinal
++)
703 if (eth
->seg_number
>= 0xfe)
705 etm
= entry_tab_pointer
.etm
++;
707 if (current_ordinal
== ordinal
)
709 return ((unsigned int)
710 (wpnt
->selector_table
[etm
->seg_number
- 1].base_addr
+
716 etf
= entry_tab_pointer
.etf
++;
718 if (current_ordinal
== ordinal
)
720 return ((unsigned int)
721 (wpnt
->selector_table
[eth
->seg_number
- 1].base_addr
+
722 (int) etf
->offset
[0] +
723 ((int) etf
->offset
[1] << 8)));
730 /**********************************************************************
733 FixupFunctionPrologs(struct w_files
* wpnt
)
735 struct mz_header_s
*mz_header
= wpnt
->mz_header
;
736 struct ne_header_s
*ne_header
= wpnt
->ne_header
;
737 union lookup entry_tab_pointer
;
738 struct entry_tab_header_s
*eth
;
739 struct entry_tab_movable_s
*etm
;
740 struct entry_tab_fixed_s
*etf
;
741 unsigned char *fixup_ptr
;
744 if (!(ne_header
->format_flags
& 0x0001))
747 entry_tab_pointer
.cpnt
= wpnt
->lookup_table
;
749 * Let's walk through the table and fixup prologs as we go.
753 /* Get bundle header */
754 eth
= entry_tab_pointer
.eth
++;
756 /* Check for end of table */
757 if (eth
->n_entries
== 0)
760 /* Check for empty bundle */
761 if (eth
->seg_number
== 0)
764 /* Examine each bundle */
765 for (i
= 0; i
< eth
->n_entries
; i
++)
767 /* Moveable segment */
768 if (eth
->seg_number
>= 0xfe)
770 etm
= entry_tab_pointer
.etm
++;
771 fixup_ptr
= (wpnt
->selector_table
[etm
->seg_number
-1].base_addr
776 etf
= entry_tab_pointer
.etf
++;
777 fixup_ptr
= (wpnt
->selector_table
[eth
->seg_number
-1].base_addr
778 + (int) etf
->offset
[0]
779 + ((int) etf
->offset
[1] << 8));
783 /* Verify the signature */
784 if (((fixup_ptr
[0] == 0x1e && fixup_ptr
[1] == 0x58)
785 || (fixup_ptr
[0] == 0x8c && fixup_ptr
[1] == 0xd8))
786 && fixup_ptr
[2] == 0x90)
788 fixup_ptr
[0] = 0xb8; /* MOV AX, */
789 fixup_ptr
[1] = wpnt
->hinstance
;
790 fixup_ptr
[2] = (wpnt
->hinstance
>> 8);
797 /**********************************************************************
800 LPSTR
GetDOSEnvironment(void)
802 return (LPSTR
) EnvironmentSelector
->base_addr
;
805 /**********************************************************************
809 CreateEnvironment(void)
816 s
= CreateNewSegments(0, 0, PAGE_SIZE
, 1);
821 * Fill environment with Windows path, the Unix environment,
824 p
= (char *) s
->base_addr
;
826 strcat(p
, WindowsPath
);
829 for (e
= environ
; *e
; e
++)
831 if (strncasecmp(*e
, "path", 4))
839 w
= (unsigned short *) p
;
840 *w
= strlen(WIN_ProgramName
);
841 strcpy(p
+ 2, WIN_ProgramName
);
844 * Display environment
846 fprintf(stderr
, "Environment at %08.8x\n", s
->base_addr
);
847 for (p
= s
->base_addr
; *p
; p
+= strlen(p
) + 1)
848 fprintf(stderr
, " %s\n", p
);
850 fprintf(stderr
, " Program: %s\n", p
);
855 /**********************************************************************
862 /**********************************************************************
868 struct dos_psp_s
*psp
;
874 s
= CreateNewSegments(0, 0, PAGE_SIZE
, 1);
879 PSPSelector
= s
->selector
;
880 psp
= (struct dos_psp_s
*) s
->base_addr
;
881 psp
->pspInt20
= 0x20cd;
882 psp
->pspDispatcher
[0] = 0x9a;
883 usp
= (unsigned short *) &psp
->pspDispatcher
[1];
884 *usp
= (unsigned short) KERNEL_Ordinal_102
;
885 *(usp
+ 1) = UTEXTSEL
;
886 psp
->pspTerminateVector
[0] = (unsigned short) UNIXLIB_Ordinal_0
;
887 psp
->pspTerminateVector
[1] = UTEXTSEL
;
888 psp
->pspControlCVector
[0] = (unsigned short) UNIXLIB_Ordinal_0
;
889 psp
->pspControlCVector
[1] = UTEXTSEL
;
890 psp
->pspCritErrorVector
[0] = (unsigned short) UNIXLIB_Ordinal_0
;
891 psp
->pspCritErrorVector
[1] = UTEXTSEL
;
892 psp
->pspEnvironment
= EnvironmentSelector
->selector
;
894 p1
= psp
->pspCommandTail
;
895 for (i
= 1; i
< Argc
; i
++)
897 if ((int) ((int) p1
- (int) psp
->pspCommandTail
) +
898 strlen(Argv
[i
]) > 124)
904 for (p2
= Argv
[i
]; *p2
!= '\0'; )
909 psp
->pspCommandTailCount
= strlen(psp
->pspCommandTail
);
914 /**********************************************************************
918 CreateSelectors(struct w_files
* wpnt
)
921 struct ne_segment_table_entry_s
*seg_table
= wpnt
->seg_table
;
922 struct ne_header_s
*ne_header
= wpnt
->ne_header
;
923 SEGDESC
*selectors
, *s
, *stmp
;
924 unsigned short auto_data_sel
;
925 int contents
, read_only
;
926 int SelectorTableLength
;
929 int old_length
, file_image_length
;
930 int saved_old_length
;
933 * Allocate memory for the table to keep track of all selectors.
935 SelectorTableLength
= ne_header
->n_segment_tab
;
936 selectors
= malloc(SelectorTableLength
* sizeof(*selectors
));
937 if (selectors
== NULL
)
941 * Step through the segment table in the exe header.
944 for (i
= 0; i
< ne_header
->n_segment_tab
; i
++, s
++)
947 * Store the flags in our table.
949 s
->flags
= seg_table
[i
].seg_flags
;
952 * Is there an image for this segment in the file?
954 if (seg_table
[i
].seg_data_offset
== 0)
957 * No image in exe file, let's allocate some memory for it.
959 s
->length
= seg_table
[i
].min_alloc
;
964 * Image in file, let's just point to the image in memory.
966 s
->length
= seg_table
[i
].min_alloc
;
967 file_image_length
= seg_table
[i
].seg_data_length
;
968 if (file_image_length
== 0) file_image_length
= 0x10000;
973 old_length
= s
->length
;
976 * If this is the automatic data segment, its size must be adjusted.
977 * First we need to check for local heap. Second we nee to see if
978 * this is also the stack segment.
980 if (i
+ 1 == ne_header
->auto_data_seg
|| i
+ 1 == ne_header
->ss
)
983 ne_header
->sp
= s
->length
- 2;
987 * Is this a DATA or CODE segment?
990 if (s
->flags
& NE_SEGFLAGS_DATA
)
992 contents
= MODIFY_LDT_CONTENTS_DATA
;
993 if (s
->flags
& NE_SEGFLAGS_READONLY
)
998 contents
= MODIFY_LDT_CONTENTS_CODE
;
999 if (s
->flags
& NE_SEGFLAGS_EXECUTEONLY
)
1004 stmp
= CreateNewSegments(!(s
->flags
& NE_SEGFLAGS_DATA
), read_only
,
1006 s
->base_addr
= stmp
->base_addr
;
1007 s
->selector
= stmp
->selector
;
1009 s
->selector
= GlobalAlloc(GMEM_FIXED
, s
->length
);
1010 if (s
->selector
== 0)
1011 myerror("CreateSelectors: GlobalAlloc() failed");
1013 s
->base_addr
= (void *) ((LONG
) s
->selector
<< 16);
1017 if (!(s
->flags
& NE_SEGFLAGS_DATA
))
1018 PrestoChangoSelector(s
->selector
, s
->selector
);
1020 memset(s
->base_addr
, 0, s
->length
);
1022 if (seg_table
[i
].seg_data_offset
!= 0)
1027 status
= lseek(fd
, seg_table
[i
].seg_data_offset
*
1028 (1 << ne_header
->align_shift_count
), SEEK_SET
);
1029 if(read(fd
, s
->base_addr
, file_image_length
) != file_image_length
)
1030 myerror("Unable to read segment from file");
1034 * If this is the automatic data segment, then we must initialize
1037 if (i
+ 1 == ne_header
->auto_data_seg
)
1039 auto_data_sel
= s
->selector
;
1040 saved_old_length
= old_length
;
1045 for (i
= 0; i
< ne_header
->n_segment_tab
; i
++, s
++)
1047 Segments
[s
->selector
>> 3].owner
= auto_data_sel
;
1048 if (s
->selector
== auto_data_sel
)
1049 HEAP_LocalInit(auto_data_sel
, s
->base_addr
+ saved_old_length
,
1050 0x10000 - 2 - saved_old_length
1051 - ne_header
->stack_length
);
1054 if(!EnvironmentSelector
) {
1055 EnvironmentSelector
= CreateEnvironment();
1056 PSP_Selector
= CreatePSP();
1057 MakeProcThunks
= CreateNewSegments(1, 0, 0x10000, 1);
1063 /***********************************************************************
1064 * GetSelectorBase (KERNEL.186)
1066 DWORD
GetSelectorBase(WORD wSelector
)
1068 fprintf(stderr
, "GetSelectorBase(selector %4X) stub!\n", wSelector
);
1071 /***********************************************************************
1072 * SetSelectorBase (KERNEL.187)
1074 void SetSelectorBase(WORD wSelector
, DWORD dwBase
)
1076 fprintf(stderr
, "SetSelectorBase(selector %4X, base %8X) stub!\n",
1080 /***********************************************************************
1081 * GetSelectorLimit (KERNEL.188)
1083 DWORD
GetSelectorLimit(WORD wSelector
)
1085 fprintf(stderr
, "GetSelectorLimit(selector %4X) stub!\n", wSelector
);
1090 /***********************************************************************
1091 * SetSelectorLimit (KERNEL.189)
1093 void SetSelectorLimit(WORD wSelector
, DWORD dwLimit
)
1095 fprintf(stderr
, "SetSelectorLimit(selector %4X, base %8X) stub!\n",
1096 wSelector
, dwLimit
);
1099 #endif /* ifndef WINELIB */