The lcall7 call gate for iBCS no longer seems to be active by default.
The following patch ought to add a call gate for lcall27, to allow Solaris/x86
binary emulation, but obviously it doesn't work either.
--- ./linux/kernel/exec_domain.c.lcall27 Fri Aug 27 14:52:49 1999
+++ ./linux/kernel/exec_domain.c Sat Aug 28 13:25:17 1999
@@ -2,7 +2,7 @@
#include <linux/smp_lock.h>
#include <linux/module.h>
-static asmlinkage void no_lcall7(struct pt_regs * regs);
+static asmlinkage void no_lcall7(int segment, struct pt_regs * regs);
static unsigned long ident_map[32] = {
@@ -25,7 +25,7 @@
static struct exec_domain *exec_domains = &default_exec_domain;
-static asmlinkage void no_lcall7(struct pt_regs * regs)
+static asmlinkage void no_lcall7(int segment, struct pt_regs * regs)
{
/*
@@ -33,6 +33,7 @@
* personality set incorrectly. Check to see whether SVr4 is available,
* and use it, otherwise give the user a SEGV.
*/
+ printk("Kernel no_lcall7 called\n");
if (current->exec_domain && current->exec_domain->module)
__MOD_DEC_USE_COUNT(current->exec_domain->module);
@@ -44,7 +45,7 @@
if (current->exec_domain && current->exec_domain->handler
&& current->exec_domain->handler != no_lcall7) {
- current->exec_domain->handler(regs);
+ current->exec_domain->handler(segment, regs);
return;
}
--- ./linux/include/linux/personality.h.lcall27 Fri Aug 27 14:52:48 1999
+++ ./linux/include/linux/personality.h Sat Aug 28 12:33:53 1999
@@ -28,9 +28,10 @@
#define PER_IRIXN32 (0x000a | STICKY_TIMEOUTS) /* IRIX6 new 32-bit */
#define PER_IRIX64 (0x000b | STICKY_TIMEOUTS) /* IRIX6 64-bit */
#define PER_RISCOS (0x000c)
+#define PER_SOLARIS (0x000d | STICKY_TIMEOUTS)
/* Prototype for an lcall7 syscall handler. */
-typedef void (*lcall7_func)(struct pt_regs *);
+typedef void (*lcall7_func)(int, struct pt_regs *);
/* Description of an execution domain - personality range supported,
--- ./linux/include/asm-i386/desc.h.lcall27 Mon Jul 26 07:15:13 1999
+++ ./linux/include/asm-i386/desc.h Sat Aug 28 13:46:20 1999
@@ -64,7 +64,7 @@
* This is the ldt that every process will get unless we need
* something other than this.
*/
-extern struct desc_struct default_ldt;
+extern struct desc_struct default_ldt[];
extern void set_intr_gate(unsigned int irq, void * addr);
extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
extern void set_tss_desc(unsigned int n, void *addr);
@@ -72,7 +72,7 @@
extern inline void clear_LDT(void)
{
int cpu = smp_processor_id();
- set_ldt_desc(cpu, &default_ldt, 1);
+ set_ldt_desc(cpu, &default_ldt[0], 5);
__load_LDT(cpu);
}
@@ -86,8 +86,8 @@
int count = LDT_ENTRIES;
if (!segments) {
- segments = &default_ldt;
- count = 1;
+ segments = &default_ldt[0];
+ count = 5;
}
set_ldt_desc(cpu, segments, count);
--- ./linux/arch/i386/kernel/entry.S.lcall27 Thu Jul 29 23:18:50 1999
+++ ./linux/arch/i386/kernel/entry.S Sat Aug 28 12:31:59 1999
@@ -145,7 +145,30 @@
andl $-8192,%ebx # GET_CURRENT
movl exec_domain(%ebx),%edx # Get the execution domain
movl 4(%edx),%edx # Get the lcall7 handler for the domain
+ pushl $0x7
call *%edx
+ addl $4, %esp
+ popl %eax
+ jmp ret_from_sys_call
+
+ENTRY(lcall27)
+ pushfl # We get a different stack layout with call gates,
+ pushl %eax # which has to be cleaned up later..
+ SAVE_ALL
+ movl EIP(%esp),%eax # due to call gates, this is eflags, not eip..
+ movl CS(%esp),%edx # this is eip..
+ movl EFLAGS(%esp),%ecx # and this is cs..
+ movl %eax,EFLAGS(%esp) #
+ movl %edx,EIP(%esp) # Now we move them to their "normal" places
+ movl %ecx,CS(%esp) #
+ movl %esp,%ebx
+ pushl %ebx
+ andl $-8192,%ebx # GET_CURRENT
+ movl exec_domain(%ebx),%edx # Get the execution domain
+ movl 4(%edx),%edx # Get the lcall7 handler for the domain
+ pushl $0x27
+ call *%edx
+ addl $4, %esp
popl %eax
jmp ret_from_sys_call
--- ./linux/arch/i386/kernel/traps.c.lcall27 Wed Aug 18 19:27:34 1999
+++ ./linux/arch/i386/kernel/traps.c Sat Aug 28 12:36:12 1999
@@ -46,8 +46,10 @@
asmlinkage int system_call(void);
asmlinkage void lcall7(void);
+asmlinkage void lcall27(void);
-struct desc_struct default_ldt = { 0, 0 };
+struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 } };
/*
* The IDT has to be page-aligned to simplify the Pentium
@@ -696,9 +698,11 @@
set_system_gate(SYSCALL_VECTOR,&system_call);
/*
- * default LDT is a single-entry callgate to lcall7
+ * default LDT is a single-entry callgate to lcall7 for iBCS
+ * and a callgate to lcall27 for Solaris/x86 binaries
*/
set_call_gate(&default_ldt,lcall7);
+ set_call_gate(&default_ldt,lcall27);
/*
* on SMP we do not yet know which CPU is on which TSS,
---- ---- ----
David Woodhouse David.Woodhouse@mvhi.com Office: (+44) 1223 810302
Project Leader, Process Information Systems Mobile: (+44) 976 658355
Axiom (Cambridge) Ltd., Swaffham Bulbeck, Cambridge, CB5 0NA, UK.
finger dwmw2@ferret.lmh.ox.ac.uk for PGP key.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/