From e85e399fd7b229b8bc92f28928a059876d7216d3 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Sun, 17 Mar 2013 20:49:58 +0100 Subject: [PATCH] commpage: randomize position of commpage This patch introduces randomization of commpage position. From now on commpage table contains offsets from begining to of the commpage to the particular commpage entry. Similary addresses of symbols in ELF memory image "commpage" are just offsets from the begining of the commpage. This patch also updates KDL so that commpage entries are recognized and shown correctly in stack trace. An update of Debugger is yet to be done. --- headers/private/kernel/commpage.h | 3 +- headers/private/kernel/ksignal.h | 1 + headers/private/kernel/thread_types.h | 2 ++ headers/private/libroot/libroot_private.h | 2 +- .../private/runtime_loader/runtime_loader.h | 1 + .../system/arch/arm/arch_commpage_defs.h | 4 --- .../system/arch/m68k/arch_commpage_defs.h | 3 -- .../system/arch/mipsel/arch_commpage_defs.h | 2 -- .../system/arch/ppc/arch_commpage_defs.h | 2 -- .../system/arch/x86/arch_commpage_defs.h | 2 -- .../system/arch/x86_64/arch_commpage_defs.h | 2 -- headers/private/system/commpage_defs.h | 5 --- src/system/kernel/arch/x86/32/interrupts.S | 4 ++- src/system/kernel/arch/x86/32/signals.cpp | 13 ++++---- src/system/kernel/arch/x86/32/signals_asm.S | 6 ++-- src/system/kernel/arch/x86/32/syscalls.cpp | 6 ++-- src/system/kernel/arch/x86/32/thread.cpp | 8 +++-- src/system/kernel/arch/x86/64/signals.cpp | 6 ++-- src/system/kernel/arch/x86/64/thread.cpp | 9 +++-- src/system/kernel/arch/x86/arch_cpu.cpp | 22 ++++++------- src/system/kernel/arch/x86/asm_offsets.cpp | 5 +++ src/system/kernel/arch/x86/x86_signals.h | 3 +- src/system/kernel/commpage.cpp | 30 ++++++++--------- src/system/kernel/debug/BreakpointManager.cpp | 7 ---- src/system/kernel/elf.cpp | 19 ++++++++++- src/system/kernel/signal.cpp | 4 +++ src/system/kernel/team.cpp | 33 ++++++++++++++++++- src/system/libroot/libroot_init.c | 6 +++- src/system/libroot/os/arch/x86/syscalls.inc | 12 ++++--- src/system/libroot/os/time.cpp | 5 +-- .../posix/string/arch/x86/arch_string.S | 8 +++-- .../posix/string/arch/x86_64/arch_string.S | 11 +++++-- src/system/runtime_loader/export.cpp | 1 + src/system/runtime_loader/runtime_loader.cpp | 4 ++- .../runtime_loader/runtime_loader_private.h | 3 +- 35 files changed, 158 insertions(+), 96 deletions(-) diff --git a/headers/private/kernel/commpage.h b/headers/private/kernel/commpage.h index b30f82a4cb..dd8ac97612 100644 --- a/headers/private/kernel/commpage.h +++ b/headers/private/kernel/commpage.h @@ -18,8 +18,9 @@ extern "C" { status_t commpage_init(void); status_t commpage_init_post_cpus(void); void* allocate_commpage_entry(int entry, size_t size); -void* fill_commpage_entry(int entry, const void* copyFrom, size_t size); +addr_t fill_commpage_entry(int entry, const void* copyFrom, size_t size); image_id get_commpage_image(); +area_id clone_commpage_area(team_id team, void** address); // implemented in the architecture specific part status_t arch_commpage_init(void); diff --git a/headers/private/kernel/ksignal.h b/headers/private/kernel/ksignal.h index b7ec3c3bab..4727053c8d 100644 --- a/headers/private/kernel/ksignal.h +++ b/headers/private/kernel/ksignal.h @@ -52,6 +52,7 @@ struct signal_frame_data { int32 thread_flags; uint64 syscall_restart_return_value; uint8 syscall_restart_parameters[SYSCALL_RESTART_PARAMETER_SIZE]; + void* commpage_address; }; diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 78e893da3b..1c06271a50 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -259,6 +259,8 @@ struct Team : TeamThreadIteratorEntry, KernelReferenceable, size_t used_user_data; struct free_user_thread* free_user_threads; + void* commpage_address; + struct team_debug_info debug_info; // protected by scheduler lock diff --git a/headers/private/libroot/libroot_private.h b/headers/private/libroot/libroot_private.h index 7a3357b614..593ffd3526 100644 --- a/headers/private/libroot/libroot_private.h +++ b/headers/private/libroot/libroot_private.h @@ -34,7 +34,7 @@ void __init_env(const struct user_space_program_args *args); void __init_heap(void); void __init_heap_post_env(void); -void __init_time(void); +void __init_time(addr_t commPageTable); void __arch_init_time(struct real_time_data *data, bool setDefaults); bigtime_t __arch_get_system_time_offset(struct real_time_data *data); bigtime_t __get_system_time_offset(); diff --git a/headers/private/runtime_loader/runtime_loader.h b/headers/private/runtime_loader/runtime_loader.h index cc9b96cd98..39e675f8a9 100644 --- a/headers/private/runtime_loader/runtime_loader.h +++ b/headers/private/runtime_loader/runtime_loader.h @@ -51,6 +51,7 @@ struct rld_export { void (*call_termination_hooks)(); const struct user_space_program_args *program_args; + const void* commpage_address; }; extern struct rld_export *__gRuntimeLoader; diff --git a/headers/private/system/arch/arm/arch_commpage_defs.h b/headers/private/system/arch/arm/arch_commpage_defs.h index 57fb821e96..39bf6f641d 100644 --- a/headers/private/system/arch/arm/arch_commpage_defs.h +++ b/headers/private/system/arch/arm/arch_commpage_defs.h @@ -12,8 +12,4 @@ //#define COMMPAGE_ENTRY_M68K_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) //#define COMMPAGE_ENTRY_M68K_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) -/* 0xffff0000 colides with IO space mapped with TT1 on Atari */ -#warning ARM: determine good place for compage.. -#define ARCH_USER_COMMPAGE_ADDR (0xfeff0000) - #endif /* _SYSTEM_ARCH_M68K_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/m68k/arch_commpage_defs.h b/headers/private/system/arch/m68k/arch_commpage_defs.h index 0b6d6e354d..71bc119904 100644 --- a/headers/private/system/arch/m68k/arch_commpage_defs.h +++ b/headers/private/system/arch/m68k/arch_commpage_defs.h @@ -12,7 +12,4 @@ #define COMMPAGE_ENTRY_M68K_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) #define COMMPAGE_ENTRY_M68K_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) -/* 0xffff0000 colides with IO space mapped with TT1 on Atari */ -#define ARCH_USER_COMMPAGE_ADDR (0xfeff0000) - #endif /* _SYSTEM_ARCH_M68K_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/mipsel/arch_commpage_defs.h b/headers/private/system/arch/mipsel/arch_commpage_defs.h index 64320ef662..516877d8be 100644 --- a/headers/private/system/arch/mipsel/arch_commpage_defs.h +++ b/headers/private/system/arch/mipsel/arch_commpage_defs.h @@ -14,7 +14,5 @@ #define COMMPAGE_ENTRY_MIPSEL_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) #define COMMPAGE_ENTRY_MIPSEL_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) -#define ARCH_USER_COMMPAGE_ADDR (0xffff0000) - #endif /* _SYSTEM_ARCH_MIPSEL_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/ppc/arch_commpage_defs.h b/headers/private/system/arch/ppc/arch_commpage_defs.h index 419d388a1a..d2cd8cbe6c 100644 --- a/headers/private/system/arch/ppc/arch_commpage_defs.h +++ b/headers/private/system/arch/ppc/arch_commpage_defs.h @@ -12,6 +12,4 @@ #define COMMPAGE_ENTRY_PPC_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) #define COMMPAGE_ENTRY_PPC_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) -#define ARCH_USER_COMMPAGE_ADDR (0xffff0000) - #endif /* _SYSTEM_ARCH_PPC_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/x86/arch_commpage_defs.h b/headers/private/system/arch/x86/arch_commpage_defs.h index eb959e14c2..f2bda3e148 100644 --- a/headers/private/system/arch/x86/arch_commpage_defs.h +++ b/headers/private/system/arch/x86/arch_commpage_defs.h @@ -19,6 +19,4 @@ #define COMMPAGE_ENTRY_X86_THREAD_EXIT \ (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 5) -#define ARCH_USER_COMMPAGE_ADDR (0xffff0000) - #endif /* _SYSTEM_ARCH_x86_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/x86_64/arch_commpage_defs.h b/headers/private/system/arch/x86_64/arch_commpage_defs.h index dabf8f0d54..85fa54e104 100644 --- a/headers/private/system/arch/x86_64/arch_commpage_defs.h +++ b/headers/private/system/arch/x86_64/arch_commpage_defs.h @@ -16,6 +16,4 @@ #define COMMPAGE_ENTRY_X86_THREAD_EXIT \ (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3) -#define ARCH_USER_COMMPAGE_ADDR (0xffffffffffff0000) - #endif /* _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/commpage_defs.h b/headers/private/system/commpage_defs.h index c47c0b828d..0a69403182 100644 --- a/headers/private/system/commpage_defs.h +++ b/headers/private/system/commpage_defs.h @@ -19,11 +19,6 @@ #define COMMPAGE_SIGNATURE 'COMM' #define COMMPAGE_VERSION 1 -#define USER_COMMPAGE_ADDR ARCH_USER_COMMPAGE_ADDR - // set by the architecture specific implementation - -#define USER_COMMPAGE_TABLE ((void**)(USER_COMMPAGE_ADDR)) - #include #endif /* _SYSTEM_COMMPAGE_DEFS_H */ diff --git a/src/system/kernel/arch/x86/32/interrupts.S b/src/system/kernel/arch/x86/32/interrupts.S index 5fde6b901e..912c583cb9 100644 --- a/src/system/kernel/arch/x86/32/interrupts.S +++ b/src/system/kernel/arch/x86/32/interrupts.S @@ -766,7 +766,9 @@ FUNCTION(x86_sysenter): pushl $USER_CODE_SEG // user cs // user_eip - movl USER_COMMPAGE_ADDR + 4 * COMMPAGE_ENTRY_X86_SYSCALL, %edx + movl THREAD_team(%edx), %edx + movl TEAM_commpage_address(%edx), %edx + addl 4 * COMMPAGE_ENTRY_X86_SYSCALL(%edx), %edx addl $4, %edx // sysenter is at offset 2, 2 bytes long pushl %edx diff --git a/src/system/kernel/arch/x86/32/signals.cpp b/src/system/kernel/arch/x86/32/signals.cpp index 80977a331c..fe3913f95e 100644 --- a/src/system/kernel/arch/x86/32/signals.cpp +++ b/src/system/kernel/arch/x86/32/signals.cpp @@ -89,14 +89,13 @@ register_signal_handler_function(const char* functionName, int32 commpageIndex, ASSERT(expectedAddress == symbolInfo.address); // fill in the commpage table entry - fill_commpage_entry(commpageIndex, (void*)symbolInfo.address, - symbolInfo.size); + addr_t position = fill_commpage_entry(commpageIndex, + (void*)symbolInfo.address, symbolInfo.size); // add symbol to the commpage image image_id image = get_commpage_image(); - elf_add_memory_image_symbol(image, commpageSymbolName, - ((addr_t*)USER_COMMPAGE_ADDR)[commpageIndex], symbolInfo.size, - B_SYMBOL_TYPE_TEXT); + elf_add_memory_image_symbol(image, commpageSymbolName, position, + symbolInfo.size, B_SYMBOL_TYPE_TEXT); } @@ -116,10 +115,10 @@ x86_initialize_commpage_signal_handler() addr_t -x86_get_user_signal_handler_wrapper(bool beosHandler) +x86_get_user_signal_handler_wrapper(bool beosHandler, void* commPageAdddress) { int32 index = beosHandler ? COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS : COMMPAGE_ENTRY_X86_SIGNAL_HANDLER; - return ((addr_t*)USER_COMMPAGE_ADDR)[index]; + return ((addr_t*)commPageAdddress)[index] + (addr_t)commPageAdddress; } diff --git a/src/system/kernel/arch/x86/32/signals_asm.S b/src/system/kernel/arch/x86/32/signals_asm.S index 38c32e9d54..2618d17481 100644 --- a/src/system/kernel/arch/x86/32/signals_asm.S +++ b/src/system/kernel/arch/x86/32/signals_asm.S @@ -37,7 +37,8 @@ FUNCTION(x86_signal_frame_function_beos): lea SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%esi), %eax push %eax push %edi - movl USER_COMMPAGE_ADDR + 4 * COMMPAGE_ENTRY_X86_MEMCPY, %eax + movl SIGNAL_FRAME_DATA_commpage_address(%esi), %eax + addl 4 * COMMPAGE_ENTRY_X86_MEMCPY(%eax), %eax call *%eax addl $12, %esp @@ -57,7 +58,8 @@ FUNCTION(x86_signal_frame_function_beos): push %edi lea SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%esi), %eax push %eax - movl USER_COMMPAGE_ADDR + 4 * COMMPAGE_ENTRY_X86_MEMCPY, %eax + movl SIGNAL_FRAME_DATA_commpage_address(%esi), %eax + addl 4 * COMMPAGE_ENTRY_X86_MEMCPY(%eax), %eax call *%eax addl $12 + VREGS_sizeof, %esp diff --git a/src/system/kernel/arch/x86/32/syscalls.cpp b/src/system/kernel/arch/x86/32/syscalls.cpp index f0c9b7c1a0..5b007e61e1 100644 --- a/src/system/kernel/arch/x86/32/syscalls.cpp +++ b/src/system/kernel/arch/x86/32/syscalls.cpp @@ -106,11 +106,11 @@ x86_initialize_syscall(void) // fill in the table entry size_t len = (size_t)((addr_t)syscallCodeEnd - (addr_t)syscallCode); - fill_commpage_entry(COMMPAGE_ENTRY_X86_SYSCALL, syscallCode, len); + addr_t position = fill_commpage_entry(COMMPAGE_ENTRY_X86_SYSCALL, + syscallCode, len); // add syscall to the commpage image image_id image = get_commpage_image(); - elf_add_memory_image_symbol(image, "commpage_syscall", - ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SYSCALL], len, + elf_add_memory_image_symbol(image, "commpage_syscall", position, len, B_SYMBOL_TYPE_TEXT); } diff --git a/src/system/kernel/arch/x86/32/thread.cpp b/src/system/kernel/arch/x86/32/thread.cpp index f50b5f4519..10ea4b234e 100644 --- a/src/system/kernel/arch/x86/32/thread.cpp +++ b/src/system/kernel/arch/x86/32/thread.cpp @@ -226,8 +226,9 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, // Copy the address of the stub that calls exit_thread() when the thread // entry function returns to the top of the stack to act as the return // address. The stub is inside commpage. - args[0] = *(addr_t*)(USER_COMMPAGE_ADDR - + COMMPAGE_ENTRY_X86_THREAD_EXIT * sizeof(addr_t)); + addr_t commPageAddress = (addr_t)thread->team->commpage_address; + args[0] = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT] + + commPageAddress; args[1] = (uint32)args1; args[2] = (uint32)args2; stackTop -= sizeof(args); @@ -351,7 +352,8 @@ arch_setup_signal_frame(Thread* thread, struct sigaction* action, // the prepared stack, executing the signal handler wrapper function. frame->user_sp = (addr_t)userStack; frame->ip = x86_get_user_signal_handler_wrapper( - (action->sa_flags & SA_BEOS_COMPATIBLE_HANDLER) != 0); + (action->sa_flags & SA_BEOS_COMPATIBLE_HANDLER) != 0, + thread->team->commpage_address); return B_OK; } diff --git a/src/system/kernel/arch/x86/64/signals.cpp b/src/system/kernel/arch/x86/64/signals.cpp index 947e76fbb7..06d41ac6b2 100644 --- a/src/system/kernel/arch/x86/64/signals.cpp +++ b/src/system/kernel/arch/x86/64/signals.cpp @@ -28,12 +28,12 @@ x86_initialize_commpage_signal_handler() // Copy the signal handler code to the commpage. size_t len = (size_t)((addr_t)handlerCodeEnd - (addr_t)handlerCode); - fill_commpage_entry(COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, handlerCode, len); + addr_t position = fill_commpage_entry(COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, + handlerCode, len); // Add symbol to the commpage image. image_id image = get_commpage_image(); - elf_add_memory_image_symbol(image, "commpage_signal_handler", - ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER], + elf_add_memory_image_symbol(image, "commpage_signal_handler", position, len, B_SYMBOL_TYPE_TEXT); } diff --git a/src/system/kernel/arch/x86/64/thread.cpp b/src/system/kernel/arch/x86/64/thread.cpp index 4b80ea6c4f..ebc8ec55e7 100644 --- a/src/system/kernel/arch/x86/64/thread.cpp +++ b/src/system/kernel/arch/x86/64/thread.cpp @@ -221,8 +221,9 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, // Copy the address of the stub that calls exit_thread() when the thread // entry function returns to the top of the stack to act as the return // address. The stub is inside commpage. - addr_t codeAddr = *(addr_t*)(USER_COMMPAGE_ADDR - + COMMPAGE_ENTRY_X86_THREAD_EXIT * sizeof(addr_t)); + addr_t commPageAddress = (addr_t)thread->team->commpage_address; + addr_t codeAddr = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT] + + commPageAddress; stackTop -= sizeof(codeAddr); if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr)) != B_OK) @@ -341,8 +342,10 @@ arch_setup_signal_frame(Thread* thread, struct sigaction* action, // Set up the iframe to execute the signal handler wrapper on our prepared // stack. First argument points to the frame data. + addr_t* commPageAddress = (addr_t*)thread->team->commpage_address; frame->user_sp = (addr_t)userStack; - frame->ip = ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER]; + frame->ip = commPageAddress[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + + (addr_t)commPageAddress; frame->di = (addr_t)userSignalFrameData; return B_OK; diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index cafc2daf6d..ff35238130 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -864,28 +864,26 @@ arch_cpu_init_post_modules(kernel_args* args) // put the optimized functions into the commpage size_t memcpyLen = (addr_t)gOptimizedFunctions.memcpy_end - (addr_t)gOptimizedFunctions.memcpy; - fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMCPY, + addr_t memcpyPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMCPY, (const void*)gOptimizedFunctions.memcpy, memcpyLen); size_t memsetLen = (addr_t)gOptimizedFunctions.memset_end - (addr_t)gOptimizedFunctions.memset; - fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET, + addr_t memsetPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET, (const void*)gOptimizedFunctions.memset, memsetLen); size_t threadExitLen = (addr_t)x86_end_userspace_thread_exit - (addr_t)x86_userspace_thread_exit; - fill_commpage_entry(COMMPAGE_ENTRY_X86_THREAD_EXIT, - (const void*)x86_userspace_thread_exit, threadExitLen); + addr_t threadExitPosition = fill_commpage_entry( + COMMPAGE_ENTRY_X86_THREAD_EXIT, (const void*)x86_userspace_thread_exit, + threadExitLen); // add the functions to the commpage image image_id image = get_commpage_image(); - elf_add_memory_image_symbol(image, "commpage_memcpy", - ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_MEMCPY], memcpyLen, - B_SYMBOL_TYPE_TEXT); - elf_add_memory_image_symbol(image, "commpage_memset", - ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_MEMSET], memsetLen, - B_SYMBOL_TYPE_TEXT); + elf_add_memory_image_symbol(image, "commpage_memcpy", memcpyPosition, + memcpyLen, B_SYMBOL_TYPE_TEXT); + elf_add_memory_image_symbol(image, "commpage_memset", memsetPosition, + memsetLen, B_SYMBOL_TYPE_TEXT); elf_add_memory_image_symbol(image, "commpage_thread_exit", - ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_THREAD_EXIT], - threadExitLen, B_SYMBOL_TYPE_TEXT); + threadExitPosition, threadExitLen, B_SYMBOL_TYPE_TEXT); return B_OK; } diff --git a/src/system/kernel/arch/x86/asm_offsets.cpp b/src/system/kernel/arch/x86/asm_offsets.cpp index 88082f90ce..787fef10e9 100644 --- a/src/system/kernel/arch/x86/asm_offsets.cpp +++ b/src/system/kernel/arch/x86/asm_offsets.cpp @@ -34,7 +34,11 @@ dummy() DEFINE_OFFSET_MACRO(CPU_ENT, cpu_ent, fault_handler); DEFINE_OFFSET_MACRO(CPU_ENT, cpu_ent, fault_handler_stack_pointer); + // struct Team + DEFINE_OFFSET_MACRO(TEAM, Team, commpage_address); + // struct Thread + DEFINE_OFFSET_MACRO(THREAD, Thread, team); DEFINE_OFFSET_MACRO(THREAD, Thread, time_lock); DEFINE_OFFSET_MACRO(THREAD, Thread, kernel_time); DEFINE_OFFSET_MACRO(THREAD, Thread, user_time); @@ -88,6 +92,7 @@ dummy() DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, user_data); DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, handler); DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, siginfo_handler); + DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, commpage_address); // struct ucontext_t DEFINE_OFFSET_MACRO(UCONTEXT_T, __ucontext_t, uc_mcontext); diff --git a/src/system/kernel/arch/x86/x86_signals.h b/src/system/kernel/arch/x86/x86_signals.h index 0e6cb50801..e37bb0dda5 100644 --- a/src/system/kernel/arch/x86/x86_signals.h +++ b/src/system/kernel/arch/x86/x86_signals.h @@ -11,7 +11,8 @@ void x86_initialize_commpage_signal_handler(); #ifndef __x86_64__ -addr_t x86_get_user_signal_handler_wrapper(bool beosHandler); +addr_t x86_get_user_signal_handler_wrapper(bool beosHandler, + void* commPageAddress); #endif diff --git a/src/system/kernel/commpage.cpp b/src/system/kernel/commpage.cpp index 4419bfd6cf..be962fdd72 100644 --- a/src/system/kernel/commpage.cpp +++ b/src/system/kernel/commpage.cpp @@ -15,9 +15,7 @@ static area_id sCommPageArea; -static area_id sUserCommPageArea; static addr_t* sCommPageAddress; -static addr_t* sUserCommPageAddress; static void* sFreeCommPageSpace; static image_id sCommPageImage; @@ -30,20 +28,19 @@ allocate_commpage_entry(int entry, size_t size) { void* space = sFreeCommPageSpace; sFreeCommPageSpace = ALIGN_ENTRY((addr_t)sFreeCommPageSpace + size); - sCommPageAddress[entry] = (addr_t)sUserCommPageAddress - + ((addr_t)space - (addr_t)sCommPageAddress); + sCommPageAddress[entry] = (addr_t)space - (addr_t)sCommPageAddress; dprintf("allocate_commpage_entry(%d, %lu) -> %p\n", entry, size, (void*)sCommPageAddress[entry]); return space; } -void* +addr_t fill_commpage_entry(int entry, const void* copyFrom, size_t size) { void* space = allocate_commpage_entry(entry, size); memcpy(space, copyFrom, size); - return space; + return (addr_t)space - (addr_t)sCommPageAddress; } @@ -54,20 +51,23 @@ get_commpage_image() } +area_id +clone_commpage_area(team_id team, void** address) +{ + return vm_clone_area(team, "commpage", address, + B_RANDOMIZED_ANY_ADDRESS, B_READ_AREA | B_EXECUTE_AREA | B_KERNEL_AREA, + REGION_PRIVATE_MAP, sCommPageArea, true); +} + + status_t commpage_init(void) { // create a read/write kernel area - sCommPageArea = create_area("commpage", (void **)&sCommPageAddress, + sCommPageArea = create_area("kernel_commpage", (void **)&sCommPageAddress, B_ANY_ADDRESS, COMMPAGE_SIZE, B_FULL_LOCK, B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA); - // clone it at a fixed address with user read/only permissions - sUserCommPageAddress = (addr_t*)USER_COMMPAGE_ADDR; - sUserCommPageArea = clone_area("user_commpage", - (void **)&sUserCommPageAddress, B_EXACT_ADDRESS, - B_READ_AREA | B_EXECUTE_AREA, sCommPageArea); - // zero it out memset(sCommPageAddress, 0, COMMPAGE_SIZE); @@ -79,10 +79,10 @@ commpage_init(void) sFreeCommPageSpace = ALIGN_ENTRY(&sCommPageAddress[COMMPAGE_TABLE_ENTRIES]); // create the image for the commpage - sCommPageImage = elf_create_memory_image("commpage", USER_COMMPAGE_ADDR, + sCommPageImage = elf_create_memory_image("commpage", 0, COMMPAGE_SIZE, 0, 0); elf_add_memory_image_symbol(sCommPageImage, "commpage_table", - USER_COMMPAGE_ADDR, COMMPAGE_TABLE_ENTRIES * sizeof(addr_t), + 0, COMMPAGE_TABLE_ENTRIES * sizeof(addr_t), B_SYMBOL_TYPE_DATA); arch_commpage_init(); diff --git a/src/system/kernel/debug/BreakpointManager.cpp b/src/system/kernel/debug/BreakpointManager.cpp index ceed7c8fb3..f105a4040a 100644 --- a/src/system/kernel/debug/BreakpointManager.cpp +++ b/src/system/kernel/debug/BreakpointManager.cpp @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -257,12 +256,6 @@ BreakpointManager::CanAccessAddress(const void* _address, bool write) if (IS_USER_ADDRESS(address)) return true; - // a commpage address can at least be read - if (address >= USER_COMMPAGE_ADDR - && address < USER_COMMPAGE_ADDR + COMMPAGE_SIZE) { - return !write; - } - return false; } diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp index 0bb496fa7b..307b55b537 100644 --- a/src/system/kernel/elf.cpp +++ b/src/system/kernel/elf.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -1363,6 +1364,7 @@ public: if (!_Read((runtime_loader_debug_area*)area->Base(), fDebugArea)) return B_BAD_ADDRESS; + fTeam = team; return B_OK; } @@ -1381,8 +1383,22 @@ public: // get the image for the address image_t image; status_t error = _FindImageAtAddress(address, image); - if (error != B_OK) + if (error != B_OK) { + // commpage requires special treatment since kernel stores symbol + // information + addr_t commPageAddress = (addr_t)fTeam->commpage_address; + if (address >= commPageAddress + && address < commPageAddress + COMMPAGE_SIZE) { + if (*_imageName) + *_imageName = "commpage"; + address -= (addr_t)commPageAddress; + error = elf_debug_lookup_symbol_address(address, _baseAddress, + _symbolName, NULL, _exactMatch); + if (_baseAddress) + *_baseAddress += (addr_t)fTeam->commpage_address; + } return error; + } strlcpy(fImageName, image.name, sizeof(fImageName)); @@ -1522,6 +1538,7 @@ public: // gcc 2.95.3 doesn't like it defined in-place private: + Team* fTeam; runtime_loader_debug_area fDebugArea; char fImageName[B_OS_NAME_LENGTH]; char fSymbolName[256]; diff --git a/src/system/kernel/signal.cpp b/src/system/kernel/signal.cpp index 3279233357..a28533f645 100644 --- a/src/system/kernel/signal.cpp +++ b/src/system/kernel/signal.cpp @@ -892,6 +892,10 @@ setup_signal_frame(Thread* thread, struct sigaction* action, Signal* signal, memcpy(frameData.syscall_restart_parameters, thread->syscall_restart.parameters, sizeof(frameData.syscall_restart_parameters)); + + // commpage address + frameData.commpage_address = thread->team->commpage_address; + // syscall_restart_return_value is filled in by the architecture specific // code. diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 974719b81a..da98e04096 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -450,6 +451,8 @@ Team::Team(team_id id, bool kernel) user_data_size = 0; free_user_threads = NULL; + commpage_address = NULL; + supplementary_groups = NULL; supplementary_group_count = 0; @@ -1562,6 +1565,32 @@ team_create_thread_start_internal(void* args) // the arguments are already on the user stack, we no longer need // them in this form + // Clone commpage area + area_id commPageArea = clone_commpage_area(team->id, + &team->commpage_address); + if (commPageArea < B_OK) { + TRACE(("team_create_thread_start: clone_commpage_area() failed: %s\n", + strerror(commPageArea))); + return commPageArea; + } + + // Register commpage image + image_id commPageImage = get_commpage_image(); + image_info imageInfo; + err = get_image_info(commPageImage, &imageInfo); + if (err != B_OK) { + TRACE(("team_create_thread_start: get_image_info() failed: %s\n", + strerror(err))); + return err; + } + imageInfo.text = team->commpage_address; + image_id image = register_image(team, &imageInfo, sizeof(image_info)); + if (image < 0) { + TRACE(("team_create_thread_start: register_image() failed: %s\n", + strerror(image))); + return image; + } + // NOTE: Normally arch_thread_enter_userspace() never returns, that is // automatic variables with function scope will never be destroyed. { @@ -1595,7 +1624,7 @@ team_create_thread_start_internal(void* args) // enter userspace -- returns only in case of error return thread_enter_userspace_new_team(thread, (addr_t)entry, - programArgs, NULL); + programArgs, team->commpage_address); } @@ -1995,6 +2024,8 @@ fork_team(void) team->SetName(parentTeam->Name()); team->SetArgs(parentTeam->Args()); + team->commpage_address = parentTeam->commpage_address; + // Inherit the parent's user/group. inherit_parent_user_and_group(team, parentTeam); diff --git a/src/system/libroot/libroot_init.c b/src/system/libroot/libroot_init.c index 68137366eb..cf6fc668fc 100644 --- a/src/system/libroot/libroot_init.c +++ b/src/system/libroot/libroot_init.c @@ -24,6 +24,8 @@ struct rld_export *__gRuntimeLoader = NULL; // This little bugger is set to something meaningful by the runtime loader // Ugly, eh? +const void* __gCommPageAddress; + char *__progname = NULL; int __libc_argc; char **__libc_argv; @@ -44,6 +46,8 @@ void initialize_before(image_id imageID) { char *programPath = __gRuntimeLoader->program_args->args[0]; + __gCommPageAddress = __gRuntimeLoader->commpage_address; + if (programPath) { if ((__progname = strrchr(programPath, '/')) == NULL) __progname = programPath; @@ -62,7 +66,7 @@ initialize_before(image_id imageID) pthread_self()->id = find_thread(NULL); - __init_time(); + __init_time((addr_t)__gCommPageAddress); __init_heap(); __init_env(__gRuntimeLoader->program_args); __init_heap_post_env(); diff --git a/src/system/libroot/os/arch/x86/syscalls.inc b/src/system/libroot/os/arch/x86/syscalls.inc index 95aa740535..517d650d09 100644 --- a/src/system/libroot/os/arch/x86/syscalls.inc +++ b/src/system/libroot/os/arch/x86/syscalls.inc @@ -17,11 +17,13 @@ #include #include -#define _SYSCALL(name, n) \ - .align 8; \ - FUNCTION(name): \ - movl $n,%eax; \ - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_SYSCALL * 4); \ +#define _SYSCALL(name, n) \ + .align 8; \ + FUNCTION(name): \ + movl $n, %eax; \ + movl __gCommPageAddress, %edx; \ + addl 4 * COMMPAGE_ENTRY_X86_SYSCALL(%edx), %edx; \ + jmp %edx; \ FUNCTION_END(name) #define SYSCALL0(name, n) _SYSCALL(name, n) diff --git a/src/system/libroot/os/time.cpp b/src/system/libroot/os/time.cpp index 19d29536a5..7b882cd8e7 100644 --- a/src/system/libroot/os/time.cpp +++ b/src/system/libroot/os/time.cpp @@ -24,10 +24,11 @@ static struct real_time_data* sRealTimeData; void -__init_time(void) +__init_time(addr_t commPageTable) { sRealTimeData = (struct real_time_data*) - USER_COMMPAGE_TABLE[COMMPAGE_ENTRY_REAL_TIME_DATA]; + (((addr_t*)commPageTable)[COMMPAGE_ENTRY_REAL_TIME_DATA] + + commPageTable); __arch_init_time(sRealTimeData, false); } diff --git a/src/system/libroot/posix/string/arch/x86/arch_string.S b/src/system/libroot/posix/string/arch/x86/arch_string.S index 4ab85e7da0..1518baa207 100644 --- a/src/system/libroot/posix/string/arch/x86/arch_string.S +++ b/src/system/libroot/posix/string/arch/x86/arch_string.S @@ -10,9 +10,13 @@ .align 4 FUNCTION(memcpy): - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMCPY * 4) + movl __gCommPageAddress, %eax + addl 4 * COMMPAGE_ENTRY_X86_MEMCPY(%eax), %eax + jmp *%eax FUNCTION_END(memcpy) FUNCTION(memset): - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMSET * 4) + movl __gCommPageAddress, %eax + addl 4 * COMMPAGE_ENTRY_X86_MEMSET(%eax), %eax + jmp *%eax FUNCTION_END(memset) diff --git a/src/system/libroot/posix/string/arch/x86_64/arch_string.S b/src/system/libroot/posix/string/arch/x86_64/arch_string.S index 8bbadb31ca..e1273fdc3c 100644 --- a/src/system/libroot/posix/string/arch/x86_64/arch_string.S +++ b/src/system/libroot/posix/string/arch/x86_64/arch_string.S @@ -8,10 +8,15 @@ FUNCTION(memcpy): - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMCPY * 8) + movq __gCommPageAddress@GOTPCREL(%rip), %rax + movq (%rax), %rax + addq 8 * COMMPAGE_ENTRY_X86_MEMCPY(%rax), %rax + jmp *%rax FUNCTION_END(memcpy) - FUNCTION(memset): - jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMSET * 8) + movq __gCommPageAddress@GOTPCREL(%rip), %rax + movq (%rax), %rax + addq 8 * COMMPAGE_ENTRY_X86_MEMSET(%rax), %rax + jmp *%rax FUNCTION_END(memset) diff --git a/src/system/runtime_loader/export.cpp b/src/system/runtime_loader/export.cpp index 62275c5974..adfd2a4dd9 100644 --- a/src/system/runtime_loader/export.cpp +++ b/src/system/runtime_loader/export.cpp @@ -65,4 +65,5 @@ void rldexport_init(void) { gRuntimeLoader.program_args = gProgramArgs; + gRuntimeLoader.commpage_address = __gCommPageAddress; } diff --git a/src/system/runtime_loader/runtime_loader.cpp b/src/system/runtime_loader/runtime_loader.cpp index 3389103901..140a7574b6 100644 --- a/src/system/runtime_loader/runtime_loader.cpp +++ b/src/system/runtime_loader/runtime_loader.cpp @@ -22,6 +22,7 @@ struct user_space_program_args *gProgramArgs; +void *__gCommPageAddress; static const char * @@ -366,12 +367,13 @@ out: specified by its ld-script. */ int -runtime_loader(void *_args) +runtime_loader(void* _args, void* commpage) { void *entry = NULL; int returnCode; gProgramArgs = (struct user_space_program_args *)_args; + __gCommPageAddress = commpage; // Relocate the args and env arrays -- they are organized in a contiguous // buffer which the kernel just copied into user space without adjusting the diff --git a/src/system/runtime_loader/runtime_loader_private.h b/src/system/runtime_loader/runtime_loader_private.h index f3f6dd38e0..2720a659a8 100644 --- a/src/system/runtime_loader/runtime_loader_private.h +++ b/src/system/runtime_loader/runtime_loader_private.h @@ -43,6 +43,7 @@ struct SymbolLookupCache; extern struct user_space_program_args* gProgramArgs; +extern void* __gCommPageAddress; extern struct rld_export gRuntimeLoader; extern char* (*gGetEnv)(const char* name); extern bool gProgramLoaded; @@ -53,7 +54,7 @@ extern image_t* gProgramImage; extern "C" { #endif -int runtime_loader(void* arg); +int runtime_loader(void* arg, void* commpage); int open_executable(char* name, image_type type, const char* rpath, const char* programPath, const char* compatibilitySubDir); status_t test_executable(const char* path, char* interpreter);