Disable check for OSABI field, now that I have changed it to 0 in binutils
[nativeclient.git] / service_runtime / modify_ldt.c
blobc0752641d9ae19e981b142be2dc654fe9a844c82
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
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
14 * distribution.
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.
35 #include <stdio.h>
36 #include <stdint.h>
37 #include <errno.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <sys/types.h>
41 #include <asm/ldt.h>
43 void hex_dump(uint8_t *buf,
44 int size)
46 int i;
47 int sep;
48 for (i = 0; i < size; ++i) {
49 sep = ' ';
50 if (!(i & 0x3)) sep = '\t';
51 if (!(i & 0xf)) sep = '\n';
52 printf("%c%02x", sep, buf[i]);
54 printf("\n");
57 extern int modify_ldt(int, void *, unsigned long);
58 extern int etext;
60 unsigned short getds(void)
62 unsigned short ds;
64 asm("mov %%ds, %0"
65 : "=r" (ds)
66 : );
68 return ds;
71 void setds(unsigned short ds)
73 asm("movw %0, %%ds"
74 : : "r" (ds));
77 void print_segreg(unsigned short seg)
79 printf("%02x: index %d (%x), %s, rpl %d\n",
80 seg,
81 (seg >> 3),
82 (seg >> 3),
83 (seg & 0x4) ? "LDT" : "GDT",
84 (seg & 0x3));
87 void print_segdesc(uint8_t *ptr)
89 uint32_t base_addr;
90 uint32_t seg_limit; /* 20 bits */
91 uint32_t v;
92 int g, db, p, dpl, s, type;
94 v = *ptr++;
95 seg_limit = v;
96 v = *ptr++;
97 seg_limit |= (v << 8);
98 v = *ptr++;
99 base_addr = v;
100 v = *ptr++;
101 base_addr |= (v << 8);
102 v = *ptr++;
103 base_addr |= (v << 16);
104 v = *ptr++;
105 type = v & 0xf;
106 s = (v >> 4) & 1;
107 dpl = (v >> 5) & 0x3;
108 p = (v>>7) & 1;
109 v = *ptr++;
110 seg_limit |= (v & 0xf) << 16;
111 db = (v >> 6) & 1;
112 g = (v >> 7) & 1;
113 v = *ptr++;
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);
122 int main(int ac,
123 char **av)
125 int opt;
127 intptr_t base_addr = 0; // 0x08048000;
128 int num_pages = -1;
129 intptr_t addr;
130 uint8_t buf[LDT_ENTRIES * LDT_ENTRY_SIZE];
131 int actual;
132 struct user_desc ud;
133 uint16_t ds, nds;
134 char const *fmt = "mem[0x%08x] = %02x\n";
135 char ch;
137 while ((opt = getopt(ac, av, "a:b:p:")) != -1) {
138 switch (opt) {
139 case 'a':
140 addr = strtoul(optarg, (char **) 0, 0);
141 break;
142 case 'b':
143 base_addr = strtoul(optarg, (char **) 0, 0);
144 break;
145 case 'p':
146 num_pages = strtoul(optarg, (char **) 0, 0);
147 break;
148 default:
149 fprintf(stderr, "Usage: modify_ldt [-a addr-to-read] [-b base_addr] [-p num_pages]\n");
150 return 1;
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);
163 if (-1 == actual) {
164 perror("modify_ldt");
165 exit(1);
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());
173 ud.entry_number = 0;
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;
183 ud.seg_32bit = 1;
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;
188 ud.useable = 1;
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);
197 ds = getds();
198 setds((ud.entry_number << 3) | (1<<2) | (0x3));
199 nds = getds();
201 if (0 != addr) {
202 unsigned char *p = (unsigned char *) addr;
204 ch = *p;
207 setds(ds);
209 if (0 != addr) {
210 printf(fmt, addr, ch);
213 printf("while ds modified:\n");
214 print_segreg(nds);
216 actual = modify_ldt(0, buf, sizeof buf);
217 if (-1 == actual) {
218 perror("modify_ldt");
219 exit(1);
221 printf("LDT size %d (0x%x)\n", actual, actual);
222 print_segdesc(buf);
223 hex_dump(buf, 10 * LDT_ENTRY_SIZE);
225 return 0;