Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

16224 lines (16060 sloc) 426.497 kb
diff -Naur ./old//arch/arm/boot/compressed/misc.c ./kern//arch/arm/boot/compressed/misc.c
--- ./old//arch/arm/boot/compressed/misc.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/boot/compressed/misc.c 2012-04-18 13:37:43.000000000 -0400
@@ -200,9 +200,10 @@
tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
output_ptr = get_unaligned_le32(tmp);
- putstr("Uncompressing Linux...");
+ putstr("Decompressing kernel ...");
do_decompress(input_data, input_data_end - input_data,
output_data, error);
- putstr(" done, booting the kernel.\n");
+ putstr("\nDone, booting the kernel ...\n\n");
+
return output_ptr;
}
diff -Naur ./old//arch/arm/include/asm/signal.h ./kern//arch/arm/include/asm/signal.h
--- ./old//arch/arm/include/asm/signal.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/include/asm/signal.h 2012-06-13 16:30:48.000000000 -0400
@@ -14,7 +14,7 @@
#define _NSIG_BPW 32
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-typedef unsigned long old_sigset_t; /* at least 32 bits */
+typedef uint32_t old_sigset_t; /* at least 32 bits */
typedef struct {
unsigned long sig[_NSIG_WORDS];
@@ -28,43 +28,47 @@
#endif /* __KERNEL__ */
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
+
+#define SIGHUP 1 /* hangup */
+#define SIGINT 2 /* interrupt */
+#define SIGQUIT 3 /* quit */
+#define SIGILL 4 /* illegal instruction (not reset when caught) */
+#define SIGTRAP 5 /* trace trap (not reset when caught) */
+#define SIGABRT 6 /* abort() */
+#define SIGPOLL 7 /* pollable event ([XSR] generated, not supported) */
+#define SIGIOT SIGABRT /* compatibility */
+#define SIGEMT 7 /* EMT instruction */
+#define SIGFPE 8 /* floating point exception */
+#define SIGKILL 9 /* kill (cannot be caught or ignored) */
+#define SIGBUS 10 /* bus error */
+#define SIGSEGV 11 /* segmentation violation */
+#define SIGSYS 12 /* bad argument to system call */
+#define SIGPIPE 13 /* write on a pipe with no one to read it */
+#define SIGALRM 14 /* alarm clock */
+#define SIGTERM 15 /* software termination signal from kill */
+#define SIGURG 16 /* urgent condition on IO channel */
+#define SIGSTOP 17 /* sendable stop signal not from tty */
+#define SIGTSTP 18 /* stop signal from tty */
+#define SIGCONT 19 /* continue a stopped process */
+#define SIGCHLD 20 /* to parent on child stop or exit */
+#define SIGTTIN 21 /* to readers pgrp upon background tty read */
+#define SIGTTOU 22 /* like TTIN for output if (tp->t_local&LTOSTOP) */
+#define SIGIO 23 /* input/output possible signal */
+#define SIGXCPU 24 /* exceeded CPU time limit */
+#define SIGXFSZ 25 /* exceeded file size limit */
+#define SIGVTALRM 26 /* virtual time alarm */
+#define SIGPROF 27 /* profiling time alarm */
+#define SIGWINCH 28 /* window size changes */
+#define SIGINFO 29 /* information request */
+#define SIGUSR1 30 /* user defined signal 1 */
+#define SIGUSR2 31 /* user defined signal 2 */
+
/*
#define SIGLOST 29
*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
+#define SIGPWR 32
+#define SIGUNUSED 32
+#define SIGSTKFLT 32
/* These should not be considered constants from userland. */
#define SIGRTMIN 32
@@ -114,11 +118,14 @@
#include <asm-generic/signal-defs.h>
#ifdef __KERNEL__
+
+#include <DarwinTypes.h>
+
struct old_sigaction {
__sighandler_t sa_handler;
old_sigset_t sa_mask;
- unsigned long sa_flags;
- __sigrestore_t sa_restorer;
+ int sa_flags;
+ //__sigrestore_t sa_restorer;
};
struct sigaction {
@@ -141,8 +148,8 @@
void (*_sa_sigaction)(int, struct siginfo *, void *);
} _u;
sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
+ int sa_flags;
+ //void (*sa_restorer)(void);
};
#define sa_handler _u._sa_handler
diff -Naur ./old//arch/arm/include/asm/socket.h ./kern//arch/arm/include/asm/socket.h
--- ./old//arch/arm/include/asm/socket.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/include/asm/socket.h 2012-06-13 09:11:44.000000000 -0400
@@ -4,31 +4,50 @@
#include <asm/sockios.h>
/* For setsockopt(2) */
+
+#define SO_DEBUG 0x0001 /* turn on debugging info recording */
+#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
+#define SO_REUSEADDR 0x0004 /* allow local address reuse */
+#define SO_KEEPALIVE 0x0008 /* keep connections alive */
+#define SO_DONTROUTE 0x0010 /* just use interface addresses */
+#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
+#define SO_SNDBUF 0x1001 /* send buffer size */
+#define SO_RCVBUF 0x1002 /* receive buffer size */
+#define SO_SNDLOWAT 0x1003 /* send low-water mark */
+#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
+#define SO_SNDTIMEO 0x1005 /* send timeout */
+#define SO_RCVTIMEO 0x1006 /* receive timeout */
+#define SO_ERROR 0x1007 /* get error status and clear */
+#define SO_TYPE 0x1008 /* get socket type */
+
+#define SO_LINGER 0x1080 /* linger on close if data present (in seconds) */
+#define SO_OOBINLINE 0x0100
+
#define SOL_SOCKET 1
-#define SO_DEBUG 1
-#define SO_REUSEADDR 2
-#define SO_TYPE 3
-#define SO_ERROR 4
-#define SO_DONTROUTE 5
-#define SO_BROADCAST 6
-#define SO_SNDBUF 7
-#define SO_RCVBUF 8
-#define SO_SNDBUFFORCE 32
-#define SO_RCVBUFFORCE 33
-#define SO_KEEPALIVE 9
-#define SO_OOBINLINE 10
+//[bsd]//#define SO_DEBUG 1
+//[bsd]//#define SO_REUSEADDR 2
+//[bsd]//#define SO_TYPE 3
+//[bsd]//#define SO_ERROR 4
+//[bsd]//#define SO_DONTROUTE 5
+//[bsd]//#define SO_BROADCAST 6
+//[bsd]//#define SO_SNDBUF 7
+//[bsd]//#define SO_RCVBUF 8
+#define SO_SNDBUFFORCE 52 /* used to be 32 */
+#define SO_RCVBUFFORCE 53
+//[bsd]//#define SO_KEEPALIVE 9
+//[bsd]//#define SO_OOBINLINE 10
#define SO_NO_CHECK 11
#define SO_PRIORITY 12
-#define SO_LINGER 13
+//[bsd]//#define SO_LINGER 13
#define SO_BSDCOMPAT 14
/* To add :#define SO_REUSEPORT 15 */
-#define SO_PASSCRED 16
+#define SO_PASSCRED 56
#define SO_PEERCRED 17
-#define SO_RCVLOWAT 18
-#define SO_SNDLOWAT 19
-#define SO_RCVTIMEO 20
-#define SO_SNDTIMEO 21
+//[bsd]//#define SO_RCVLOWAT 18
+//[bsd]//#define SO_SNDLOWAT 19
+//[bsd]//#define SO_RCVTIMEO 20
+//[bsd]//#define SO_SNDTIMEO 21
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 22
@@ -45,7 +64,7 @@
#define SO_TIMESTAMP 29
#define SCM_TIMESTAMP SO_TIMESTAMP
-#define SO_ACCEPTCONN 30
+//[bsd]//#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
#define SO_PASSSEC 34
diff -Naur ./old//arch/arm/include/asm/termbits.h ./kern//arch/arm/include/asm/termbits.h
--- ./old//arch/arm/include/asm/termbits.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/include/asm/termbits.h 2012-05-14 16:38:39.000000000 -0400
@@ -2,9 +2,12 @@
#define __ASM_ARM_TERMBITS_H
typedef unsigned char cc_t;
+
+/* int -> long */
typedef unsigned int speed_t;
typedef unsigned int tcflag_t;
+/* 19 -> 20 */
#define NCCS 19
struct termios {
tcflag_t c_iflag; /* input mode flags */
@@ -39,6 +42,7 @@
/* c_cc characters */
+
#define VINTR 0
#define VQUIT 1
#define VERASE 2
@@ -58,6 +62,7 @@
#define VEOL2 16
/* c_iflag bits */
+
#define IGNBRK 0000001
#define BRKINT 0000002
#define IGNPAR 0000004
diff -Naur ./old//arch/arm/include/asm/unistd.h ./kern//arch/arm/include/asm/unistd.h
--- ./old//arch/arm/include/asm/unistd.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/include/asm/unistd.h 2012-04-21 12:52:10.000000000 -0400
@@ -397,6 +397,8 @@
#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368)
#define __NR_prlimit64 (__NR_SYSCALL_BASE+369)
+#define __NR_mach_msg_trap (__NR_SYSCALL_BASE+370)
+
/*
* The following SWIs are ARM private.
*/
diff -Naur ./old//arch/arm/kernel/calls.S ./kern//arch/arm/kernel/calls.S
--- ./old//arch/arm/kernel/calls.S 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/kernel/calls.S 2012-04-21 13:12:11.000000000 -0400
@@ -379,6 +379,8 @@
CALL(sys_fanotify_init)
CALL(sys_fanotify_mark)
CALL(sys_prlimit64)
+/* 370 */ CALL(sys_mach_msg_trap)
+
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff -Naur ./old//arch/arm/kernel/entry-armv.S ./kern//arch/arm/kernel/entry-armv.S
--- ./old//arch/arm/kernel/entry-armv.S 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/kernel/entry-armv.S 2012-08-03 20:49:56.000000000 -0400
@@ -230,6 +230,10 @@
#endif
irq_handler
+
+ /* irqs are lol */
+ get_thread_info tsk
+
#ifdef CONFIG_PREEMPT
str r8, [tsk, #TI_PREEMPT] @ restore preempt count
ldr r0, [tsk, #TI_FLAGS] @ get flags
@@ -459,6 +463,10 @@
#endif
irq_handler
+
+ /* irqs are lol */
+ get_thread_info tsk
+
#ifdef CONFIG_PREEMPT
ldr r0, [tsk, #TI_PREEMPT]
str r8, [tsk, #TI_PREEMPT]
diff -Naur ./old//arch/arm/kernel/entry-common.S ./kern//arch/arm/kernel/entry-common.S
--- ./old//arch/arm/kernel/entry-common.S 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/kernel/entry-common.S 2012-08-06 11:12:29.000000000 -0400
@@ -8,6 +8,15 @@
* published by the Free Software Foundation.
*/
+
+ /*
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Darwin ABI support and preservation of the r9 register in
+ * order to support running swi handlers that use this ABI
+ * as it can sometimes trash r9.
+ */
+
#include <asm/unistd.h>
#include <asm/ftrace.h>
#include <mach/entry-macro.S>
@@ -15,30 +24,73 @@
#include "entry-header.S"
+#define __apple_darwin_abi__
+
+#if defined(CONFIG_OABI_COMPAT)
+#error config_oabi_compat is not supported by this kernel
+#endif
.align 5
+
+/*
+ * Common.
+ */
+Restore_user_high:
+ arch_ret_to_user r1, lr
+ restore_user_regs fast = 1, offset = S_OFF
+
+/*
+ * Return to the userspace from *any point* in the system call.
+ */
+.globl Return_to_user_from_swi
+Return_to_user_from_swi:
+ disable_irq /* disable irq */
+
+ /* restore r9 */
+ get_thread_info tsk
+
+ /*
+ * Recover the stack frame.
+ * (oh god wtf)
+ */
+ add sp, tsk, #8192
+ sub sp, #S_FRAME_SIZE+S_OFF+8
+
+ /* force work pending */
+ b fast_work_pending
+
+ /* switch back to userspace */
+ mov r1, #0
+ b Restore_user_high
+
+
/*
* This is the fast syscall return path. We do as little as
* possible here, and this includes saving r0 back into the SVC
* stack.
*/
-ret_fast_syscall:
+.globl Return_to_user_from_swi_fast
+Return_to_user_from_swi_fast:
UNWIND(.fnstart )
UNWIND(.cantunwind )
- disable_irq @ disable interrupts
+
+ /* restore r9 */
+ get_thread_info tsk
+
+ disable_irq /* disable irq */
ldr r1, [tsk, #TI_FLAGS]
tst r1, #_TIF_WORK_MASK
bne fast_work_pending
+
#if defined(CONFIG_IRQSOFF_TRACER)
asm_trace_hardirqs_on
#endif
/* perform architecture specific actions before user return */
- arch_ret_to_user r1, lr
-
- restore_user_regs fast = 1, offset = S_OFF
+ b Restore_user_high
UNWIND(.fnend )
+
/*
* Ok, we need to do extra processing, enter the slow path.
*/
@@ -73,7 +125,6 @@
#endif
/* perform architecture specific actions before user return */
arch_ret_to_user r1, lr
-
restore_user_regs fast = 0, offset = 0
ENDPROC(ret_to_user)
@@ -214,7 +265,7 @@
#ifdef CONFIG_OLD_MCOUNT
/*
* This is under an ifdef in order to force link-time errors for people trying
- * to build with !FRAME_POINTER with a GCC which doesn't use the new-style
+ * to build with !FRAME_POINTER with a GCC which does not use the new-style
* mcount.
*/
ENTRY(mcount)
@@ -247,18 +298,17 @@
#endif /* CONFIG_FUNCTION_TRACER */
-/*=============================================================================
- * SWI handler
- *-----------------------------------------------------------------------------
- */
+/* Handle a Darwin system call (0x80) */
+ENTRY(Fleh_swi_darwin)
+ adr lr, BSYM(Return_to_user_from_swi_fast)
+ b Sleh_swi_darwin
+ENDPROC(Fleh_swi_darwin)
+
- /* If we're optimising for StrongARM the resulting code won't
- run on an ARM7 and we can save a couple of instructions.
- --pb */
#ifdef CONFIG_CPU_ARM710
#define A710(code...) code
.Larm710bug:
- ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
+ ldmia sp, {r0 - lr}^ // Get calling r0 - lr
mov r0, r0
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4
@@ -267,121 +317,120 @@
#endif
.align 5
+
+/* Software interrupt vector */
ENTRY(vector_swi)
sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - r12} @ Calling r0 - r12
- ARM( add r8, sp, #S_PC )
- ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr
- THUMB( mov r8, sp )
- THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr
- mrs r8, spsr @ called from non-FIQ mode, so ok.
- str lr, [sp, #S_PC] @ Save calling PC
- str r8, [sp, #S_PSR] @ Save CPSR
- str r0, [sp, #S_OLD_R0] @ Save OLD_R0
+ stmia sp, {r0 - r12} // Calling r0 - r12
+
+ ARM( add r11, sp, #S_PC )
+ ARM( stmdb r11, {sp, lr}^ ) // Calling sp, lr
+ THUMB( mov r11, sp )
+ THUMB( store_user_sp_lr r11, r10, S_SP ) // calling sp, lr
+
+ mrs r11, spsr // called from non-FIQ mode, so ok.
+ str lr, [sp, #S_PC] // Save calling PC
+ str r11, [sp, #S_PSR] // Save CPSR
+ str r0, [sp, #S_OLD_R0] // Save OLD_R0
zero_fp
- /*
- * Get the system call number.
- */
+ /* args to the syscall */
+ sub sp, #8
+ stmdb sp!, {r4, r5, r6, r8}
-#if defined(CONFIG_OABI_COMPAT)
+ /* ghey */
+ mov r8, r11
/*
- * If we have CONFIG_OABI_COMPAT then we need to look at the swi
- * value to determine if it is an EABI or an old ABI call.
+ * If this is a darwin system call, move r12 to scno.
*/
-#ifdef CONFIG_ARM_THUMB
- tst r8, #PSR_T_BIT
- movne r10, #0 @ no thumb OABI emulation
- ldreq r10, [lr, #-4] @ get SWI instruction
-#else
- ldr r10, [lr, #-4] @ get SWI instruction
- A710( and ip, r10, #0x0f000000 @ check for SWI )
- A710( teq ip, #0x0f000000 )
- A710( bne .Larm710bug )
-#endif
-#ifdef CONFIG_CPU_ENDIAN_BE8
- rev r10, r10 @ little endian instruction
-#endif
+ ldr r11, [lr, #-4] /* svc instr */
+ bics r11, r11, #0xff000000 /* strip the instr opcode */
+ cmp r11, #0x80 /* svc 0x80 means darwin */
+
+ /* move r12 to scno and skip all the linux crap */
+ moveq scno, r12
+ beq darwin_2
+
+ /* stripped oabi code */
-#elif defined(CONFIG_AEABI)
+#if defined(CONFIG_AEABI)
/*
* Pure EABI user space always put syscall number into scno (r7).
*/
- A710( ldr ip, [lr, #-4] @ get SWI instruction )
- A710( and ip, ip, #0x0f000000 @ check for SWI )
- A710( teq ip, #0x0f000000 )
- A710( bne .Larm710bug )
+ A710( ldr ip, [lr, #-4] ) // get SWI instruction
+ A710( and ip, ip, #0x0f000000 ) // check for SWI
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
#elif defined(CONFIG_ARM_THUMB)
/* Legacy ABI only, possibly thumb mode. */
- tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
- addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
+ tst r8, #PSR_T_BIT //this is SPSR from save_user_regs
+ addne scno, r7, #__NR_SYSCALL_BASE // put OS number in
ldreq scno, [lr, #-4]
#else
/* Legacy ABI only. */
- ldr scno, [lr, #-4] @ get SWI instruction
- A710( and ip, scno, #0x0f000000 @ check for SWI )
- A710( teq ip, #0x0f000000 )
- A710( bne .Larm710bug )
+ ldr scno, [lr, #-4] // get SWI instruction
+ A710( and ip, scno, #0x0f000000 )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug ) // check for SWI
#endif
#ifdef CONFIG_ALIGNMENT_TRAP
ldr ip, __cr_alignment
ldr ip, [ip]
- mcr p15, 0, ip, c1, c0 @ update control register
+ mcr p15, 0, ip, c1, c0 // update control register
#endif
- enable_irq
- get_thread_info tsk
- adr tbl, sys_call_table @ load syscall table pointer
+ adr tbl, sys_call_table // load syscall table pointer
-#if defined(CONFIG_OABI_COMPAT)
- /*
- * If the swi argument is zero, this is an EABI call and we do nothing.
- *
- * If this is an old ABI call, get the syscall number into scno and
- * get the old ABI syscall table address.
- */
- bics r10, r10, #0xff000000
- eorne scno, r10, #__NR_OABI_SYSCALL_BASE
- ldrne tbl, =sys_oabi_call_table
-#elif !defined(CONFIG_AEABI)
- bic scno, scno, #0xff000000 @ mask off SWI op-code
- eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
+#if !defined(CONFIG_AEABI)
+ bic scno, scno, #0xff000000 // mask off SWI op-code
+ eor scno, scno, #__NR_SYSCALL_BASE // check OS number
#endif
- ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
- stmdb sp!, {r4, r5} @ push fifth and sixth args
+
+darwin_2:
+ /***** darwin syscalls start here *****/
+ enable_irq
+
+ get_thread_info tsk
+ ldr r10, [tsk, #TI_FLAGS] // check for syscall tracing
#ifdef CONFIG_SECCOMP
tst r10, #_TIF_SECCOMP
beq 1f
mov r0, scno
bl __secure_computing
- add r0, sp, #S_R0 + S_OFF @ pointer to regs
- ldmia r0, {r0 - r3} @ have to reload r0 - r3
+ add r0, sp, #S_R0 + S_OFF // pointer to regs
+ ldmia r0, {r0 - r3} // have to reload r0 - r3
1:
#endif
- tst r10, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
+ /* is this a darwin call? */
+ cmp r11, #0x80
+ beq Fleh_swi_darwin
+
+ tst r10, #_TIF_SYSCALL_TRACE // are we tracing syscalls?
bne __sys_trace
- cmp scno, #NR_syscalls @ check upper syscall limit
- adr lr, BSYM(ret_fast_syscall) @ return address
- ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
+Llinux_syscall:
+ adr lr, BSYM(Return_to_user_from_swi_fast) // return address
+ cmp scno, #NR_syscalls // check upper syscall limit
+
+ ldrcc pc, [tbl, scno, lsl #2] // call sys_* routine
add r1, sp, #S_OFF
2: mov why, #0 @ no longer a real syscall
cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
- eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back
+ eor r0, scno, #__NR_SYSCALL_BASE // put OS number back
bcs arm_syscall
- b sys_ni_syscall @ not private func
+ b sys_ni_syscall // not private func
ENDPROC(vector_swi)
/*
@@ -438,13 +487,13 @@
/*============================================================================
* Special system call wrappers
*/
-@ r0 = syscall number
-@ r8 = syscall table
+// r0 = syscall number
+// r8 = syscall table
sys_syscall:
bic scno, r0, #__NR_OABI_SYSCALL_BASE
cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
- cmpne scno, #NR_syscalls @ check range
- stmloia sp, {r5, r6} @ shuffle args
+ cmpne scno, #NR_syscalls // check range
+ stmloia sp, {r5, r6} // shuffle args
movlo r0, r1
movlo r1, r2
movlo r2, r3
@@ -476,13 +525,13 @@
sys_sigreturn_wrapper:
add r0, sp, #S_OFF
- mov why, #0 @ prevent syscall restart handling
+ mov why, #0 // prevent syscall restart handling
b sys_sigreturn
ENDPROC(sys_sigreturn_wrapper)
sys_rt_sigreturn_wrapper:
add r0, sp, #S_OFF
- mov why, #0 @ prevent syscall restart handling
+ mov why, #0 // prevent syscall restart handling
b sys_rt_sigreturn
ENDPROC(sys_rt_sigreturn_wrapper)
diff -Naur ./old//arch/arm/kernel/entry-header.S ./kern//arch/arm/kernel/entry-header.S
--- ./old//arch/arm/kernel/entry-header.S 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/kernel/entry-header.S 2012-08-05 10:00:45.000000000 -0400
@@ -20,7 +20,7 @@
@ the addition of 8 bytes for storing syscall args 5 and 6.
@ This _must_ remain a multiple of 8 for EABI.
@
-#define S_OFF 8
+#define S_OFF 24
/*
* The SWI code relies on the fact that R0 is at the bottom of the stack
diff -Naur ./old//arch/arm/kernel/signal.c ./kern//arch/arm/kernel/signal.c
--- ./old//arch/arm/kernel/signal.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/kernel/signal.c 2012-06-13 16:34:58.000000000 -0400
@@ -90,8 +90,7 @@
if (act) {
old_sigset_t mask;
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+ __get_user(new_ka.sa.sa_handler, &act->sa_handler))
return -EFAULT;
__get_user(new_ka.sa.sa_flags, &act->sa_flags);
__get_user(mask, &act->sa_mask);
@@ -102,8 +101,7 @@
if (!ret && oact) {
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler))
return -EFAULT;
__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
@@ -502,7 +500,8 @@
#endif
if (ka->sa.sa_flags & SA_RESTORER) {
- retcode = (unsigned long)ka->sa.sa_restorer;
+ panic("signal.c: (ka->sa.sa_flags & SA_RESTORER)");
+ retcode = (unsigned long)0;
} else {
unsigned int idx = thumb << 1;
diff -Naur ./old//arch/arm/mm/mmap.c ./kern//arch/arm/mm/mmap.c
--- ./old//arch/arm/mm/mmap.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//arch/arm/mm/mmap.c 2012-08-04 10:33:47.000000000 -0400
@@ -25,10 +25,9 @@
* in the VIVT case, we optimise out the alignment rules.
*/
unsigned long
-arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ARM_get_unmapped_area(struct mm_struct *mm, struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
{
- struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned long start_addr;
#ifdef CONFIG_CPU_V6
@@ -120,6 +119,13 @@
}
}
+unsigned long
+arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ /* classic */
+ return ARM_get_unmapped_area(current->mm, filp, addr, len, pgoff, flags);
+}
/*
* You really shouldn't be using read() or write() on /dev/mem. This
diff -Naur ./old//drivers/tty/vt/vt.c ./kern//drivers/tty/vt/vt.c
--- ./old//drivers/tty/vt/vt.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//drivers/tty/vt/vt.c 2012-06-24 07:51:24.000000000 -0400
@@ -2480,6 +2480,8 @@
* The console must be locked when we get here.
*/
+static unsigned int printk_color = 0x17;
+
static void vt_console_print(struct console *co, const char *b, unsigned count)
{
struct vc_data *vc = vc_cons[fg_console].d;
@@ -2518,12 +2520,19 @@
hide_cursor(vc);
start = (ushort *)vc->vc_pos;
+
+ vc->vc_color = printk_color;
+ update_attr(vc);
/* Contrived structure to try to emulate original need_wrap behaviour
* Problems caused when we have need_wrap set on '\n' character */
while (count--) {
c = *b++;
if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
+
+ vc->vc_color = vc->vc_def_color;
+ update_attr(vc);
+
if (cnt > 0) {
if (CON_IS_VISIBLE(vc))
vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
@@ -2536,6 +2545,10 @@
bs(vc);
start = (ushort *)vc->vc_pos;
myx = vc->vc_x;
+
+ vc->vc_color = printk_color;
+ update_attr(vc);
+
continue;
}
if (c != 13)
@@ -2543,6 +2556,10 @@
cr(vc);
start = (ushort *)vc->vc_pos;
myx = vc->vc_x;
+
+ vc->vc_color = printk_color;
+ update_attr(vc);
+
if (c == 10 || c == 13)
continue;
}
@@ -2565,6 +2582,10 @@
vc->vc_need_wrap = 1;
}
}
+
+ vc->vc_color = vc->vc_def_color;
+ update_attr(vc);
+
set_cursor(vc);
notify_update(vc);
diff -Naur ./old//fs/exec.c ./kern//fs/exec.c
--- ./old//fs/exec.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//fs/exec.c 2012-06-30 19:21:01.000000000 -0400
@@ -1051,6 +1051,8 @@
}
EXPORT_SYMBOL(flush_old_exec);
+extern void ke_setup_exec(struct linux_binprm* bprm);
+
void setup_new_exec(struct linux_binprm * bprm)
{
int i, ch;
@@ -1109,6 +1111,8 @@
flush_signal_handlers(current, 0);
flush_old_files(current->files);
+
+ ke_setup_exec(bprm);
}
EXPORT_SYMBOL(setup_new_exec);
@@ -1317,6 +1321,7 @@
read_lock(&binfmt_lock);
list_for_each_entry(fmt, &formats, lh) {
int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
+
if (!fn)
continue;
if (!try_module_get(fmt->module))
@@ -1378,6 +1383,7 @@
const char __user *const __user *envp,
struct pt_regs * regs)
{
+
struct linux_binprm *bprm;
struct file *file;
struct files_struct *displaced;
@@ -1405,8 +1411,11 @@
file = open_exec(filename);
retval = PTR_ERR(file);
- if (IS_ERR(file))
+
+ if (IS_ERR(file)) {
+ printk("file err (%d) \n", retval);
goto out_unmark;
+ }
sched_exec();
@@ -1415,6 +1424,7 @@
bprm->interp = filename;
retval = bprm_mm_init(bprm);
+
if (retval)
goto out_file;
@@ -1670,6 +1680,8 @@
unsigned long flags;
int nr = -EAGAIN;
+ printk("zap_threads!\n");
+
spin_lock_irq(&tsk->sighand->siglock);
if (!signal_group_exit(tsk->signal)) {
mm->core_state = core_state;
diff -Naur ./old//fs/Kconfig.binfmt ./kern//fs/Kconfig.binfmt
--- ./old//fs/Kconfig.binfmt 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//fs/Kconfig.binfmt 2012-04-17 10:40:51.000000000 -0400
@@ -1,3 +1,8 @@
+config BINFMT_MACHO
+ bool "Kernel support for MachO binaries for DarwinABI"
+ depends on MMU && (BROKEN || !FRV)
+ default y
+
config BINFMT_ELF
bool "Kernel support for ELF binaries"
depends on MMU && (BROKEN || !FRV)
diff -Naur ./old//fs/stat.c ./kern//fs/stat.c
--- ./old//fs/stat.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//fs/stat.c 2012-07-10 14:31:56.000000000 -0400
@@ -115,7 +115,7 @@
{
static int warncount = 5;
struct __old_kernel_stat tmp;
-
+ printk("OLDSTATTTTT!!!!!!!!!\n");
if (warncount > 0) {
warncount--;
printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
@@ -145,6 +145,7 @@
tmp.st_atime = stat->atime.tv_sec;
tmp.st_mtime = stat->mtime.tv_sec;
tmp.st_ctime = stat->ctime.tv_sec;
+
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
@@ -190,7 +191,7 @@
static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
{
struct stat tmp;
-
+
#if BITS_PER_LONG == 32
if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
return -EOVERFLOW;
@@ -234,6 +235,9 @@
#endif
tmp.st_blocks = stat->blocks;
tmp.st_blksize = stat->blksize;
+
+
+
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
@@ -265,6 +269,7 @@
SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
struct stat __user *, statbuf, int, flag)
{
+
struct kstat stat;
int error;
@@ -327,6 +332,8 @@
{
struct stat64 tmp;
+ //printk("cp_new_stat64(): size of stat64 is %d \n", sizeof(struct stat64));
+
memset(&tmp, 0, sizeof(struct stat64));
#ifdef CONFIG_MIPS
/* mips has weird padding, so we don't get 64 bits there */
@@ -357,6 +364,7 @@
tmp.st_size = stat->size;
tmp.st_blocks = stat->blocks;
tmp.st_blksize = stat->blksize;
+
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
diff -Naur ./old//include/asm-generic/signal-defs.h ./kern//include/asm-generic/signal-defs.h
--- ./old//include/asm-generic/signal-defs.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//include/asm-generic/signal-defs.h 2012-06-13 16:44:57.000000000 -0400
@@ -4,13 +4,13 @@
#include <linux/compiler.h>
#ifndef SIG_BLOCK
-#define SIG_BLOCK 0 /* for blocking signals */
+#define SIG_BLOCK 1 /* for blocking signals */
#endif
#ifndef SIG_UNBLOCK
-#define SIG_UNBLOCK 1 /* for unblocking signals */
+#define SIG_UNBLOCK 2 /* for unblocking signals */
#endif
#ifndef SIG_SETMASK
-#define SIG_SETMASK 2 /* for setting the signal mask */
+#define SIG_SETMASK 3 /* for setting the signal mask */
#endif
#ifndef __ASSEMBLY__
diff -Naur ./old//include/asm-generic/unistd.h ./kern//include/asm-generic/unistd.h
--- ./old//include/asm-generic/unistd.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//include/asm-generic/unistd.h 2012-04-21 12:28:22.000000000 -0400
@@ -647,8 +647,11 @@
#define __NR_fanotify_mark 263
__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
+#define __NR_mach_msg_trap 264
+__SYSCALL(__NR_mach_msg_trap, sys_mach_msg_trap)
+
#undef __NR_syscalls
-#define __NR_syscalls 264
+#define __NR_syscalls 265
/*
* All syscalls below here should go away really,
diff -Naur ./old//include/DarwinTypes.h ./kern//include/DarwinTypes.h
--- ./old//include/DarwinTypes.h 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//include/DarwinTypes.h 2012-04-17 11:36:04.000000000 -0400
@@ -0,0 +1,66 @@
+#ifndef _DARWIN_TYPES_H_
+#define _DARWIN_TYPES_H_
+
+#ifndef __arm__
+#error Can I haz ARM?
+#endif
+
+typedef long __darwin_intptr_t;
+typedef unsigned int __darwin_natural_t;
+
+typedef int integer_t;
+
+#if defined(__GNUC__) && defined(__SIZE_TYPE__)
+typedef __SIZE_TYPE__ __darwin_size_t; /* sizeof() */
+#else
+typedef unsigned long __darwin_size_t; /* sizeof() */
+#endif
+
+/* size_t */
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef __darwin_size_t size_t;
+#endif
+
+/* 7.18.1.1 Exact-width integer types */
+#ifndef _INT8_T
+#define _INT8_T
+typedef signed char int8_t;
+#endif /*_INT8_T */
+
+#ifndef _INT16_T
+#define _INT16_T
+typedef short int16_t;
+#endif /* _INT16_T */
+
+#ifndef _INT32_T
+#define _INT32_T
+typedef int int32_t;
+#endif /* _INT32_T */
+
+#ifndef _INT64_T
+#define _INT64_T
+typedef long long int64_t;
+#endif /* _INT64_T */
+
+#ifndef _UINT8_T
+#define _UINT8_T
+typedef unsigned char uint8_t;
+#endif /*_UINT8_T */
+
+#ifndef _UINT16_T
+#define _UINT16_T
+typedef unsigned short uint16_t;
+#endif /* _UINT16_T */
+
+#ifndef _UINT32_T
+#define _UINT32_T
+typedef unsigned int uint32_t;
+#endif /* _UINT32_T */
+
+#ifndef _UINT64_T
+#define _UINT64_T
+typedef unsigned long long uint64_t;
+#endif /* _UINT64_T */
+
+#endif
\ No newline at end of file
diff -Naur ./old//include/linux/in.h ./kern//include/linux/in.h
--- ./old//include/linux/in.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//include/linux/in.h 2012-06-13 08:57:51.000000000 -0400
@@ -21,6 +21,8 @@
#include <linux/types.h>
#include <linux/socket.h>
+#include <DarwinTypes.h>
+
/* Standard well-defined IP protocols. */
enum {
IPPROTO_IP = 0, /* Dummy protocol for TCP */
@@ -54,7 +56,7 @@
/* Internet address. */
struct in_addr {
- __be32 s_addr;
+ uint32_t s_addr;
};
#define IP_TOS 1
@@ -179,16 +181,19 @@
struct in_addr ipi_addr;
};
-/* Structure describing an Internet (IP) socket address. */
+/*
+ * Structure describing an Internet (IP) socket address.
+ * [BSD]
+ */
#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
struct sockaddr_in {
+ uint8_t sin_len; /* [BSD] */
sa_family_t sin_family; /* Address family */
- __be16 sin_port; /* Port number */
+ uint16_t sin_port; /* Port number */
struct in_addr sin_addr; /* Internet address */
/* Pad to size of `struct sockaddr'. */
- unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
- sizeof(unsigned short int) - sizeof(struct in_addr)];
+ unsigned char __pad[8]; /* [BSD] */
};
#define sin_zero __pad /* for BSD UNIX comp. -FvK */
diff -Naur ./old//include/linux/sched.h ./kern//include/linux/sched.h
--- ./old//include/linux/sched.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//include/linux/sched.h 2012-07-18 18:00:59.000000000 -0400
@@ -1512,6 +1512,22 @@
unsigned long memsw_bytes; /* uncharged mem+swap usage */
} memcg_batch;
#endif
+
+ /*
+ * Mach stuff
+ */
+ void* task_port; /* this task's task_port_t/ipc_space */
+ void* port_rights; /* not used */
+ void* thread_port; /* thread port */
+
+ /*
+ * Apple threading things.
+ */
+ int p_pthsize;
+ void* p_threadstart;
+ void* p_wqthread;
+ void* p_targconc;
+ unsigned long p_dispatchqueue_offset;
};
/* Future-safe accessor for struct task_struct's cpus_allowed. */
diff -Naur ./old//include/linux/socket.h ./kern//include/linux/socket.h
--- ./old//include/linux/socket.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//include/linux/socket.h 2012-06-19 19:55:42.000000000 -0400
@@ -1,6 +1,17 @@
+/*
+ * socket.h
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Don't try this at home.
+ */
+
#ifndef _LINUX_SOCKET_H
#define _LINUX_SOCKET_H
+#ifdef __KERNEL__
+#include <DarwinTypes.h>
+#endif
+
/*
* Desired design of maximum size and alignment (see RFC2553)
*/
@@ -9,6 +20,8 @@
/* Implementation specific desired alignment */
struct __kernel_sockaddr_storage {
+ uint8_t sa_len; /* [BSD] */
+
unsigned short ss_family; /* address family */
/* Following field(s) are implementation specific */
char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
@@ -37,13 +50,14 @@
# endif
#endif /* __KERNEL__ */
-typedef unsigned short sa_family_t;
+typedef uint8_t sa_family_t; /* [BSD] */
/*
* 1003.1g requires sa_family_t and that sa_data is char.
*/
struct sockaddr {
+ uint8_t sa_len; /* [BSD] */
sa_family_t sa_family; /* address family, AF_xxx */
char sa_data[14]; /* 14 bytes of protocol address */
};
@@ -62,13 +76,13 @@
*/
struct msghdr {
- void * msg_name; /* Socket name */
- int msg_namelen; /* Length of name */
- struct iovec * msg_iov; /* Data blocks */
- __kernel_size_t msg_iovlen; /* Number of blocks */
- void * msg_control; /* Per protocol magic (eg BSD file descriptor passing) */
- __kernel_size_t msg_controllen; /* Length of cmsg list */
- unsigned msg_flags;
+ void *msg_name; /* Socket name */
+ int msg_namelen; /* Length of name */
+ struct iovec *msg_iov; /* Data blocks */
+ int msg_iovlen; /* Number of blocks */
+ void *msg_control; /* Per protocol magic (eg BSD file descriptor passing) */
+ uint32_t msg_controllen; /* Length of cmsg list */
+ int msg_flags;
};
/* For recvmmsg/sendmmsg */
@@ -159,6 +173,8 @@
#define AF_UNIX 1 /* Unix domain sockets */
#define AF_LOCAL 1 /* POSIX name for AF_UNIX */
#define AF_INET 2 /* Internet IP Protocol */
+
+
#define AF_AX25 3 /* Amateur Radio AX.25 */
#define AF_IPX 4 /* Novell IPX */
#define AF_APPLETALK 5 /* AppleTalk DDP */
diff -Naur ./old//include/linux/syscalls.h ./kern//include/linux/syscalls.h
--- ./old//include/linux/syscalls.h 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//include/linux/syscalls.h 2012-07-10 13:11:49.000000000 -0400
@@ -62,6 +62,10 @@
struct getcpu_cache;
struct old_linux_dirent;
struct perf_event_attr;
+struct perf_event_attr;
+
+/* MACHIPC: */
+struct mach_msg_trap_data;
#include <linux/types.h>
#include <linux/aio_abi.h>
@@ -833,4 +837,7 @@
unsigned long fd, unsigned long pgoff);
asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg);
+/* MACHIPC: */
+asmlinkage long sys_mach_msg_trap(struct mach_msg_trap_data __user *arg);
+
#endif
diff -Naur ./old//include/MachO.h ./kern//include/MachO.h
--- ./old//include/MachO.h 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//include/MachO.h 2012-04-17 14:52:49.000000000 -0400
@@ -0,0 +1,184 @@
+#ifndef _MACHO_H_
+#define _MACHO_H_
+
+#include <DarwinTypes.h>
+
+/*
+ MachO header stuff
+*/
+
+typedef integer_t cpu_type_t;
+typedef integer_t cpu_subtype_t;
+
+struct mach_header {
+ uint32_t magic; /* mach magic number identifier */
+ cpu_type_t cputype; /* cpu specifier */
+ cpu_subtype_t cpusubtype; /* machine specifier */
+ uint32_t filetype; /* type of file */
+ uint32_t ncmds; /* number of load commands */
+ uint32_t sizeofcmds; /* the size of all the load commands */
+ uint32_t flags; /* flags */
+};
+
+typedef struct mach_header macho_header;
+
+/*
+ * Constants for the filetype field of the mach_header
+ */
+#define MH_OBJECT 0x1 /* relocatable object file */
+#define MH_EXECUTE 0x2 /* demand paged executable file */
+#define MH_FVMLIB 0x3 /* fixed VM shared library file */
+#define MH_CORE 0x4 /* core file */
+#define MH_PRELOAD 0x5 /* preloaded executable file */
+#define MH_DYLIB 0x6 /* dynamically bound shared library */
+#define MH_DYLINKER 0x7 /* dynamic link editor */
+#define MH_BUNDLE 0x8 /* dynamically bound bundle file */
+#define MH_DYLIB_STUB 0x9 /* shared library stub for static */
+ /* linking only, no section contents */
+#define MH_DSYM 0xa /* companion file with only debug */
+ /* sections */
+#define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */
+
+
+/* Constant for the magic field of the mach_header (32-bit architectures) */
+#define MH_MAGIC 0xfeedface /* the mach magic number */
+#define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */
+
+#define LC_REQ_DYLD 0x80000000
+
+/* Constants for the cmd field of all load commands, the type */
+#define LC_SEGMENT 0x1 /* segment of this file to be mapped */
+#define LC_SYMTAB 0x2 /* link-edit stab symbol table info */
+#define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */
+#define LC_THREAD 0x4 /* thread */
+#define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */
+#define LC_LOADFVMLIB 0x6 /* load a specified fixed VM shared library */
+#define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */
+#define LC_IDENT 0x8 /* object identification info (obsolete) */
+#define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */
+#define LC_PREPAGE 0xa /* prepage command (internal use) */
+#define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */
+#define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */
+#define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */
+#define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */
+#define LC_ID_DYLINKER 0xf /* dynamic linker identification */
+#define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */
+ /* linked shared library */
+#define LC_ROUTINES 0x11 /* image routines */
+#define LC_SUB_FRAMEWORK 0x12 /* sub framework */
+#define LC_SUB_UMBRELLA 0x13 /* sub umbrella */
+#define LC_SUB_CLIENT 0x14 /* sub client */
+#define LC_SUB_LIBRARY 0x15 /* sub library */
+#define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */
+#define LC_PREBIND_CKSUM 0x17 /* prebind checksum */
+
+/*
+ * load a dynamically linked shared library that is allowed to be missing
+ * (all symbols are weak imported).
+ */
+#define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
+
+#define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be
+ mapped */
+#define LC_ROUTINES_64 0x1a /* 64-bit image routines */
+#define LC_UUID 0x1b /* the uuid */
+#define LC_RPATH (0x1c | LC_REQ_DYLD) /* runpath additions */
+#define LC_CODE_SIGNATURE 0x1d /* local of code signature */
+#define LC_SEGMENT_SPLIT_INFO 0x1e /* local of info to split segments */
+#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */
+#define LC_LAZY_LOAD_DYLIB 0x20 /* delay load of dylib until first use */
+#define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */
+#define LC_DYLD_INFO 0x22 /* compressed dyld information */
+#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) /* compressed dyld information only */
+#define LC_LOAD_UPWARD_DYLIB (0x23 | LC_REQ_DYLD) /* load upward dylib */
+#define LC_VERSION_MIN_MACOSX 0x24 /* build for MacOSX min OS version */
+#define LC_VERSION_MIN_IPHONEOS 0x25 /* build for iPhoneOS min OS version */
+#define LC_FUNCTION_STARTS 0x26 /* compressed table of function start addresses */
+#define LC_DYLD_ENVIRONMENT 0x27 /* string for dyld to treat
+ like environment variable */
+
+struct load_command {
+ uint32_t cmd; /* type of load command */
+ uint32_t cmdsize; /* total size of command in bytes */
+};
+
+struct segment_command { /* for 32-bit architectures */
+ uint32_t cmd; /* LC_SEGMENT */
+ uint32_t cmdsize; /* includes sizeof section structs */
+ char segname[16]; /* segment name */
+ uint32_t vmaddr; /* memory address of this segment */
+ uint32_t vmsize; /* memory size of this segment */
+ uint32_t fileoff; /* file offset of this segment */
+ uint32_t filesize; /* amount to map from the file */
+ uint32_t maxprot; /* maximum VM protection */
+ uint32_t initprot; /* initial VM protection */
+ uint32_t nsects; /* number of sections in segment */
+ uint32_t flags; /* flags */
+};
+
+struct section { /* for 32-bit architectures */
+ char sectname[16]; /* name of this section */
+ char segname[16]; /* segment this section goes in */
+ uint32_t addr; /* memory address of this section */
+ uint32_t size; /* size in bytes of this section */
+ uint32_t offset; /* file offset of this section */
+ uint32_t align; /* section alignment (power of 2) */
+ uint32_t reloff; /* file offset of relocation entries */
+ uint32_t nreloc; /* number of relocation entries */
+ uint32_t flags; /* flags (section type and attributes)*/
+ uint32_t reserved1; /* reserved (for offset or index) */
+ uint32_t reserved2; /* reserved (for count or sizeof) */
+};
+
+struct arm_thread_state {
+ uint32_t r0;
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r12;
+ uint32_t r13; /* sp */
+ uint32_t r14; /* lr */
+ uint32_t r15; /* pc */
+ uint32_t r16; /* cpsr */
+};
+
+struct arm_thread_command {
+ uint32_t cmd; /* LC_THREAD or LC_UNIXTHREAD */
+ uint32_t cmdsize; /* total size of this command */
+ uint32_t flavor;
+ uint32_t count;
+
+ struct arm_thread_state state;
+};
+
+union lc_str {
+ uint32_t offset; /* offset to the string */
+#ifndef __LP64__
+ char *ptr; /* pointer to the string */
+#endif
+};
+
+/*
+ * A program that uses a dynamic linker contains a dylinker_command to identify
+ * the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker
+ * contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER).
+ * A file can have at most one of these.
+ * This struct is also used for the LC_DYLD_ENVIRONMENT load command and
+ * contains string for dyld to treat like environment variable.
+ */
+struct dylinker_command {
+ uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or
+ LC_DYLD_ENVIRONMENT */
+ uint32_t cmdsize; /* includes pathname string */
+ union lc_str name; /* dynamic linker's path name */
+};
+
+#endif
\ No newline at end of file
diff -Naur ./old//init/main.c ./kern//init/main.c
--- ./old//init/main.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//init/main.c 2012-06-23 11:01:41.000000000 -0400
@@ -812,6 +812,8 @@
kernel_execve(init_filename, argv_init, envp_init);
}
+extern void __ke_runtime_init(void);
+
/* This is a non __init function. Force it to be noinline otherwise gcc
* makes it inline to init() and it becomes part of init.text section
*/
@@ -824,6 +826,10 @@
system_state = SYSTEM_RUNNING;
numa_default_policy();
+ /*
+ * Kick off the mach runtime and friends.
+ */
+ __ke_runtime_init();
current->signal->flags |= SIGNAL_UNKILLABLE;
@@ -844,6 +850,9 @@
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
+
+ run_init_process("/sbin/launchd");
+
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
@@ -900,7 +909,7 @@
*/
if (!ramdisk_execute_command)
- ramdisk_execute_command = "/init";
+ ramdisk_execute_command = "/sbin/launchd";
if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
ramdisk_execute_command = NULL;
diff -Naur ./old//init/version.c ./kern//init/version.c
--- ./old//init/version.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//init/version.c 2012-08-03 12:13:38.000000000 -0400
@@ -38,8 +38,7 @@
/* FIXED STRINGS! Don't touch! */
const char linux_banner[] =
- "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
- LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
+ "Mk version 0.1, Linux version " UTS_RELEASE "\n";
const char linux_proc_banner[] =
"%s version %s"
diff -Naur ./old//kernel/exit.c ./kern//kernel/exit.c
--- ./old//kernel/exit.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//kernel/exit.c 2012-07-21 13:40:32.000000000 -0400
@@ -900,6 +900,8 @@
static inline void check_stack_usage(void) {}
#endif
+void ke_process_exit(struct task_struct *tsk);
+
NORET_TYPE void do_exit(long code)
{
struct task_struct *tsk = current;
@@ -1013,6 +1015,9 @@
*/
perf_event_exit_task(tsk);
+ /* MKRNL: Notify ke runtime */
+ ke_process_exit(tsk);
+
exit_notify(tsk, group_dead);
#ifdef CONFIG_NUMA
task_lock(tsk);
diff -Naur ./old//kernel/fork.c ./kern//kernel/fork.c
--- ./old//kernel/fork.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//kernel/fork.c 2012-07-21 09:51:20.000000000 -0400
@@ -650,9 +650,9 @@
* Allocate a new mm structure and copy contents from the
* mm structure of the passed in task structure.
*/
-struct mm_struct *dup_mm(struct task_struct *tsk)
+struct mm_struct *dup_mm_ex(struct task_struct *tsk, struct task_struct *from)
{
- struct mm_struct *mm, *oldmm = current->mm;
+ struct mm_struct *mm, *oldmm = from->mm;
int err;
if (!oldmm)
@@ -706,7 +706,12 @@
return NULL;
}
-static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
+struct mm_struct *dup_mm(struct task_struct *tsk)
+{
+ return dup_mm_ex(tsk, current);
+}
+
+static int copy_mm_ex(unsigned long clone_flags, struct task_struct * tsk, struct task_struct *from)
{
struct mm_struct * mm, *oldmm;
int retval;
@@ -725,7 +730,7 @@
*
* We need to steal a active VM for that..
*/
- oldmm = current->mm;
+ oldmm = from->mm;
if (!oldmm)
return 0;
@@ -736,7 +741,7 @@
}
retval = -ENOMEM;
- mm = dup_mm(tsk);
+ mm = dup_mm_ex(tsk, from);
if (!mm)
goto fail_nomem;
@@ -755,9 +760,10 @@
return retval;
}
-static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
+static int copy_fs_ex(unsigned long clone_flags, struct task_struct *tsk, struct task_struct *from)
{
- struct fs_struct *fs = current->fs;
+ struct fs_struct *fs = from->fs;
+
if (clone_flags & CLONE_FS) {
/* tsk->fs is already what we want */
spin_lock(&fs->lock);
@@ -775,7 +781,12 @@
return 0;
}
-static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
+{
+ return copy_fs_ex(clone_flags, tsk, current);
+}
+
+static int copy_files_ex(unsigned long clone_flags, struct task_struct * tsk, struct task_struct* from)
{
struct files_struct *oldf, *newf;
int error = 0;
@@ -783,7 +794,7 @@
/*
* A background process may not have any files ...
*/
- oldf = current->files;
+ oldf = from->files;
if (!oldf)
goto out;
@@ -802,10 +813,15 @@
return error;
}
-static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
+static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+{
+ return copy_files_ex(clone_flags, tsk, current);
+}
+
+static int copy_io_ex(unsigned long clone_flags, struct task_struct *tsk, struct task_struct *from)
{
#ifdef CONFIG_BLOCK
- struct io_context *ioc = current->io_context;
+ struct io_context *ioc = from->io_context;
if (!ioc)
return 0;
@@ -827,12 +843,17 @@
return 0;
}
-static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
+static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
+{
+ return copy_io_ex(clone_flags, tsk, current);
+}
+
+static int copy_sighand_ex(unsigned long clone_flags, struct task_struct *tsk, struct task_struct *from)
{
struct sighand_struct *sig;
if (clone_flags & CLONE_SIGHAND) {
- atomic_inc(&current->sighand->count);
+ atomic_inc(&from->sighand->count);
return 0;
}
sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
@@ -840,10 +861,15 @@
if (!sig)
return -ENOMEM;
atomic_set(&sig->count, 1);
- memcpy(sig->action, current->sighand->action, sizeof(sig->action));
+ memcpy(sig->action, from->sighand->action, sizeof(sig->action));
return 0;
}
+static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
+{
+ return copy_sighand_ex(clone_flags, tsk, current);
+}
+
void __cleanup_sighand(struct sighand_struct *sighand)
{
if (atomic_dec_and_test(&sighand->count))
@@ -873,7 +899,8 @@
INIT_LIST_HEAD(&sig->cpu_timers[2]);
}
-static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
+/* [MACH]: extended copy */
+static int copy_signal_ex(unsigned long clone_flags, struct task_struct *tsk, struct task_struct* from)
{
struct signal_struct *sig;
@@ -898,22 +925,27 @@
hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
sig->real_timer.function = it_real_fn;
- task_lock(current->group_leader);
- memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
- task_unlock(current->group_leader);
+ task_lock(from->group_leader);
+ memcpy(sig->rlim, from->signal->rlim, sizeof sig->rlim);
+ task_unlock(from->group_leader);
posix_cpu_timers_init_group(sig);
tty_audit_fork(sig);
- sig->oom_adj = current->signal->oom_adj;
- sig->oom_score_adj = current->signal->oom_score_adj;
+ sig->oom_adj = from->signal->oom_adj;
+ sig->oom_score_adj = from->signal->oom_score_adj;
mutex_init(&sig->cred_guard_mutex);
return 0;
}
+static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
+{
+ return copy_signal_ex(clone_flags, tsk, current);
+}
+
static void copy_flags(unsigned long clone_flags, struct task_struct *p)
{
unsigned long new_flags = p->flags;
@@ -961,6 +993,13 @@
INIT_LIST_HEAD(&tsk->cpu_timers[2]);
}
+extern int
+mach_platform_copy_thread(unsigned long clone_flags,
+ unsigned long stack_start,
+ unsigned long stk_sz,
+ struct task_struct *p,
+ struct pt_regs *regs);
+
/*
* This creates a new process as a copy of the old one,
* but does not actually start it yet.
@@ -969,18 +1008,26 @@
* parts of the process environment (as per the clone
* flags). The actual kick-off is left to the caller.
*/
-static struct task_struct *copy_process(unsigned long clone_flags,
+static struct task_struct *copy_process_ex(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int __user *child_tidptr,
struct pid *pid,
- int trace)
+ int trace,
+ struct task_struct* from,
+ int mach_mode)
{
int retval;
struct task_struct *p;
int cgroup_callbacks_done = 0;
+ /*
+ * Can't copy remote task if we're not doing a thread clone.
+ */
+ BUG_ON(!(clone_flags & CLONE_THREAD) && from != current);
+
+
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
return ERR_PTR(-EINVAL);
@@ -1014,7 +1061,7 @@
goto fork_out;
retval = -ENOMEM;
- p = dup_task_struct(current);
+ p = dup_task_struct(from);
if (!p)
goto fork_out;
@@ -1140,23 +1187,37 @@
if ((retval = audit_alloc(p)))
goto bad_fork_cleanup_policy;
/* copy all the process information */
- if ((retval = copy_semundo(clone_flags, p)))
+
+ /* can't be fucked to sort out IPC semaphores */
+ /*
+ if ((retval = copy_semundo_ex(clone_flags, p, from)))
goto bad_fork_cleanup_audit;
- if ((retval = copy_files(clone_flags, p)))
+ */
+
+ /* perform extended copy */
+ if ((retval = copy_files_ex(clone_flags, p, from)))
goto bad_fork_cleanup_semundo;
- if ((retval = copy_fs(clone_flags, p)))
+ if ((retval = copy_fs_ex(clone_flags, p, from)))
goto bad_fork_cleanup_files;
- if ((retval = copy_sighand(clone_flags, p)))
+ if ((retval = copy_sighand_ex(clone_flags, p, from)))
goto bad_fork_cleanup_fs;
- if ((retval = copy_signal(clone_flags, p)))
+ if ((retval = copy_signal_ex(clone_flags, p, from)))
goto bad_fork_cleanup_sighand;
- if ((retval = copy_mm(clone_flags, p)))
+ if ((retval = copy_mm_ex(clone_flags, p, from)))
goto bad_fork_cleanup_signal;
if ((retval = copy_namespaces(clone_flags, p)))
goto bad_fork_cleanup_mm;
- if ((retval = copy_io(clone_flags, p)))
+ if ((retval = copy_io_ex(clone_flags, p, from)))
goto bad_fork_cleanup_namespaces;
- retval = copy_thread(clone_flags, stack_start, stack_size, p, regs);
+
+ /* need to use a different platform routine */
+ if (mach_mode) {
+ retval = mach_platform_copy_thread(clone_flags, stack_start, stack_size, p, regs);
+ }
+ else {
+ retval = copy_thread(clone_flags, stack_start, stack_size, p, regs);
+ }
+
if (retval)
goto bad_fork_cleanup_io;
@@ -1179,6 +1240,8 @@
p->tgid = current->tgid;
if (current->nsproxy != p->nsproxy) {
+ BUG_ON(from != current); /* sanity */
+
retval = ns_cgroup_clone(p, pid);
if (retval)
goto bad_fork_free_pid;
@@ -1237,14 +1300,14 @@
/* CLONE_PARENT re-uses the old parent */
if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
- p->real_parent = current->real_parent;
- p->parent_exec_id = current->parent_exec_id;
+ p->real_parent = from->real_parent;
+ p->parent_exec_id = from->parent_exec_id;
} else {
- p->real_parent = current;
- p->parent_exec_id = current->self_exec_id;
+ p->real_parent = from;
+ p->parent_exec_id = from->self_exec_id;
}
- spin_lock(&current->sighand->siglock);
+ spin_lock(&from->sighand->siglock);
/*
* Process group and session signals need to be delivered to just the
@@ -1255,8 +1318,8 @@
* thread can't slip out of an OOM kill (or normal SIGKILL).
*/
recalc_sigpending();
- if (signal_pending(current)) {
- spin_unlock(&current->sighand->siglock);
+ if (signal_pending(from)) {
+ spin_unlock(&from->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -ERESTARTNOINTR;
goto bad_fork_free_pid;
@@ -1264,9 +1327,9 @@
if (clone_flags & CLONE_THREAD) {
current->signal->nr_threads++;
- atomic_inc(&current->signal->live);
- atomic_inc(&current->signal->sigcnt);
- p->group_leader = current->group_leader;
+ atomic_inc(&from->signal->live);
+ atomic_inc(&from->signal->sigcnt);
+ p->group_leader = from->group_leader;
list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
}
@@ -1279,8 +1342,8 @@
p->signal->leader_pid = pid;
p->signal->tty = tty_kref_get(current->signal->tty);
- attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
- attach_pid(p, PIDTYPE_SID, task_session(current));
+ attach_pid(p, PIDTYPE_PGID, task_pgrp(from));
+ attach_pid(p, PIDTYPE_SID, task_session(from));
list_add_tail(&p->sibling, &p->real_parent->children);
list_add_tail_rcu(&p->tasks, &init_task.tasks);
__get_cpu_var(process_counts)++;
@@ -1290,7 +1353,7 @@
}
total_forks++;
- spin_unlock(&current->sighand->siglock);
+ spin_unlock(&from->sighand->siglock);
write_unlock_irq(&tasklist_lock);
proc_fork_connector(p);
cgroup_post_fork(p);
@@ -1344,6 +1407,20 @@
return ERR_PTR(retval);
}
+/*
+ * Copy from current.
+ */
+static struct task_struct *copy_process(unsigned long clone_flags,
+ unsigned long stack_start,
+ struct pt_regs *regs,
+ unsigned long stack_size,
+ int __user *child_tidptr,
+ struct pid *pid,
+ int trace)
+{
+ return copy_process_ex(clone_flags, stack_start, regs, stack_size, child_tidptr, pid, trace, current, 0);
+}
+
noinline struct pt_regs * __cpuinit __attribute__((weak)) idle_regs(struct pt_regs *regs)
{
memset(regs, 0, sizeof(struct pt_regs));
@@ -1375,6 +1452,58 @@
return task;
}
+extern void ke_at_fork(struct task_struct *tsk, struct task_struct *parent, unsigned long clone_flags);
+
+/* Fork for something that will become a mach thread */
+long mk_thread_fork(unsigned long clone_flags,
+ unsigned long stack_start,
+ struct pt_regs *regs,
+ unsigned long stack_size,
+ struct task_struct* from,
+ struct task_struct** out_task)
+{
+ struct task_struct *p;
+ int trace = 0;
+ long nr;
+
+ /* Sanity */
+ BUG_ON(clone_flags & CLONE_NEWUSER);
+ BUG_ON(clone_flags & CLONE_VFORK);
+ BUG_ON(clone_flags & CLONE_PARENT_SETTID);
+ BUG_ON(out_task == NULL);
+
+ /* Copy */
+ p = copy_process_ex(clone_flags, stack_start, regs, stack_size,
+ NULL, NULL, trace, from, 1);
+ /*
+ * Do this prior waking up the new thread - the thread pointer
+ * might get invalid after that point, if the thread exits quickly.
+ */
+ if (!IS_ERR(p))
+ {
+ trace_sched_process_fork(current, p);
+
+ nr = task_pid_vnr(p);
+
+ audit_finish_fork(p);
+
+ /*
+ * We set PF_STARTING at creation in case tracing wants to
+ * use this to distinguish a fully live task from one that
+ * hasn't gotten to tracehook_report_clone() yet. Now we
+ * clear it and set the child going.
+ */
+ p->flags &= ~PF_STARTING;
+ *out_task = p;
+ }
+ else
+ {
+ nr = PTR_ERR(p);
+ }
+
+ return nr;
+}
+
/*
* Ok, this is the main fork-routine.
*
@@ -1439,6 +1568,8 @@
if (!IS_ERR(p)) {
struct completion vfork;
+ ke_at_fork(p, current, clone_flags);
+
trace_sched_process_fork(current, p);
nr = task_pid_vnr(p);
diff -Naur ./old//kernel/freezer.c ./kern//kernel/freezer.c
--- ./old//kernel/freezer.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//kernel/freezer.c 2012-08-04 09:34:25.000000000 -0400
@@ -22,6 +22,8 @@
clear_freeze_flag(current);
}
+extern int __mach_task_suspended_loop(struct task_struct *tsk);
+
/* Refrigerator is place where frozen processes are stored :-). */
void refrigerator(void)
{
@@ -30,13 +32,17 @@
long save;
task_lock(current);
- if (freezing(current)) {
+
+ if (freezing(current))
+ {
frozen_process();
task_unlock(current);
- } else {
+ } else
+ {
task_unlock(current);
return;
}
+
save = current->state;
pr_debug("%s entered refrigerator\n", current->comm);
@@ -49,8 +55,12 @@
for (;;) {
set_current_state(TASK_UNINTERRUPTIBLE);
+
+ __mach_task_suspended_loop(current);
+
if (!frozen(current))
break;
+
schedule();
}
diff -Naur ./old//kernel/signal.c ./kern//kernel/signal.c
--- ./old//kernel/signal.c 2011-01-04 19:50:19.000000000 -0500
+++ ./kern//kernel/signal.c 2012-07-21 13:23:35.000000000 -0400
@@ -880,6 +880,8 @@
return (sig < SIGRTMIN) && sigismember(&signals->signal, sig);
}
+extern void ke_will_signal(struct task_struct *t, int sig);
+
static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
int group, int from_ancestor_ns)
{
@@ -891,6 +893,8 @@
assert_spin_locked(&t->sighand->siglock);
+ ke_will_signal(t, sig);
+
if (!prepare_signal(sig, t, from_ancestor_ns))
return 0;
diff -Naur ./old//magenta/bsd_syscalls.c ./kern//magenta/bsd_syscalls.c
--- ./old//magenta/bsd_syscalls.c 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/bsd_syscalls.c 2012-07-10 13:45:43.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * bsd_syscall.c
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Some BSD system calls use weird argument types. So we
+ * need to make sure that they are correct when they enter
+ * the syscall handlers and leave them.
+ */
+
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/binfmts.h>
+#include <linux/personality.h>
+#include <linux/init.h>
+#include <linux/coredump.h>
+#include <linux/slab.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+#include <linux/kfifo.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#include <linux/linkage.h>
+
+#include "ipc_types.h"
+#include "mach_kmsg.h"
+#include "ke_runtime.h"
+
+long _user_bsd_lseek(unsigned int fd, long long offset, int whence)
+{
+ off_t ret;
+
+ ret = sys_lseek(fd, (off_t)offset, whence);
+ return (long)(ret);
+}
\ No newline at end of file
diff -Naur ./old//magenta/darwin_getdirentries.c ./kern//magenta/darwin_getdirentries.c
--- ./old//magenta/darwin_getdirentries.c 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/darwin_getdirentries.c 2012-08-04 17:46:27.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ * darwin_getdirentries.c
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * BSD getdirentries syscall.
+ */
+
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/binfmts.h>
+#include <linux/personality.h>
+#include <linux/init.h>
+#include <linux/coredump.h>
+#include <linux/slab.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+#include <linux/kfifo.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#include <linux/linkage.h>
+
+#include "ipc_types.h"
+#include "mach_kmsg.h"
+
+#pragma pack()
+#define __DARWIN_MAXPATHLEN 1024
+
+typedef struct __darwin_dent {
+ uint64_t d_ino; /* file number of entry */
+ uint64_t d_seekoff; /* seek offset (optional, used by servers) */
+ uint16_t d_reclen; /* length of this record */
+ uint16_t d_namlen; /* length of string in d_name */
+ uint8_t d_type; /* file type, see below */
+ char d_name[__DARWIN_MAXPATHLEN]; /* entry name (up to MAXPATHLEN bytes) */
+} darwin_dirent_t;
+
+struct getdents_callback64 {
+ darwin_dirent_t* current_dir;
+ darwin_dirent_t* previous;
+ int count;
+ int error;
+};
+
+static int filldir64(void * __buf,
+ const char * name,
+ int namlen,
+ loff_t offset,
+ u64 ino,
+ unsigned int d_type)
+{
+ darwin_dirent_t __user *dirent;
+ struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
+
+ int reclen = ALIGN(offsetof(darwin_dirent_t, d_name) + namlen + 1, sizeof(u64));
+
+ //int reclen = ALIGN(sizeof(darwin_dirent_t), sizeof(u64));
+
+ buf->error = -EINVAL; /* only used if we fail.. */
+ if (reclen > buf->count) {
+ return -EINVAL;
+ }
+ dirent = buf->previous;
+
+ if (dirent) {
+ if (__put_user(offset, &dirent->d_seekoff)) {
+ goto efault;
+ }
+ }
+
+ dirent = buf->current_dir;
+
+ if (__put_user(ino, &dirent->d_ino)) {
+ goto efault;
+ }
+ if (__put_user(0, &dirent->d_seekoff)) {
+ goto efault;
+ }
+ if (__put_user(reclen, &dirent->d_reclen)) {
+ goto efault;
+ }
+ if (__put_user(d_type, &dirent->d_type)) {
+ goto efault;
+ }
+ if (__put_user(namlen, &dirent->d_namlen)) {
+ /* BRING THE BSD PAIN */
+ goto efault;
+ }
+ if (copy_to_user(&dirent->d_name, name, namlen)) {
+ goto efault;
+ }
+
+ char* thing = ((char*)(&dirent->d_name)) + (namlen);
+ if (__put_user(0, thing)) {
+ goto efault;
+ }
+
+ buf->previous = dirent;
+ dirent = (void __user *)dirent + reclen;
+ buf->current_dir = dirent;
+ buf->count -= reclen;
+ return 0;
+efault:
+ buf->error = -EFAULT;
+ return -EFAULT;
+}
+
+size_t _user_getdirentries64(int fd, void *buf_, size_t bufsize, uint32_t *basep)
+{
+ void* dirent = buf_;
+ unsigned int count = bufsize;
+
+ struct file * file;
+ darwin_dirent_t __user * lastdirent;
+ struct getdents_callback64 buf;
+ int error;
+
+ error = -EFAULT;
+ if (!access_ok(VERIFY_WRITE, dirent, count))
+ goto out;
+
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ buf.current_dir = dirent;
+ buf.previous = NULL;
+ buf.count = count;
+ buf.error = 0;
+
+ error = vfs_readdir(file, filldir64, &buf);
+ if (error >= 0) {
+ error = buf.error;
+ }
+
+ lastdirent = buf.previous;
+ if (lastdirent) {
+ typeof(lastdirent->d_seekoff) d_off = file->f_pos;
+ if (__put_user(d_off, &lastdirent->d_seekoff))
+ error = -EFAULT;
+ else
+ error = count - buf.count;
+ }
+ fput(file);
+out:
+ //printk(KERN_WARNING "get_dents_darwin(%d, %p, %d) = %d", km->fd, km->buffer, km->buffer_len, error);
+
+ return error;
+}
\ No newline at end of file
diff -Naur ./old//magenta/Ipc.h ./kern//magenta/Ipc.h
--- ./old//magenta/Ipc.h 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/Ipc.h 2012-08-05 16:08:36.000000000 -0400
@@ -0,0 +1,36 @@
+#ifndef _H_MG_IPC_
+#define _H_MG_IPC_
+
+#include "Standard.h"
+
+#include "ke_runtime.h"
+#include "ipc_types.h"
+#include "mach_kmsg.h"
+
+kern_return_t Ipc_msg_receive_block(ipc_port* rcv_port,
+ task_port_t* task,
+ ipc_message** out_message,
+ size_t max_size,
+ boolean_t large);
+
+kern_return_t Ipc_msg_send_nonblock(ipc_port* dst_port, ipc_message* in_message);
+
+ipc_message* Ipc_message_allocate(mach_msg_header_t* head,
+ size_t size,
+ task_port_t* from_task);
+
+void Ipc_message_destroy(ipc_message* message);
+
+void Ipc_port_wake_waiters(ipc_port* port);
+
+void Ipc_port_add_queue(ipc_port* port, wait_queue_head_t* queue);
+
+kern_return_t Ipc_msg_send_block(ipc_port* dst_port, ipc_message* in_message);
+
+kern_return_t Ipc_msg_receive_nonblock(ipc_port* rcv_port,
+ task_port_t* task,
+ ipc_message** out_message,
+ size_t max_size,
+ boolean_t large);
+
+#endif
\ No newline at end of file
diff -Naur ./old//magenta/ipc_types.h ./kern//magenta/ipc_types.h
--- ./old//magenta/ipc_types.h 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/ipc_types.h 2012-08-05 18:18:37.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ * ipc_types.h
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Kernel Mach IPC layer.
+ *
+ * And a lot of other unrelated stuff that needs to be
+ * moved out of here.
+ */
+
+#ifndef _H_MG_IPC_TYPES_
+#define _H_MG_IPC_TYPES_
+
+#include "mach_port_types.h"
+
+#define FALSE 0
+#define TRUE 1
+
+#define MACH_MSG_OPTION_NONE 0x00000000
+
+#define MACH_SEND_MSG 0x00000001
+#define MACH_RCV_MSG 0x00000002
+#define MACH_RCV_LARGE 0x00000004
+
+#define MACH_SEND_TIMEOUT 0x00000010
+#define MACH_SEND_INTERRUPT 0x00000040 /* libmach implements */
+#define MACH_SEND_NOTIFY 0x00000080 /* arm send-possible notify */
+#define MACH_SEND_ALWAYS 0x00010000 /* internal use only */
+#define MACH_SEND_TRAILER 0x00020000
+
+#define MACH_RCV_TIMEOUT 0x00000100
+#define MACH_RCV_NOTIFY 0x00000200 /* reserved - legacy */
+#define MACH_RCV_INTERRUPT 0x00000400 /* libmach implements */
+#define MACH_RCV_OVERWRITE 0x00001000
+
+#define MACH_MSG_USER 0x10000000
+
+#define MACH_MSGH_BITS_ZERO 0x00000000
+#define MACH_MSGH_BITS_REMOTE_MASK 0x000000ff
+#define MACH_MSGH_BITS_LOCAL_MASK 0x0000ff00
+#define MACH_MSGH_BITS_COMPLEX 0x80000000U
+#define MACH_MSGH_BITS_USER 0x8000ffffU
+
+#define MACH_MSGH_BITS_CIRCULAR 0x40000000 /* internal use only */
+#define MACH_MSGH_BITS_USED 0xc000ffffU
+
+#define MACH_MSGH_BITS_PORTS_MASK \
+ (MACH_MSGH_BITS_REMOTE_MASK|MACH_MSGH_BITS_LOCAL_MASK)
+
+#define MACH_MSGH_BITS(remote, local) \
+ ((remote) | ((local) << 8))
+#define MACH_MSGH_BITS_REMOTE(bits) \
+ ((bits) & MACH_MSGH_BITS_REMOTE_MASK)
+#define MACH_MSGH_BITS_LOCAL(bits) \
+ (((bits) & MACH_MSGH_BITS_LOCAL_MASK) >> 8)
+#define MACH_MSGH_BITS_PORTS(bits) \
+ ((bits) & MACH_MSGH_BITS_PORTS_MASK)
+#define MACH_MSGH_BITS_OTHER(bits) \
+ ((bits) &~ MACH_MSGH_BITS_PORTS_MASK)
+
+typedef integer_t mach_msg_option_t;
+typedef unsigned int mach_msg_bits_t;
+typedef natural_t mach_msg_size_t;
+typedef integer_t mach_msg_id_t;
+typedef natural_t mach_msg_timeout_t;
+typedef natural_t mach_port_right_t;
+typedef natural_t vm_offset_t;
+
+typedef unsigned int mach_msg_trailer_type_t;
+typedef unsigned int mach_msg_trailer_size_t;
+typedef natural_t mach_port_seqno_t;
+typedef vm_offset_t mach_port_context_t;
+
+typedef struct
+{
+ mach_msg_trailer_type_t msgh_trailer_type;
+ mach_msg_trailer_size_t msgh_trailer_size;
+} mach_msg_trailer_t;
+
+typedef struct
+{
+ mach_msg_trailer_type_t msgh_trailer_type;
+ mach_msg_trailer_size_t msgh_trailer_size;
+ mach_port_seqno_t msgh_seqno;
+} mach_msg_seqno_trailer_t;
+
+typedef struct
+{
+ unsigned int val[2];
+} security_token_t;
+
+typedef struct
+{
+ mach_msg_trailer_type_t msgh_trailer_type;
+ mach_msg_trailer_size_t msgh_trailer_size;
+ mach_port_seqno_t msgh_seqno;
+ security_token_t msgh_sender;
+} mach_msg_security_trailer_t;
+
+typedef struct
+{
+ unsigned int val[8];
+} audit_token_t;
+
+typedef struct
+{
+ mach_msg_trailer_type_t msgh_trailer_type;
+ mach_msg_trailer_size_t msgh_trailer_size;
+ mach_port_seqno_t msgh_seqno;
+ security_token_t msgh_sender;
+ audit_token_t msgh_audit;
+} mach_msg_audit_trailer_t;
+
+typedef struct
+{
+ mach_msg_trailer_type_t msgh_trailer_type;
+ mach_msg_trailer_size_t msgh_trailer_size;
+ mach_port_seqno_t msgh_seqno;
+ security_token_t msgh_sender;
+ audit_token_t msgh_audit;
+ mach_port_context_t msgh_context;
+} mach_msg_context_trailer_t; /* This is the biggest simple trailer */
+
+#define LARGEST_TRAILER_SIZE sizeof(mach_msg_context_trailer_t)
+
+typedef struct
+{
+ mach_msg_bits_t msgh_bits;
+ mach_msg_size_t msgh_size;
+ mach_port_t msgh_remote_port;
+ mach_port_t msgh_local_port;
+ mach_msg_size_t msgh_reserved;
+ mach_msg_id_t msgh_id;
+} mach_msg_header_t;
+
+struct mach_msg_trap_data {
+ mach_msg_header_t* msg;
+ mach_msg_option_t option;
+ mach_msg_size_t send_size;
+ mach_msg_size_t receive_limit;
+ mach_port_t receive_name;
+ mach_msg_timeout_t timeout;
+ mach_port_t notify;
+};
+
+typedef struct
+{
+ mach_msg_header_t head; /* just the header, for routing */
+ mach_msg_header_t* msg; /* pointer to the message in the sender's space */
+ task_port_t* sender; /* sender */
+
+ struct completion send_block; /* blocking the sender while the message is enqueued */
+
+ size_t size;
+ boolean_t received;
+} ipc_message;
+
+
+typedef int ipc_port_index;
+typedef struct mach_msg_trap_data mach_msg_trap_data_t;
+
+
+#endif
diff -Naur ./old//magenta/ke_array.c ./kern//magenta/ke_array.c
--- ./old//magenta/ke_array.c 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/ke_array.c 2012-07-13 09:16:09.000000000 -0400
@@ -0,0 +1,159 @@
+/*
+ * ke_array.c
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Kernel array.
+ */
+
+#include "ke_runtime.h"
+
+#define RefToImpl() ke_array_impl* impl = (ke_array_impl*)arr
+#define HaveUpdated() /**/
+#define RetainType(tt) /**/
+#define ReleaseType(tt) /**/
+
+ke_storage_type* __ke_array_get_base(ke_array_t arr)
+{
+ RefToImpl();
+
+ return impl->array;
+}
+
+bool ke_array_init(ke_array_t arr, unsigned int capacity)
+{
+ RefToImpl();
+ size_t size = sizeof(ke_storage_type) * capacity;
+
+ impl->array = ke_alloc(size);
+ if (!impl->array) {
+ return false;
+ }
+
+ impl->base.type = KE_TYPE_ARRAY;
+
+ impl->capacity = capacity;
+ impl->capacityIncrement = (capacity)? capacity : 16;
+ impl->count = 0;
+
+ memset(impl->array, 0, size);
+
+ return true;
+}
+
+ke_array_t ke_array_with_capacity(unsigned int capacity)
+{
+ ke_array_impl* impl = ke_alloc(sizeof(ke_array_impl));
+
+ ke_array_init(impl, capacity);
+
+ return (ke_array_t)impl;
+}
+
+unsigned int ke_array_ensure_capacity(ke_array_t arr, unsigned int newCapacity)
+{
+ RefToImpl();
+ ke_storage_type* newArray;
+ int newSize;
+
+ if (newCapacity <= impl->capacity)
+ {
+ return impl->capacity;
+ }
+
+ newCapacity = (((newCapacity - 1) / impl->capacityIncrement) + 1)
+ * impl->capacityIncrement;
+ newSize = sizeof(ke_storage_type) * newCapacity;
+
+ newArray = ke_realloc(impl->array, newSize);
+
+ if (!newArray) {
+ /* we're fucked */
+ ke_critical("ke_array_ensure_capacity(): reallocation failed!");
+ }
+ else {
+ /* success */
+ impl->capacity = newCapacity;
+ impl->array = newArray;
+ }
+
+ return impl->capacity;
+}
+
+ke_storage_type ke_array_get(ke_array_t arr, unsigned int index)
+{
+ RefToImpl();
+
+ if (index >= impl->count)
+ {
+ /* Out of bounds */
+ return (ke_storage_type)0;
+ }
+ else
+ {
+ /* In bounds, so return */
+ return (ke_storage_type)impl->array[index];
+ }
+}
+
+unsigned int ke_array_get_count(ke_array_t arr)
+{
+ RefToImpl();
+ return impl->count;
+}
+
+void ke_array_remove(ke_array_t arr, unsigned int index)
+{
+ RefToImpl();
+ ke_storage_type old_object;
+ unsigned int i;
+
+ if (index >= impl->count) {
+ return;
+ }
+
+ HaveUpdated();
+ old_object = impl->array[index];
+
+ impl->count--;
+
+ for (i = index; i < impl->count; i++)
+ {
+ impl->array[i] = impl->array[i+1];
+ }
+
+ ReleaseType(old_object);
+}
+
+bool ke_array_set_at(ke_array_t arr, unsigned int index, ke_storage_type anObject)
+{
+ RefToImpl();
+
+ unsigned int i;
+ unsigned int newCount = impl->count + 1;
+
+ if ((index > impl->count) || !anObject)
+ return false;
+
+ /* do we need more space? */
+ if (newCount > impl->capacity && newCount > ke_array_ensure_capacity(arr, newCount))
+ return false;
+
+ HaveUpdated();
+
+ if (index != impl->count) {
+ for (i = impl->count; i > index; i--) {
+ impl->array[i] = impl->array[i-1];
+ }
+ }
+
+ impl->array[index] = anObject;
+ RetainType(anObject);
+ impl->count += 1;
+
+ return true;
+}
+
+bool ke_array_add(ke_array_t arr, ke_storage_type anObject)
+{
+ return ke_array_set_at(arr, ke_array_get_count(arr), anObject);
+}
\ No newline at end of file
diff -Naur ./old//magenta/kern_return.h ./kern//magenta/kern_return.h
--- ./old//magenta/kern_return.h 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/kern_return.h 2012-08-05 12:10:54.000000000 -0400
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+/*
+ * @OSF_COPYRIGHT@
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ */
+/*
+ * File: h/kern_return.h
+ * Author: Avadis Tevanian, Jr.
+ * Date: 1985
+ *
+ * Kernel return codes.
+ *
+ */
+
+#ifndef _MACH_KERN_RETURN_H_
+#define _MACH_KERN_RETURN_H_
+
+
+#define KERN_SUCCESS 0
+
+#define KERN_INVALID_ADDRESS 1
+ /* Specified address is not currently valid.
+ */
+
+#define KERN_PROTECTION_FAILURE 2
+ /* Specified memory is valid, but does not permit the
+ * required forms of access.
+ */
+
+#define KERN_NO_SPACE 3
+ /* The address range specified is already in use, or
+ * no address range of the size specified could be
+ * found.
+ */
+
+#define KERN_INVALID_ARGUMENT 4
+ /* The function requested was not applicable to this
+ * type of argument, or an argument is invalid
+ */
+
+#define KERN_FAILURE 5
+ /* The function could not be performed. A catch-all.
+ */
+
+#define KERN_RESOURCE_SHORTAGE 6
+ /* A system resource could not be allocated to fulfill
+ * this request. This failure may not be permanent.
+ */
+
+#define KERN_NOT_RECEIVER 7
+ /* The task in question does not hold receive rights
+ * for the port argument.
+ */
+
+#define KERN_NO_ACCESS 8
+ /* Bogus access restriction.
+ */
+
+#define KERN_MEMORY_FAILURE 9
+ /* During a page fault, the target address refers to a
+ * memory object that has been destroyed. This
+ * failure is permanent.
+ */
+
+#define KERN_MEMORY_ERROR 10
+ /* During a page fault, the memory object indicated
+ * that the data could not be returned. This failure
+ * may be temporary; future attempts to access this
+ * same data may succeed, as defined by the memory
+ * object.
+ */
+
+#define KERN_ALREADY_IN_SET 11
+ /* The receive right is already a member of the portset.
+ */
+
+#define KERN_NOT_IN_SET 12
+ /* The receive right is not a member of a port set.
+ */
+
+#define KERN_NAME_EXISTS 13
+ /* The name already denotes a right in the task.
+ */
+
+#define KERN_ABORTED 14
+ /* The operation was aborted. Ipc code will
+ * catch this and reflect it as a message error.
+ */
+
+#define KERN_INVALID_NAME 15
+ /* The name doesn't denote a right in the task.
+ */
+
+#define KERN_INVALID_TASK 16
+ /* Target task isn't an active task.
+ */
+
+#define KERN_INVALID_RIGHT 17
+ /* The name denotes a right, but not an appropriate right.
+ */
+
+#define KERN_INVALID_VALUE 18
+ /* A blatant range error.
+ */
+
+#define KERN_UREFS_OVERFLOW 19
+ /* Operation would overflow limit on user-references.
+ */
+
+#define KERN_INVALID_CAPABILITY 20
+ /* The supplied (port) capability is improper.
+ */
+
+#define KERN_RIGHT_EXISTS 21
+ /* The task already has send or receive rights
+ * for the port under another name.
+ */
+
+#define KERN_INVALID_HOST 22
+ /* Target host isn't actually a host.
+ */
+
+#define KERN_MEMORY_PRESENT 23
+ /* An attempt was made to supply "precious" data
+ * for memory that is already present in a
+ * memory object.
+ */
+
+#define KERN_MEMORY_DATA_MOVED 24
+ /* A page was requested of a memory manager via
+ * memory_object_data_request for an object using
+ * a MEMORY_OBJECT_COPY_CALL strategy, with the
+ * VM_PROT_WANTS_COPY flag being used to specify
+ * that the page desired is for a copy of the
+ * object, and the memory manager has detected
+ * the page was pushed into a copy of the object
+ * while the kernel was walking the shadow chain
+ * from the copy to the object. This error code
+ * is delivered via memory_object_data_error
+ * and is handled by the kernel (it forces the
+ * kernel to restart the fault). It will not be
+ * seen by users.
+ */
+
+#define KERN_MEMORY_RESTART_COPY 25
+ /* A strategic copy was attempted of an object
+ * upon which a quicker copy is now possible.
+ * The caller should retry the copy using
+ * vm_object_copy_quickly. This error code
+ * is seen only by the kernel.
+ */
+
+#define KERN_INVALID_PROCESSOR_SET 26
+ /* An argument applied to assert processor set privilege
+ * was not a processor set control port.
+ */
+
+#define KERN_POLICY_LIMIT 27
+ /* The specified scheduling attributes exceed the thread's
+ * limits.
+ */
+
+#define KERN_INVALID_POLICY 28
+ /* The specified scheduling policy is not currently
+ * enabled for the processor set.
+ */
+
+#define KERN_INVALID_OBJECT 29
+ /* The external memory manager failed to initialize the
+ * memory object.
+ */
+
+#define KERN_ALREADY_WAITING 30
+ /* A thread is attempting to wait for an event for which
+ * there is already a waiting thread.
+ */
+
+#define KERN_DEFAULT_SET 31
+ /* An attempt was made to destroy the default processor
+ * set.
+ */
+
+#define KERN_EXCEPTION_PROTECTED 32
+ /* An attempt was made to fetch an exception port that is
+ * protected, or to abort a thread while processing a
+ * protected exception.
+ */
+
+#define KERN_INVALID_LEDGER 33
+ /* A ledger was required but not supplied.
+ */
+
+#define KERN_INVALID_MEMORY_CONTROL 34
+ /* The port was not a memory cache control port.
+ */
+
+#define KERN_INVALID_SECURITY 35
+ /* An argument supplied to assert security privilege
+ * was not a host security port.
+ */
+
+#define KERN_NOT_DEPRESSED 36
+ /* thread_depress_abort was called on a thread which
+ * was not currently depressed.
+ */
+
+#define KERN_TERMINATED 37
+ /* Object has been terminated and is no longer available
+ */
+
+#define KERN_LOCK_SET_DESTROYED 38
+ /* Lock set has been destroyed and is no longer available.
+ */
+
+#define KERN_LOCK_UNSTABLE 39
+ /* The thread holding the lock terminated before releasing
+ * the lock
+ */
+
+#define KERN_LOCK_OWNED 40
+ /* The lock is already owned by another thread
+ */
+
+#define KERN_LOCK_OWNED_SELF 41
+ /* The lock is already owned by the calling thread
+ */
+
+#define KERN_SEMAPHORE_DESTROYED 42
+ /* Semaphore has been destroyed and is no longer available.
+ */
+
+#define KERN_RPC_SERVER_TERMINATED 43
+ /* Return from RPC indicating the target server was
+ * terminated before it successfully replied
+ */
+
+#define KERN_RPC_TERMINATE_ORPHAN 44
+ /* Terminate an orphaned activation.
+ */
+
+#define KERN_RPC_CONTINUE_ORPHAN 45
+ /* Allow an orphaned activation to continue executing.
+ */
+
+#define KERN_NOT_SUPPORTED 46
+ /* Empty thread activation (No thread linked to it)
+ */
+
+#define KERN_NODE_DOWN 47
+ /* Remote node down or inaccessible.
+ */
+
+#define KERN_NOT_WAITING 48
+ /* A signalled thread was not actually waiting. */
+
+#define KERN_OPERATION_TIMED_OUT 49
+ /* Some thread-oriented operation (semaphore_wait) timed out
+ */
+
+#define KERN_CODESIGN_ERROR 50
+ /* During a page fault, indicates that the page was rejected
+ * as a result of a signature check.
+ */
+
+#define KERN_RETURN_MAX 0x100
+ /* Maximum return value allowable
+ */
+
+#define MACH_MSG_SUCCESS 0x00000000
+
+
+#define MACH_MSG_MASK 0x00003e00
+ /* All special error code bits defined below. */
+#define MACH_MSG_IPC_SPACE 0x00002000
+ /* No room in IPC name space for another capability name. */
+#define MACH_MSG_VM_SPACE 0x00001000
+ /* No room in VM address space for out-of-line memory. */
+#define MACH_MSG_IPC_KERNEL 0x00000800
+ /* Kernel resource shortage handling an IPC capability. */
+#define MACH_MSG_VM_KERNEL 0x00000400
+ /* Kernel resource shortage handling out-of-line memory. */
+
+#define MACH_SEND_IN_PROGRESS 0x10000001
+ /* Thread is waiting to send. (Internal use only.) */
+#define MACH_SEND_INVALID_DATA 0x10000002
+ /* Bogus in-line data. */
+#define MACH_SEND_INVALID_DEST 0x10000003
+ /* Bogus destination port. */
+#define MACH_SEND_TIMED_OUT 0x10000004
+ /* Message not sent before timeout expired. */
+#define MACH_SEND_INTERRUPTED 0x10000007
+ /* Software interrupt. */
+#define MACH_SEND_MSG_TOO_SMALL 0x10000008
+ /* Data doesn't contain a complete message. */
+#define MACH_SEND_INVALID_REPLY 0x10000009
+ /* Bogus reply port. */
+#define MACH_SEND_INVALID_RIGHT 0x1000000a
+ /* Bogus port rights in the message body. */
+#define MACH_SEND_INVALID_NOTIFY 0x1000000b
+ /* Bogus notify port argument. */
+#define MACH_SEND_INVALID_MEMORY 0x1000000c
+ /* Invalid out-of-line memory pointer. */
+#define MACH_SEND_NO_BUFFER 0x1000000d
+ /* No message buffer is available. */
+#define MACH_SEND_TOO_LARGE 0x1000000e
+ /* Send is too large for port */
+#define MACH_SEND_INVALID_TYPE 0x1000000f
+ /* Invalid msg-type specification. */
+#define MACH_SEND_INVALID_HEADER 0x10000010
+ /* A field in the header had a bad value. */
+#define MACH_SEND_INVALID_TRAILER 0x10000011
+ /* The trailer to be sent does not match kernel format. */
+#define MACH_SEND_INVALID_RT_OOL_SIZE 0x10000015
+ /* compatibility: no longer a returned error */
+
+#define MACH_RCV_IN_PROGRESS 0x10004001
+ /* Thread is waiting for receive. (Internal use only.) */
+#define MACH_RCV_INVALID_NAME 0x10004002
+ /* Bogus name for receive port/port-set. */
+#define MACH_RCV_TIMED_OUT 0x10004003
+ /* Didn't get a message within the timeout value. */
+#define MACH_RCV_TOO_LARGE 0x10004004
+ /* Message buffer is not large enough for inline data. */
+#define MACH_RCV_INTERRUPTED 0x10004005
+ /* Software interrupt. */
+#define MACH_RCV_PORT_CHANGED 0x10004006
+ /* compatibility: no longer a returned error */
+#define MACH_RCV_INVALID_NOTIFY 0x10004007
+ /* Bogus notify port argument. */
+#define MACH_RCV_INVALID_DATA 0x10004008
+ /* Bogus message buffer for inline data. */
+#define MACH_RCV_PORT_DIED 0x10004009
+ /* Port/set was sent away/died during receive. */
+#define MACH_RCV_IN_SET 0x1000400a
+ /* compatibility: no longer a returned error */
+#define MACH_RCV_HEADER_ERROR 0x1000400b
+ /* Error receiving message header. See special bits. */
+#define MACH_RCV_BODY_ERROR 0x1000400c
+ /* Error receiving message body. See special bits. */
+#define MACH_RCV_INVALID_TYPE 0x1000400d
+ /* Invalid msg-type specification in scatter list. */
+#define MACH_RCV_SCATTER_SMALL 0x1000400e
+ /* Out-of-line overwrite region is not large enough */
+#define MACH_RCV_INVALID_TRAILER 0x1000400f
+ /* trailer type or number of trailer elements not supported */
+#define MACH_RCV_IN_PROGRESS_TIMED 0x10004011
+
+#endif /* _MACH_KERN_RETURN_H_ */
diff -Naur ./old//magenta/ke_runtime.c ./kern//magenta/ke_runtime.c
--- ./old//magenta/ke_runtime.c 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/ke_runtime.c 2012-08-06 10:27:43.000000000 -0400
@@ -0,0 +1,164 @@
+/*
+ * ke_runtime.c
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Kernel runtime support.
+ */
+
+#include "ke_runtime.h"
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/binfmts.h>
+#include <linux/signal.h>
+
+#include "mach_port_types.h"
+
+/* External initializers */
+extern int init_mach_ipc(void);
+extern int init_macho_binfmt(void);
+static bool _ke_initialized = false;
+extern void __ke_memtest(void);
+extern void mach_host_init(void);
+extern void mach_thread_bootstrap(struct task_struct* task);
+
+void* ke_alloc(size_t size)
+{
+ return kmalloc(size, GFP_KERNEL);
+}
+
+void ke_free(void* ptr)
+{
+ kfree(ptr);
+}
+
+void ke_will_signal(struct task_struct *t, int sig)
+{
+ return;
+}
+
+void* ke_realloc(void* ptr, size_t size)
+{
+ return krealloc(ptr, size, GFP_KERNEL);
+}
+
+/*
+ * Called when the darwin system call number is invalid.
+ */
+void ke_darwin_syscall_error(int c)
+{
+ panic("ke_darwin_syscall_error(): invalid trap #: %d", c);
+}
+
+void ke_at_fork(struct task_struct *task, struct task_struct *parent, unsigned long clone_flags)
+{
+ boolean_t need_ref = false;
+
+ if (!_ke_initialized) {
+ return;
+ }
+
+ if (task->mm && !(clone_flags & CLONE_THREAD))
+ {
+ /*
+ * Only userspace tasks need new task ports.
+ * Kernel tasks don't need them. Clone threads inherit
+ * them from parents.
+ */
+
+ Xlog("creating task port for task[%p]", task);
+ Native_setup_task(task);
+ }
+ else
+ {
+ need_ref = true;
+ }
+
+ if (task->mm)
+ {
+ /*
+ * Every single user scheduler entry must have a thread
+ * port attached to it.
+ */
+
+ task->thread_port = NULL;
+
+ /* This should increase the refcount ... */
+ mach_thread_bootstrap(task);
+
+ if (!need_ref)
+ {
+ /* ... so decrease it. */
+ PortRelease(task->task_port);
+
+ /* And do a sanity check */
+ BUG_ON(PortGetRefcount(task->task_port) != 1);
+ }
+ }
+}
+
+/**/
+void ke_setup_exec(struct linux_binprm* bprm)
+{
+ if (!_ke_initialized) {
+ return;
+ }
+
+ if (current->pid == 1)
+ {
+ /*
+ * Task 1 doesn't have a mm in at_fork, so do
+ * port init in the execve hook instead.
+ */
+
+ if (current->task_port) {
+ panic("ke_setup_exec(): pid 1 has a task port already");
+ }
+
+ Xlog("creating task & thread ports for pid 1");
+ Native_setup_task(current);
+ mach_thread_bootstrap(current);
+
+ __ke_memtest();
+ }
+}
+
+void ke_process_exit(struct task_struct *tsk)
+{
+ task_port_t* tp;
+ int refcount;
+
+ if (!_ke_initialized) {
+ return;
+ }
+
+ /*
+ * Only do it if the task has a task port.
+ * Otherwise it's a kthread.
+ */
+ if (tsk->task_port)
+ {
+ tp = Native_get_task(tsk);
+
+ /* Thread is now dead, decrease the refcount */
+ mach_task_dec_thread_count(tp);
+
+ refcount = PortGetRefcount(tp) - 1; /* ignore the current ref */
+
+ Xlog("exit, task port has %d references", refcount);
+
+ PortRelease(tp);
+ }
+}
+
+int __init __ke_runtime_init(void)
+{
+ init_mach_ipc();
+ init_macho_binfmt();
+ mach_host_init();
+
+ _ke_initialized = true;
+
+ Xlog("runtime started, size_t: %d", sizeof(size_t));
+ return 0;
+}
+
diff -Naur ./old//magenta/ke_runtime.h ./kern//magenta/ke_runtime.h
--- ./old//magenta/ke_runtime.h 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/ke_runtime.h 2012-08-06 10:15:12.000000000 -0400
@@ -0,0 +1,78 @@
+/*
+ * ke_runtime.h
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Kernel runtime support.
+ */
+
+#ifndef _H_MG_KE_RUNTIME_
+#define _H_MG_KE_RUNTIME_
+
+#include "libkern.h"
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <DarwinTypes.h>
+#include <MachO.h>
+
+#define KE_TYPE_UNKNOWN 0
+#define KE_TYPE_ARRAY 1
+
+/**/
+#define ke_storage_type void*
+#define Boolean int
+
+typedef struct {
+ uint16_t type;
+} ke_type_impl;
+
+typedef struct {
+ ke_type_impl base;
+
+ unsigned int count;
+ unsigned int capacity;
+ unsigned int capacityIncrement;
+
+ ke_storage_type* array;
+} ke_array_impl;
+
+typedef void* ke_type_t;
+typedef ke_type_t ke_array_t;
+
+/* Memory */
+void* ke_alloc(size_t size);
+void ke_free(void* ptr);
+void* ke_realloc(void* ptr, size_t size);
+
+/* Array */
+ke_array_t ke_array_with_capacity(unsigned int capacity);
+bool ke_array_init(ke_array_t arr, unsigned int capacity);
+ke_storage_type ke_array_get(ke_array_t arr, unsigned int index);
+bool ke_array_set_at(ke_array_t arr, unsigned int index, ke_storage_type anObject);
+unsigned int ke_array_get_count(ke_array_t arr);
+bool ke_array_add(ke_array_t arr, ke_storage_type anObject);
+ke_storage_type* __ke_array_get_base(ke_array_t arr);
+
+int ke_log(const char *fmt, ...);
+int ke_warn(const char *fmt, ...);
+
+int OSLog(const char *fmt, ...);
+int OSLogFn(const char *fn, const char *fmt, ...);
+int OSWarnFn(const char *fn, const char *fmt, ...);
+
+#define XLog(...) OSLogFn(__FUNCTION__, __VA_ARGS__)
+#define XWarn(...) OSWarnFn(__FUNCTION__, __VA_ARGS__)
+
+/* gah easier to type */
+#define Xlog(...) OSLogFn(__FUNCTION__, __VA_ARGS__)
+#define Xwarn(...) OSWarnFn(__FUNCTION__, __VA_ARGS__)
+
+
+/* Port */
+void Native_setup_task(struct task_struct* task);
+
+#define ke_critical panic
+
+#endif
\ No newline at end of file
diff -Naur ./old//magenta/kext.c ./kern//magenta/kext.c
--- ./old//magenta/kext.c 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/kext.c 2012-08-08 10:24:18.000000000 -0400
@@ -0,0 +1,745 @@
+/*
+ * kext.c
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * What is this, I don't even ...
+ */
+
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/binfmts.h>
+#include <linux/personality.h>
+#include <linux/init.h>
+#include <linux/coredump.h>
+#include <linux/slab.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+#include <linux/kfifo.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+#include "ipc_types.h"
+#include "mach_kmsg.h"
+#include "ke_runtime.h"
+#include "loader.h"
+
+typedef struct kernel_symbol ksym_t;
+
+/*
+ * Symbols in the main image's symbtab.
+ */
+extern const ksym_t __start___ksymtab[];
+extern const ksym_t __stop___ksymtab[];
+extern const ksym_t __start___ksymtab_gpl[];
+extern const ksym_t __stop___ksymtab_gpl[];
+extern const ksym_t __start___ksymtab_gpl_future[];
+extern const ksym_t __stop___ksymtab_gpl_future[];
+
+static Boolean _verbose_log = false;
+
+#define doIfVerbose() if (_verbose_log)
+
+typedef struct __KXFile {
+ unsigned char *fMachO;
+ struct symtab_command *fSymtab;
+
+ uintptr_t fSegmentOffset;
+ char *fStringBase;
+ struct nlist *fSymbolBase;
+ const struct nlist *fLocalSyms;
+ int fStringSectionOrdinal;
+
+ unsigned char* fSegmentBase;
+
+ int fConstructorSize;
+ void* fConstructorBase;
+} KXFile;
+
+void *kmalloc_non_inline(size_t size, gfp_t flags)
+{
+ return kmalloc(size, flags);
+}
+EXPORT_SYMBOL(kmalloc_non_inline);
+
+const ksym_t*
+find_kernel_symbol_in(const char* name, const ksym_t* start, const ksym_t* end)
+{
+ const ksym_t* sym = start;
+
+ while (1) {
+ if (strcmp(sym->name, name) == 0) {
+ /* Found */
+ return sym;
+ }
+
+ sym++;
+
+ if (sym > end) {
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+ksym_t*
+find_kernel_symbol(const char* name)
+{
+ const ksym_t* sym = NULL;
+
+ if (!sym) {
+ sym = find_kernel_symbol_in(name, __start___ksymtab, __stop___ksymtab);
+ }
+
+ return (ksym_t*)sym;
+}
+
+void*
+kld_alloc(size_t sz)
+{
+ return ke_alloc(sz);
+}
+
+static const struct nlist *
+kld_find_symbol_by_name(KXFile *file, const char* name)
+{
+ /*
+ This is slow, but I don't care.
+ */
+
+ const struct nlist *sym;
+ int nsyms;
+
+ nsyms = file->fSymtab->nsyms;
+ sym = file->fSymbolBase;
+
+ while (nsyms--) {
+ /*
+ if ((sym->n_type & N_EXT))
+ return NULL;
+ */
+
+ long strx = sym->n_un.n_strx;
+ const char *symname = file->fStringBase + strx;
+
+ if (strcmp(name, symname) == 0 && !(sym->n_type & N_STAB))
+ return sym;
+
+ sym += 1;
+ }
+
+ return NULL;
+}
+
+static const struct nlist *
+kld_find_symbol_by_address(KXFile *file, void *entry)
+{
+ /*
+ This is slow, but I don't care.
+ */
+
+ const struct nlist *sym;
+ int nsyms;
+
+ nsyms = file->fSymtab->nsyms;
+ sym = file->fSymbolBase;
+
+ while (nsyms--) {
+ uint32_t addr = (uint32_t)entry;
+ /*
+ if ((sym->n_type & N_EXT))
+ return NULL;
+ */
+
+ if (sym->n_desc & N_ARM_THUMB_DEF) {
+ addr = addr & ~1;
+ }
+
+ if (sym->n_value == addr && !(sym->n_type & N_STAB)) {
+ return sym;
+ }
+
+ sym += 1;
+ }
+
+ return NULL;
+}
+
+Boolean kld_relocate_section(KXFile* file , struct section* sect, vm_offset_t delta)
+{
+ uint8_t* sbase;
+ uint32_t nreloc;
+ struct relocation_info *rinfo;
+
+ sbase = (uint8_t*)sect->addr;
+ nreloc = sect->nreloc;
+ rinfo = (struct relocation_info *)(file->fMachO + sect->reloff);
+
+ while (nreloc--) {
+ void** entry;
+ void** abs_entry;
+ unsigned long r_symbolnum, r_length;
+ const struct nlist *symbol = NULL;
+ enum reloc_type_generic r_type;
+ void *addr = NULL;
+
+ /* Ignore scattered relocations */
+ if ((rinfo->r_address & R_SCATTERED))
+ {
+ continue;
+ }
+
+ /* This is why we can't have nice things */
+ entry = (void**)( (uintptr_t)rinfo->r_address + (uintptr_t)sbase );
+ abs_entry = ((void**)( (uintptr_t)file->fSegmentBase + (uintptr_t)entry ));
+
+ r_type = (enum reloc_type_generic)rinfo->r_type;
+ r_length = rinfo->r_length;
+
+ /*
+ * In r_length, 2 stands for long.
+ */
+ if (r_type != GENERIC_RELOC_VANILLA || r_length != 2)
+ {
+ continue;
+ }
+
+ r_symbolnum = rinfo->r_symbolnum;
+
+ if (rinfo->r_extern) {
+ /* External symbol entry */
+ long strx;
+ const char *symname;
+ ksym_t* ks;
+
+ if(r_symbolnum >= file->fSymtab->nsyms)
+ {
+ Xlog("invalid reloc entry");
+ return false;
+ }
+
+ symbol = file->fSymbolBase;
+
+ if ((symbol[r_symbolnum].n_type & N_TYPE) == N_INDR) {
+ /*
+ This is an indirect symbol, so get the value
+ for the actual thing.
+ */
+ r_symbolnum = symbol[r_symbolnum].n_value;
+ }
+
+ symbol = &symbol[r_symbolnum];
+
+ if (symbol->n_type != (N_EXT | N_UNDF)) {
+ Xwarn("invalid reloc symbol type - !(N_EXT | N_UNDF)");
+ return false;
+ }
+
+ strx = symbol->n_un.n_strx;
+ symname = file->fStringBase + strx;
+
+ if (symname[0] == '_') {
+ symname++;
+ }
+ else {
+ Xwarn("'%s' doesn't start with '_'", symname);
+ return false;
+ }
+
+ ks = find_kernel_symbol(symname);
+ if (!ks) {
+ Xwarn("failed to resolve '%s'", symname);
+ return false;
+ }
+
+ doIfVerbose() {
+ Xlog("\tBind : sym_addr=%p, r_addr= %p, l_addr= %p, nm= '%s', ks= %p",
+ (void*)symbol,
+ (void*)rinfo->r_address,
+ (void*)addr,
+ symname,
+ (void*)ks);
+ }
+
+ *abs_entry = (void*)(ks->value);
+ }
+ else {
+ /*
+ * Relocate a local symbol. Local symbols in object files
+ * are not attached to each other which means that all jumps
+ * have to be fixed up.
+ */
+
+ /* Derp */
+ if (r_symbolnum == R_ABS)
+ {
+ rinfo++;
+ continue;
+ }
+
+ /* Not this pointer crap again */
+ addr = *abs_entry;
+
+ if (r_symbolnum == file->fStringSectionOrdinal)
+ {
+ /*
+ * This is a string section
+ * Here we just need to slide the pointers relative to
+ * the load address of the segment.
+ */
+
+ doIfVerbose() {
+ Xlog("\tRelocate: (cstr) l_addr: %p, val: %p",
+ (void*)symbol,
+ (void*)addr);
+ }
+
+ *abs_entry = ((void*)( (uintptr_t)file->fSegmentBase + (uintptr_t)addr) );
+
+ rinfo++;
+ continue;
+ }
+
+ symbol = kld_find_symbol_by_address(file, addr);
+
+ if (symbol) {
+ uint32_t val = symbol->n_value;
+
+ if (symbol->n_desc & N_ARM_THUMB_DEF) {
+ val |= 1;
+ }
+
+ /* reloc "(uintptr_t)sbase +" */
+ *abs_entry = ((void*)( (uintptr_t)file->fSegmentBase + (uintptr_t)val ));
+
+ doIfVerbose() {
+ Xlog("\tRelocate: sym_record= %p, sect_base= %p, sym_value= %p, relocated_to= %p",
+ (void*)symbol,
+ (void*)sect->offset,
+ (void*)val,
+ (void*)*abs_entry);
+ }
+ }
+ else {
+
+ doIfVerbose() {
+ Xwarn("can't find symbol at %p (ord: %d)",
+ (void*)addr,
+ (int)r_symbolnum);
+ }
+
+ return false;
+ }
+ }
+
+ rinfo++;
+ }
+
+ return true;
+}
+
+Boolean kld_transfer(KXFile* file, void* src, void* dest, size_t sz)
+{
+ void* in_src = (void*)((uintptr_t)file->fMachO + (uintptr_t)src);
+ bcopy(in_src, dest, sz);
+
+ return true;
+}
+
+Boolean kld_parse_symtab(KXFile* file)
+{
+ const struct nlist *sym;
+ unsigned int i, firstlocal = 0, nsyms;
+ const char *strbase;
+ unsigned int strsize;
+ unsigned int symsize;
+
+ nsyms = file->fSymtab->nsyms;
+ symsize = nsyms * sizeof(struct nlist);
+
+ /* load the symbols */
+ sym = (const struct nlist *)kld_alloc(symsize);
+ kld_transfer(file, (void*)file->fSymtab->symoff, (void*)sym, symsize);
+ file->fSymbolBase = sym;
+
+ /* load the string table */
+ strsize = file->fSymtab->strsize;
+ strbase = kld_alloc(strsize);
+ kld_transfer(file, (void*)file->fSymtab->stroff, strbase, strsize);
+ file->fStringBase = strbase;
+
+ i = 0;
+
+ while (i < nsyms) {
+ long strx = sym->n_un.n_strx;
+ const char *symname = strbase + strx;
+ unsigned char n_type = sym->n_type & N_TYPE;
+
+ doIfVerbose() {
+ Xlog("type=%d, val=%p, name='%s'",
+ n_type,
+ (void*)sym->n_value,
+ symname);
+ }
+
+ n_type = sym->n_type & (N_TYPE | N_EXT);
+
+ /*
+ * First exported symbol
+ * This is done for the sake of performance
+ */
+ if ( !firstlocal && (n_type & N_EXT) ) {
+ firstlocal = i;
+ file->fLocalSyms = sym;
+ }
+
+ /* Increment stuff */
+ i += 1;
+ sym += 1;
+ }
+
+ if (!file->fLocalSyms) {
+ Xlog("no symbols found");
+ return false;
+ }
+
+ doIfVerbose() {
+ Xlog("{loc=%p}",
+ file->fLocalSyms);
+ }
+
+ return true;
+}
+
+Boolean kld_map_sect(KXFile* file, struct section* sect)
+{
+ uintptr_t sect_mem_addr =
+ ((uintptr_t)( (uintptr_t)file->fSegmentBase + (uintptr_t)sect->addr ));
+
+ doIfVerbose() {
+ Xlog("addr: %p, name: '%s', type: %d, size: %d\n",
+ (void*)sect->addr,
+ sect->sectname,
+ (int)(sect->flags & SECTION_TYPE),
+ (int)sect->size);
+ }
+
+ if ((sect->flags & SECTION_TYPE) == S_ZEROFILL)
+ {
+ memset((void*)sect_mem_addr, 0, sect->size);
+ }
+ else {
+ kld_transfer(file, (void*)sect->offset, (void*)sect_mem_addr, sect->size);
+ }
+
+ if (strcmp("__constructor", sect->sectname) == 0)
+ {
+ /* global constructors */
+ file->fConstructorBase = (void*)sect_mem_addr;
+ file->fConstructorSize = sect->size;
+ }
+
+ return true;
+}
+
+Boolean kld_process_segment(KXFile* file, struct segment_command* seg)
+{
+ struct section* sect = NULL;
+ uint32_t nsects = seg->nsects;
+ uint32_t total_size = 0;
+ int i = 0;
+
+#define iterate_sections() \
+ sect = (struct section*)((uintptr_t)seg + sizeof(struct segment_command)); \
+ for (i = 0; i < nsects; i++, sect++) \
+
+ /* calculate total size */
+ iterate_sections()
+ {
+ total_size += sect->size;
+ }
+
+ file->fSegmentBase = kld_alloc(total_size);
+
+ Xwarn("kext mapping region: %p - %p", file->fSegmentBase, file->fSegmentBase + total_size);
+
+ /* map sections */
+ iterate_sections()
+ {
+ kld_map_sect(file, sect);
+
+ if ((sect->flags & SECTION_TYPE) == S_CSTRING_LITERALS)
+ {
+ file->fStringSectionOrdinal = i+1;
+ }
+ }
+
+ /* perform relocation */
+ iterate_sections()
+ {
+ if (!kld_relocate_section(file, sect, 0))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+Boolean kld_file_map(void* buffer, long size, KXFile* file)
+{
+ size_t macho_header_sz = sizeof(struct mach_header);
+ uint8_t* load_commands;
+ struct mach_header* head;
+
+ /* command parser */
+ boolean_t has_segment = FALSE;
+ size_t offset;
+ size_t oldoffset;
+ uint32_t ncmds;
+
+ /* segment */
+ struct segment_command *seg_hdr;
+ uintptr_t sect_offset = 0;
+ uint32_t nsects = 0;
+
+ bzero(file, sizeof(file));
+
+ head = buffer;
+ load_commands = buffer + macho_header_sz;
+
+ /* sanity */
+ if (head->magic != MH_MAGIC)
+ {
+ Xwarn("kld_file_map: not a valid mach-o (invalid magic %p)",
+ (void*)head->magic);
+
+ return false;
+ }
+
+ /* we can only load object files */
+ if (head->filetype != MH_OBJECT)
+ {
+ Xwarn("kld_file_map: wrong mach-o type (invalid filetype %p)",
+ (void*)head->filetype);
+
+ return false;
+ }
+
+ offset = 0;
+ ncmds = head->ncmds;
+
+ file->fMachO = buffer;
+
+ doIfVerbose() {
+ Xlog("macho {fl=%d}", head->flags);
+ }
+
+ while (ncmds--) {
+ struct load_command *lcp =
+ (struct load_command *)(load_commands + offset);
+
+ oldoffset = offset;
+ offset += lcp->cmdsize;
+
+ if (oldoffset > offset ||
+ lcp->cmdsize < sizeof(struct load_command) ||
+ offset > head->sizeofcmds + macho_header_sz)
+ {
+ Xlog("malformed load command");
+ return false;
+ }
+
+ /*
+ Mach objects (MH_OBJECT) are only meant to have one segment that has all the bits.
+ */
+ switch(lcp->cmd) {
+ case LC_SEGMENT:
+ {
+ if (has_segment) {
+ Xwarn("more than one segment in the file");
+ return false;
+ }
+
+ seg_hdr = (struct segment_command *)lcp;
+
+ nsects = seg_hdr->nsects;
+ sect_offset = (uintptr_t)(seg_hdr + sizeof(struct segment_command));
+
+ file->fSegmentOffset = seg_hdr->fileoff;
+
+ doIfVerbose() {
+ Xlog("LC_SEGMENT {nsects=%d}",
+ seg_hdr->nsects);
+ }
+
+ has_segment = TRUE;
+
+ break;
+ }
+ case LC_UUID:
+ case LC_DYSYMTAB:
+ {
+ /* Do. Not. Care. */
+ break;
+ }
+ case LC_SYMTAB:
+ {
+ file->fSymtab = (struct symtab_command*)lcp;
+ break;
+ }
+ default:
+ {
+ Xwarn("unsupported load command %d",
+ lcp->cmd);
+
+ return false;
+ break;
+ }
+ }
+ }
+
+ if (!file->fSymtab) {
+ Xwarn("object file missing symbols");
+ return false;
+ }
+ else {
+ kld_parse_symtab(file);
+ }
+
+ if (!has_segment) {
+ Xwarn("object file missing segment");
+ return false;
+ }
+ else {
+ if (!kld_process_segment(file, seg_hdr))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*
+ * Gets absoulute function address that we can branch to.
+ * Sets the thumb bit if needed.
+ */
+void* kld_get_symbol_entry(KXFile* file, const struct nlist* nl)
+{
+ uintptr_t val;
+ uint16_t* addr;
+
+ /* sanity */
+ BUG_ON(file == NULL);
+ BUG_ON(nl == NULL);
+
+ val = nl->n_value;
+ addr = (uint16_t*)((val + (uintptr_t)file->fSegmentBase));
+
+ if (nl->n_desc & N_ARM_THUMB_DEF) {
+ addr = (uint16_t*)((unsigned int)addr | 1);
+ }
+
+ return (void*)addr;
+}
+
+void abi_test(int aa, long long aaa)
+{
+ ke_log("ABI_TEST: int: %d, long: %lld\n", aa, aaa);
+}
+EXPORT_SYMBOL(abi_test);
+
+int _user_load_kext(void* buffer, size_t size)
+{
+ /*
+ * mach_msg_header_t head;
+ * void* buffer;
+ * unsigned int buffer_len;
+ */
+
+ Boolean ret;
+ void* buf;
+
+ const struct nlist* nl;
+ KXFile file;
+
+ buf = kld_alloc(size);
+
+ if (copy_from_user(buf, buffer, size))
+ {
+ Xwarn("unable to copy out buffer!");
+ return KERN_FAILURE;
+ }
+
+ if (kld_file_map(buf, size, &file))
+ {
+ uintptr_t val;
+ uint16_t* addr;
+ int (*kmod_init)(void);
+ void (*static_cxx_constructor)(void);
+ void** ctor_base = NULL;
+ int kret = 0;
+ int ctor_iter = 0;
+
+ nl = kld_find_symbol_by_name(&file, "_kmod_start");
+
+ if (nl == NULL) {
+ Xwarn("symbol not found");
+ return KERN_FAILURE;
+ }
+
+ /* call constructors */
+ ctor_base = file.fConstructorBase;
+ if (ctor_base != NULL)
+ {
+ for (ctor_iter = 0; ctor_iter < file.fConstructorSize; ctor_iter += 4)
+ {
+ const struct nlist* ctor_nl;
+ void* rel_sym_addr;
+ static_cxx_constructor = *ctor_base;
+
+ rel_sym_addr = ((void*)((uintptr_t)static_cxx_constructor - (uintptr_t)file.fSegmentBase));
+
+ ctor_nl = kld_find_symbol_by_address(&file, rel_sym_addr);
+ static_cxx_constructor = kld_get_symbol_entry(&file, ctor_nl);
+
+ Xlog("call_cxx_ctor: %p (nlist: %p) %d/%d!", static_cxx_constructor, ctor_nl, ctor_iter, file.fConstructorSize);
+
+ static_cxx_constructor();
+
+ ctor_base++;
+ }
+ }
+
+ kmod_init = kld_get_symbol_entry(&file, nl);
+
+ /* Branch into the unknown */
+ kret = kmod_init();
+
+ Xlog("kmod returned %d", kret);
+
+ return KERN_SUCCESS;
+ }
+ else
+ {
+ Xwarn("failed to load object!");
+ return KERN_FAILURE;
+ }
+}
\ No newline at end of file
diff -Naur ./old//magenta/libkern.c ./kern//magenta/libkern.c
--- ./old//magenta/libkern.c 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/libkern.c 2012-08-04 17:47:18.000000000 -0400
@@ -0,0 +1,126 @@
+/*
+ * libkern.c
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Bits no one cares about.
+ */
+
+#include <linux/module.h>
+
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/binfmts.h>
+#include <linux/personality.h>
+#include <linux/init.h>
+#include <linux/coredump.h>
+#include <linux/slab.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+#include <linux/kfifo.h>
+#include <linux/sched.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#include <linux/linkage.h>
+#include <asm/thread_notify.h>
+
+#include "ke_runtime.h"
+#include "ipc_types.h"
+
+extern bool OSAtomicCompareAndSwap32( u_int32_t __oldValue, u_int32_t __newValue, volatile u_int32_t *__theValue );
+EXPORT_SYMBOL(OSAtomicCompareAndSwap32);
+
+void* kalloc(size_t size)
+{
+ void* ret = kmalloc(size, GFP_KERNEL);
+ return ret;
+}
+EXPORT_SYMBOL(kalloc);
+
+/* void *memcpy(void *dest, const void *src, size_t n); */
+void bcopy(const void *src, void *dest, size_t n)
+{
+ memmove(dest, src, n);
+}
+EXPORT_SYMBOL(bcopy);
+
+void bzero(void* base, size_t size)
+{
+ memset(base, 0, size);
+}
+EXPORT_SYMBOL(bzero);
+
+/* hax */
+void _Z5kfreePvm(void* addr, unsigned long size)
+{
+ kfree(addr);
+}
+EXPORT_SYMBOL(_Z5kfreePvm);
+
+/* pure virtual function can't ever be called */
+void __cxa_pure_virtual( void ) { panic("%s", __FUNCTION__); }
+void __pure_virtual( void ) { panic("%s", __FUNCTION__); }
+
+EXPORT_SYMBOL(__cxa_pure_virtual);
+EXPORT_SYMBOL(__pure_virtual);
+
+/* operator delete(void *) */
+void _ZdlPv(void* ptr)
+{
+ kfree(ptr);
+}
+EXPORT_SYMBOL(_ZdlPv);
+
+/* operator delete[](void *) */
+void _ZdaPv(void* ptr)
+{
+ kfree(ptr);
+}
+EXPORT_SYMBOL(_ZdaPv);
+
+/* operator new[](unsigned long) */
+void* _Znam(unsigned long size)
+{
+ void* ret;
+
+ ret = kalloc(size);
+
+ if (!ret) {
+ panic("new(): c++ allocation failed!");
+ }
+
+ bzero(ret, size);
+
+ return ret;
+}
+EXPORT_SYMBOL(_Znam);
+
+/* operator new(unsigned long) */
+void* _Znwm(unsigned long size)
+{
+ void* ret;
+
+ ret = kalloc(size);
+
+ if (!ret) {
+ panic("new(): c++ allocation failed!");
+ }
+
+ bzero(ret, size);
+
+ return ret;
+}
+EXPORT_SYMBOL(_Znwm);
\ No newline at end of file
diff -Naur ./old//magenta/libkern.h ./kern//magenta/libkern.h
--- ./old//magenta/libkern.h 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/libkern.h 2012-08-04 17:47:23.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * libkern.c
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Bits no one cares about.
+ */
+
+#ifndef _H_MG_LIBK_
+#define _H_MG_LIBK_
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <DarwinTypes.h>
+#include <MachO.h>
+
+void bzero(void* base, size_t size);
+void bcopy(const void *src, void *dest, size_t n);
+
+#endif
\ No newline at end of file
diff -Naur ./old//magenta/loader.h ./kern//magenta/loader.h
--- ./old//magenta/loader.h 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/loader.h 2012-06-16 17:04:07.000000000 -0400
@@ -0,0 +1,120 @@
+/*
+ * loader.h
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Loader types.
+ */
+
+#ifndef _H_MG_LOADER_
+#define _H_MG_LOADER_
+
+#include "ipc_types.h"
+#include <DarwinTypes.h>
+#include <MachO.h>
+
+/* Section */
+
+ /*
+ * The flags field of a section structure is separated into two parts a section
+ * type and section attributes. The section types are mutually exclusive (it
+ * can only have one type) but the section attributes are not (it may have more
+ * than one attribute).
+ */
+#define SECTION_TYPE 0x000000ff /* 256 section types */
+#define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes */
+
+/* Constants for the type of a section */
+#define S_REGULAR 0x0 /* regular section */
+#define S_ZEROFILL 0x1 /* zero fill on demand section */
+#define S_CSTRING_LITERALS 0x2 /* section with only literal C strings*/
+#define S_4BYTE_LITERALS 0x3 /* section with only 4 byte literals */
+#define S_8BYTE_LITERALS 0x4 /* section with only 8 byte literals */
+#define S_LITERAL_POINTERS 0x5 /* section with only pointers to */
+ /* literals */
+
+
+/* Nlist */
+
+#define N_STAB 0xe0 /* if any of these bits set, a symbolic debugging entry */
+#define N_PEXT 0x10 /* private external symbol bit */
+#define N_TYPE 0x0e /* mask for the type bits */
+#define N_EXT 0x01 /* external symbol bit, set for external symbols */
+
+/*
+ * Only symbolic debugging entries have some of the N_STAB bits set and if any
+ * of these bits are set then it is a symbolic debugging entry (a stab). In
+ * which case then the values of the n_type field (the entire field) are given
+ * in <mach-o/stab.h>
+ */
+
+/*
+ * Values for N_TYPE bits of the n_type field.
+ */
+#define N_UNDF 0x0 /* undefined, n_sect == NO_SECT */
+#define N_ABS 0x2 /* absolute, n_sect == NO_SECT */
+#define N_SECT 0xe /* defined in section number n_sect */
+#define N_PBUD 0xc /* prebound undefined (defined in a dylib) */
+#define N_INDR 0xa /* indirect */
+
+struct nlist {
+ union {
+#ifndef __LP64__
+ char *n_name; /* for use when in-core */
+#endif
+ int32_t n_strx; /* index into the string table */
+ } n_un;
+ uint8_t n_type; /* type flag, see below */
+ uint8_t n_sect; /* section number or NO_SECT */
+ int16_t n_desc; /* see <mach-o/stab.h> */
+ uint32_t n_value; /* value of this symbol (or stab offset) */
+};
+
+#define N_NO_DEAD_STRIP 0x0020 /* symbol is not to be dead stripped */
+#define N_DESC_DISCARDED 0x0020 /* symbol is discarded */
+#define N_WEAK_REF 0x0040 /* symbol is weak referenced */
+#define N_WEAK_DEF 0x0080 /* coalesed symbol is a weak definition */
+#define N_REF_TO_WEAK 0x0080 /* reference to a weak symbol */
+#define N_ARM_THUMB_DEF 0x0008 /* symbol is a Thumb function (ARM) */
+#define N_SYMBOL_RESOLVER 0x0100
+
+/* Reloc stuff */
+
+ #define R_SCATTERED 0x80000000 /* mask to be applied to the r_address field
+ of a relocation_info structure to tell that
+ is is really a scattered_relocation_info
+ stucture */
+
+enum reloc_type_generic
+{
+ GENERIC_RELOC_VANILLA, /* generic relocation as discribed above */
+ GENERIC_RELOC_PAIR, /* Only follows a GENERIC_RELOC_SECTDIFF */
+ GENERIC_RELOC_SECTDIFF,
+ GENERIC_RELOC_PB_LA_PTR, /* prebound lazy pointer */
+ GENERIC_RELOC_LOCAL_SECTDIFF,
+ GENERIC_RELOC_TLV /* thread local variables */
+};
+
+struct relocation_info {
+ int32_t r_address; /* offset in the section to what is being
+ relocated */
+ uint32_t r_symbolnum:24, /* symbol index if r_extern == 1 or section
+ ordinal if r_extern == 0 */
+ r_pcrel:1, /* was relocated pc relative already */
+ r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */
+ r_extern:1, /* does not include value of sym referenced */
+ r_type:4; /* if not 0, machine specific relocation type */
+};
+
+#define R_ABS 0 /* absolute relocation type for Mach-O files */
+
+/* Actual loader stuff */
+struct symtab_command {
+ uint32_t cmd; /* LC_SYMTAB */
+ uint32_t cmdsize; /* sizeof(struct symtab_command) */
+ uint32_t symoff; /* symbol table offset */
+ uint32_t nsyms; /* number of symbol table entries */
+ uint32_t stroff; /* string table offset */
+ uint32_t strsize; /* string table size in bytes */
+};
+
+#endif
\ No newline at end of file
diff -Naur ./old//magenta/Log.c ./kern//magenta/Log.c
--- ./old//magenta/Log.c 1969-12-31 19:00:00.000000000 -0500
+++ ./kern//magenta/Log.c 2012-08-08 10:19:02.000000000 -0400
@@ -0,0 +1,129 @@
+/*
+ * Log.c
+ * Copyright (c) 2012 Christina Brooks
+ *
+ * Logging stuff.
+ */
+
+#include "ke_runtime.h"
+
+/*
+ * Logging routine.
+ */
+#define ChristinasSillyUartDebugging 0
+#define BRIGHT 1
+
+#define BLACK 0
+#define RED 1
+#define GREEN 2
+#define YELLOW 3
+#define BLUE 4
+#define MAGENTA 5
+#define CYAN 6
+#define WHITE 7
+#define VT_DEFAULT 9
+
+#define default_attributes "\33[0m"
+
+int OSLog(const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+#if defined(ChristinasSillyUartDebugging)
+ char pre[13];
+ sprintf(pre, "%c[%d;%d;%dm", 0x1B, BRIGHT, WHITE + 30, BLUE + 40);
+ printk("%s[os]%s: ", pre, default_attributes);
+#endif
+
+ va_start(args, fmt);
+ r = vprintk(fmt, args);
+ va_end(args);
+
+ printk("\n");
+
+ return r;
+}
+
+#define LOGFNC GREEN
+int OSLogFn(const char *fn, const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+#if defined(ChristinasSillyUartDebugging)
+ char pre[13];
+ sprintf(pre, "%c[%d;%d;%dm", 0x1B, BRIGHT, LOGFNC + 30, VT_DEFAULT);
+ printk("%s[kern]%s ", pre, default_attributes);
+
+ sprintf(pre, "%c[%d;%d;%dm", 0x1B, 0, LOGFNC + 30, VT_DEFAULT + 40);
+ printk("%s%s():%s ", pre, fn, default_attributes);
+#endif
+
+ va_start(args, fmt);
+ r = vprintk(fmt, args);
+ va_end(args);
+
+ printk("\n");
+
+ return r;
+}
+
+int OSWarnFn(const char *fn, const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+#if defined(ChristinasSillyUartDebugging)
+ char pre[13];
+ sprintf(pre, "%c[%d;%d;%dm", 0x1B, BRIGHT, RED + 30, VT_DEFAULT);
+ printk("%s[warn]%s ", pre, default_attributes);
+
+ sprintf(pre, "%c[%d;%d;%dm", 0x1B, 0, RED + 30, VT_DEFAULT + 40);
+ printk("%s%s():%s ", pre, fn, default_attributes);
+#endif
+
+ va_start(args, fmt);
+ r = vprintk(fmt, args);
+ va_end(args);
+
+ printk("\n");
+
+ return r;
+}
+
+int ke_log(const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+#if defined(ChristinasSillyUartDebugging)
+ char pre[13];
+ sprintf(pre, "%c[%d;%d;%dm", 0x1B, BRIGHT, WHITE + 30, BLUE + 40);
+ printk("%s[kern]%s: ", pre, default_attributes);