Mercurial > mplayer.hg
annotate loader/ldt_keeper.c @ 34593:83f7a2f8af3b
Adjust content of GUI configuration file to MPlayer configuration files.
Use option=<value> without spaces and quote value only if necessary.
(The change of the output format is purely cosmetic, but shall make the
interested GUI user aware that defining options is basically the same
for MPlayer and the GUI.)
author | ib |
---|---|
date | Fri, 10 Feb 2012 14:57:29 +0000 |
parents | 2a2e9b6551d8 |
children | 0989cbea18b4 |
rev | line source |
---|---|
2067 | 1 /** |
2 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
3 * This file MUST be in main library because LDT must | |
4 * be modified before program creates first thread | |
5 * - avifile includes this file from C++ code | |
6 * and initializes it at the start of player! | |
7386 | 7 * it might sound like a hack and it really is - but |
8 * as aviplay is deconding video with more than just one | |
9 * thread currently it's necessary to do it this way | |
10 * this might change in the future | |
2067 | 11 */ |
12 | |
7386 | 13 /* applied some modification to make make our xine friend more happy */ |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
14537
diff
changeset
|
14 |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
14537
diff
changeset
|
15 /* |
18783 | 16 * Modified for use with MPlayer, detailed changelog at |
17 * http://svn.mplayerhq.hu/mplayer/trunk/ | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
14537
diff
changeset
|
18 */ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
14537
diff
changeset
|
19 |
26105 | 20 #include "config.h" |
2139 | 21 #include "ldt_keeper.h" |
22 | |
2067 | 23 #include <string.h> |
24 #include <stdlib.h> | |
25 #include <errno.h> | |
26 #include <fcntl.h> | |
33412
2a2e9b6551d8
configure: Convert HAVE_SYS_MMAN_H into a 0/1 definition.
diego
parents:
32537
diff
changeset
|
27 #if HAVE_SYS_MMAN_H |
2067 | 28 #include <sys/mman.h> |
26111
eb82d1524b6d
#include osdep/mman.h if sys/mman.h is not available.
diego
parents:
26105
diff
changeset
|
29 #else |
eb82d1524b6d
#include osdep/mman.h if sys/mman.h is not available.
diego
parents:
26105
diff
changeset
|
30 #include "osdep/mmap.h" |
26105 | 31 #endif |
2067 | 32 #include <sys/types.h> |
33 #include <stdio.h> | |
34 #include <unistd.h> | |
21187
d9cedf7b8069
added mmap_anon to osdep lib. Used in loader for now
nplourde
parents:
18878
diff
changeset
|
35 #include "osdep/mmap_anon.h" |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
36 #include "mp_msg.h" |
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
37 #include "help_mp.h" |
2067 | 38 #ifdef __linux__ |
39 #include <asm/unistd.h> | |
40 #include <asm/ldt.h> | |
8213 | 41 // 2.5.xx+ calls this user_desc: |
42 #include <linux/version.h> | |
43 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,47) | |
44 #define modify_ldt_ldt_s user_desc | |
45 #endif | |
13351
698fe63084d3
declare modify_ldt with syscall3 macro for older glibcs patch by Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz>
faust3
parents:
10821
diff
changeset
|
46 /// declare modify_ldt with the _syscall3 macro for older glibcs |
13361 | 47 #if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)) |
13351
698fe63084d3
declare modify_ldt with syscall3 macro for older glibcs patch by Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz>
faust3
parents:
10821
diff
changeset
|
48 _syscall3( int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount ); |
698fe63084d3
declare modify_ldt with syscall3 macro for older glibcs patch by Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz>
faust3
parents:
10821
diff
changeset
|
49 #else |
7386 | 50 int modify_ldt(int func, void *ptr, unsigned long bytecount); |
13351
698fe63084d3
declare modify_ldt with syscall3 macro for older glibcs patch by Mikulas Patocka <mikulas at artax.karlin.mff.cuni.cz>
faust3
parents:
10821
diff
changeset
|
51 #endif |
2067 | 52 #else |
15566 | 53 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) |
5872 | 54 #include <machine/segments.h> |
2067 | 55 #include <machine/sysarch.h> |
30483
74d33572f1ff
Merge some preprocessor conditionals where appropriate.
diego
parents:
29263
diff
changeset
|
56 #elif defined(__APPLE__) |
26054
d9b11d83367f
Add missing #includes for Mac OS X, fixes the warning
diego
parents:
25849
diff
changeset
|
57 #include <architecture/i386/table.h> |
d9b11d83367f
Add missing #includes for Mac OS X, fixes the warning
diego
parents:
25849
diff
changeset
|
58 #include <i386/user_ldt.h> |
30483
74d33572f1ff
Merge some preprocessor conditionals where appropriate.
diego
parents:
29263
diff
changeset
|
59 #elif defined(__svr4__) |
2067 | 60 #include <sys/segment.h> |
61 #include <sys/sysi86.h> | |
62 | |
22715
363c84953547
check that definition of prototype of sysi86(int, void*) doesn't conflict; fixed compilation in opensolaris
nicodvb
parents:
21290
diff
changeset
|
63 /* solaris x86: add missing prototype for sysi86(), but only when sysi86(int, void*) is known to be valid */ |
363c84953547
check that definition of prototype of sysi86(int, void*) doesn't conflict; fixed compilation in opensolaris
nicodvb
parents:
21290
diff
changeset
|
64 #ifdef HAVE_SYSI86_iv |
7386 | 65 int sysi86(int, void*); |
18362
29b2221982b3
Add a check for sysi86() on Solaris systems, solving a build failure on Solaris
diego
parents:
17605
diff
changeset
|
66 #endif |
2067 | 67 |
2139 | 68 #ifndef NUMSYSLDTS /* SunOS 2.5.1 does not define NUMSYSLDTS */ |
69 #define NUMSYSLDTS 6 /* Let's hope the SunOS 5.8 value is OK */ | |
2067 | 70 #endif |
71 | |
72 #define TEB_SEL_IDX NUMSYSLDTS | |
73 #endif | |
74 | |
75 #define LDT_ENTRIES 8192 | |
76 #define LDT_ENTRY_SIZE 8 | |
77 #pragma pack(4) | |
78 struct modify_ldt_ldt_s { | |
79 unsigned int entry_number; | |
80 unsigned long base_addr; | |
81 unsigned int limit; | |
82 unsigned int seg_32bit:1; | |
83 unsigned int contents:2; | |
84 unsigned int read_exec_only:1; | |
85 unsigned int limit_in_pages:1; | |
86 unsigned int seg_not_present:1; | |
87 unsigned int useable:1; | |
88 }; | |
89 | |
90 #define MODIFY_LDT_CONTENTS_DATA 0 | |
91 #define MODIFY_LDT_CONTENTS_STACK 1 | |
92 #define MODIFY_LDT_CONTENTS_CODE 2 | |
93 #endif | |
94 | |
95 | |
96 /* user level (privilege level: 3) ldt (1<<2) segment selector */ | |
97 #define LDT_SEL(idx) ((idx) << 3 | 1 << 2 | 3) | |
98 | |
7386 | 99 /* i got this value from wine sources, it's the first free LDT entry */ |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
100 #if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(LDT_AUTO_ALLOC) |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
101 #define TEB_SEL_IDX LDT_AUTO_ALLOC |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
102 #define USE_LDT_AA |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
103 #endif |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
104 |
2067 | 105 #ifndef TEB_SEL_IDX |
7386 | 106 #define TEB_SEL_IDX 17 |
2067 | 107 #endif |
7386 | 108 |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
109 static unsigned int fs_ldt = TEB_SEL_IDX; |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
110 |
2067 | 111 |
112 /** | |
113 * here is a small logical problem with Restore for multithreaded programs - | |
114 * in C++ we use static class for this... | |
115 */ | |
116 | |
117 void Setup_FS_Segment(void) | |
118 { | |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
119 unsigned int ldt_desc = LDT_SEL(fs_ldt); |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
120 |
27757
b5a46071062a
Replace all occurrences of '__volatile__' and '__volatile' by plain 'volatile'.
diego
parents:
26111
diff
changeset
|
121 __asm__ volatile( |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
122 "movl %0,%%eax; movw %%ax, %%fs" : : "r" (ldt_desc) |
14212
540903a59fc0
add missing registers in clobber list, fixes bug #169
reimar
parents:
13361
diff
changeset
|
123 :"eax" |
2067 | 124 ); |
125 } | |
126 | |
7386 | 127 /* we don't need this - use modify_ldt instead */ |
128 #if 0 | |
2067 | 129 #ifdef __linux__ |
130 /* XXX: why is this routine from libc redefined here? */ | |
131 /* NOTE: the redefined version ignores the count param, count is hardcoded as 16 */ | |
132 static int LDT_Modify( int func, struct modify_ldt_ldt_s *ptr, | |
133 unsigned long count ) | |
134 { | |
135 int res; | |
136 #ifdef __PIC__ | |
27757
b5a46071062a
Replace all occurrences of '__volatile__' and '__volatile' by plain 'volatile'.
diego
parents:
26111
diff
changeset
|
137 __asm__ volatile( "pushl %%ebx\n\t" |
2067 | 138 "movl %2,%%ebx\n\t" |
139 "int $0x80\n\t" | |
140 "popl %%ebx" | |
141 : "=a" (res) | |
142 : "0" (__NR_modify_ldt), | |
143 "r" (func), | |
144 "c" (ptr), | |
145 "d"(16)//sizeof(*ptr) from kernel point of view | |
146 :"esi" ); | |
147 #else | |
27757
b5a46071062a
Replace all occurrences of '__volatile__' and '__volatile' by plain 'volatile'.
diego
parents:
26111
diff
changeset
|
148 __asm__ volatile("int $0x80" |
2067 | 149 : "=a" (res) |
150 : "0" (__NR_modify_ldt), | |
151 "b" (func), | |
152 "c" (ptr), | |
153 "d"(16) | |
154 :"esi"); | |
155 #endif /* __PIC__ */ | |
156 if (res >= 0) return res; | |
157 errno = -res; | |
158 return -1; | |
159 } | |
160 #endif | |
7386 | 161 #endif |
2067 | 162 |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
163 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__) |
2067 | 164 static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content ) |
165 { | |
166 *buffer++ = ((content->base_addr & 0x0000ffff) << 16) | | |
167 (content->limit & 0x0ffff); | |
168 *buffer = (content->base_addr & 0xff000000) | | |
169 ((content->base_addr & 0x00ff0000)>>16) | | |
170 (content->limit & 0xf0000) | | |
171 (content->contents << 10) | | |
172 ((content->read_exec_only == 0) << 9) | | |
173 ((content->seg_32bit != 0) << 22) | | |
174 ((content->limit_in_pages != 0) << 23) | | |
175 0xf000; | |
176 } | |
177 #endif | |
178 | |
8223 | 179 void* fs_seg=0; |
7386 | 180 |
181 ldt_fs_t* Setup_LDT_Keeper(void) | |
2067 | 182 { |
183 struct modify_ldt_ldt_s array; | |
184 int ret; | |
30702 | 185 ldt_fs_t* ldt_fs = malloc(sizeof(ldt_fs_t)); |
2067 | 186 |
7386 | 187 if (!ldt_fs) |
188 return NULL; | |
2067 | 189 |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
190 #ifdef __APPLE__ |
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
191 if (getenv("DYLD_BIND_AT_LAUNCH") == NULL) |
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
192 mp_msg(MSGT_LOADER, MSGL_WARN, MSGTR_LOADER_DYLD_Warning); |
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
193 #endif /* __APPLE__ */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27757
diff
changeset
|
194 |
8223 | 195 fs_seg= |
21248 | 196 ldt_fs->fs_seg = mmap_anon(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE, 0); |
7386 | 197 if (ldt_fs->fs_seg == (void*)-1) |
2067 | 198 { |
199 perror("ERROR: Couldn't allocate memory for fs segment"); | |
7386 | 200 free(ldt_fs); |
201 return NULL; | |
2067 | 202 } |
7386 | 203 *(void**)((char*)ldt_fs->fs_seg+0x18) = ldt_fs->fs_seg; |
14537 | 204 memset(&array, 0, sizeof(array)); |
7386 | 205 array.base_addr=(int)ldt_fs->fs_seg; |
2067 | 206 array.entry_number=TEB_SEL_IDX; |
207 array.limit=array.base_addr+getpagesize()-1; | |
208 array.seg_32bit=1; | |
209 array.read_exec_only=0; | |
210 array.seg_not_present=0; | |
211 array.contents=MODIFY_LDT_CONTENTS_DATA; | |
212 array.limit_in_pages=0; | |
213 #ifdef __linux__ | |
7386 | 214 //ret=LDT_Modify(0x1, &array, sizeof(struct modify_ldt_ldt_s)); |
215 ret=modify_ldt(0x1, &array, sizeof(struct modify_ldt_ldt_s)); | |
2067 | 216 if(ret<0) |
217 { | |
218 perror("install_fs"); | |
219 printf("Couldn't install fs segment, expect segfault\n"); | |
220 } | |
30483
74d33572f1ff
Merge some preprocessor conditionals where appropriate.
diego
parents:
29263
diff
changeset
|
221 #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__) |
2067 | 222 { |
223 unsigned long d[2]; | |
224 | |
225 LDT_EntryToBytes( d, &array ); | |
21290
efc774a1e5a4
fix compilation for win32 dll codec support for intel osx
nplourde
parents:
21248
diff
changeset
|
226 #ifdef USE_LDT_AA |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
227 ret = i386_set_ldt(LDT_AUTO_ALLOC, (union descriptor *)d, 1); |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
228 array.entry_number = ret; |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
229 fs_ldt = ret; |
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
230 #else |
2067 | 231 ret = i386_set_ldt(array.entry_number, (union descriptor *)d, 1); |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
232 #endif |
2067 | 233 if (ret < 0) |
234 { | |
235 perror("install_fs"); | |
236 printf("Couldn't install fs segment, expect segfault\n"); | |
237 printf("Did you reconfigure the kernel with \"options USER_LDT\"?\n"); | |
17605 | 238 #ifdef __OpenBSD__ |
239 printf("On newer OpenBSD systems did you set machdep.userldt to 1?\n"); | |
240 #endif | |
2067 | 241 } |
242 } | |
30483
74d33572f1ff
Merge some preprocessor conditionals where appropriate.
diego
parents:
29263
diff
changeset
|
243 #elif defined(__svr4__) |
2070
c1edbb8bfc0c
(solaris x86) C++ style variable declaration not at the start of a block does
jkeil
parents:
2069
diff
changeset
|
244 { |
2139 | 245 struct ssd ssd; |
10821
e9e5dca4af9e
FreeBSD 5.0 (libkse/libthr) support by Dan Eischen <eischen@vigrid.com>
alex
parents:
8223
diff
changeset
|
246 ssd.sel = LDT_SEL(TEB_SEL_IDX); |
2139 | 247 ssd.bo = array.base_addr; |
248 ssd.ls = array.limit - array.base_addr; | |
249 ssd.acc1 = ((array.read_exec_only == 0) << 1) | | |
250 (array.contents << 2) | | |
251 0xf0; /* P(resent) | DPL3 | S */ | |
252 ssd.acc2 = 0x4; /* byte limit, 32-bit segment */ | |
253 if (sysi86(SI86DSCR, &ssd) < 0) { | |
254 perror("sysi86(SI86DSCR)"); | |
255 printf("Couldn't install fs segment, expect segfault\n"); | |
256 } | |
2070
c1edbb8bfc0c
(solaris x86) C++ style variable declaration not at the start of a block does
jkeil
parents:
2069
diff
changeset
|
257 } |
30499 | 258 #elif defined(__OS2__) |
259 /* convert flat addr to sel idx for LDT_SEL() */ | |
260 fs_ldt = (uintptr_t)fs_seg >> 16; | |
2067 | 261 #endif |
262 | |
263 Setup_FS_Segment(); | |
264 | |
18878 | 265 ldt_fs->prev_struct = malloc(8); |
7386 | 266 *(void**)array.base_addr = ldt_fs->prev_struct; |
267 | |
268 return ldt_fs; | |
2067 | 269 } |
270 | |
7386 | 271 void Restore_LDT_Keeper(ldt_fs_t* ldt_fs) |
2067 | 272 { |
7386 | 273 if (ldt_fs == NULL || ldt_fs->fs_seg == 0) |
2067 | 274 return; |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30702
diff
changeset
|
275 free(ldt_fs->prev_struct); |
7386 | 276 munmap((char*)ldt_fs->fs_seg, getpagesize()); |
277 ldt_fs->fs_seg = 0; | |
278 free(ldt_fs); | |
2067 | 279 } |