Xbe Loading Improvements
- Rather than copying the entire Xbe into the xbox address space, we copy only the header - Only sections marked as 'preload' are loaded at boot time - All other sections are loaded/unloaded on demand by the running title, via calls to XLoadSecton/XUnloadSection - Fixed an off-by-one error in Xbe section name parsing - Fix an incorrect assumption that section names are always 8 characters null-terminated. They are 9 characters, null padded
This commit is contained in:
parent
853eea7bdb
commit
4b35db183c
|
@ -187,18 +187,18 @@ Xbe::Xbe(const char *x_szFilename)
|
|||
{
|
||||
printf("Xbe::Xbe: Reading Section Names...\n");
|
||||
|
||||
m_szSectionName = new char[m_Header.dwSections][9];
|
||||
m_szSectionName = new char[m_Header.dwSections][10];
|
||||
for(uint32 v=0;v<m_Header.dwSections;v++)
|
||||
{
|
||||
printf("Xbe::Xbe: Reading Section Name 0x%.04X...", v);
|
||||
|
||||
uint08 *sn = GetAddr(m_SectionHeader[v].dwSectionNameAddr);
|
||||
|
||||
memset(m_szSectionName[v], 0, 9);
|
||||
memset(m_szSectionName[v], 0, 10);
|
||||
|
||||
if(sn != 0)
|
||||
{
|
||||
for(int b=0;b<8;b++)
|
||||
for(int b=0;b<9;b++)
|
||||
{
|
||||
m_szSectionName[v][b] = sn[b];
|
||||
|
||||
|
|
|
@ -222,8 +222,8 @@ class Xbe : public Error
|
|||
#include "AlignPosfix1.h"
|
||||
*m_TLS;
|
||||
|
||||
// Xbe section names, each 8 bytes max and null terminated
|
||||
char (*m_szSectionName)[9];
|
||||
// Xbe section names, stored null terminated
|
||||
char (*m_szSectionName)[10];
|
||||
|
||||
// Xbe sections
|
||||
uint08 **m_bzSection;
|
||||
|
@ -360,4 +360,11 @@ const uint32 XBEIMAGE_MEDIA_TYPE_NONSECURE_HARD_DISK = 0x40000000;
|
|||
const uint32 XBEIMAGE_MEDIA_TYPE_NONSECURE_MODE = 0x80000000;
|
||||
const uint32 XBEIMAGE_MEDIA_TYPE_MEDIA_MASK = 0x00FFFFFF;
|
||||
|
||||
// section type flags for Xbe
|
||||
const uint32 XBEIMAGE_SECTION_WRITEABLE = 0x00000001;
|
||||
const uint32 XBEIMAGE_SECTION_PRELOAD = 0x00000002;
|
||||
const uint32 XBEIMAGE_SECTION_EXECUTABLE = 0x00000004;
|
||||
const uint32 XBEIMAGE_SECTION_INSERTFILE = 0x00000008;
|
||||
const uint32 XBEIMAGE_SECTION_HEAD_PAGE_READONLY = 0x00000010;
|
||||
const uint32 XBEIMAGE_SECTION_TAIL_PAGE_READONLY = 0x00000020;
|
||||
#endif
|
||||
|
|
|
@ -177,7 +177,6 @@ void CxbxLaunchXbe(void(*Entry)())
|
|||
__try
|
||||
{
|
||||
Entry();
|
||||
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
|
@ -503,29 +502,18 @@ void CxbxKrnlMain(int argc, char* argv[])
|
|||
// Determine memory size accordingly :
|
||||
SIZE_T memorySize = (g_bIsChihiro ? CHIHIRO_MEMORY_SIZE : XBOX_MEMORY_SIZE);
|
||||
|
||||
// Copy over loaded Xbe Header to specified base address
|
||||
// Copy over loaded Xbe Headers to specified base address
|
||||
memcpy((void*)CxbxKrnl_Xbe->m_Header.dwBaseAddr, &CxbxKrnl_Xbe->m_Header, sizeof(Xbe::Header));
|
||||
// Copy over the certificate
|
||||
memcpy((void*)(CxbxKrnl_Xbe->m_Header.dwBaseAddr + sizeof(Xbe::Header)), CxbxKrnl_Xbe->m_HeaderEx, CxbxKrnl_Xbe->m_ExSize);
|
||||
// Copy over the library versions
|
||||
memcpy((void*)CxbxKrnl_Xbe->m_Header.dwLibraryVersionsAddr, CxbxKrnl_Xbe->m_LibraryVersion, CxbxKrnl_Xbe->m_Header.dwLibraryVersions * sizeof(DWORD));
|
||||
// TODO : Actually, instead of copying from CxbxKrnl_Xbe, we should load the entire Xbe directly into memory, like Dxbx does - see _ReadXbeBlock()
|
||||
|
||||
// Verify no section would load outside virtual_memory_placeholder (which would overwrite Cxbx code)
|
||||
// Load all sections marked as preload using the in-memory copy of the xbe header
|
||||
xboxkrnl::PXBEIMAGE_SECTION sectionHeaders = (xboxkrnl::PXBEIMAGE_SECTION)CxbxKrnl_Xbe->m_Header.dwSectionHeadersAddr;
|
||||
for (uint32 i = 0; i < CxbxKrnl_Xbe->m_Header.dwSections; i++) {
|
||||
xbaddr section_end = CxbxKrnl_Xbe->m_SectionHeader[i].dwVirtualAddr + CxbxKrnl_Xbe->m_SectionHeader[i].dwSizeofRaw;
|
||||
if (section_end >= XBE_MAX_VA)
|
||||
{
|
||||
CxbxPopupMessage("Couldn't load XBE section - please report this!");
|
||||
return; // TODO : Halt(0);
|
||||
if ((sectionHeaders[i].Flags & XBEIMAGE_SECTION_PRELOAD) != 0) {
|
||||
xboxkrnl::XeLoadSection(§ionHeaders[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Load all sections to their requested Virtual Address :
|
||||
for (uint32 i = 0; i < CxbxKrnl_Xbe->m_Header.dwSections; i++) {
|
||||
memcpy((void*)CxbxKrnl_Xbe->m_SectionHeader[i].dwVirtualAddr, CxbxKrnl_Xbe->m_bzSection[i], CxbxKrnl_Xbe->m_SectionHeader[i].dwSizeofRaw);
|
||||
}
|
||||
|
||||
// We need to remember a few XbeHeader fields, so we can switch between a valid ExeHeader and XbeHeader :
|
||||
StoreXbeImageHeader();
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#define CXBXKRNL_H
|
||||
|
||||
#include "Cxbx.h"
|
||||
|
||||
#include "Common/Xbe.h"
|
||||
|
||||
#undef FIELD_OFFSET // prevent macro redefinition warnings
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace xboxkrnl
|
|||
#include <xboxkrnl/xboxkrnl.h> // For XeImageFileName, etc.
|
||||
};
|
||||
|
||||
#include "CxbxKrnl.h" // For CxbxKrnl_Xbe
|
||||
#include "Logging.h" // For LOG_FUNC()
|
||||
#include "EmuKrnlLogging.h"
|
||||
#include "Emu.h" // For EmuWarning()
|
||||
|
@ -76,12 +77,24 @@ XBSYSAPI EXPORTNUM(327) xboxkrnl::NTSTATUS NTAPI xboxkrnl::XeLoadSection
|
|||
LOG_FUNC_ARG(Section)
|
||||
LOG_FUNC_END;
|
||||
|
||||
NTSTATUS ret = STATUS_SUCCESS;
|
||||
NTSTATUS ret = STATUS_INVALID_HANDLE;
|
||||
|
||||
if (Section->SectionReferenceCount++ == 0) {
|
||||
LOG_INCOMPLETE(); // TODO : Load section - probably lock this too
|
||||
void* sectionData = CxbxKrnl_Xbe->FindSection((char*)std::string(Section->SectionName, 9).c_str());
|
||||
if (sectionData != nullptr) {
|
||||
// If the reference count was zero, load the section
|
||||
if (Section->SectionReferenceCount == 0) {
|
||||
// Clear the memory the section requires
|
||||
memset(Section->VirtualAddress, 0, Section->VirtualSize);
|
||||
// Copy the section data
|
||||
memcpy(Section->VirtualAddress, sectionData, Section->FileSize);
|
||||
}
|
||||
|
||||
// Increment the reference count
|
||||
Section->SectionReferenceCount++;
|
||||
|
||||
ret = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
||||
|
@ -101,15 +114,18 @@ XBSYSAPI EXPORTNUM(328) xboxkrnl::NTSTATUS NTAPI xboxkrnl::XeUnloadSection
|
|||
LOG_FUNC_ARG(Section)
|
||||
LOG_FUNC_END;
|
||||
|
||||
NTSTATUS ret = STATUS_SUCCESS;
|
||||
NTSTATUS ret = STATUS_INVALID_PARAMETER;
|
||||
|
||||
// If the section was loaded, process it
|
||||
if (Section->SectionReferenceCount > 0) {
|
||||
if (--Section->SectionReferenceCount == 0) {
|
||||
LOG_INCOMPLETE(); // TODO : Unload section - probably lock this too
|
||||
// Decrement the reference count
|
||||
Section->SectionReferenceCount -= 1;
|
||||
|
||||
// Free the section if necessary
|
||||
if (Section->SectionReferenceCount == 0) {
|
||||
memset(Section->VirtualAddress, 0, Section->VirtualSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = STATUS_INVALID_PARAMETER;
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue