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);