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:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -65,4 +65,5 @@ void
|
|||||||
rldexport_init(void)
|
rldexport_init(void)
|
||||||
{
|
{
|
||||||
gRuntimeLoader.program_args = gProgramArgs;
|
gRuntimeLoader.program_args = gProgramArgs;
|
||||||
|
gRuntimeLoader.commpage_address = __gCommPageAddress;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user