From e955705ad7e5f59cdad456d0bd6680083d03758f Mon Sep 17 00:00:00 2001 From: Erik Abair Date: Sun, 2 Jul 2023 10:43:25 -0700 Subject: [PATCH] cxbe: Populate debug path header fields --- tools/cxbe/Exe.h | 2 ++ tools/cxbe/Main.cpp | 16 ++++++++-------- tools/cxbe/Xbe.cpp | 44 +++++++++++++++++++++++++++++++++++--------- tools/cxbe/Xbe.h | 3 +-- 4 files changed, 46 insertions(+), 19 deletions(-) diff --git a/tools/cxbe/Exe.h b/tools/cxbe/Exe.h index 1d2bff887..d1adcaff5 100644 --- a/tools/cxbe/Exe.h +++ b/tools/cxbe/Exe.h @@ -7,6 +7,8 @@ #ifndef EXE_H #define EXE_H +#include + #include "Error.h" typedef struct IMAGE_IMPORT_DESCRIPTOR diff --git a/tools/cxbe/Main.cpp b/tools/cxbe/Main.cpp index 179c63413..d24b5d12d 100644 --- a/tools/cxbe/Main.cpp +++ b/tools/cxbe/Main.cpp @@ -21,17 +21,17 @@ int main(int argc, char *argv[]) char szXbeTitle[OPTION_LEN + 1] = "Untitled"; char szMode[OPTION_LEN + 1] = "retail"; char szLogo[OPTION_LEN + 1] = ""; + char szDebugPath[OPTION_LEN + 1] = ""; bool bRetail; const char *program = argv[0]; const char *program_desc = "CXBE EXE to XBE (win32 to Xbox) Relinker (Version: " VERSION ")"; - Option options[] = { { szExeFilename, NULL, "exefile" }, - { szXbeFilename, "OUT", "filename" }, - { szDumpFilename, "DUMPINFO", "filename" }, - { szXbeTitle, "TITLE", "title" }, - { szMode, "MODE", "{debug|retail}" }, - { szLogo, "LOGO", "filename" }, - { NULL } }; + Option options[] = { + { szExeFilename, NULL, "exefile" }, { szXbeFilename, "OUT", "filename" }, + { szDumpFilename, "DUMPINFO", "filename" }, { szXbeTitle, "TITLE", "title" }, + { szMode, "MODE", "{debug|retail}" }, { szLogo, "LOGO", "filename" }, + { szDebugPath, "DEBUGPATH", "path" }, { NULL } + }; if(ParseOptions(argv, argc, options, szErrorMessage)) { @@ -90,7 +90,7 @@ int main(int argc, char *argv[]) LogoPtr = &logo; } - Xbe *XbeFile = new Xbe(ExeFile, szXbeTitle, bRetail, LogoPtr); + Xbe *XbeFile = new Xbe(ExeFile, szXbeTitle, bRetail, LogoPtr, szDebugPath); if(XbeFile->GetError() != 0) { diff --git a/tools/cxbe/Xbe.cpp b/tools/cxbe/Xbe.cpp index 33e3b52a9..b02b9996a 100644 --- a/tools/cxbe/Xbe.cpp +++ b/tools/cxbe/Xbe.cpp @@ -20,8 +20,20 @@ static const char kKernelImageName[] = "xboxkrnl.exe"; static uint32 CountNonKernelImportTableEntries(class Exe *x_Exe, uint32_t *extra_bytes); +static size_t BasenameOffset(const std::string &path) +{ + size_t sep_offset = path.find_last_of("/\\"); + if(sep_offset == std::string::npos) + { + return 0; + } + + return sep_offset + 1; +} + // construct via Exe file object -Xbe::Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail, const std::vector *logo) +Xbe::Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail, const std::vector *logo, + const char *x_szDebugPath) { ConstructorInit(); @@ -30,6 +42,7 @@ Xbe::Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail, const std::vec time(&CurrentTime); printf("Xbe::Xbe: Pass 1 (Simple Pass)..."); + std::string debug_path = x_szDebugPath; // pass 1 { @@ -159,12 +172,17 @@ Xbe::Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail, const std::vec // make room for debug path / debug file names { - // TODO: allow this to be configured, right now we will just null out these values + uint32 path_bytes = debug_path.size() + 1; + size_t sep_offset = BasenameOffset(debug_path); + uint32 filename_bytes = path_bytes - sep_offset; + + mrc = RoundUp(mrc, 0x04); m_Header.dwDebugUnicodeFilenameAddr = mrc; - m_Header.dwDebugPathnameAddr = mrc; - m_Header.dwDebugFilenameAddr = mrc; + mrc = RoundUp(mrc + filename_bytes * 2, 0x04); - mrc += 2; + m_Header.dwDebugPathnameAddr = mrc; + m_Header.dwDebugFilenameAddr = m_Header.dwDebugPathnameAddr + sep_offset; + mrc += path_bytes; } // make room for largest possible logo bitmap @@ -238,6 +256,7 @@ Xbe::Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail, const std::vec uint32 ExSize = RoundUp(m_Header.dwSizeofHeaders - sizeof(m_Header), 0x1000); m_HeaderEx = new char[ExSize]; + memset(m_HeaderEx, 0, ExSize); printf("OK\n"); } @@ -478,10 +497,17 @@ Xbe::Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail, const std::vec // write debug path / debug file names { - *(uint16 *)szBuffer = 0x0000; + uint08 *debug_path_field = GetAddr(m_Header.dwDebugPathnameAddr); + uint32 path_size_with_terminator = debug_path.size() + 1; + memcpy(debug_path_field, debug_path.c_str(), path_size_with_terminator); - szBuffer += 2; - hwc += 2; + uint08 *unicode_filename = GetAddr(m_Header.dwDebugUnicodeFilenameAddr); + uint08 *filename = GetAddr(m_Header.dwDebugFilenameAddr); + do + { + *unicode_filename++ = *filename++; + *unicode_filename++ = 0; + } while(*filename); } { @@ -894,7 +920,7 @@ void Xbe::DumpInformation(FILE *x_file) fprintf(x_file, "\n"); } - char AsciiFilename[40]; + char AsciiFilename[40] = { 0 }; setlocale(LC_ALL, "English"); diff --git a/tools/cxbe/Xbe.h b/tools/cxbe/Xbe.h index 9706e0532..fe685a0fb 100644 --- a/tools/cxbe/Xbe.h +++ b/tools/cxbe/Xbe.h @@ -27,11 +27,10 @@ class Xbe : public Error public: // construct via Exe file object Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail, - const std::vector *logo = nullptr); + const std::vector *logo = nullptr, const char *x_szDebugPath = nullptr); // deconstructor ~Xbe(); - // export to Xbe file void Export(const char *x_szXbeFilename);