#ifndef WINELIB /* static char RCSId[] = "$Id: ldtlib.c,v 1.2 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; */ #include #include #include #include "stddebug.h" #include "debug.h" #ifdef linux #include #include #include _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) #endif #if defined(__NetBSD__) || defined(__FreeBSD__) #include extern int i386_get_ldt(int, union descriptor *, int); extern int i386_set_ldt(int, union descriptor *, int); struct segment_descriptor * make_sd(unsigned base, unsigned limit, int contents, int read_exec_only, int seg32, int inpgs) { static long d[2]; d[0] = ((base & 0x0000ffff) << 16) | (limit & 0x0ffff); d[1] = (base & 0xff000000) | ((base & 0x00ff0000)>>16) | (limit & 0xf0000) | (contents << 10) | ((read_exec_only ^ 1) << 9) | (seg32 << 22) | (inpgs << 23) | 0xf000; return ((struct segment_descriptor *)d); } #endif int get_ldt(void *buffer) { #ifdef linux return modify_ldt(0, buffer, 32 * sizeof(struct modify_ldt_ldt_s)); #endif #if defined(__NetBSD__) || defined(__FreeBSD__) return i386_get_ldt(0, (union descriptor *)buffer, 32); #endif } int set_ldt_entry(int entry, unsigned long base, unsigned int limit, int seg_32bit_flag, int contents, int read_only_flag, int limit_in_pages_flag) { #ifdef linux struct modify_ldt_ldt_s ldt_info; ldt_info.entry_number = entry; ldt_info.base_addr = base; ldt_info.limit = limit; ldt_info.seg_32bit = seg_32bit_flag; ldt_info.contents = contents; ldt_info.read_exec_only = read_only_flag; ldt_info.limit_in_pages = limit_in_pages_flag; #ifdef NEW_LDT_STRUCT ldt_info.seg_not_present = 0; #endif return modify_ldt(1, &ldt_info, sizeof(ldt_info)); #endif #if defined(__NetBSD__) || defined(__FreeBSD__) struct segment_descriptor *sd; int ret; dprintf_ldt(stddeb, "set_ldt_entry: entry=%x base=%x limit=%x%s %s-bit contents=%d %s\n", entry, base, limit, limit_in_pages_flag?"-pages":"", seg_32bit_flag?"32":"16", contents, read_only_flag?"read-only":""); sd = make_sd(base, limit, contents, read_only_flag, seg_32bit_flag, limit_in_pages_flag); ret = i386_set_ldt(entry, (union descriptor *)sd, 1); if (ret < 0) { perror("i386_set_ldt"); fprintf(stderr, "Did you reconfigure the kernel with \"options USER_LDT\"?\n"); exit(1); } return ret; #endif } #endif /* ifndef WINELIB */