blob: 0f8cb2d8cfde935ed61ff51523023edd0735a08c [file] [log] [blame]
njn912ec7c2002-10-02 10:36:46 +00001
2#include <stdio.h>
3#include <errno.h>
4#include <string.h>
5
6/* Stuff from Wine. */
7
8typedef unsigned short WORD; /* I guess */
9typedef unsigned char BYTE;
10
11typedef struct _LDT_ENTRY {
12 WORD LimitLow;
13 WORD BaseLow;
14 union {
15 struct {
16 BYTE BaseMid;
17 BYTE Flags1;
18 /*Declare as bytes to avoid alignment problems */
19 BYTE Flags2;
20 BYTE BaseHi;
21 } Bytes;
22 struct {
23 unsigned BaseMid : 8;
24 unsigned Type : 5;
25 unsigned Dpl : 2;
26 unsigned Pres : 1;
27 unsigned LimitHi : 4;
28 unsigned Sys : 1;
29 unsigned Reserved_0 : 1;
30 unsigned Default_Big : 1;
31 unsigned Granularity : 1;
32 unsigned BaseHi : 8;
33 } Bits;
34 } HighWord;
35} LDT_ENTRY;
36
37inline static void *wine_ldt_get_base( const LDT_ENTRY *ent )
38{
39 return (void *)(ent->BaseLow |
40 (unsigned long)ent->HighWord.Bits.BaseMid << 16 |
41 (unsigned long)ent->HighWord.Bits.BaseHi << 24);
42}
43inline static unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
44{
45 unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
46 if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
47 return limit;
48}
49
50
51/* our copy of the ldt */
52LDT_ENTRY ldt_copy[8192];
53
54/* System call to set LDT entry. */
55//extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
56extern int __modify_ldt (int, void *, size_t);
57
58void print_ldt ( void )
59{
60 int res;
61 res = __modify_ldt( 0, ldt_copy, 8192*sizeof(LDT_ENTRY) );
62 printf("got %d bytes\n", res );
63 perror("error is");
64}
65
66/* Structure passed on `modify_ldt' call. */
67#define MODIFY_LDT_CONTENTS_DATA 0
68#define MODIFY_LDT_CONTENTS_STACK 1
69#define MODIFY_LDT_CONTENTS_CODE 2
70
71struct modify_ldt_ldt_s
72{
73 unsigned int entry_number;
74 unsigned long int base_addr;
75 unsigned int limit;
76 unsigned int seg_32bit:1;
77 unsigned int contents:2;
78 unsigned int read_exec_only:1;
79 unsigned int limit_in_pages:1;
80 unsigned int seg_not_present:1;
81 unsigned int useable:1;
82 unsigned int empty:25;
83};
84
85/* System call to set LDT entry. */
86//extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
87
88void set_ldt1 ( void* base )
89{
90 int stat;
91 struct modify_ldt_ldt_s ldt_entry;
92
93 /* stop valgrind yelping about initialised holes in this struct. */
94 memset(&ldt_entry, 0, sizeof(ldt_entry));
95
96 ldt_entry.entry_number = 1;
97 ldt_entry.base_addr = (unsigned)base; //0x12345678;
98 ldt_entry.limit = 10;
99 ldt_entry.seg_32bit = 1;
100 ldt_entry.contents = MODIFY_LDT_CONTENTS_DATA;
101 ldt_entry.read_exec_only = 0;
102 ldt_entry.limit_in_pages = 0;
103 ldt_entry.seg_not_present = 0;
104 stat = __modify_ldt (1, &ldt_entry, sizeof (ldt_entry));
105 printf("stat = %d\n", stat);
106}
107
108
109void ldt_seg_write ( int ldt_entno, unsigned offset, unsigned val )
110{
111 asm volatile("movl %2, %%eax\n\t"
112 "movl %1, %%edx\n\t"
fitzhardinge47735af2004-01-21 01:27:27 +0000113 "movl %0, %%fs\n\t"
114 "movl %%eax, %%fs:(%%edx)\t"
njn912ec7c2002-10-02 10:36:46 +0000115 :
116 : "r" (7 /* LDT(TI), least privilege */ + (ldt_entno << 3)),
117 "r" (offset), "r" (val)
118 : "eax", "edx", "cc" );
119}
120
121int main ( void )
122{
123 int i;
124 int arr[9];
125
126 for (i = 0; i < 9; i++) arr[i] = 11*i;
127
128 set_ldt1( &arr[4] );
129 print_ldt();
130
131 ldt_seg_write(1 /* ldt entry # */, 4 /* offset */, 4444);
132
133 for (i = 0; i < 9; i++) printf("%d ", arr[i]);
134 printf("\n");
135
136 return 0;
137}
138