Fixing/implementing static TLS entries.

This commit is contained in:
Ben Vanik 2013-05-31 10:01:32 -07:00
parent 38efd3837d
commit d53458023e
4 changed files with 40 additions and 7 deletions

View File

@ -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) {

View File

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

View File

@ -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); // ?

View File

@ -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_;
};