Fixing/implementing static TLS entries.
This commit is contained in:
parent
38efd3837d
commit
d53458023e
|
@ -163,6 +163,13 @@ uint8_t *xe_memory_addr(xe_memory_ref memory, size_t guest_addr) {
|
|||
return (uint8_t*)memory->ptr + guest_addr;
|
||||
}
|
||||
|
||||
void xe_memory_copy(xe_memory_ref memory,
|
||||
uint32_t dest, uint32_t src, uint32_t size) {
|
||||
uint8_t* pdest = (uint8_t*)memory->ptr + dest;
|
||||
uint8_t* psrc = (uint8_t*)memory->ptr + src;
|
||||
XEIGNORE(xe_copy_memory(pdest, size, psrc, size));
|
||||
}
|
||||
|
||||
uint32_t xe_memory_search_aligned(xe_memory_ref memory, size_t start,
|
||||
size_t end, const uint32_t *values,
|
||||
const size_t value_count) {
|
||||
|
|
|
@ -30,6 +30,9 @@ void xe_memory_release(xe_memory_ref memory);
|
|||
size_t xe_memory_get_length(xe_memory_ref memory);
|
||||
uint8_t *xe_memory_addr(xe_memory_ref memory, size_t guest_addr = 0);
|
||||
|
||||
void xe_memory_copy(xe_memory_ref memory,
|
||||
uint32_t dest, uint32_t src, uint32_t size);
|
||||
|
||||
uint32_t xe_memory_search_aligned(xe_memory_ref memory, size_t start,
|
||||
size_t end, const uint32_t *values,
|
||||
const size_t value_count);
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/objects/xmodule.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
@ -48,6 +50,9 @@ XThread::~XThread() {
|
|||
if (processor_state_) {
|
||||
kernel_state()->processor()->DeallocThread(processor_state_);
|
||||
}
|
||||
if (tls_address_) {
|
||||
xe_memory_heap_free(kernel_state()->memory(), tls_address_, 0);
|
||||
}
|
||||
if (thread_state_address_) {
|
||||
xe_memory_heap_free(kernel_state()->memory(), thread_state_address_, 0);
|
||||
}
|
||||
|
@ -82,20 +87,37 @@ X_STATUS XThread::Create() {
|
|||
// (like GetLastError/etc) will poke it directly.
|
||||
// We try to use it as our primary store of data just to keep things all
|
||||
// consistent.
|
||||
thread_state_address_ = xe_memory_heap_alloc(memory(), 0, 2048, 0);
|
||||
if (!thread_state_address_) {
|
||||
XELOGW("Unable to allocate thread state block");
|
||||
return X_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
// Setup the thread state block (last error/etc).
|
||||
// 0x000: pointer to tls data
|
||||
// 0x100: pointer to self?
|
||||
// 0x14C: thread id
|
||||
// 0x150: if >0 then error states don't get set
|
||||
// 0x160: last error
|
||||
// So, at offset 0x100 we have a 4b pointer to offset 200, then have the
|
||||
// structure.
|
||||
thread_state_address_ = xe_memory_heap_alloc(memory(), 0, 2048, 0);
|
||||
if (!thread_state_address_) {
|
||||
XELOGW("Unable to allocate thread state block");
|
||||
return X_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
// Allocate TLS block.
|
||||
XModule* module = kernel_state()->GetExecutableModule();
|
||||
const xe_xex2_header_t* header = module->xex_header();
|
||||
uint32_t tls_size = header->tls_info.slot_count * header->tls_info.data_size;
|
||||
tls_address_ = xe_memory_heap_alloc(memory(), 0, tls_size, 0);
|
||||
if (!tls_address_) {
|
||||
XELOGW("Unable to allocate thread local storage block");
|
||||
return X_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
// Copy in default TLS info.
|
||||
// TODO(benvanik): is this correct?
|
||||
xe_memory_copy(memory(),
|
||||
tls_address_, header->tls_info.raw_data_address, tls_size);
|
||||
|
||||
// Setup the thread state block (last error/etc).
|
||||
uint8_t *p = xe_memory_addr(memory(), thread_state_address_);
|
||||
XESETUINT32BE(p + 0x000, tls_address_);
|
||||
XESETUINT32BE(p + 0x100, thread_state_address_);
|
||||
XESETUINT32BE(p + 0x14C, thread_id_);
|
||||
XESETUINT32BE(p + 0x150, 0); // ?
|
||||
|
|
|
@ -55,6 +55,7 @@ private:
|
|||
|
||||
uint32_t thread_id_;
|
||||
void* thread_handle_;
|
||||
uint32_t tls_address_;
|
||||
uint32_t thread_state_address_;
|
||||
cpu::ThreadState* processor_state_;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue