readline1.stderr.exp readline1.stderr.exp.hd readline1.stdout.exp \
readline1.vgtest \
resolv.stderr.exp resolv.stderr.exp.hd resolv.stdout.exp resolv.vgtest \
+ seg_override.stderr.exp seg_override.stderr.exp.hd \
+ seg_override.stdout.exp seg_override.vgtest \
sha1_test.stderr.exp sha1_test.stderr.exp.hd sha1_test.vgtest \
shortpush.stderr.exp shortpush.stderr.exp.hd shortpush.vgtest \
shorts.stderr.exp shorts.stderr.exp.hd shorts.vgtest \
noinst_PROGRAMS = \
bitfield1 bt_everything bt_literal coolo_strlen \
cpuid dastest floored fork fucomip munmap_exe rcl_assert \
- rcrl readline1 resolv sha1_test shortpush shorts smc1 \
+ rcrl readline1 resolv seg_override sha1_test shortpush shorts smc1 \
pth_blockedsig \
coolo_sigaction gxx304
rcrl_SOURCES = rcrl.c
readline1_SOURCES = readline1.c
resolv_SOURCES = resolv.c
+seg_override_SOURCES = seg_override.c
smc1_SOURCES = smc1.c
sha1_test_SOURCES = sha1_test.c
shortpush_SOURCES = shortpush.c
--- /dev/null
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+/* Stuff from Wine. */
+
+typedef unsigned short WORD; /* I guess */
+typedef unsigned char BYTE;
+
+typedef struct _LDT_ENTRY {
+ WORD LimitLow;
+ WORD BaseLow;
+ union {
+ struct {
+ BYTE BaseMid;
+ BYTE Flags1;
+ /*Declare as bytes to avoid alignment problems */
+ BYTE Flags2;
+ BYTE BaseHi;
+ } Bytes;
+ struct {
+ unsigned BaseMid : 8;
+ unsigned Type : 5;
+ unsigned Dpl : 2;
+ unsigned Pres : 1;
+ unsigned LimitHi : 4;
+ unsigned Sys : 1;
+ unsigned Reserved_0 : 1;
+ unsigned Default_Big : 1;
+ unsigned Granularity : 1;
+ unsigned BaseHi : 8;
+ } Bits;
+ } HighWord;
+} LDT_ENTRY;
+
+inline static void *wine_ldt_get_base( const LDT_ENTRY *ent )
+{
+ return (void *)(ent->BaseLow |
+ (unsigned long)ent->HighWord.Bits.BaseMid << 16 |
+ (unsigned long)ent->HighWord.Bits.BaseHi << 24);
+}
+inline static unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
+{
+ unsigned int limit = ent->LimitLow | (ent->HighWord.Bits.LimitHi << 16);
+ if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
+ return limit;
+}
+
+
+/* our copy of the ldt */
+LDT_ENTRY ldt_copy[8192];
+
+/* System call to set LDT entry. */
+//extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
+extern int __modify_ldt (int, void *, size_t);
+
+void print_ldt ( void )
+{
+ int res;
+ res = __modify_ldt( 0, ldt_copy, 8192*sizeof(LDT_ENTRY) );
+ printf("got %d bytes\n", res );
+ perror("error is");
+}
+
+/* Structure passed on `modify_ldt' call. */
+#define MODIFY_LDT_CONTENTS_DATA 0
+#define MODIFY_LDT_CONTENTS_STACK 1
+#define MODIFY_LDT_CONTENTS_CODE 2
+
+struct modify_ldt_ldt_s
+{
+ unsigned int entry_number;
+ unsigned long int base_addr;
+ unsigned int limit;
+ unsigned int seg_32bit:1;
+ unsigned int contents:2;
+ unsigned int read_exec_only:1;
+ unsigned int limit_in_pages:1;
+ unsigned int seg_not_present:1;
+ unsigned int useable:1;
+ unsigned int empty:25;
+};
+
+/* System call to set LDT entry. */
+//extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
+
+void set_ldt1 ( void* base )
+{
+ int stat;
+ struct modify_ldt_ldt_s ldt_entry;
+
+ /* stop valgrind yelping about initialised holes in this struct. */
+ memset(&ldt_entry, 0, sizeof(ldt_entry));
+
+ ldt_entry.entry_number = 1;
+ ldt_entry.base_addr = (unsigned)base; //0x12345678;
+ ldt_entry.limit = 10;
+ ldt_entry.seg_32bit = 1;
+ ldt_entry.contents = MODIFY_LDT_CONTENTS_DATA;
+ ldt_entry.read_exec_only = 0;
+ ldt_entry.limit_in_pages = 0;
+ ldt_entry.seg_not_present = 0;
+ stat = __modify_ldt (1, &ldt_entry, sizeof (ldt_entry));
+ printf("stat = %d\n", stat);
+}
+
+
+void ldt_seg_write ( int ldt_entno, unsigned offset, unsigned val )
+{
+ asm volatile("movl %2, %%eax\n\t"
+ "movl %1, %%edx\n\t"
+ "movl %0, %%gs\n\t"
+ "movl %%eax, %%gs:(%%edx)\t"
+ :
+ : "r" (7 /* LDT(TI), least privilege */ + (ldt_entno << 3)),
+ "r" (offset), "r" (val)
+ : "eax", "edx", "cc" );
+}
+
+int main ( void )
+{
+ int i;
+ int arr[9];
+
+ for (i = 0; i < 9; i++) arr[i] = 11*i;
+
+ set_ldt1( &arr[4] );
+ print_ldt();
+
+ ldt_seg_write(1 /* ldt entry # */, 4 /* offset */, 4444);
+
+ for (i = 0; i < 9; i++) printf("%d ", arr[i]);
+ printf("\n");
+
+ return 0;
+}
+
--- /dev/null
+
+The following failure _might_ be caused by linking to NVidia's
+ libGL.so, so avoiding it, if you can, _might_ help you. For example,
+ re-build any Qt libraries you are using without OpenGL support.
+
+Valgrind detected that your program requires
+the following unimplemented functionality:
+ modify_ldt(): I (JRS) haven't investigated this yet; sorry.
+This may be because the functionality is hard to implement,
+or because no reasonable program would behave this way,
+or because nobody has yet needed it. In any case, let me know
+(jseward@acm.org) and/or try to work around the problem, if you can.
+
+Valgrind has to exit now. Sorry. Bye!
+
+
+sched status:
+
+Thread 1: status = Runnable, associated_mx = 0x0, associated_cv = 0x0
+ at 0x4032F974: __modify_ldt (in /lib/i686/libc-2.2.2.so)
+ by 0x804865F: main (seg_override.c:128)
+ by 0x40265177: __libc_start_main (../sysdeps/generic/libc-start.c:129)
+ by 0x80483F1: memset@@GLIBC_2.0 (in /local/scratch-2/njn25/local/src/grind/head/none/tests/a.out)
+