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;
|
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,
|
uint32_t xe_memory_search_aligned(xe_memory_ref memory, size_t start,
|
||||||
size_t end, const uint32_t *values,
|
size_t end, const uint32_t *values,
|
||||||
const size_t value_count) {
|
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);
|
size_t xe_memory_get_length(xe_memory_ref memory);
|
||||||
uint8_t *xe_memory_addr(xe_memory_ref memory, size_t guest_addr = 0);
|
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,
|
uint32_t xe_memory_search_aligned(xe_memory_ref memory, size_t start,
|
||||||
size_t end, const uint32_t *values,
|
size_t end, const uint32_t *values,
|
||||||
const size_t value_count);
|
const size_t value_count);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
||||||
|
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/objects/xmodule.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
using namespace xe::kernel;
|
using namespace xe::kernel;
|
||||||
|
@ -48,6 +50,9 @@ XThread::~XThread() {
|
||||||
if (processor_state_) {
|
if (processor_state_) {
|
||||||
kernel_state()->processor()->DeallocThread(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_) {
|
if (thread_state_address_) {
|
||||||
xe_memory_heap_free(kernel_state()->memory(), thread_state_address_, 0);
|
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.
|
// (like GetLastError/etc) will poke it directly.
|
||||||
// We try to use it as our primary store of data just to keep things all
|
// We try to use it as our primary store of data just to keep things all
|
||||||
// consistent.
|
// consistent.
|
||||||
thread_state_address_ = xe_memory_heap_alloc(memory(), 0, 2048, 0);
|
// 0x000: pointer to tls data
|
||||||
if (!thread_state_address_) {
|
|
||||||
XELOGW("Unable to allocate thread state block");
|
|
||||||
return X_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup the thread state block (last error/etc).
|
|
||||||
// 0x100: pointer to self?
|
// 0x100: pointer to self?
|
||||||
// 0x14C: thread id
|
// 0x14C: thread id
|
||||||
// 0x150: if >0 then error states don't get set
|
// 0x150: if >0 then error states don't get set
|
||||||
// 0x160: last error
|
// 0x160: last error
|
||||||
// So, at offset 0x100 we have a 4b pointer to offset 200, then have the
|
// So, at offset 0x100 we have a 4b pointer to offset 200, then have the
|
||||||
// structure.
|
// 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_);
|
uint8_t *p = xe_memory_addr(memory(), thread_state_address_);
|
||||||
|
XESETUINT32BE(p + 0x000, tls_address_);
|
||||||
XESETUINT32BE(p + 0x100, thread_state_address_);
|
XESETUINT32BE(p + 0x100, thread_state_address_);
|
||||||
XESETUINT32BE(p + 0x14C, thread_id_);
|
XESETUINT32BE(p + 0x14C, thread_id_);
|
||||||
XESETUINT32BE(p + 0x150, 0); // ?
|
XESETUINT32BE(p + 0x150, 0); // ?
|
||||||
|
|
|
@ -55,6 +55,7 @@ private:
|
||||||
|
|
||||||
uint32_t thread_id_;
|
uint32_t thread_id_;
|
||||||
void* thread_handle_;
|
void* thread_handle_;
|
||||||
|
uint32_t tls_address_;
|
||||||
uint32_t thread_state_address_;
|
uint32_t thread_state_address_;
|
||||||
cpu::ThreadState* processor_state_;
|
cpu::ThreadState* processor_state_;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue