2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * Test code for exercising the modify_ldt function.
40 #include <sys/types.h>
43 void hex_dump(uint8_t *buf
,
48 for (i
= 0; i
< size
; ++i
) {
50 if (!(i
& 0x3)) sep
= '\t';
51 if (!(i
& 0xf)) sep
= '\n';
52 printf("%c%02x", sep
, buf
[i
]);
57 extern int modify_ldt(int, void *, unsigned long);
60 unsigned short getds(void)
71 void setds(unsigned short ds
)
77 void print_segreg(unsigned short seg
)
79 printf("%02x: index %d (%x), %s, rpl %d\n",
83 (seg
& 0x4) ? "LDT" : "GDT",
87 void print_segdesc(uint8_t *ptr
)
90 uint32_t seg_limit
; /* 20 bits */
92 int g
, db
, p
, dpl
, s
, type
;
97 seg_limit
|= (v
<< 8);
101 base_addr
|= (v
<< 8);
103 base_addr
|= (v
<< 16);
107 dpl
= (v
>> 5) & 0x3;
110 seg_limit
|= (v
& 0xf) << 16;
114 base_addr
|= (v
<< 24);
116 printf("base addr: 0x%08x\n", base_addr
);
117 printf("limit: 0x%05x\n", seg_limit
);
118 printf("g %d, db %d, p %d, dpl %x, s %d, type %x\n",
119 g
, db
, p
, dpl
, s
, type
);
127 intptr_t base_addr
= 0; // 0x08048000;
130 uint8_t buf
[LDT_ENTRIES
* LDT_ENTRY_SIZE
];
134 char const *fmt
= "mem[0x%08x] = %02x\n";
137 while ((opt
= getopt(ac
, av
, "a:b:p:")) != -1) {
140 addr
= strtoul(optarg
, (char **) 0, 0);
143 base_addr
= strtoul(optarg
, (char **) 0, 0);
146 num_pages
= strtoul(optarg
, (char **) 0, 0);
149 fprintf(stderr
, "Usage: modify_ldt [-a addr-to-read] [-b base_addr] [-p num_pages]\n");
154 printf("main: 0x%08x\n", (intptr_t) main
);
155 printf("etext: 0x%08x\n", (intptr_t) &etext
);
156 printf("aprox stack loc: 0x%08x\n", (intptr_t) &opt
);
157 printf("fmt loc: 0x%08x\n", (intptr_t) fmt
);
159 printf("ds = %x\n", getds());
160 print_segreg(getds());
162 actual
= modify_ldt(0, buf
, sizeof buf
);
164 perror("modify_ldt");
167 printf("LDT size %d (0x%x)\n", actual
, actual
);
168 hex_dump(buf
, actual
);
170 printf("ds = %x\n", getds());
171 print_segreg(getds());
174 ud
.base_addr
= base_addr
;
175 if (-1 == num_pages
) {
176 num_pages
= ((1 << 20)-1) - base_addr
/ (4 << 10);
179 if (num_pages
!= (0xfffff & num_pages
)) {
180 fprintf(stderr
, "WARNING: num_pages overflows\n");
182 ud
.limit
= num_pages
;
184 ud
.contents
= MODIFY_LDT_CONTENTS_DATA
;
185 ud
.read_exec_only
= 0;
186 ud
.limit_in_pages
= 1;
187 ud
.seg_not_present
= 0;
190 printf("base addr: 0x%08x\n", base_addr
);
191 printf("num pages: 0x%08x\n", num_pages
);
192 printf("end addr: 0x%08x\n", base_addr
+ ((num_pages
+1) << 12));
194 actual
= modify_ldt(1, &ud
, sizeof ud
);
195 printf("returned %d\n", actual
);
198 setds((ud
.entry_number
<< 3) | (1<<2) | (0x3));
202 unsigned char *p
= (unsigned char *) addr
;
210 printf(fmt
, addr
, ch
);
213 printf("while ds modified:\n");
216 actual
= modify_ldt(0, buf
, sizeof buf
);
218 perror("modify_ldt");
221 printf("LDT size %d (0x%x)\n", actual
, actual
);
223 hex_dump(buf
, 10 * LDT_ENTRY_SIZE
);