• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include <stdio.h>
3 #include <errno.h>
4 #include <string.h>
5 
6 /* Stuff from Wine. */
7 
8 typedef  unsigned short  WORD;  /* I guess */
9 typedef  unsigned char   BYTE;
10 
11 typedef 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 
wine_ldt_get_base(const LDT_ENTRY * ent)37 inline 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 }
wine_ldt_get_limit(const LDT_ENTRY * ent)43 inline 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 */
52 LDT_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);
56 extern int __modify_ldt (int, void *, size_t);
57 
print_ldt(void)58 void 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 
71 struct 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 
set_ldt1(void * base)88 void 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 
ldt_seg_write(int ldt_entno,unsigned offset,unsigned val)109 void 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"
113 	       "movl %0, %%fs\n\t"
114                "movl %%eax, %%fs:(%%edx)\t"
115 	       :
116                : "r" (7 /* LDT(TI), least privilege */ + (ldt_entno << 3)),
117                  "r" (offset), "r" (val)
118                : "eax", "edx", "cc" );
119 }
120 
main(void)121 int 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 
139