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.
This commit is contained in:
Pawel Dziepak
2013-04-04 15:27:22 +02:00
parent 966f207668
commit e85e399fd7
35 changed files with 158 additions and 96 deletions
+2 -1
View File
@@ -18,8 +18,9 @@ extern "C" {
status_t commpage_init(void); status_t commpage_init(void);
status_t commpage_init_post_cpus(void); status_t commpage_init_post_cpus(void);
void* allocate_commpage_entry(int entry, size_t size); 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(); image_id get_commpage_image();
area_id clone_commpage_area(team_id team, void** address);
// implemented in the architecture specific part // implemented in the architecture specific part
status_t arch_commpage_init(void); status_t arch_commpage_init(void);
+1
View File
@@ -52,6 +52,7 @@ struct signal_frame_data {
int32 thread_flags; int32 thread_flags;
uint64 syscall_restart_return_value; uint64 syscall_restart_return_value;
uint8 syscall_restart_parameters[SYSCALL_RESTART_PARAMETER_SIZE]; uint8 syscall_restart_parameters[SYSCALL_RESTART_PARAMETER_SIZE];
void* commpage_address;
}; };
+2
View File
@@ -259,6 +259,8 @@ struct Team : TeamThreadIteratorEntry<team_id>, KernelReferenceable,
size_t used_user_data; size_t used_user_data;
struct free_user_thread* free_user_threads; struct free_user_thread* free_user_threads;
void* commpage_address;
struct team_debug_info debug_info; struct team_debug_info debug_info;
// protected by scheduler lock // protected by scheduler lock
+1 -1
View File
@@ -34,7 +34,7 @@ void __init_env(const struct user_space_program_args *args);
void __init_heap(void); void __init_heap(void);
void __init_heap_post_env(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); 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 __arch_get_system_time_offset(struct real_time_data *data);
bigtime_t __get_system_time_offset(); bigtime_t __get_system_time_offset();
@@ -51,6 +51,7 @@ struct rld_export {
void (*call_termination_hooks)(); void (*call_termination_hooks)();
const struct user_space_program_args *program_args; const struct user_space_program_args *program_args;
const void* commpage_address;
}; };
extern struct rld_export *__gRuntimeLoader; extern struct rld_export *__gRuntimeLoader;
@@ -12,8 +12,4 @@
//#define COMMPAGE_ENTRY_M68K_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) //#define COMMPAGE_ENTRY_M68K_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
//#define COMMPAGE_ENTRY_M68K_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) //#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 */ #endif /* _SYSTEM_ARCH_M68K_COMMPAGE_DEFS_H */
@@ -12,7 +12,4 @@
#define COMMPAGE_ENTRY_M68K_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) #define COMMPAGE_ENTRY_M68K_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
#define COMMPAGE_ENTRY_M68K_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) #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 */ #endif /* _SYSTEM_ARCH_M68K_COMMPAGE_DEFS_H */
@@ -14,7 +14,5 @@
#define COMMPAGE_ENTRY_MIPSEL_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) #define COMMPAGE_ENTRY_MIPSEL_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
#define COMMPAGE_ENTRY_MIPSEL_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) #define COMMPAGE_ENTRY_MIPSEL_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1)
#define ARCH_USER_COMMPAGE_ADDR (0xffff0000)
#endif /* _SYSTEM_ARCH_MIPSEL_COMMPAGE_DEFS_H */ #endif /* _SYSTEM_ARCH_MIPSEL_COMMPAGE_DEFS_H */
@@ -12,6 +12,4 @@
#define COMMPAGE_ENTRY_PPC_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) #define COMMPAGE_ENTRY_PPC_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
#define COMMPAGE_ENTRY_PPC_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) #define COMMPAGE_ENTRY_PPC_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1)
#define ARCH_USER_COMMPAGE_ADDR (0xffff0000)
#endif /* _SYSTEM_ARCH_PPC_COMMPAGE_DEFS_H */ #endif /* _SYSTEM_ARCH_PPC_COMMPAGE_DEFS_H */
@@ -19,6 +19,4 @@
#define COMMPAGE_ENTRY_X86_THREAD_EXIT \ #define COMMPAGE_ENTRY_X86_THREAD_EXIT \
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 5) (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 5)
#define ARCH_USER_COMMPAGE_ADDR (0xffff0000)
#endif /* _SYSTEM_ARCH_x86_COMMPAGE_DEFS_H */ #endif /* _SYSTEM_ARCH_x86_COMMPAGE_DEFS_H */
@@ -16,6 +16,4 @@
#define COMMPAGE_ENTRY_X86_THREAD_EXIT \ #define COMMPAGE_ENTRY_X86_THREAD_EXIT \
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3) (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3)
#define ARCH_USER_COMMPAGE_ADDR (0xffffffffffff0000)
#endif /* _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H */ #endif /* _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H */
-5
View File
@@ -19,11 +19,6 @@
#define COMMPAGE_SIGNATURE 'COMM' #define COMMPAGE_SIGNATURE 'COMM'
#define COMMPAGE_VERSION 1 #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 <arch_commpage_defs.h> #include <arch_commpage_defs.h>
#endif /* _SYSTEM_COMMPAGE_DEFS_H */ #endif /* _SYSTEM_COMMPAGE_DEFS_H */
+3 -1
View File
@@ -766,7 +766,9 @@ FUNCTION(x86_sysenter):
pushl $USER_CODE_SEG // user cs pushl $USER_CODE_SEG // user cs
// user_eip // 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 addl $4, %edx // sysenter is at offset 2, 2 bytes long
pushl %edx pushl %edx
+6 -7
View File
@@ -89,14 +89,13 @@ register_signal_handler_function(const char* functionName, int32 commpageIndex,
ASSERT(expectedAddress == symbolInfo.address); ASSERT(expectedAddress == symbolInfo.address);
// fill in the commpage table entry // fill in the commpage table entry
fill_commpage_entry(commpageIndex, (void*)symbolInfo.address, addr_t position = fill_commpage_entry(commpageIndex,
symbolInfo.size); (void*)symbolInfo.address, symbolInfo.size);
// add symbol to the commpage image // add symbol to the commpage image
image_id image = get_commpage_image(); image_id image = get_commpage_image();
elf_add_memory_image_symbol(image, commpageSymbolName, elf_add_memory_image_symbol(image, commpageSymbolName, position,
((addr_t*)USER_COMMPAGE_ADDR)[commpageIndex], symbolInfo.size, symbolInfo.size, B_SYMBOL_TYPE_TEXT);
B_SYMBOL_TYPE_TEXT);
} }
@@ -116,10 +115,10 @@ x86_initialize_commpage_signal_handler()
addr_t addr_t
x86_get_user_signal_handler_wrapper(bool beosHandler) x86_get_user_signal_handler_wrapper(bool beosHandler, void* commPageAdddress)
{ {
int32 index = beosHandler int32 index = beosHandler
? COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS ? COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS
: COMMPAGE_ENTRY_X86_SIGNAL_HANDLER; : COMMPAGE_ENTRY_X86_SIGNAL_HANDLER;
return ((addr_t*)USER_COMMPAGE_ADDR)[index]; return ((addr_t*)commPageAdddress)[index] + (addr_t)commPageAdddress;
} }
+4 -2
View File
@@ -37,7 +37,8 @@ FUNCTION(x86_signal_frame_function_beos):
lea SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%esi), %eax lea SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%esi), %eax
push %eax push %eax
push %edi 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 call *%eax
addl $12, %esp addl $12, %esp
@@ -57,7 +58,8 @@ FUNCTION(x86_signal_frame_function_beos):
push %edi push %edi
lea SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%esi), %eax lea SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%esi), %eax
push %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 call *%eax
addl $12 + VREGS_sizeof, %esp addl $12 + VREGS_sizeof, %esp
+3 -3
View File
@@ -106,11 +106,11 @@ x86_initialize_syscall(void)
// fill in the table entry // fill in the table entry
size_t len = (size_t)((addr_t)syscallCodeEnd - (addr_t)syscallCode); 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 // add syscall to the commpage image
image_id image = get_commpage_image(); image_id image = get_commpage_image();
elf_add_memory_image_symbol(image, "commpage_syscall", elf_add_memory_image_symbol(image, "commpage_syscall", position, len,
((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SYSCALL], len,
B_SYMBOL_TYPE_TEXT); B_SYMBOL_TYPE_TEXT);
} }
+5 -3
View File
@@ -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 // 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 // entry function returns to the top of the stack to act as the return
// address. The stub is inside commpage. // address. The stub is inside commpage.
args[0] = *(addr_t*)(USER_COMMPAGE_ADDR addr_t commPageAddress = (addr_t)thread->team->commpage_address;
+ COMMPAGE_ENTRY_X86_THREAD_EXIT * sizeof(addr_t)); args[0] = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT]
+ commPageAddress;
args[1] = (uint32)args1; args[1] = (uint32)args1;
args[2] = (uint32)args2; args[2] = (uint32)args2;
stackTop -= sizeof(args); 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. // the prepared stack, executing the signal handler wrapper function.
frame->user_sp = (addr_t)userStack; frame->user_sp = (addr_t)userStack;
frame->ip = x86_get_user_signal_handler_wrapper( 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; return B_OK;
} }
+3 -3
View File
@@ -28,12 +28,12 @@ x86_initialize_commpage_signal_handler()
// Copy the signal handler code to the commpage. // Copy the signal handler code to the commpage.
size_t len = (size_t)((addr_t)handlerCodeEnd - (addr_t)handlerCode); 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. // Add symbol to the commpage image.
image_id image = get_commpage_image(); image_id image = get_commpage_image();
elf_add_memory_image_symbol(image, "commpage_signal_handler", elf_add_memory_image_symbol(image, "commpage_signal_handler", position,
((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER],
len, B_SYMBOL_TYPE_TEXT); len, B_SYMBOL_TYPE_TEXT);
} }
+6 -3
View File
@@ -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 // 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 // entry function returns to the top of the stack to act as the return
// address. The stub is inside commpage. // address. The stub is inside commpage.
addr_t codeAddr = *(addr_t*)(USER_COMMPAGE_ADDR addr_t commPageAddress = (addr_t)thread->team->commpage_address;
+ COMMPAGE_ENTRY_X86_THREAD_EXIT * sizeof(addr_t)); addr_t codeAddr = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT]
+ commPageAddress;
stackTop -= sizeof(codeAddr); stackTop -= sizeof(codeAddr);
if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr)) if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr))
!= B_OK) != 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 // Set up the iframe to execute the signal handler wrapper on our prepared
// stack. First argument points to the frame data. // stack. First argument points to the frame data.
addr_t* commPageAddress = (addr_t*)thread->team->commpage_address;
frame->user_sp = (addr_t)userStack; 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; frame->di = (addr_t)userSignalFrameData;
return B_OK; return B_OK;
+10 -12
View File
@@ -864,28 +864,26 @@ arch_cpu_init_post_modules(kernel_args* args)
// put the optimized functions into the commpage // put the optimized functions into the commpage
size_t memcpyLen = (addr_t)gOptimizedFunctions.memcpy_end size_t memcpyLen = (addr_t)gOptimizedFunctions.memcpy_end
- (addr_t)gOptimizedFunctions.memcpy; - (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); (const void*)gOptimizedFunctions.memcpy, memcpyLen);
size_t memsetLen = (addr_t)gOptimizedFunctions.memset_end size_t memsetLen = (addr_t)gOptimizedFunctions.memset_end
- (addr_t)gOptimizedFunctions.memset; - (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); (const void*)gOptimizedFunctions.memset, memsetLen);
size_t threadExitLen = (addr_t)x86_end_userspace_thread_exit size_t threadExitLen = (addr_t)x86_end_userspace_thread_exit
- (addr_t)x86_userspace_thread_exit; - (addr_t)x86_userspace_thread_exit;
fill_commpage_entry(COMMPAGE_ENTRY_X86_THREAD_EXIT, addr_t threadExitPosition = fill_commpage_entry(
(const void*)x86_userspace_thread_exit, threadExitLen); COMMPAGE_ENTRY_X86_THREAD_EXIT, (const void*)x86_userspace_thread_exit,
threadExitLen);
// add the functions to the commpage image // add the functions to the commpage image
image_id image = get_commpage_image(); image_id image = get_commpage_image();
elf_add_memory_image_symbol(image, "commpage_memcpy", elf_add_memory_image_symbol(image, "commpage_memcpy", memcpyPosition,
((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_MEMCPY], memcpyLen, memcpyLen, B_SYMBOL_TYPE_TEXT);
B_SYMBOL_TYPE_TEXT); elf_add_memory_image_symbol(image, "commpage_memset", memsetPosition,
elf_add_memory_image_symbol(image, "commpage_memset", memsetLen, B_SYMBOL_TYPE_TEXT);
((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_MEMSET], memsetLen,
B_SYMBOL_TYPE_TEXT);
elf_add_memory_image_symbol(image, "commpage_thread_exit", elf_add_memory_image_symbol(image, "commpage_thread_exit",
((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_THREAD_EXIT], threadExitPosition, threadExitLen, B_SYMBOL_TYPE_TEXT);
threadExitLen, B_SYMBOL_TYPE_TEXT);
return B_OK; return B_OK;
} }
@@ -34,7 +34,11 @@ dummy()
DEFINE_OFFSET_MACRO(CPU_ENT, cpu_ent, fault_handler); DEFINE_OFFSET_MACRO(CPU_ENT, cpu_ent, fault_handler);
DEFINE_OFFSET_MACRO(CPU_ENT, cpu_ent, fault_handler_stack_pointer); DEFINE_OFFSET_MACRO(CPU_ENT, cpu_ent, fault_handler_stack_pointer);
// struct Team
DEFINE_OFFSET_MACRO(TEAM, Team, commpage_address);
// struct Thread // struct Thread
DEFINE_OFFSET_MACRO(THREAD, Thread, team);
DEFINE_OFFSET_MACRO(THREAD, Thread, time_lock); DEFINE_OFFSET_MACRO(THREAD, Thread, time_lock);
DEFINE_OFFSET_MACRO(THREAD, Thread, kernel_time); DEFINE_OFFSET_MACRO(THREAD, Thread, kernel_time);
DEFINE_OFFSET_MACRO(THREAD, Thread, user_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, user_data);
DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, handler); 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, siginfo_handler);
DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, commpage_address);
// struct ucontext_t // struct ucontext_t
DEFINE_OFFSET_MACRO(UCONTEXT_T, __ucontext_t, uc_mcontext); DEFINE_OFFSET_MACRO(UCONTEXT_T, __ucontext_t, uc_mcontext);
+2 -1
View File
@@ -11,7 +11,8 @@
void x86_initialize_commpage_signal_handler(); void x86_initialize_commpage_signal_handler();
#ifndef __x86_64__ #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 #endif
+15 -15
View File
@@ -15,9 +15,7 @@
static area_id sCommPageArea; static area_id sCommPageArea;
static area_id sUserCommPageArea;
static addr_t* sCommPageAddress; static addr_t* sCommPageAddress;
static addr_t* sUserCommPageAddress;
static void* sFreeCommPageSpace; static void* sFreeCommPageSpace;
static image_id sCommPageImage; static image_id sCommPageImage;
@@ -30,20 +28,19 @@ allocate_commpage_entry(int entry, size_t size)
{ {
void* space = sFreeCommPageSpace; void* space = sFreeCommPageSpace;
sFreeCommPageSpace = ALIGN_ENTRY((addr_t)sFreeCommPageSpace + size); sFreeCommPageSpace = ALIGN_ENTRY((addr_t)sFreeCommPageSpace + size);
sCommPageAddress[entry] = (addr_t)sUserCommPageAddress sCommPageAddress[entry] = (addr_t)space - (addr_t)sCommPageAddress;
+ ((addr_t)space - (addr_t)sCommPageAddress);
dprintf("allocate_commpage_entry(%d, %lu) -> %p\n", entry, size, dprintf("allocate_commpage_entry(%d, %lu) -> %p\n", entry, size,
(void*)sCommPageAddress[entry]); (void*)sCommPageAddress[entry]);
return space; return space;
} }
void* addr_t
fill_commpage_entry(int entry, const void* copyFrom, size_t size) fill_commpage_entry(int entry, const void* copyFrom, size_t size)
{ {
void* space = allocate_commpage_entry(entry, size); void* space = allocate_commpage_entry(entry, size);
memcpy(space, copyFrom, 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 status_t
commpage_init(void) commpage_init(void)
{ {
// create a read/write kernel area // 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_ANY_ADDRESS, COMMPAGE_SIZE, B_FULL_LOCK,
B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA); 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 // zero it out
memset(sCommPageAddress, 0, COMMPAGE_SIZE); memset(sCommPageAddress, 0, COMMPAGE_SIZE);
@@ -79,10 +79,10 @@ commpage_init(void)
sFreeCommPageSpace = ALIGN_ENTRY(&sCommPageAddress[COMMPAGE_TABLE_ENTRIES]); sFreeCommPageSpace = ALIGN_ENTRY(&sCommPageAddress[COMMPAGE_TABLE_ENTRIES]);
// create the image for the commpage // 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); COMMPAGE_SIZE, 0, 0);
elf_add_memory_image_symbol(sCommPageImage, "commpage_table", 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); B_SYMBOL_TYPE_DATA);
arch_commpage_init(); arch_commpage_init();
@@ -9,7 +9,6 @@
#include <AutoDeleter.h> #include <AutoDeleter.h>
#include <commpage_defs.h>
#include <kernel.h> #include <kernel.h>
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include <vm/vm.h> #include <vm/vm.h>
@@ -257,12 +256,6 @@ BreakpointManager::CanAccessAddress(const void* _address, bool write)
if (IS_USER_ADDRESS(address)) if (IS_USER_ADDRESS(address))
return true; 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; return false;
} }
+18 -1
View File
@@ -23,6 +23,7 @@
#include <algorithm> #include <algorithm>
#include <AutoDeleter.h> #include <AutoDeleter.h>
#include <commpage.h>
#include <boot/kernel_args.h> #include <boot/kernel_args.h>
#include <debug.h> #include <debug.h>
#include <image_defs.h> #include <image_defs.h>
@@ -1363,6 +1364,7 @@ public:
if (!_Read((runtime_loader_debug_area*)area->Base(), fDebugArea)) if (!_Read((runtime_loader_debug_area*)area->Base(), fDebugArea))
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
fTeam = team;
return B_OK; return B_OK;
} }
@@ -1381,8 +1383,22 @@ public:
// get the image for the address // get the image for the address
image_t image; image_t image;
status_t error = _FindImageAtAddress(address, 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; return error;
}
strlcpy(fImageName, image.name, sizeof(fImageName)); strlcpy(fImageName, image.name, sizeof(fImageName));
@@ -1522,6 +1538,7 @@ public:
// gcc 2.95.3 doesn't like it defined in-place // gcc 2.95.3 doesn't like it defined in-place
private: private:
Team* fTeam;
runtime_loader_debug_area fDebugArea; runtime_loader_debug_area fDebugArea;
char fImageName[B_OS_NAME_LENGTH]; char fImageName[B_OS_NAME_LENGTH];
char fSymbolName[256]; char fSymbolName[256];
+4
View File
@@ -892,6 +892,10 @@ setup_signal_frame(Thread* thread, struct sigaction* action, Signal* signal,
memcpy(frameData.syscall_restart_parameters, memcpy(frameData.syscall_restart_parameters,
thread->syscall_restart.parameters, thread->syscall_restart.parameters,
sizeof(frameData.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 // syscall_restart_return_value is filled in by the architecture specific
// code. // code.
+32 -1
View File
@@ -26,6 +26,7 @@
#include <extended_system_info_defs.h> #include <extended_system_info_defs.h>
#include <commpage.h>
#include <boot_device.h> #include <boot_device.h>
#include <elf.h> #include <elf.h>
#include <file_cache.h> #include <file_cache.h>
@@ -450,6 +451,8 @@ Team::Team(team_id id, bool kernel)
user_data_size = 0; user_data_size = 0;
free_user_threads = NULL; free_user_threads = NULL;
commpage_address = NULL;
supplementary_groups = NULL; supplementary_groups = NULL;
supplementary_group_count = 0; 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 // the arguments are already on the user stack, we no longer need
// them in this form // 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 // NOTE: Normally arch_thread_enter_userspace() never returns, that is
// automatic variables with function scope will never be destroyed. // 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 // enter userspace -- returns only in case of error
return thread_enter_userspace_new_team(thread, (addr_t)entry, 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->SetName(parentTeam->Name());
team->SetArgs(parentTeam->Args()); team->SetArgs(parentTeam->Args());
team->commpage_address = parentTeam->commpage_address;
// Inherit the parent's user/group. // Inherit the parent's user/group.
inherit_parent_user_and_group(team, parentTeam); inherit_parent_user_and_group(team, parentTeam);
+5 -1
View File
@@ -24,6 +24,8 @@ struct rld_export *__gRuntimeLoader = NULL;
// This little bugger is set to something meaningful by the runtime loader // This little bugger is set to something meaningful by the runtime loader
// Ugly, eh? // Ugly, eh?
const void* __gCommPageAddress;
char *__progname = NULL; char *__progname = NULL;
int __libc_argc; int __libc_argc;
char **__libc_argv; char **__libc_argv;
@@ -44,6 +46,8 @@ void
initialize_before(image_id imageID) initialize_before(image_id imageID)
{ {
char *programPath = __gRuntimeLoader->program_args->args[0]; char *programPath = __gRuntimeLoader->program_args->args[0];
__gCommPageAddress = __gRuntimeLoader->commpage_address;
if (programPath) { if (programPath) {
if ((__progname = strrchr(programPath, '/')) == NULL) if ((__progname = strrchr(programPath, '/')) == NULL)
__progname = programPath; __progname = programPath;
@@ -62,7 +66,7 @@ initialize_before(image_id imageID)
pthread_self()->id = find_thread(NULL); pthread_self()->id = find_thread(NULL);
__init_time(); __init_time((addr_t)__gCommPageAddress);
__init_heap(); __init_heap();
__init_env(__gRuntimeLoader->program_args); __init_env(__gRuntimeLoader->program_args);
__init_heap_post_env(); __init_heap_post_env();
+7 -5
View File
@@ -17,11 +17,13 @@
#include <asm_defs.h> #include <asm_defs.h>
#include <commpage_defs.h> #include <commpage_defs.h>
#define _SYSCALL(name, n) \ #define _SYSCALL(name, n) \
.align 8; \ .align 8; \
FUNCTION(name): \ FUNCTION(name): \
movl $n,%eax; \ movl $n, %eax; \
jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_SYSCALL * 4); \ movl __gCommPageAddress, %edx; \
addl 4 * COMMPAGE_ENTRY_X86_SYSCALL(%edx), %edx; \
jmp %edx; \
FUNCTION_END(name) FUNCTION_END(name)
#define SYSCALL0(name, n) _SYSCALL(name, n) #define SYSCALL0(name, n) _SYSCALL(name, n)
+3 -2
View File
@@ -24,10 +24,11 @@ static struct real_time_data* sRealTimeData;
void void
__init_time(void) __init_time(addr_t commPageTable)
{ {
sRealTimeData = (struct real_time_data*) 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); __arch_init_time(sRealTimeData, false);
} }
@@ -10,9 +10,13 @@
.align 4 .align 4
FUNCTION(memcpy): 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_END(memcpy)
FUNCTION(memset): 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) FUNCTION_END(memset)
@@ -8,10 +8,15 @@
FUNCTION(memcpy): 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_END(memcpy)
FUNCTION(memset): 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) FUNCTION_END(memset)
+1
View File
@@ -65,4 +65,5 @@ void
rldexport_init(void) rldexport_init(void)
{ {
gRuntimeLoader.program_args = gProgramArgs; gRuntimeLoader.program_args = gProgramArgs;
gRuntimeLoader.commpage_address = __gCommPageAddress;
} }
+3 -1
View File
@@ -22,6 +22,7 @@
struct user_space_program_args *gProgramArgs; struct user_space_program_args *gProgramArgs;
void *__gCommPageAddress;
static const char * static const char *
@@ -366,12 +367,13 @@ out:
specified by its ld-script. specified by its ld-script.
*/ */
int int
runtime_loader(void *_args) runtime_loader(void* _args, void* commpage)
{ {
void *entry = NULL; void *entry = NULL;
int returnCode; int returnCode;
gProgramArgs = (struct user_space_program_args *)_args; gProgramArgs = (struct user_space_program_args *)_args;
__gCommPageAddress = commpage;
// Relocate the args and env arrays -- they are organized in a contiguous // Relocate the args and env arrays -- they are organized in a contiguous
// buffer which the kernel just copied into user space without adjusting the // buffer which the kernel just copied into user space without adjusting the
@@ -43,6 +43,7 @@ struct SymbolLookupCache;
extern struct user_space_program_args* gProgramArgs; extern struct user_space_program_args* gProgramArgs;
extern void* __gCommPageAddress;
extern struct rld_export gRuntimeLoader; extern struct rld_export gRuntimeLoader;
extern char* (*gGetEnv)(const char* name); extern char* (*gGetEnv)(const char* name);
extern bool gProgramLoaded; extern bool gProgramLoaded;
@@ -53,7 +54,7 @@ extern image_t* gProgramImage;
extern "C" { extern "C" {
#endif #endif
int runtime_loader(void* arg); int runtime_loader(void* arg, void* commpage);
int open_executable(char* name, image_type type, const char* rpath, int open_executable(char* name, image_type type, const char* rpath,
const char* programPath, const char* compatibilitySubDir); const char* programPath, const char* compatibilitySubDir);
status_t test_executable(const char* path, char* interpreter); status_t test_executable(const char* path, char* interpreter);