diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..62bc968 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,93 @@ +name: Build + +on: + push: + branches: + - main + paths-ignore: + - '.github/**' + - '!.github/workflows/**' + - 'README.md' + pull_request: + paths-ignore: + - '.github/**' + - '!.github/workflows/**' + - 'README.md' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref }} + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} + +jobs: + BuildLinux: + name: Build Linux + runs-on: ubuntu-latest + steps: + - name: Clone tree + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + cmake \ + libboost-all-dev \ + llvm + - name: Compile + run: | + cmake -B build -DCMAKE_BUILD_TYPE=Release + cmake --build build -- -j$(grep -c processor /proc/cpuinfo) + - name: Test + run: | + ctest --test-dir build --output-on-failure + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: xbox_bios_tool_linux + path: build/xbox_bios_tool + + BuildMacOS: + name: Build macOS + runs-on: macOS-latest + steps: + - name: Clone tree + uses: actions/checkout@v4 + - name: Install dependencies + run: | + export HOMEBREW_NO_AUTO_UPDATE=1 + export HOMEBREW_NO_INSTALL_CLEANUP=1 + brew install \ + cmake \ + coreutils \ + boost \ + llvm + - name: Compile + run: | + export PATH="$(brew --prefix llvm@18)/bin:$PATH" + cmake -B build -DCMAKE_BUILD_TYPE=Release + cmake --build build -- -j + - name: Test + run: | + ctest --test-dir build --output-on-failure + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: xbox_bios_tool_macos + path: build/xbox_bios_tool + + BuildWindows: + runs-on: windows-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v2.0.0 + - name: Build solution + run: msbuild vc/XboxBiosTools.sln /p:Configuration=Release + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: xbox_bios_tool_win64 + path: | + bin diff --git a/.gitignore b/.gitignore index 89e1221..78111eb 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,7 @@ obj/ XbBiosTool.vcxproj.filters XbBiosTool.vcxproj.user /tests/xcodes_no_branching.txt +.idea/ + +cmake-build-debug/ +cmake-build-release/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0aba5f3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 3.30) + +project(XboxBiosTool) + +set(CMAKE_VERBOSE_MAKEFILE TRUE) + +set(CMAKE_CXX_STANDARD 17) +include(CMakePushCheckState) +set(_CMAKE_PROCESSING_LANGUAGE "C") +include(CheckSymbolExists) +include (ExternalProject) +include(FindPkgConfig) + +add_library( + compressor_lib + src/lzx_decoder.c + src/lzx_encoder.c +) + +target_include_directories( + compressor_lib + PUBLIC + inc +) + +target_compile_options( + compressor_lib + PRIVATE + -Wstrict-aliasing +) + +add_executable( + xbox_bios_tool + src/Bios.cpp + src/Mcpx.c + src/XbTool.cpp + src/XcodeDecoder.cpp + src/XcodeInterp.cpp + src/cli_tbl.cpp + src/file.c + src/loadini.c + src/mem_tracking.cpp + src/nt_headers.c + src/rc4.c + src/rsa.c + src/sha1.c + src/str_util.c + src/tea.c + src/util.c + inc/posix_shims.h +) + +target_include_directories( + xbox_bios_tool + PRIVATE + inc +) + +target_compile_definitions( + xbox_bios_tool + PUBLIC + -D __STDC_WANT_LIB_EXT1__=1 +) + +target_link_libraries( + xbox_bios_tool + PRIVATE + compressor_lib +) + +target_compile_options( + xbox_bios_tool + PRIVATE + -Wstrict-aliasing +) + +add_subdirectory(tests) diff --git a/README.md b/README.md index ab2ffe6..d833fb2 100644 --- a/README.md +++ b/README.md @@ -397,6 +397,7 @@ xbios.exe /replicate /binsize 512 ## Building +### Windows The project is built in Visual Studio 2022 1. Clone the repo @@ -407,6 +408,22 @@ The project is built in Visual Studio 2022 2. Open vc\XboxBiosTools.sln in visual studio and build and run +### Linux/macOS +This project is built using CMake and Clang or GCC. + + 1. Clone the repo + + ``` + git clone https://github.com/tommojphillips/XboxBiosTool.git + ``` + + 2. Inside the cloned workspace: + + ``` + cmake -B build -DCMAKE_BUILD_TYPE=Release + cmake --build build + ``` + ## Credits / Resources - [Xbox Dev Wiki](https://xboxdevwiki.net/Main_Page) diff --git a/inc/XcodeDecoder.h b/inc/XcodeDecoder.h index f2d56d9..6e1a102 100644 --- a/inc/XcodeDecoder.h +++ b/inc/XcodeDecoder.h @@ -121,7 +121,7 @@ class XcodeDecoder private: int loadSettings(const char* ini, DECODE_SETTINGS* settings) const; - int getCommentStr(char* str); + int getCommentStr(char* str, size_t buf_size); }; #endif // !XCODE_DECODER_H diff --git a/inc/lzx.h b/inc/lzx.h index eee336d..dc219df 100644 --- a/inc/lzx.h +++ b/inc/lzx.h @@ -22,6 +22,10 @@ #ifndef LZX_H #define LZX_H +#ifdef __cplusplus +extern "C" { +#endif + // std incl #include #include @@ -66,16 +70,16 @@ typedef struct { uint32_t window_size; uint32_t window_mask; uint32_t last_matchpos_offset[LZX_NUM_REPEATED_OFFSETS]; - short main_tree_table[1 << MAIN_TREE_TABLE_BITS]; - short secondary_len_tree_table[1 << SECONDARY_LEN_TREE_TABLE_BITS]; + int16_t main_tree_table[1 << MAIN_TREE_TABLE_BITS]; + int16_t secondary_len_tree_table[1 << SECONDARY_LEN_TREE_TABLE_BITS]; uint8_t main_tree_len[LZX_MAX_MAIN_TREE_ELEMENTS]; uint8_t secondary_len_tree_len[LZX_NUM_SECONDARY_LEN]; uint8_t pad1[2]; uint8_t num_position_slots; char aligned_table[1 << LZX_ALIGNED_TABLE_BITS]; uint8_t aligned_len[LZX_ALIGNED_NUM_ELEMENTS]; - short main_tree_left_right[LZX_MAX_MAIN_TREE_ELEMENTS * 4]; - short secondary_len_tree_left_right[LZX_NUM_SECONDARY_LEN * 4]; + int16_t main_tree_left_right[LZX_MAX_MAIN_TREE_ELEMENTS * 4]; + int16_t secondary_len_tree_left_right[LZX_NUM_SECONDARY_LEN * 4]; const uint8_t* input_curpos; const uint8_t* end_input_pos; uint8_t* output_buffer; @@ -111,11 +115,11 @@ typedef struct { uint32_t* left; uint32_t* right; uint32_t bitbuf; - char bitcount; - char depth; + uint8_t bitcount; + uint8_t depth; bool output_overflow; uint32_t literals; - uint32_t distances; + int32_t distances; uint32_t* dist_data; uint8_t* lit_data; uint8_t* item_type; @@ -140,15 +144,15 @@ typedef struct { uint32_t earliest_window_data_remaining; uint32_t bufpos_at_last_block; uint8_t* input_ptr; - long input_left; + uint32_t input_left; uint32_t instr_pos; uint16_t* tree_freq; uint16_t* tree_sortptr; uint8_t* len; - short tree_heap[LZX_MAX_MAIN_TREE_ELEMENTS + 2]; + uint16_t tree_heap[LZX_MAX_MAIN_TREE_ELEMENTS + 2]; uint16_t tree_leftright[2 * (2 * LZX_MAX_MAIN_TREE_ELEMENTS - 1)]; - uint16_t tree_len_cnt[17]; - short tree_heapsize; + int16_t tree_len_cnt[17]; + uint16_t tree_heapsize; int tree_n; uint32_t next_tree_create; uint32_t last_literals; @@ -176,10 +180,6 @@ typedef struct { uint32_t output_buffer_block_count; } ENCODER_CONTEXT; -#ifdef __cplusplus -extern "C" { -#endif - /* Create lzx decoder */ LZX_DECODER_CONTEXT* lzx_create_decompression(); @@ -199,7 +199,7 @@ int lzx_decompress_next_block(LZX_DECODER_CONTEXT* context, const uint8_t** src, dest_size: Output buffer size; returns the output buffer size. if output buffer is pre-allocated, this should be the size of the pre-allocated buffer. decompressed_size: Returns the decompressed size. returns 0 on SUCCESS, otherwise LZX_ERROR */ -int lzx_decompress(const uint8_t* src, const uint32_t src_size, uint8_t** dest, uint32_t* dest_size, uint32_t* decompressed_size); +int lzx_decompress(const uint8_t* src, uint32_t src_size, uint8_t** dest, uint32_t* dest_size, uint32_t* decompressed_size); /* Create lzx encoder */ ENCODER_CONTEXT* lzx_create_compression(uint8_t* dest); @@ -222,7 +222,7 @@ void lzx_flush_compression(ENCODER_CONTEXT* context); dest: Address of the output buffer. pre-allocate or null buffer compressed_size: Returns the compressed size returns 0 on SUCCESS, otherwise LZX_ERROR */ -int lzx_compress(const uint8_t* src, const uint32_t src_size, uint8_t** dest, uint32_t* compressed_size); +int lzx_compress(const uint8_t* src, uint32_t src_size, uint8_t** dest, uint32_t* compressed_size); #ifdef __cplusplus }; diff --git a/inc/posix_shims.h b/inc/posix_shims.h new file mode 100644 index 0000000..0c3e2f3 --- /dev/null +++ b/inc/posix_shims.h @@ -0,0 +1,31 @@ +#ifndef POSIX_SHIMS_H +#define POSIX_SHIMS_H + +#if !defined(_WIN32) && !defined(_WIN64) + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + static void fopen_s( + FILE** pFile, + const char *filename, + const char *mode + ) { + *pFile = fopen(filename, mode); + } + +#define strncpy_s strncpy +#define strcat_s strcat +#define strcpy_s strcpy +#define _chdir chdir + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // !defined(_WIN32) && !defined(_WIN64) + +#endif //POSIX_SHIMS_H diff --git a/inc/rc4.h b/inc/rc4.h index 2c29b08..fe11de1 100644 --- a/inc/rc4.h +++ b/inc/rc4.h @@ -22,6 +22,7 @@ #ifndef RC4_H #define RC4_H +#include #include typedef struct _RC4_CONTEXT { diff --git a/src/Bios.cpp b/src/Bios.cpp index 0f5b6a3..d43a6a1 100644 --- a/src/Bios.cpp +++ b/src/Bios.cpp @@ -1,7 +1,7 @@ // Bios.cpp: Implements functions for loading an Original Xbox BIOS file, decrypting it, and extracting the bootloader, kernel, and other data. - + /* Copyright(C) 2024 tommojphillips - * + * * This program is free software : you can redistribute it and /or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -20,11 +20,13 @@ // GitHub: https:\\github.com\tommojphillips // std incl -#include -#include -#include -#include +#include +#include +#include +#include +#if !__APPLE__ #include +#endif // user incl #include "Bios.h" @@ -71,14 +73,14 @@ int Bios::load(uint8_t* buff, const uint32_t binsize, const BIOS_LOAD_PARAMS* bi if (sbkey != NULL) { /*if we found FBL, dont mangle FBL section of 2BL.*/ if (preldr.status == PRELDR_STATUS_FOUND) { - preldrSymmetricEncDecBldr(sbkey, XB_KEY_SIZE); + preldrSymmetricEncDecBldr(sbkey, XB_KEY_SIZE); } else { symmetricEncDecBldr(sbkey, XB_KEY_SIZE); } } } - + bios_status = validateBldrBootParams(); if (bios_status != 0) { return bios_status; @@ -107,6 +109,9 @@ int Bios::build(BIOS_BUILD_PARAMS* build_params, uint32_t binsize, BIOS_LOAD_PAR bios_status = BIOS_LOAD_STATUS_FAILED; return bios_status; } + if (params.romsize != bios_params->romsize) { + printf("Adjusted rom size:\t%u kb\n", bios_params->romsize / 1024); + } if (binsize < bios_params->romsize) { binsize = bios_params->romsize; @@ -253,7 +258,7 @@ int Bios::init(uint8_t* buff, const uint32_t binsize, const BIOS_LOAD_PARAMS* bi if (bios_params != NULL) { memcpy(¶ms, bios_params, sizeof(BIOS_LOAD_PARAMS)); } - + if (buff == NULL) { data = (uint8_t*)malloc(binsize); if (data == NULL) @@ -294,13 +299,13 @@ void Bios::getOffsets() { void Bios::getOffsets2() { // calculate the pointers to the 2bl entry and keys. 2BL needs to be unencrypted for this to work. - uint32_t entry_offset = (bldr.ldr_params->bldr_entry_point & 0x0000FFFF/*- BLDR_BASE*/); + uint32_t entry_offset = (bldr.ldr_params->bldr_entry_point & 0x0000FFFF/*- BLDR_BASE*/); bldr.entry = (BLDR_ENTRY*)(bldr.data + entry_offset - sizeof(BLDR_ENTRY)); if (IN_BOUNDS(bldr.entry, bldr.data, BLDR_BLOCK_SIZE) == false) { bldr.entry = NULL; } else { - uint32_t keys_offset = (bldr.entry->keys_ptr & 0x0000FFFF/*- BLDR_RELOC*/); + uint32_t keys_offset = (bldr.entry->keys_ptr & 0x0000FFFF/*- BLDR_RELOC*/); bldr.keys = (BLDR_KEYS*)(bldr.data + keys_offset); if (IN_BOUNDS(bldr.keys, bldr.data, BLDR_BLOCK_SIZE) == false) { bldr.keys = NULL; @@ -325,11 +330,11 @@ int Bios::validateBldrBootParams() { const uint32_t kernel_size = bldr.boot_params->compressed_kernel_size; const uint32_t kernel_data_size = bldr.boot_params->uncompressed_kernel_data_size; - const uint32_t inittbl_size = bldr.boot_params->init_tbl_size; + const uint32_t inittbl_size = bldr.boot_params->init_tbl_size; const uint32_t kernel_size_valid = kernel_size >= 0 && kernel_size <= size; const uint32_t kernel_data_size_valid = kernel_data_size >= 0 && kernel_data_size <= size; const uint32_t inittbl_size_valid = inittbl_size >= 0 && inittbl_size <= size; - + return (kernel_size_valid && kernel_data_size_valid && inittbl_size_valid) ? BIOS_LOAD_STATUS_SUCCESS : BIOS_LOAD_STATUS_INVALID_BLDR; } @@ -352,7 +357,7 @@ void Bios::preldrValidateAndDecryptBldr() { preldr.status = PRELDR_STATUS_NOT_FOUND; preldr.params = (PRELDR_PARAMS*)(preldr.data); preldr.jmp_offset = preldr.params->jmp_offset + 5; // +5 bytes (opcode + offset) - + if (preldr.params->jmp_opcode != 0xE9) { return; } @@ -412,11 +417,11 @@ void Bios::preldrValidateAndDecryptBldr() { // restore 2BL loader params. // the first 16 bytes of 2BL were zeroed during the build process. - // it makes up the 2BL entry point (4 bytes), and part of the + // it makes up the 2BL entry point (4 bytes), and part of the // command line argument buffer (12 bytes) memset(bldr.data, 0, 16); bldr.ldr_params->bldr_entry_point = BLDR_BASE + entry->bldr_entry_offset; - + if (params.restore_boot_params) { // restore 2BL boot params; move the boot params 16 bytes right // this will write over the preldr nonce. @@ -469,7 +474,7 @@ void Bios::symmetricEncDecBldr(const uint8_t* key, const uint32_t len) { } printf("%s 2BL\n", bldr.encryption_state ? "Decrypting" : "Encrypting"); - + RC4_CONTEXT context = { 0 }; rc4_key(&context, key, len); rc4(&context, bldr.data, BLDR_BLOCK_SIZE); @@ -484,7 +489,7 @@ void Bios::symmetricEncDecKernel() { if (key == NULL) { if (bldr.keys == NULL) return; - + key = bldr.keys->kernel_key; if (key == NULL) return; @@ -506,7 +511,7 @@ void Bios::symmetricEncDecKernel() { } printf("%s kernel\n", kernel.encryption_state ? "Decrypting" : "Encrypting"); - + RC4_CONTEXT context = { 0 }; rc4_key(&context, key, XB_KEY_SIZE); rc4(&context, kernel.compressed_kernel_ptr, bldr.boot_params->compressed_kernel_size); @@ -527,7 +532,7 @@ int Bios::decompressKrnl() { if (kernel.img == NULL) return 1; if (lzx_decompress(kernel.compressed_kernel_ptr, bldr.boot_params->compressed_kernel_size, &kernel.img, &buffer_size, &kernel.img_size) != 0) - return 1; + return 1; return 0; } int Bios::preldrDecryptPublicKey() { @@ -547,7 +552,7 @@ int Bios::preldrDecryptPublicKey() { else { return 1; } - + RC4_CONTEXT context = { 0 }; rc4_key(&context, sbkey, 12); rc4(&context, (uint8_t*)preldr.public_key, sizeof(XB_PUBLIC_KEY)); diff --git a/src/Mcpx.c b/src/Mcpx.c index e9d5dca..b531cd2 100644 --- a/src/Mcpx.c +++ b/src/Mcpx.c @@ -21,7 +21,11 @@ // std incl #include +#if !__APPLE__ #include +#else +#include +#endif // user incl #include "Mcpx.h" diff --git a/src/XbTool.cpp b/src/XbTool.cpp index bc4fe07..07246c1 100644 --- a/src/XbTool.cpp +++ b/src/XbTool.cpp @@ -20,11 +20,21 @@ // GitHub: https:\\github.com\tommojphillips // std incl -#include -#include -#include +#include +#include +#include +#include +#if defined(_WIN32) || defined(_WIN64) #include +#else +#include +#include "posix_shims.h" +#endif +#if !__APPLE__ #include +#else +#include +#endif // user incl #include "XbTool.h" @@ -71,8 +81,8 @@ static const PARAM_TBL param_tbl[] = { { "romsize", ¶ms.romsize, SW_ROMSIZE, PARAM_TBL::INT }, { "binsize", ¶ms.binsize, SW_BINSIZE, PARAM_TBL::INT }, - { "enc-bldr", NULL, SW_ENC_BLDR, PARAM_TBL::FLAG }, - { "enc-krnl", NULL, SW_ENC_KRNL, PARAM_TBL::FLAG }, + { "enc-bldr", nullptr, SW_ENC_BLDR, PARAM_TBL::FLAG }, + { "enc-krnl", nullptr, SW_ENC_KRNL, PARAM_TBL::FLAG }, { "key-krnl", ¶ms.kernel_key_file, SW_KEY_KRNL_FILE, PARAM_TBL::STR }, { "key-bldr", ¶ms.bldr_key_file, SW_KEY_BLDR_FILE, PARAM_TBL::STR}, { "mcpx", ¶ms.mcpx_file, SW_MCPX_FILE, PARAM_TBL::STR }, @@ -83,18 +93,18 @@ static const PARAM_TBL param_tbl[] = { { "krnldata", ¶ms.kernel_data_file, SW_KRNL_DATA_FILE, PARAM_TBL::STR }, { "inittbl", ¶ms.init_tbl_file, SW_INITTBL_FILE, PARAM_TBL::STR }, - { "nv2a", NULL, SW_LS_NV2A_TBL, PARAM_TBL::FLAG }, - { "datatbl", NULL, SW_LS_DATA_TBL, PARAM_TBL::FLAG }, - { "img", NULL, SW_DUMP_KRNL, PARAM_TBL::FLAG }, + { "nv2a", nullptr, SW_LS_NV2A_TBL, PARAM_TBL::FLAG }, + { "datatbl", nullptr, SW_LS_DATA_TBL, PARAM_TBL::FLAG }, + { "img", nullptr, SW_DUMP_KRNL, PARAM_TBL::FLAG }, { "pubkey", ¶ms.public_key_file, SW_PUB_KEY_FILE, PARAM_TBL::STR }, { "certkey", ¶ms.cert_key_file, SW_CERT_KEY_FILE, PARAM_TBL::STR }, { "eepromkey", ¶ms.eeprom_key_file, SW_EEPROM_KEY_FILE, PARAM_TBL::STR }, - { "bfm", NULL, SW_BLD_BFM, PARAM_TBL::FLAG }, - { "d", NULL, SW_DMP, PARAM_TBL::FLAG }, + { "bfm", nullptr, SW_BLD_BFM, PARAM_TBL::FLAG }, + { "d", nullptr, SW_DMP, PARAM_TBL::FLAG }, { "simsize", ¶ms.simSize, SW_SIM_SIZE, PARAM_TBL::INT }, - { "nomaxsize", NULL, SW_NO_MAX_SIZE, PARAM_TBL::FLAG }, + { "nomaxsize", nullptr, SW_NO_MAX_SIZE, PARAM_TBL::FLAG }, { "bank1", ¶ms.bank_files[0], SW_BANK1_FILE, PARAM_TBL::STR }, { "bank2", ¶ms.bank_files[1], SW_BANK2_FILE, PARAM_TBL::STR }, @@ -102,15 +112,15 @@ static const PARAM_TBL param_tbl[] = { { "bank4", ¶ms.bank_files[3], SW_BANK4_FILE, PARAM_TBL::STR }, { "ini", ¶ms.settings_file, SW_INI_FILE, PARAM_TBL::STR }, - { "?", NULL, SW_HELP, PARAM_TBL::FLAG }, - { "keys", NULL, SW_KEYS, PARAM_TBL::FLAG }, + { "?", nullptr, SW_HELP, PARAM_TBL::FLAG }, + { "keys", nullptr, SW_KEYS, PARAM_TBL::FLAG }, { "base", ¶ms.base, SW_BASE, PARAM_TBL::INT }, - { "hackinittbl", NULL, SW_HACK_INITTBL, PARAM_TBL::FLAG }, - { "hacksignature", NULL, SW_HACK_SIGNATURE, PARAM_TBL::FLAG }, - { "nobootparams", NULL, SW_UPDATE_BOOT_PARAMS, PARAM_TBL::FLAG }, - { "help-all", NULL, SW_HELP_ALL, PARAM_TBL::FLAG }, - { "help-enc", NULL, SW_HELP_ENCRYPTION, PARAM_TBL::FLAG }, - { "branch", NULL, SW_BRANCH, PARAM_TBL::FLAG }, + { "hackinittbl", nullptr, SW_HACK_INITTBL, PARAM_TBL::FLAG }, + { "hacksignature", nullptr, SW_HACK_SIGNATURE, PARAM_TBL::FLAG }, + { "nobootparams", nullptr, SW_UPDATE_BOOT_PARAMS, PARAM_TBL::FLAG }, + { "help-all", nullptr, SW_HELP_ALL, PARAM_TBL::FLAG }, + { "help-enc", nullptr, SW_HELP_ENCRYPTION, PARAM_TBL::FLAG }, + { "branch", nullptr, SW_BRANCH, PARAM_TBL::FLAG }, { "dir", ¶ms.working_directory_path, SW_WORKING_DIRECTORY, PARAM_TBL::STR }, { "xcodes", ¶ms.xcodes_file, SW_XCODES, PARAM_TBL::STR }, { "offset", ¶ms.offset, SW_OFFSET, PARAM_TBL::INT }, @@ -124,7 +134,7 @@ void lzx_print_error(int error); int buildBios() { int result = 0; const char* filename = params.out_file; - + Bios bios; BIOS_LOAD_PARAMS bios_params; BIOS_BUILD_PARAMS build_params; @@ -145,22 +155,22 @@ int buildBios() { build_params.hacksignature = isFlagSet(SW_HACK_SIGNATURE); build_params.nobootparams = isFlagSet(SW_UPDATE_BOOT_PARAMS); - if (params.mcpx_file != NULL) + if (params.mcpx_file != nullptr) printf("mcpx file:\t\t%s\n", params.mcpx_file); - // init tbl file + // init tbl file printf("Init tbl file:\t\t%s\n", params.init_tbl_file); build_params.init_tbl = readFile(params.init_tbl_file, &build_params.init_tbl_size, 0); - if (build_params.init_tbl == NULL) { + if (build_params.init_tbl == nullptr) { result = 1; goto Cleanup; } // preldr file printf("Preldr file:\t\t%s\n", params.preldr_file); - if (params.preldr_file != NULL) { + if (params.preldr_file != nullptr) { build_params.preldr = readFile(params.preldr_file, &build_params.preldr_size, 0); - if (build_params.preldr == NULL) { + if (build_params.preldr == nullptr) { build_params.preldr_size = 0; } } @@ -168,7 +178,7 @@ int buildBios() { // 2bl file printf("2BL file:\t\t%s\n", params.bldr_file); build_params.bldr = readFile(params.bldr_file, &build_params.bldrSize, 0); - if (build_params.bldr == NULL) { + if (build_params.bldr == nullptr) { result = 1; goto Cleanup; } @@ -176,7 +186,7 @@ int buildBios() { // compressed krnl image printf("Kernel file:\t\t%s\n", params.kernel_file); build_params.compressed_kernel = readFile(params.kernel_file, &build_params.kernel_size, 0); - if (build_params.compressed_kernel == NULL) { + if (build_params.compressed_kernel == nullptr) { result = 1; goto Cleanup; } @@ -184,21 +194,21 @@ int buildBios() { // uncompressed kernel data printf("Kernel data file:\t%s\n", params.kernel_data_file); build_params.kernel_data = readFile(params.kernel_data_file, &build_params.kernel_data_size, 0); - if (build_params.kernel_data == NULL) { + if (build_params.kernel_data == nullptr) { result = 1; goto Cleanup; } // eeprom key - if (params.eeprom_key_file != NULL) { + if (params.eeprom_key_file != nullptr) { printf("Eeprom key file:\t\t%s\n", params.eeprom_key_file); - build_params.eeprom_key = readFile(params.eeprom_key_file, NULL, XB_KEY_SIZE); + build_params.eeprom_key = readFile(params.eeprom_key_file, nullptr, XB_KEY_SIZE); } // cert key - if (params.cert_key_file != NULL) { + if (params.cert_key_file != nullptr) { printf("Cert key file:\t\t%s\n", params.cert_key_file); - build_params.cert_key = readFile(params.cert_key_file, NULL, XB_KEY_SIZE); + build_params.cert_key = readFile(params.cert_key_file, nullptr, XB_KEY_SIZE); } printf("rom size:\t\t%u kb\n\n", params.romsize / 1024); @@ -209,13 +219,13 @@ int buildBios() { if (isFlagSet(SW_XCODES)) { uint32_t xcodesSize; uint8_t* xcodes = readFile(params.xcodes_file, &xcodesSize, 0); - if (xcodes == NULL) { + if (xcodes == nullptr) { result = 1; } else { result = inject_xcodes(bios.data, bios.size, xcodes, xcodesSize); free(xcodes); - xcodes = NULL; + xcodes = nullptr; } } @@ -224,22 +234,22 @@ int buildBios() { } else { filename = params.out_file; - if (filename == NULL) + if (filename == nullptr) filename = "bios.bin"; result = writeFileF(filename, "bios", bios.data, bios.size); } Cleanup: - + bios_free_build_params(&build_params); - + return result; } int extractBios() { // Extract components from the bios file. int result = 0; - const char* filename; + const char* filename; size_t init_tbl_size = 0; Bios bios; BIOS_LOAD_PARAMS bios_params; @@ -253,12 +263,12 @@ int extractBios() { bios_params.enc_bldr = isFlagSet(SW_ENC_BLDR); bios_params.enc_kernel = isFlagSet(SW_ENC_KRNL); bios_params.restore_boot_params = isFlagClear(SW_UPDATE_BOOT_PARAMS); - + printf("Extract BIOS\n\n"); uint32_t size = 0; uint8_t* buffer = readFile(params.in_file, &size, 0); - if (buffer == NULL) { + if (buffer == nullptr) { return 1; } @@ -267,13 +277,13 @@ int extractBios() { return 1; } - if (params.mcpx_file != NULL) + if (params.mcpx_file != nullptr) printf("mcpx file: %s\n", params.mcpx_file); printf("bios file: %s\nbios size: %d kb\nrom size: %d kb\n\n", params.in_file, size / 1024, params.romsize / 1024); result = bios.load(buffer, size, &bios_params); if (result != BIOS_LOAD_STATUS_SUCCESS) { - printf("Error: invalid 2BL\n"); + printf("Error: invalid 2BL\n"); return 1; } @@ -281,21 +291,21 @@ int extractBios() { if (isFlagSet(SW_WORKING_DIRECTORY)) { if (_chdir(params.working_directory_path) == -1) { if (errno == ENOENT) { // directory not found - printf("Error: '%s' directory not found.\n", params.working_directory_path); + printf("Error: '%s' directory not found.\n", params.working_directory_path); return 1; } } } // zero rom digest so we have a clean 2bl; - if (bios.rom_digest != NULL) { + if (bios.rom_digest != nullptr) { memset(bios.rom_digest, 0, ROM_DIGEST_SIZE); } // preldr if (bios.preldr.status < PRELDR_STATUS_NOT_FOUND) { filename = params.preldr_file; - if (filename == NULL) + if (filename == nullptr) filename = "preldr.bin"; writeFileF(filename, "preldr", bios.preldr.data, PRELDR_SIZE); @@ -307,35 +317,35 @@ int extractBios() { // 2bl filename = params.bldr_file; - if (filename == NULL) + if (filename == nullptr) filename = "bldr.bin"; writeFileF(filename, "2BL", bios.bldr.data, BLDR_BLOCK_SIZE); - + // extract init tbl init_tbl_size = bios.bldr.boot_params->init_tbl_size; if (init_tbl_size > 0) { filename = params.init_tbl_file; - if (filename == NULL) + if (filename == nullptr) filename = "inittbl.bin"; writeFileF(filename, "init table", bios.data, init_tbl_size); } // extract compressed kernel filename = params.kernel_file; - if (filename == NULL) + if (filename == nullptr) filename = "krnl.bin"; writeFileF(filename, "compressed kernel", bios.kernel.compressed_kernel_ptr, bios.bldr.boot_params->compressed_kernel_size); - + // extract uncompressed kernel section data filename = params.kernel_data_file; - if (filename == NULL) + if (filename == nullptr) filename = "krnl_data.bin"; writeFileF(filename, "kernel data", bios.kernel.uncompressed_data_ptr, bios.bldr.boot_params->uncompressed_kernel_data_size); - + // decompress the kernel now so the public key can be extracted. if (bios.decompressKrnl() == 0) { // extract decompressed kernel image ( pe/coff executable ) - if (bios.kernel.img != NULL) { + if (bios.kernel.img != nullptr) { writeFileF("krnl.img", "decompressed kernel", bios.kernel.img, bios.kernel.img_size); } } @@ -343,41 +353,41 @@ int extractBios() { if (isFlagSet(SW_KEYS)) { // 2BL rc4 keys - if (bios.bldr.keys != NULL) { - + if (bios.bldr.keys != nullptr) { + // eeprom rc4 key filename = params.eeprom_key_file; - if (filename == NULL) + if (filename == nullptr) filename = "eeprom_key.bin"; writeFileF(filename, "eeprom key", bios.bldr.keys->eeprom_key, XB_KEY_SIZE); // cert rc4 key filename = params.cert_key_file; - if (filename == NULL) + if (filename == nullptr) filename = "cert_key.bin"; writeFileF(filename, "cert key", bios.bldr.keys->cert_key, XB_KEY_SIZE); - + // kernel rc4 key writeFileF("krnl_key.bin", "kernel key", bios.bldr.keys->kernel_key, XB_KEY_SIZE); } // bfm key - if (bios.bldr.bfm_key != NULL) { + if (bios.bldr.bfm_key != nullptr) { writeFileF("bfm_key.bin", "bfm key", bios.bldr.bfm_key, XB_KEY_SIZE); } // secret boot key - if (params.mcpx.sbkey != NULL) { + if (params.mcpx.sbkey != nullptr) { writeFileF("sb_key.bin", "secret boot key", params.mcpx.sbkey, XB_KEY_SIZE); } // extract decompressed kernel rsa pub key - if (bios.kernel.img != NULL) { + if (bios.kernel.img != nullptr) { PUBLIC_KEY* pubkey; filename = params.public_key_file; - if (filename == NULL) + if (filename == nullptr) filename = "pubkey.bin"; - if (rsa_findPublicKey(bios.kernel.img, bios.kernel.img_size, &pubkey, NULL) == RSA_ERROR_SUCCESS) + if (rsa_findPublicKey(bios.kernel.img, bios.kernel.img_size, &pubkey, nullptr) == RSA_ERROR_SUCCESS) writeFileF(filename, "public key", pubkey, RSA_PUBKEY_SIZE(&pubkey->header)); } @@ -391,7 +401,7 @@ int extractBios() { } int splitBios() { int result = 0; - uint8_t* data = NULL; + uint8_t* data = nullptr; uint32_t size = 0; uint32_t fnLen = 0; uint32_t bankFnLen = 0; @@ -399,20 +409,20 @@ int splitBios() { uint32_t loopCount = 0; int bank = 0; const char suffix[] = "_bank"; - char* biosFn = NULL; - char* ext = NULL; - char* bankFn = NULL; + char* biosFn = nullptr; + char* ext = nullptr; + char* bankFn = nullptr; int i; int j; printf("Split BIOS\n\n"); - + //romsize sanity check if (params.romsize < MIN_BIOS_SIZE) return 1; - + data = readFile(params.in_file, &size, 0); - if (data == NULL) + if (data == nullptr) return 1; result = bios_check_size(size); @@ -420,7 +430,7 @@ int splitBios() { printf("Error: Invalid bios file size: %d\n", size); goto Cleanup; } - + printf("bios file: %s\nbios size: %dkb\nrom size: %dkb\n\n", params.in_file, size / 1024, params.romsize / 1024); // check if bios size is less than or equal to rom size @@ -432,7 +442,7 @@ int splitBios() { fnLen = strlen(params.in_file); biosFn = (char*)malloc(fnLen + 1); - if (biosFn == NULL) { + if (biosFn == nullptr) { result = 1; goto Cleanup; } @@ -449,7 +459,7 @@ int splitBios() { for (i = fnLen - 1; i >= 0; i--) { if (biosFn[i] == '.') { ext = (char*)malloc(fnLen - i + 1); // +1 for null terminator - if (ext == NULL) { + if (ext == nullptr) { result = 1; goto Cleanup; } @@ -460,7 +470,7 @@ int splitBios() { } } - if (ext == NULL) { + if (ext == nullptr) { printf("Error: Invalid bios file name. no file extension.\n"); result = 1; goto Cleanup; @@ -468,7 +478,7 @@ int splitBios() { bankFnLen = strlen(biosFn) + strlen(suffix) + strlen(ext) + 3U; // +3 for the bank number bankFn = (char*)malloc(bankFnLen); - if (bankFn == NULL) { + if (bankFn == nullptr) { result = 1; goto Cleanup; } @@ -479,7 +489,7 @@ int splitBios() { loopCount = 0; while (dataLeft > 0) { // safe guard - if (loopCount > 4) { + if (loopCount > 4) { printf("Error: LoopCount exceeded 5\n"); result = 1; break; @@ -488,7 +498,7 @@ int splitBios() { // set bank filename = [name][suffix][number].[ext] = bios_bank1.bin bankFn[0] = '\0'; - sprintf(bankFn, "%s%s%d%s", biosFn, suffix, bank + 1, ext); + snprintf(bankFn, bankFnLen, "%s%s%d%s", biosFn, suffix, bank + 1, ext); // write bank to file printf("Writing bank %d to %s\n", bank + 1, bankFn); @@ -504,16 +514,16 @@ int splitBios() { printf("BIOS split into %d banks\n", bank); Cleanup: - if (data != NULL) { + if (data != nullptr) { free(data); } - if (biosFn != NULL) { + if (biosFn != nullptr) { free(biosFn); } - if (bankFn != NULL) { + if (bankFn != nullptr) { free(bankFn); } - if (ext != NULL) { + if (ext != nullptr) { free(ext); } @@ -527,27 +537,27 @@ int combineBios() { int result = 0; int numBanks = 0; - uint8_t* data = NULL; + uint8_t* data = nullptr; - uint8_t* banks[MAX_BANKS] = { NULL }; + uint8_t* banks[MAX_BANKS] = { nullptr }; uint32_t bankSizes[MAX_BANKS] = { 0 }; printf("Combine BIOS\n\n"); const char* filename = params.out_file; - if (filename == NULL) { + if (filename == nullptr) { filename = "bios.bin"; } for (i = 0; i < MAX_BANKS; i++) { - if (params.bank_files[i] == NULL) + if (params.bank_files[i] == nullptr) continue; numBanks++; - + banks[i] = readFile(params.bank_files[i], &bankSizes[i], 0); - if (banks[i] == NULL) { + if (banks[i] == nullptr) { result = 1; goto Cleanup; } @@ -557,7 +567,7 @@ int combineBios() { result = 1; goto Cleanup; } - + totalSize += bankSizes[i]; } @@ -574,13 +584,13 @@ int combineBios() { } data = (uint8_t*)malloc(totalSize); - if (data == NULL) { + if (data == nullptr) { result = 1; goto Cleanup; } for (i = 0; i < MAX_BANKS; i++) { - if (banks[i] != NULL) { + if (banks[i] != nullptr) { printf("Copying %s %d kb into offset 0x%x (bank %d)\n", params.bank_files[i], bankSizes[i] / 1024, offset, i + 1); memcpy(data + offset, banks[i], bankSizes[i]); offset += bankSizes[i]; @@ -588,17 +598,17 @@ int combineBios() { } result = writeFileF(filename, "bios", data, totalSize); - + Cleanup: - if (data != NULL) { + if (data != nullptr) { free(data); } for (i = 0; i < MAX_BANKS; i++) { - if (banks[i] != NULL) { + if (banks[i] != nullptr) { free(banks[i]); - banks[i] = NULL; + banks[i] = nullptr; } } @@ -623,7 +633,7 @@ int listBios() { uint32_t size = 0; uint8_t* buffer = readFile(params.in_file, &size, 0); - if (buffer == NULL) { + if (buffer == nullptr) { return 1; } @@ -632,10 +642,10 @@ int listBios() { return 1; } - if (params.mcpx_file != NULL) printf("mcpx file: %s\n", params.mcpx_file); + if (params.mcpx_file != nullptr) printf("mcpx file: %s\n", params.mcpx_file); printf("bios file: %s\nbios size: %d kb\nrom size: %d kb\n\n", params.in_file, size / 1024, params.romsize / 1024); - biosStatus = bios.load(buffer, size, &bios_params); + biosStatus = bios.load(buffer, size, &bios_params); if (biosStatus > BIOS_LOAD_STATUS_INVALID_BLDR) { printf("Error: Failed to load BIOS\n"); return 1; @@ -674,7 +684,7 @@ int listBios() { bios.decompressKrnl(); printf("Kernel:\n"); - if (bios.kernel.img != NULL) { + if (bios.kernel.img != nullptr) { printf("Image size: %d bytes\n", bios.kernel.img_size); dump_nt_headers(bios.kernel.img, bios.kernel.img_size, false); print_krnl_data_section_header((IMAGE_DOS_HEADER*)bios.kernel.img); @@ -695,25 +705,25 @@ int listBios() { uprintc(valid, "%d", bios.available_space); printf(" bytes\n"); } - + return result; } int replicateBios() { uint32_t size; - uint8_t* bios = NULL; - uint8_t* bank = NULL; + uint8_t* bios = nullptr; + uint8_t* bank = nullptr; int result = 0; uint32_t binsize; const char* filename = params.out_file; - if (filename == NULL) { + if (filename == nullptr) { filename = "bios.bin"; } printf("Replicate BIOS\n\n"); bank = readFile(params.in_file, &size, 0); - if (bank == NULL) { + if (bank == nullptr) { result = 1; goto Cleanup; } @@ -741,7 +751,7 @@ int replicateBios() { } bios = (uint8_t*)malloc(binsize); - if (bios == NULL) { + if (bios == nullptr) { result = 1; goto Cleanup; } @@ -754,25 +764,25 @@ int replicateBios() { } result = writeFileF(filename, "bios", bios, binsize); - + Cleanup: - if (bank != NULL) { + if (bank != nullptr) { free(bank); - bank = NULL; + bank = nullptr; } - if (bios != NULL) { + if (bios != nullptr) { free(bios); - bios = NULL; + bios = nullptr; } - + return result; } int decodeXcodes() { XcodeDecoder decoder; DECODE_CONTEXT* context; - uint8_t* init_tbl = NULL; + uint8_t* init_tbl = nullptr; uint32_t size = 0; uint32_t base = 0; int result = 0; @@ -780,11 +790,11 @@ int decodeXcodes() { printf("Decode Xcodes\n\n"); init_tbl = load_init_tbl_file(&size, &base); - if (init_tbl == NULL) { + if (init_tbl == nullptr) { return 1; } - - if (params.settings_file != NULL) { + + if (params.settings_file != nullptr) { if (!fileExists(params.settings_file)) { printf("Error: Settings file not found.\n"); result = 1; @@ -804,11 +814,11 @@ int decodeXcodes() { printf("init tbl file: %s\nxcode count: %d\nxcode size: %d bytes\nxcode base: 0x%x\n\n", params.in_file, context->xcodeCount, context->xcodeSize, context->xcodeBase); - + // setup the file stream, if -d flag is set if (isFlagSet(SW_DMP)) { const char* filename = params.out_file; - if (filename == NULL) { + if (filename == nullptr) { filename = "xcodes.txt"; } @@ -817,17 +827,17 @@ int decodeXcodes() { printf("Writing xcodes to %s\n", filename); FILE* stream = fopen(filename, "w"); - if (stream == NULL) { + if (stream == nullptr) { printf("Error: Failed to open file %s\n", filename); result = 1; goto Cleanup; } context->stream = stream; } - else { + else { context->stream = stdout; } - + result = decoder.decodeXcodes(); if (isFlagSet(SW_DMP)) { @@ -837,23 +847,23 @@ int decodeXcodes() { Cleanup: - if (init_tbl != NULL) { + if (init_tbl != nullptr) { free(init_tbl); - init_tbl = NULL; + init_tbl = nullptr; } return result; } int simulateXcodes() { XcodeInterp interp; - XCODE* xcode = NULL; + XCODE* xcode = nullptr; uint32_t size = 0; uint32_t base = 0; int result = 0; bool hasMemChanges_total = false; - const char* opcode_str = NULL; - uint8_t* mem_sim = NULL; - uint8_t* init_tbl = NULL; + const char* opcode_str = nullptr; + uint8_t* mem_sim = nullptr; + uint8_t* init_tbl = nullptr; uint32_t code_size = 0; uint32_t mem_size = 0; uint32_t offset = 0; @@ -861,7 +871,7 @@ int simulateXcodes() { printf("Simulate Xcodes\n\n"); init_tbl = load_init_tbl_file(&size, &base); - if (init_tbl == NULL) + if (init_tbl == nullptr) return 1; result = interp.load(init_tbl + base, size - base); @@ -885,7 +895,7 @@ int simulateXcodes() { printf("init tbl file: %s\nxcode base: 0x%x\nxcode offset: 0x%x\nmem space: %d bytes\n\n", params.in_file, base, offset, mem_size); mem_sim = (uint8_t*)malloc(mem_size); - if (mem_sim == NULL) { + if (mem_sim == nullptr) { result = 1; goto Cleanup; } @@ -915,9 +925,9 @@ int simulateXcodes() { } // print the xcode - printf("\t%04x: %s 0x%02x, 0x%08X\n", (base + interp.offset - sizeof(XCODE)), opcode_str, xcode->addr, xcode->data); + printf("\t%04lx: %s 0x%02x, 0x%08X\n", (unsigned long)(base + interp.offset - sizeof(XCODE)), opcode_str, xcode->addr, xcode->data); } - + if (!hasMemChanges_total) { printf("0 memory changes in range 0x0 - 0x%x\n", mem_size); goto Cleanup; @@ -926,7 +936,7 @@ int simulateXcodes() { // if -d flag is set, dump the memory to a file, otherwise print the memory dump if (isFlagSet(SW_DMP)) { const char* filename = params.out_file; - if (filename == NULL) + if (filename == nullptr) filename = "mem_sim.bin"; printf("\n"); @@ -952,14 +962,14 @@ int simulateXcodes() { Cleanup: - if (init_tbl != NULL) { + if (init_tbl != nullptr) { free(init_tbl); - init_tbl = NULL; + init_tbl = nullptr; } - if (mem_sim != NULL) { + if (mem_sim != nullptr) { free(mem_sim); - mem_sim = NULL; + mem_sim = nullptr; } return result; @@ -967,18 +977,18 @@ int simulateXcodes() { int encodeX86() { // encode x86 instructions to xcodes - uint8_t* data = NULL; - uint8_t* buffer = NULL; + uint8_t* data = nullptr; + uint8_t* buffer = nullptr; uint32_t dataSize = 0; uint32_t xcodeSize = 0; int result = 0; - const char* filename = NULL; + const char* filename = nullptr; printf("Encode X86\n\n"); data = readFile(params.in_file, &dataSize, 0); - if (data == NULL) { + if (data == nullptr) { return 1; } @@ -990,11 +1000,11 @@ int encodeX86() { goto Cleanup; } - printf("xcodes: %d\n", xcodeSize / sizeof(XCODE)); - + printf("xcodes: %ld\n", xcodeSize / sizeof(XCODE)); + // write the xcodes to file filename = params.out_file; - if (filename == NULL) { + if (filename == nullptr) { filename = "xcodes.bin"; } @@ -1002,11 +1012,11 @@ int encodeX86() { Cleanup: - if (data != NULL) { + if (data != nullptr) { free(data); } - if (buffer != NULL) { + if (buffer != nullptr) { free(buffer); } @@ -1015,8 +1025,8 @@ int encodeX86() { int compressFile() { // lzx compress file - uint8_t* data = NULL; - uint8_t* buff = NULL; + uint8_t* data = nullptr; + uint8_t* buff = nullptr; uint32_t dataSize = 0; uint32_t compressedSize = 0; int result = 0; @@ -1025,7 +1035,7 @@ int compressFile() { printf("Compress File\n\n"); data = readFile(params.in_file, &dataSize, 0); - if (data == NULL) { + if (data == nullptr) { return 1; } @@ -1046,14 +1056,14 @@ int compressFile() { Cleanup: - if (data != NULL) { + if (data != nullptr) { free(data); - data = NULL; + data = nullptr; } - if (buff != NULL) { + if (buff != nullptr) { free(buff); - buff = NULL; + buff = nullptr; } return result; @@ -1062,11 +1072,11 @@ int compressFile() { int decompressFile() { // lzx decompress file - uint8_t* data = NULL; + uint8_t* data = nullptr; uint32_t dataSize = 0; float savings = 0; - uint8_t* buff = NULL; + uint8_t* buff = nullptr; uint32_t decompressedSize = 0; int result = 0; @@ -1074,48 +1084,48 @@ int decompressFile() { printf("Decompress File\n\n"); data = readFile(params.in_file, &dataSize, 0); - if (data == NULL) { + if (data == nullptr) { return 1; } printf("file: %s\n\n", params.in_file); printf("Decompressing file\n"); - result = lzx_decompress(data, dataSize, &buff, NULL, &decompressedSize); + result = lzx_decompress(data, dataSize, &buff, nullptr, &decompressedSize); if (result != 0) { printf("Error: Decompression failed, "); lzx_print_error(result); goto Cleanup; } - savings = (1 - ((float)dataSize / (float)decompressedSize)) * 100; + savings = (1 - ((float)dataSize / (float)decompressedSize)) * 100; printf("Decompressed %u -> %u bytes (%.3f%% compression)\n", dataSize, decompressedSize, savings); result = writeFileF(params.out_file, "decompressed file", buff, decompressedSize); Cleanup: - if (data != NULL) { + if (data != nullptr) { free(data); - data = NULL; + data = nullptr; } - if (buff != NULL) { + if (buff != nullptr) { free(buff); - buff = NULL; + buff = nullptr; } return result; } int dumpCoffPeImg() { int result = 0; - uint8_t* data = NULL; - uint32_t size = NULL; + uint8_t* data = nullptr; + uint32_t size = 0; printf("List NT Header\n\n"); data = readFile(params.in_file, &size, 0); - if (data == NULL) + if (data == nullptr) return 1; printf("file: %s\nimage size: %d bytes\n\n", params.in_file, size); @@ -1123,7 +1133,7 @@ int dumpCoffPeImg() { result = dump_nt_headers(data, size, false); free(data); - data = NULL; + data = nullptr; return result; } @@ -1148,7 +1158,7 @@ int info() { return 0; } int help() { - + if (isFlagSet(SW_HELP_ENCRYPTION)) { helpEncryption(); return 0; @@ -1263,7 +1273,7 @@ int help() { printf("# %s\n\n %s (req) *inferred\n %s (req) %s\n %s\n\n", HELP_STR_REPLICATE, HELP_STR_PARAM_IN_BIOS_FILE, HELP_STR_PARAM_BINSIZE, HELP_STR_VALID_ROM_SIZES, HELP_STR_PARAM_OUT_FILE); return 0; - + case CMD_HELP: break; @@ -1274,12 +1284,12 @@ int help() { printf("Help\n\nSee command help, use xbios -? \n"); printf("See encryption help, use xbios -? -help-enc\n"); - + printf("\nCommands:\n"); for (int i = CMD_INFO + 1; i < sizeof(cmd_tbl) / sizeof(CMD_TBL); ++i) { printf(" %s\n", cmd_tbl[i].sw); } - + printf("\n%s\n", HELP_USAGE_STR); return 0; @@ -1288,7 +1298,7 @@ int helpEncryption() { printf("Help\n\n2BL encryption / decryption:\n" \ "Use one of the switches below to specify a key for 2BL encryption / decryption.\n"\ "Not providing a switch results in 2BL not being encrypted / decrypted\n\n"); - + // mcpx rom printf(" %s\n", HELP_STR_MCPX_ROM); @@ -1296,7 +1306,7 @@ int helpEncryption() { printf("\n -key-bldr"); printf(HELP_STR_RC4_KEY, "2BL"); - // kernel + // kernel printf("\n\nKernel encryption / decryption:\nOnly needed for custom BIOSes as keys are located in the 2BL.\n\n"); printf(" -key-krnl"); printf(HELP_STR_RC4_KEY, "kernel"); @@ -1332,13 +1342,13 @@ void init_parameters(XbToolParameters* _params) { memset(_params, 0, sizeof(XbToolParameters)); } void free_parameters(XbToolParameters* _params) { - if (_params->bldr_key != NULL) { + if (_params->bldr_key != nullptr) { free(_params->bldr_key); - _params->bldr_key = NULL; + _params->bldr_key = nullptr; } - if (_params->kernel_key != NULL) { + if (_params->kernel_key != nullptr) { free(_params->kernel_key); - _params->kernel_key = NULL; + _params->kernel_key = nullptr; } mcpx_free(&_params->mcpx); } @@ -1352,7 +1362,7 @@ int inject_xcodes(uint8_t* data, uint32_t size, uint8_t* xcodes, uint32_t xcodes } INIT_TBL* init_tbl = (INIT_TBL*)data; - XCODE* xcode = NULL; + XCODE* xcode = nullptr; while (interp.interpretNext(xcode) == 0) { if (xcode->opcode == XC_EXIT) @@ -1396,7 +1406,7 @@ int inject_xcodes(uint8_t* data, uint32_t size, uint8_t* xcodes, uint32_t xcodes xcode = (XCODE*)(data + 0x80 + interp.offset - sizeof(XCODE)); if (jmp) { - printf("XCODE: replacing quit xcode at 0x%x with jump to free space at 0x%x\n", (uint8_t*)xcode - data, 0x80 + interp.offset + offset); + printf("XCODE: replacing quit xcode at 0x%lx with jump to free space at 0x%x\n", (unsigned long)((uint8_t*)xcode - data), 0x80 + interp.offset + offset); // patch quit xcode to a jmp xcode. xcode->opcode = XC_JMP; @@ -1426,25 +1436,25 @@ int inject_xcodes(uint8_t* data, uint32_t size, uint8_t* xcodes, uint32_t xcodes int read_keys() { // read key files from command line. - if (params.bldr_key_file != NULL) { + if (params.bldr_key_file != nullptr) { printf("bldr key file: %s\n", params.bldr_key_file); - params.bldr_key = readFile(params.bldr_key_file, NULL, XB_KEY_SIZE); - if (params.bldr_key == NULL) + params.bldr_key = readFile(params.bldr_key_file, nullptr, XB_KEY_SIZE); + if (params.bldr_key == nullptr) return 1; printf("bldr key: "); uprinth(params.bldr_key, XB_KEY_SIZE); } - if (params.kernel_key_file != NULL) { + if (params.kernel_key_file != nullptr) { printf("krnl key file: %s\n", params.kernel_key_file); - params.kernel_key = readFile(params.kernel_key_file, NULL, XB_KEY_SIZE); - if (params.kernel_key == NULL) + params.kernel_key = readFile(params.kernel_key_file, nullptr, XB_KEY_SIZE); + if (params.kernel_key == nullptr) return 1; printf("krnl key: "); uprinth(params.kernel_key, XB_KEY_SIZE); } - if (params.bldr_key != NULL || params.kernel_key != NULL) + if (params.bldr_key != nullptr || params.kernel_key != nullptr) printf("\n"); return 0; @@ -1452,14 +1462,14 @@ int read_keys() { int read_mcpx() { // read and verify mcpx rom file. - uint8_t* mcpxData = NULL; + uint8_t* mcpxData = nullptr; int result = 0; - if (params.mcpx_file == NULL) + if (params.mcpx_file == nullptr) return 0; - mcpxData = readFile(params.mcpx_file, NULL, MCPX_BLOCK_SIZE); - if (mcpxData == NULL) + mcpxData = readFile(params.mcpx_file, nullptr, MCPX_BLOCK_SIZE); + if (mcpxData == nullptr) return 1; result = mcpx_load(¶ms.mcpx, mcpxData); @@ -1476,12 +1486,12 @@ int read_mcpx() { } uint8_t* load_init_tbl_file(uint32_t* size, uint32_t* base) { - uint8_t* init_tbl = NULL; + uint8_t* init_tbl = nullptr; int result = 0; init_tbl = readFile(params.in_file, size, 0); - if (init_tbl == NULL) - return NULL; + if (init_tbl == nullptr) + return nullptr; if (isFlagSet(SW_BASE)) { *base = params.base; @@ -1510,11 +1520,11 @@ uint8_t* load_init_tbl_file(uint32_t* size, uint32_t* base) { Cleanup: if (result != 0) { - if (init_tbl != NULL) { + if (init_tbl != nullptr) { free(init_tbl); - init_tbl = NULL; + init_tbl = nullptr; } - return NULL; + return nullptr; } return init_tbl; @@ -1547,12 +1557,12 @@ void lzx_print_error(int error) { void printBldrInfo(Bios* bios) { BIOS_LOAD_PARAMS bios_params = bios->params; - + printf("2BL:\n"); if (bios->bios_status == BIOS_LOAD_STATUS_SUCCESS) { printf("Entry point:\t\t0x%08x\n", bios->bldr.ldr_params->bldr_entry_point); - if (bios->bldr.entry != NULL && bios->bldr.entry->bfm_entry_point != 0) { + if (bios->bldr.entry != nullptr && bios->bldr.entry->bfm_entry_point != 0) { printf("BFM Entry point:\t0x%08x\n", bios->bldr.entry->bfm_entry_point); } } @@ -1647,6 +1657,7 @@ void printInitTblInfo(Bios* bios) { printf("\nRevision:\t\trev %d.%02d\n", init_tbl->revision >> 8, init_tbl->revision & 0xFF); printf("\n"); } + void printNv2aInfo(Bios* bios) { INIT_TBL* init_tbl = bios->init_tbl; int i; @@ -1679,13 +1690,13 @@ void printNv2aInfo(Bios* bios) { for (i = 0; i < ARRAY_SIZE; ++i) { cHasValue = false; - if (*(uint32_t*)&valArray[i] != 0) { + if (valArray[i] != 0) { cHasValue = true; hasValue = true; } if (cHasValue && hasValue) - sprintf(str + i * 3, "%02X ", *(uint32_t*)valArray[i]); + snprintf(str + i * 3, sizeof(str) - (i * 3), "%02lX ", (unsigned long)valArray[i]); } if (hasValue) { if (str[0] == '\0') { @@ -1710,7 +1721,7 @@ void printNv2aInfo(Bios* bios) { printf("\n"); } void printDataTblInfo(Bios* bios) { - + if (bios->init_tbl->data_tbl_offset == 0 || bios->size < bios->init_tbl->data_tbl_offset + sizeof(ROM_DATA_TBL)) { printf("Error: Rom Data Table not found.\n"); return; @@ -1772,18 +1783,18 @@ void printKeyInfo(Bios* bios) { MCPX* mcpx = bios->params.mcpx; PUBLIC_KEY* pubkey; - - if (mcpx->sbkey != NULL) { - printf("SB key (+%d):\t", mcpx->sbkey - mcpx->data); + + if (mcpx->sbkey != nullptr) { + printf("SB key (+%ld):\t", mcpx->sbkey - mcpx->data); uprinth(mcpx->sbkey, XB_KEY_SIZE); } - if (bios->bldr.bfm_key != NULL) { + if (bios->bldr.bfm_key != nullptr) { printf("BFM key:\t"); uprinth(bios->bldr.bfm_key, XB_KEY_SIZE); } - if (bios->bldr.keys != NULL) { + if (bios->bldr.keys != nullptr) { printf("EEPROM key:\t"); uprinth(bios->bldr.keys->eeprom_key, XB_KEY_SIZE); printf("Cert key:\t"); @@ -1797,8 +1808,8 @@ void printKeyInfo(Bios* bios) { uprinth(bios->preldr.bldr_key, SHA1_DIGEST_LEN); } - if (bios->kernel.img != NULL) { - if (rsa_findPublicKey(bios->kernel.img, bios->kernel.img_size, &pubkey, NULL) == RSA_ERROR_SUCCESS) { + if (bios->kernel.img != nullptr) { + if (rsa_findPublicKey(bios->kernel.img, bios->kernel.img_size, &pubkey, nullptr) == RSA_ERROR_SUCCESS) { printf("\nPublic key:\b\b\b\b"); uprinthl((uint8_t*)&pubkey->modulus, RSA_MOD_SIZE(&pubkey->header), 16, "\t\t", 0); } @@ -1855,7 +1866,7 @@ int main(int argc, char** argv) { printf("Xbox Bios Tools by tommojphillips\n\n"); int result = 0; - cmd = NULL; + cmd = nullptr; init_parameters(¶ms); result = parseCli(argc, argv, cmd, cmd_tbl, sizeof(cmd_tbl), param_tbl, sizeof(param_tbl)); @@ -1889,7 +1900,7 @@ int main(int argc, char** argv) { if (read_mcpx() != 0) goto Exit; - + switch (cmd->type) { case CMD_INFO: result = info(); @@ -1946,7 +1957,7 @@ int main(int argc, char** argv) { case CMD_DUMP_PE_IMG: result = dumpCoffPeImg(); break; - + default: result = ERROR_FAILED; break; diff --git a/src/XcodeDecoder.cpp b/src/XcodeDecoder.cpp index 0ae7ea5..2946cab 100644 --- a/src/XcodeDecoder.cpp +++ b/src/XcodeDecoder.cpp @@ -20,10 +20,14 @@ // GitHub: https:\\github.com\tommojphillips // std incl -#include -#include -#include +#include +#include +#include +#if !__APPLE__ #include +#else +#include +#endif // user incl #include "XcodeInterp.h" @@ -160,7 +164,7 @@ int XcodeDecoder::load(uint8_t* data, uint32_t size, uint32_t base, const char* if (result != 0) { return result; } - + interp.reset(); while (interp.interpretNext(xcode) == 0) { if (xcode->opcode == XC_JMP || xcode->opcode == XC_JNE) { @@ -175,7 +179,7 @@ int XcodeDecoder::load(uint8_t* data, uint32_t size, uint32_t base, const char* if (context->labels == NULL) { return ERROR_OUT_OF_MEMORY; } - memset(context->labels, 0, labelArraySize); + memset(context->labels, 0, labelArraySize); // initialize jmp array; jmpArraySize = sizeof(JMP_XCODE) * jmpCount; @@ -190,7 +194,7 @@ int XcodeDecoder::load(uint8_t* data, uint32_t size, uint32_t base, const char* interp.reset(); while (interp.interpretNext(xcode) == 0) { if (xcode->opcode == XC_JMP || xcode->opcode == XC_JNE) { - + // create a label if (context->labels != NULL) { if (searchLabel(context, interp.offset + xcode->data, &label) == 0) { @@ -215,7 +219,7 @@ int XcodeDecoder::load(uint8_t* data, uint32_t size, uint32_t base, const char* lbi /= 10; } context->settings.labelMaxLen += strlen(label_format) - 4; // 4 for %02d - + // xcode info context->xcodeSize = interp.offset; context->xcodeCount = interp.offset / sizeof(XCODE); @@ -233,7 +237,7 @@ int XcodeDecoder::loadSettings(const char* ini, DECODE_SETTINGS* settings) const char buf[128] = {}; static const char* default_format_str = "{offset}: {op} {addr} {data} {comment}"; - + static const LOADINI_SETTING_MAP var_map[] = { { &decode_settings_map.s[0], &settings->format_str}, { &decode_settings_map.s[1], &settings->jmp_str }, @@ -277,7 +281,7 @@ int XcodeDecoder::loadSettings(const char* ini, DECODE_SETTINGS* settings) const } // default format_str - if (settings->format_str == NULL) { + if (settings->format_str == NULL) { settings->format_str = (char*)malloc(strlen(default_format_str) + 1); if (settings->format_str == NULL) { result = ERROR_OUT_OF_MEMORY; @@ -288,7 +292,7 @@ int XcodeDecoder::loadSettings(const char* ini, DECODE_SETTINGS* settings) const len = strlen(settings->format_str); k = 1; - + for (i = 0; i < len; i++) { result = ll2(buf, settings->format_str, i, j, len); if (result == ERROR_INVALID_DATA) { @@ -386,12 +390,13 @@ int XcodeDecoder::loadSettings(const char* ini, DECODE_SETTINGS* settings) const for (j = 0; j < sizeof(num_str_fields) / sizeof(DECODE_SETTING_MAP); ++j) { if (strcmp(buf, num_str_fields[j].field) == 0) { - settings->num_str_format = (char*)malloc(strlen(settings->num_str) - 2 + 8 + 1); // +8 for digits + size_t buf_size = strlen(settings->num_str) - 2 + 8 + 1; + settings->num_str_format = (char*)malloc(buf_size); // +8 for digits if (settings->num_str_format == NULL) { result = ERROR_OUT_OF_MEMORY; goto Cleanup; } - sprintf(settings->num_str_format, settings->num_str, num_str_fields[j].value); + snprintf(settings->num_str_format, buf_size, settings->num_str, num_str_fields[j].value); break; } } @@ -446,7 +451,7 @@ int XcodeDecoder::loadSettings(const char* ini, DECODE_SETTINGS* settings) const result = 1; goto Cleanup; } - + // set default opcode string if (settings->opcodes[i].str == NULL) { settings->opcodes[i].str = (char*)malloc(strlen(str) + 1); @@ -484,8 +489,8 @@ int XcodeDecoder::decodeXcodes() { printf("Error: decode format too large.\n"); } else { - printf("Error: decoding xcode:\n\t%04X, OP: %02X, ADDR: %04X, DATA: %04X\n", - (context->xcodeBase + interp.offset - sizeof(XCODE)), context->xcode->opcode, context->xcode->addr, context->xcode->data); + printf("Error: decoding xcode:\n\t%04lX, OP: %02X, ADDR: %04X, DATA: %04X\n", + (unsigned long)(context->xcodeBase + interp.offset - sizeof(XCODE)), context->xcode->opcode, context->xcode->addr, context->xcode->data); } return result; } @@ -529,7 +534,7 @@ int XcodeDecoder::decode() { // output label if (searchLabel(context, interp.offset - sizeof(XCODE), &label) == 0) { label->defined = true; - sprintf(str, "%s:", label->name); + snprintf(str, sizeof(str), "%s:", label->name); if (context->settings.label_on_new_line) strcat(str, "\n"); } @@ -568,11 +573,11 @@ int XcodeDecoder::decode() { // append part of the decode str depending on the seq. switch (context->settings.format_map[j].type) { - + // output OFFSET case DECODE_FIELD_OFFSET: { - sprintf(str_tmp, context->settings.format_map[j].str, "%04x"); - sprintf(str, str_tmp, context->xcodeBase + interp.offset - sizeof(XCODE)); + snprintf(str_tmp, sizeof(str_tmp), context->settings.format_map[j].str, "%04x"); + snprintf(str, sizeof(str), str_tmp, context->xcodeBase + interp.offset - sizeof(XCODE)); } break; // output OPCODE @@ -580,7 +585,7 @@ int XcodeDecoder::decode() { const char* str_opcode; if (getOpcodeStr(context->settings.opcodes, context->xcode->opcode, str_opcode) != 0) return 1; - sprintf(str, context->settings.format_map[j].str, str_opcode); + snprintf(str, sizeof(str), context->settings.format_map[j].str, str_opcode); if (context->settings.pad) { rpad(str, op_len, ' '); } @@ -596,7 +601,7 @@ int XcodeDecoder::decode() { } if (searchLabel(context, interp.offset + context->xcode->data, &label) == 0) { - sprintf(str_tmp, context->settings.jmp_str, label->name); + snprintf(str_tmp, sizeof(str_tmp), context->settings.jmp_str, label->name); } } break; @@ -611,12 +616,12 @@ int XcodeDecoder::decode() { } // fall through to default default: { - sprintf(str_tmp, context->settings.num_str_format, context->xcode->addr); + snprintf(str_tmp, sizeof(str_tmp), context->settings.num_str_format, context->xcode->addr); break; } } - sprintf(str, context->settings.format_map[j].str, str_tmp); + snprintf(str, sizeof(str), context->settings.format_map[j].str, str_tmp); if (context->settings.pad) { if (context->settings.opcode_use_result && operand_len < op_len) @@ -646,23 +651,23 @@ int XcodeDecoder::decode() { case XC_JMP: if (context->settings.no_operand_str != NULL) { if (searchLabel(context, interp.offset + context->xcode->data, &label) == 0) { - sprintf(str_tmp, context->settings.jmp_str, label->name); + snprintf(str_tmp, sizeof(str_tmp), context->settings.jmp_str, label->name); } } break; - case XC_JNE: + case XC_JNE: if (searchLabel(context, interp.offset + context->xcode->data, &label) == 0) { - sprintf(str_tmp, context->settings.jmp_str, label->name); + snprintf(str_tmp, sizeof(str_tmp), context->settings.jmp_str, label->name); } break; default: - sprintf(str_tmp, context->settings.num_str_format, context->xcode->data); + snprintf(str_tmp, sizeof(str_tmp), context->settings.num_str_format, context->xcode->data); break; } - sprintf(str, context->settings.format_map[j].str, str_tmp); + snprintf(str, sizeof(str), context->settings.format_map[j].str, str_tmp); if (context->settings.pad) { if (operand_len < jmp_len) operand_len = jmp_len; @@ -675,11 +680,11 @@ int XcodeDecoder::decode() { // output COMMENT case DECODE_FIELD_COMMENT: { uint32_t prefixLen = strlen(context->settings.comment_prefix); - getCommentStr(str_tmp + prefixLen); + getCommentStr(str_tmp + prefixLen, sizeof(str_tmp) - prefixLen); if (str_tmp[prefixLen] != '\0') { memcpy(str_tmp, context->settings.comment_prefix, prefixLen); } - sprintf(str, context->settings.format_map[j].str, str_tmp); + snprintf(str, sizeof(str), context->settings.format_map[j].str, str_tmp); } break; } @@ -698,7 +703,7 @@ int XcodeDecoder::decode() { return 0; } -int XcodeDecoder::getCommentStr(char* str) { +int XcodeDecoder::getCommentStr(char* str, size_t buf_size) { // -1 = dont care about field XCODE* _ptr = interp.ptr; @@ -738,7 +743,7 @@ int XcodeDecoder::getCommentStr(char* str) { // xcalibur XC_WRITE_COMMENT("xcalibur slave address", XC_IO_WRITE, SMB_BASE + 0x04, 0xE1); - + XC_WRITE_COMMENT_NEXT_XCODE("report memory type", XC_IO_WRITE, SMB_BASE + 0x04, 0x20, XC_IO_WRITE, SMB_CMD_REGISTER, 0x13); @@ -788,12 +793,13 @@ int XcodeDecoder::getCommentStr(char* str) { // nv clk XC_WRITE_COMMENT("set nv clk 155 MHz", XC_MEM_WRITE, NV2A_BASE + NV_CLK_REG, 0x11701); + size_t str_len = strlen(str); XC_WRITE_STATEMENT(XC_MEM_WRITE, NV2A_BASE + NV_CLK_REG, -1, uint32_t base = 16667; uint32_t nvclk = base * ((_ptr->data & 0xFF00) >> 8); nvclk /= 1 << ((_ptr->data & 0x70000) >> 16); nvclk /= _ptr->data & 0xFF; nvclk /= 1000; - sprintf(str + strlen(str), "set nv clk %dMHz (@ %.3fMHz)", nvclk, (float)(base / 1000.00f))); + snprintf(str + str_len, buf_size - str_len, "set nv clk %dMHz (@ %.3fMHz)", nvclk, (float)(base / 1000.00f))); // nv gpu revision XC_WRITE_COMMENT_NEXT_XCODE("get nv rev", @@ -824,8 +830,9 @@ int XcodeDecoder::getCommentStr(char* str) { XC_MEM_WRITE, NV2A_BASE + 0x1234, 0xAAAAAAAA, XC_MEM_WRITE, NV2A_BASE + 0x1238, 0xAAAAAAAA); + str_len = strlen(str); XC_WRITE_STATEMENT(XC_PCI_WRITE, 0x80000084, -1, - sprintf(str + strlen(str), "set memory size %d Mb\n", (_ptr->data + 1) / 1024 / 1024)); + snprintf(str + str_len, buf_size - str_len, "set memory size %d Mb\n", (_ptr->data + 1) / 1024 / 1024)); XC_WRITE_COMMENT("set extbank bit (00000F00)", XC_MEM_WRITE, NV2A_BASE + 0x100200, 0x03070103); XC_WRITE_COMMENT("clear extbank bit (00000F00)", XC_MEM_WRITE, NV2A_BASE + 0x100200, 0x03070003); @@ -859,7 +866,7 @@ int XcodeDecoder::getCommentStr(char* str) { XC_WRITE_COMMENT("set ctrim2 ( micron )", XC_MEM_WRITE, 0x0f0010b8, 0xEEEE0000); XC_WRITE_COMMENT("ctrim continue", XC_MEM_WRITE, 0x0f0010d4, 0x9); XC_WRITE_COMMENT("ctrim common", XC_MEM_WRITE, 0x0f0010b4, 0x0); - + XC_WRITE_COMMENT("pll_select", XC_MEM_WRITE, 0x0f68050c, 0x000a0400); XC_WRITE_COMMENT("quit xcodes", XC_EXIT, 0x806, 0); @@ -914,7 +921,7 @@ static int ll2(char* output, char* str, uint32_t i, uint32_t& j, uint32_t len) { if (str[i] != '{') { j = i; - + while (j < len && str[j] != '{') { j++; } @@ -966,15 +973,15 @@ static void walkBranch(DECODE_CONTEXT* context, XcodeInterp* interp) { jmpOffset = offset + context->xcode->data; //fprintf(context->stream, "; walking branch\n"); - + if (jmpOffset > offset) { - // jmp offset is below; + // jmp offset is below; // walk from jmp-definition to jmp-offset endOffset = jmpOffset; } else { - // jmp offset is above or equal; + // jmp offset is above or equal; // walk from jmp-offset to jmp-definition interp->offset = jmpOffset; @@ -1027,7 +1034,7 @@ static int searchJmp(DECODE_CONTEXT* context, uint32_t offset, JMP_XCODE** jmp) static int createLabel(DECODE_CONTEXT* context, uint32_t offset, const char* label_format) { // create a label; add to label count. LABEL* label = &context->labels[context->labelCount]; - sprintf(label->name, label_format, context->labelCount); + snprintf(label->name, sizeof(label->name), label_format, context->labelCount); label->offset = offset; label->references = 1; label->defined = false; @@ -1159,4 +1166,4 @@ void destroyDecodeContext(DECODE_CONTEXT* context) { free(context); context = NULL; } -} \ No newline at end of file +} diff --git a/src/XcodeInterp.cpp b/src/XcodeInterp.cpp index bb9ce41..6786fae 100644 --- a/src/XcodeInterp.cpp +++ b/src/XcodeInterp.cpp @@ -20,9 +20,13 @@ // GitHub: https:\\github.com\tommojphillips // std incl -#include +#include #include +#if !__APPLE__ #include +#else +#include +#endif // user incl #include "XcodeInterp.h" diff --git a/src/cli_tbl.cpp b/src/cli_tbl.cpp index f3ea342..d89f728 100644 --- a/src/cli_tbl.cpp +++ b/src/cli_tbl.cpp @@ -20,12 +20,16 @@ // GitHub: https:\\github.com\tommojphillips // std incl +#include #include #include #include +#include // user incl #include "cli_tbl.h" +#include "posix_shims.h" + static int cli_flags[CLI_SWITCH_SIZE] = { 0 }; @@ -52,19 +56,19 @@ int parseCli(int argc, char* argv[], const CMD_TBL*& cmd, const CMD_TBL* cmds, c int startIndex; bool swNeedValue; char arg[CLI_SWITCH_MAX_LEN] = {}; - - if (CLI_SWITCH_MAX_COUNT - 1 < param_size / sizeof(PARAM_TBL)) + + if (CLI_SWITCH_MAX_COUNT - 1 < param_size / sizeof(PARAM_TBL)) return CLI_ERROR_INVALID_SW; - if (argc == 1) + if (argc == 1) return CLI_ERROR_NO_CMD; - if (strlen(argv[1]) < 2) + if (strlen(argv[1]) < 2) return CLI_ERROR_INVALID_CMD; if (argv[1][0] != '-' && argv[1][0] != '/') strncpy_s(arg, argv[1], CLI_SWITCH_MAX_LEN-1); else strncpy_s(arg, argv[1] + 1, CLI_SWITCH_MAX_LEN-1); - + if(getCmd(cmds, cmd_size, arg, &cmd) == 0) startIndex = 2; else @@ -75,7 +79,7 @@ int parseCli(int argc, char* argv[], const CMD_TBL*& cmd, const CMD_TBL* cmds, c printf("Error: Unknown command. %s\n", arg); return CLI_ERROR_UNKNOWN_CMD; } - + for (i = startIndex; i < argc; i++) { @@ -112,7 +116,7 @@ int parseCli(int argc, char* argv[], const CMD_TBL*& cmd, const CMD_TBL* cmds, c NextArg: continue; } - + /*if (strlen(argv[i]) > CLI_SWITCH_MAX_LEN - 1) { printf("Error: Invalid switch: %s\n", arg); @@ -174,7 +178,7 @@ int parseCli(int argc, char* argv[], const CMD_TBL*& cmd, const CMD_TBL* cmds, c return 0; // check for required switches - + bool missing = false; for (i = 0; i < (int)(param_size / sizeof(PARAM_TBL)); i++) { @@ -198,7 +202,7 @@ int parseCli(int argc, char* argv[], const CMD_TBL*& cmd, const CMD_TBL* cmds, c if (missing) return CLI_ERROR_MISSING_SW; - + return 0; } @@ -226,6 +230,9 @@ void setParamValue(const PARAM_TBL* param, char* arg) { case PARAM_TBL::FLAG: *(int*)param->var |= param->swType; break; + + case PARAM_TBL::NONE: + assert(!"Unsupported command type NONE"); } } void setFlag(const CLI_SWITCH sw) diff --git a/src/file.c b/src/file.c index 66a5600..8b874b8 100644 --- a/src/file.c +++ b/src/file.c @@ -21,9 +21,14 @@ #include #include +#if !__APPLE__ #include +#else +#include +#endif #include "file.h" +#include "posix_shims.h" #ifdef MEM_TRACKING #include "mem_tracking.h" diff --git a/src/loadini.c b/src/loadini.c index d39e85a..1b3b984 100644 --- a/src/loadini.c +++ b/src/loadini.c @@ -23,7 +23,11 @@ #include #include #include +#if !__APPLE__ #include +#else +#include +#endif // user incl #include "loadini.h" diff --git a/src/lzx_decoder.c b/src/lzx_decoder.c index dd8296c..8e73e66 100644 --- a/src/lzx_decoder.c +++ b/src/lzx_decoder.c @@ -3,7 +3,11 @@ // std incl #include #include +#if !__APPLE__ #include +#else +#include +#endif // user incl #include "lzx.h" @@ -89,7 +93,7 @@ dec_bitbuf |= ((((uint32_t) *dec_input_curpos | (((uint32_t) *(dec_input_curpos+1)) << 8))) << (-dec_bitcount)); \ dec_input_curpos += 2; \ dec_bitcount += 16; \ - } + } #define DECODE_LEN_TREE_NOEOFCHECK(matchlen) \ matchlen = context->secondary_len_tree_table[dec_bitbuf >> (32-SECONDARY_LEN_TREE_TABLE_BITS)]; \ @@ -127,7 +131,7 @@ static const long match_pos_minus2[sizeof(lzx_extra_bits)] = { 1835008 - 2, 1966080 - 2, 2097152 - 2 }; -static void init_bitbuf(LZX_DECODER_CONTEXT* context) { +static void init_bitbuf(LZX_DECODER_CONTEXT* context) { if (context->block_type == LZX_BLOCK_TYPE_UNCOMPRESSED) return; @@ -166,12 +170,12 @@ static void fill_bitbuf(LZX_DECODER_CONTEXT* context, int n) { } } -static void decode_small(LZX_DECODER_CONTEXT* context, short* temp, short* small_table, uint32_t* mask, uint8_t* small_bitlen, short* leftright_s) { +static void decode_small(LZX_DECODER_CONTEXT* context, int16_t* temp, int16_t* small_table, uint32_t* mask, uint8_t* small_bitlen, int16_t* leftright_s) { *temp = small_table[context->bitbuf >> (32 - DS_TABLE_BITS)]; if (*temp < 0) { - + *mask = (1L << (32 - 1 - DS_TABLE_BITS)); - + do { *temp = -(*temp); if (context->bitbuf & *mask) @@ -243,10 +247,10 @@ static void translate_e8(LZX_DECODER_CONTEXT* context, uint8_t* mem, long bytes) memcpy(&mem_backup[bytes - 6], temp, 6); } -static bool make_table(int nchar, const uint8_t* bitlen, uint8_t tablebits, short* table, short* leftright) { +static bool make_table(int nchar, const uint8_t* bitlen, uint8_t tablebits, int16_t* table, int16_t* leftright) { uint32_t i; int ch; - short* p; + int16_t* p; uint32_t count[17] = { 0} ; uint32_t weight[17] = { 0 }; uint32_t start[18] = { 0 }; @@ -256,6 +260,8 @@ static bool make_table(int nchar, const uint8_t* bitlen, uint8_t tablebits, shor uint8_t len; uint8_t jutbits; + memset(table, 0, sizeof(int16_t) * (1 << tablebits)); + for (i = 0; i < (uint32_t)nchar; i++) count[bitlen[i]]++; @@ -276,7 +282,7 @@ static bool make_table(int nchar, const uint8_t* bitlen, uint8_t tablebits, shor start[i] >>= jutbits; weight[i] = 1 << (tablebits - i); } - + while (i <= 16) { weight[i] = 1 << (16 - i); i++; @@ -301,7 +307,7 @@ static bool make_table(int nchar, const uint8_t* bitlen, uint8_t tablebits, shor return false; for (i = start[len]; i < nextcode; i++) - table[i] = (short)ch; + table[i] = (int16_t)ch; start[len] = nextcode; } @@ -315,21 +321,21 @@ static bool make_table(int nchar, const uint8_t* bitlen, uint8_t tablebits, shor do { if (*p == 0) { leftright[avail * 2] = leftright[avail * 2 + 1] = 0; - *p = (short)-avail; + *p = (int16_t)-avail; avail++; } - if ((short)k < 0) + if ((int16_t)k < 0) p = &leftright[-(*p) * 2 + 1]; else p = &leftright[-(*p) * 2]; k <<= 1; i--; - } + } while (i); - *p = (short)ch; + *p = (int16_t)ch; } } @@ -383,14 +389,14 @@ static bool make_table_8bit(uint8_t bitlen[], uint8_t table[]) { return true; } -static bool read_rep_tree(LZX_DECODER_CONTEXT* context, int num_elements, uint8_t* lastlen, uint8_t* len) { +static bool read_rep_tree(LZX_DECODER_CONTEXT* context, int num_elements, const uint8_t* lastlen, uint8_t* len) { int i; int consecutive; uint32_t mask; uint8_t small_bitlen[24] = { 0 }; - short small_table[1 << DS_TABLE_BITS]; - short leftright_s[2 * (2 * 24 + 241)]; - short temp; + int16_t small_table[1 << DS_TABLE_BITS]; + int16_t leftright_s[2 * (2 * 24 + 241)]; + int16_t temp; for (i = 0; i < NUM_DECODE_SMALL; i++) { small_bitlen[i] = (uint8_t)get_bits(context, 4); @@ -466,7 +472,7 @@ static bool read_main_and_secondary_trees(LZX_DECODER_CONTEXT* context) { return false; } - if (!make_table(LZX_MAIN_TREE_ELEMENTS(context->num_position_slots), context->main_tree_len, MAIN_TREE_TABLE_BITS, + if (!make_table(LZX_MAIN_TREE_ELEMENTS(context->num_position_slots), context->main_tree_len, MAIN_TREE_TABLE_BITS, context->main_tree_table, context->main_tree_left_right)) { return false; } @@ -475,7 +481,7 @@ static bool read_main_and_secondary_trees(LZX_DECODER_CONTEXT* context) { return false; } - if (!make_table(LZX_NUM_SECONDARY_LEN, context->secondary_len_tree_len, SECONDARY_LEN_TREE_TABLE_BITS, + if (!make_table(LZX_NUM_SECONDARY_LEN, context->secondary_len_tree_len, SECONDARY_LEN_TREE_TABLE_BITS, context->secondary_len_tree_table, context->secondary_len_tree_left_right)) { return false; } @@ -483,7 +489,7 @@ static bool read_main_and_secondary_trees(LZX_DECODER_CONTEXT* context) { return true; } static bool read_aligned_offset_tree(LZX_DECODER_CONTEXT* context) { - + for (int i = 0; i < 8; i++) { context->aligned_len[i] = (uint8_t)get_bits(context, 3); } @@ -586,7 +592,7 @@ static long decode_aligned_block_special(LZX_DECODER_CONTEXT* context, long pos, if (pos < 257) dec_mem_window[context->window_size + pos] = dec_mem_window[pos]; pos++; - } + } while (--match_length > 0); } } @@ -676,7 +682,7 @@ static long decode_aligned_offset_block_fast(LZX_DECODER_CONTEXT* context, long do { dec_mem_window[pos++] = dec_mem_window[match_ptr++]; - } + } while (--match_length > 0); } } @@ -694,7 +700,7 @@ static long decode_aligned_offset_block_fast(LZX_DECODER_CONTEXT* context, long } static int decode_aligned_offset_block(LZX_DECODER_CONTEXT* context, long pos, int amount_to_decode) { - if (pos < 257) { + if (pos < 257) { long amount_to_slowly_decode = min(257 - pos, amount_to_decode); long new_pos = decode_aligned_block_special(context, pos, amount_to_slowly_decode); amount_to_decode -= (new_pos - pos); @@ -845,7 +851,7 @@ static long decode_verbatim_block_fast(LZX_DECODER_CONTEXT* context, long pos, i do { context->mem_window[pos++] = context->mem_window[match_ptr++]; - } + } while (--match_length > 0); } } @@ -1190,6 +1196,7 @@ int lzx_decompress_block(LZX_DECODER_CONTEXT* context, const uint8_t* src, uint3 context->position_at_start += bytes_decoded; return 0; } + int lzx_decompress_next_block(LZX_DECODER_CONTEXT* context, const uint8_t** src, uint32_t* bytes_compressed, uint8_t** dest, uint32_t* bytes_decompressed) { int result; LZX_BLOCK* block = (LZX_BLOCK*)*src; @@ -1264,7 +1271,7 @@ int lzx_decompress(const uint8_t* src, const uint32_t src_size, uint8_t** dest, if (decompressed_size != NULL) { *decompressed_size = total_decompressed_size; } - + Cleanup: if (context != NULL) { diff --git a/src/lzx_encoder.c b/src/lzx_encoder.c index a81cfc5..85a8356 100644 --- a/src/lzx_encoder.c +++ b/src/lzx_encoder.c @@ -1,11 +1,14 @@ // lzx_encoder.c: lzx compression algorithm // std incl -#include +#include +#include #include +#include #include -#include +#if !__APPLE__ #include +#endif // user incl #include "lzx.h" @@ -64,27 +67,28 @@ #define IS_MATCH(l) (context->item_type[(l) >> 3] & (1 << ((l) & 7))) #define CHAR_EST(c) (uint32_t)(context->main_tree_len[(c)]) -#define MATCH_EST(ml,mp,result) { \ +#define MATCH_EST(ml,mp,result) do { \ uint8_t mp_slot = (uint8_t)MP_SLOT(mp); \ if (ml < (LZX_NUM_PRIMARY_LEN+2)) \ result = (uint32_t)(context->main_tree_len[(NUM_CHARS-2)+(mp_slot<main_tree_len[(NUM_CHARS+LZX_NUM_PRIMARY_LEN) + (mp_slot<secondary_tree_len[ml-(LZX_NUM_PRIMARY_LEN+2)] + lzx_extra_bits[mp_slot]); \ -} +} while (0) -#define OUT_MATCH(len, pos) { \ +#define OUT_MATCH(len, pos) do { \ context->item_type[(context->literals >> 3)] |= (1 << (context->literals & 7)); \ - context->lit_data [context->literals++] = (uint8_t)(len-2); \ + context->lit_data [context->literals++] = (uint8_t)(((len)-2) & 0xFF); \ context->dist_data[context->distances++] = pos; \ -} +} while (0) -#define TREE_CREATE_CHECK() \ -if (context->literals >= context->next_tree_create) { \ - update_tree_estimates(context); \ - context->next_tree_create += TREE_CREATE_INTERVAL; \ -} +#define TREE_CREATE_CHECK() do { \ + if (context->literals >= context->next_tree_create) { \ + update_tree_estimates(context); \ + context->next_tree_create += TREE_CREATE_INTERVAL; \ + } \ +} while (0) -#define OUTPUT_BITS(N, X) { \ +#define OUTPUT_BITS(N, X) do { \ context->bitbuf |= (((uint32_t) (X)) << (context->bitcount-(N))); \ context->bitcount -= (N); \ while (context->bitcount <= 16) { \ @@ -97,11 +101,13 @@ if (context->literals >= context->next_tree_create) { \ context->bitbuf <<= 16; \ context->bitcount += 16; \ } \ -} +} while (0) -#define OUT_CHAR_BITS OUTPUT_BITS(context->main_tree_len[context->lit_data[l]], context->main_tree_code[context->lit_data[l]]); +#define OUT_CHAR_BITS do { \ + OUTPUT_BITS(context->main_tree_len[context->lit_data[l]], context->main_tree_code[context->lit_data[l]]); \ + } while (0) -static const long square_table[17] = { +static const int32_t square_table[17] = { 0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256 }; static const uint8_t log2_table[256] = { @@ -204,13 +210,13 @@ static void create_slot_lookup_table(ENCODER_CONTEXT* context) { slotnum++; elements_to_init <<= 1; - } + } while (p < 1024); } -static void translate_e8(ENCODER_CONTEXT* context, uint8_t* mem, long bytes) { - long offset; - long absolute; +static void translate_e8(ENCODER_CONTEXT* context, uint8_t* mem, uint32_t bytes) { + uint32_t offset; + uint32_t absolute; uint32_t end_instr_pos; uint8_t temp[6]; uint8_t* mem_backup; @@ -234,7 +240,7 @@ static void translate_e8(ENCODER_CONTEXT* context, uint8_t* mem, long bytes) { if (context->instr_pos >= end_instr_pos) break; - offset = *(long*)mem; + offset = *(uint32_t*)mem; absolute = context->instr_pos + offset; if (absolute >= 0) { @@ -253,9 +259,11 @@ static void translate_e8(ENCODER_CONTEXT* context, uint8_t* mem, long bytes) { context->instr_pos = end_instr_pos + 10; } + static void output_bits(ENCODER_CONTEXT* context, int n, uint32_t x) { context->bitbuf |= (x << (context->bitcount - n)); - context->bitcount -= (char)n; + assert(n <= context->bitcount); + context->bitcount -= n; while (context->bitcount <= 16) { if (context->output_buffer_curpos >= context->output_buffer_end) { @@ -271,7 +279,7 @@ static void output_bits(ENCODER_CONTEXT* context, int n, uint32_t x) { } } -static long read_input_data(ENCODER_CONTEXT* context, uint8_t* mem, long amount) { +static uint32_t read_input_data(ENCODER_CONTEXT* context, uint8_t* mem, uint32_t amount) { if (amount <= context->input_left) { memcpy(mem, context->input_ptr, amount); context->input_left -= amount; @@ -281,7 +289,7 @@ static long read_input_data(ENCODER_CONTEXT* context, uint8_t* mem, long amount) else { if (context->input_left <= 0) return 0; - long bytes_read = context->input_left; + uint32_t bytes_read = context->input_left; memcpy(mem, context->input_ptr, context->input_left); context->input_ptr += context->input_left; context->input_left = 0; @@ -418,25 +426,25 @@ static bool alloc_compress_memory(ENCODER_CONTEXT* context) { break; } - context->tree_root = (uint32_t*)malloc(sizeof(context->tree_root[0]) * NUM_SEARCH_TREES); + context->tree_root = (uint32_t*)calloc(1, sizeof(context->tree_root[0]) * NUM_SEARCH_TREES); if (context->tree_root == NULL) { free_compress_memory(context); return false; } - context->real_left = (uint32_t*)malloc(sizeof(uint32_t) * MEM_WINDOW_ALLOC_SIZE); + context->real_left = (uint32_t*)calloc(1, sizeof(uint32_t) * MEM_WINDOW_ALLOC_SIZE); if (context->real_left == NULL) { free_compress_memory(context); return false; } - context->real_right = (uint32_t*)malloc(sizeof(uint32_t) * MEM_WINDOW_ALLOC_SIZE); + context->real_right = (uint32_t*)calloc(1, sizeof(uint32_t) * MEM_WINDOW_ALLOC_SIZE); if (context->real_right == NULL) { free_compress_memory(context); return false; } - context->real_mem_window = (uint8_t*)malloc(MEM_WINDOW_ALLOC_SIZE); + context->real_mem_window = (uint8_t*)calloc(1, MEM_WINDOW_ALLOC_SIZE); if (context->real_mem_window == NULL) { free_compress_memory(context); return false; @@ -444,19 +452,19 @@ static bool alloc_compress_memory(ENCODER_CONTEXT* context) { context->mem_window = context->real_mem_window; - context->lit_data = (uint8_t*)malloc(MAX_LITERAL_ITEMS * sizeof(uint8_t)); + context->lit_data = (uint8_t*)calloc(1, MAX_LITERAL_ITEMS * sizeof(uint8_t)); if (context->lit_data == NULL) { free_compress_memory(context); return false; } - context->dist_data = (uint32_t*)malloc(MAX_DIST_ITEMS * sizeof(*context->dist_data)); + context->dist_data = (uint32_t*)calloc(1, MAX_DIST_ITEMS * sizeof(*context->dist_data)); if (context->dist_data == NULL) { free_compress_memory(context); return false; } - context->item_type = (uint8_t*)malloc(MAX_LITERAL_ITEMS / 8); + context->item_type = (uint8_t*)calloc(1, MAX_LITERAL_ITEMS / 8); if (context->item_type == NULL) { free_compress_memory(context); @@ -471,13 +479,13 @@ static bool alloc_compress_memory(ENCODER_CONTEXT* context) { return false; } - context->decision_node = (DECISION_NODE*)malloc(sizeof(DECISION_NODE) * (LOOK + LZX_MAX_MATCH + 16)); + context->decision_node = (DECISION_NODE*)calloc(1, sizeof(DECISION_NODE) * (LOOK + LZX_MAX_MATCH + 16)); if (context->decision_node == NULL) { free_compress_memory(context); return false; } - context->input_buffer = (uint8_t*)malloc(LZX_CHUNK_SIZE); + context->input_buffer = (uint8_t*)calloc(1, LZX_CHUNK_SIZE); if (context->input_buffer == NULL) { free_compress_memory(context); return false; @@ -486,11 +494,11 @@ static bool alloc_compress_memory(ENCODER_CONTEXT* context) { return true; } -static long read_input(ENCODER_CONTEXT* context, uint32_t buf_pos, long size) { +static uint32_t read_input(ENCODER_CONTEXT* context, uint32_t buf_pos, uint32_t size) { if (size <= 0) return 0; - long bytes_read = read_input_data(context, &context->real_mem_window[buf_pos], size); + uint32_t bytes_read = read_input_data(context, &context->real_mem_window[buf_pos], size); if (bytes_read < 0) return 0; @@ -555,13 +563,13 @@ static uint32_t return_difference(ENCODER_CONTEXT* context, uint32_t item_start1 for (i = 0; i < (uint32_t)LZX_MAIN_TREE_ELEMENTS(context->num_position_slots); i++) { uint32_t log2a = (uint32_t)log2(freq1[i]); uint32_t log2b = (uint32_t)log2(freq2[i]); - uint32_t diff = square_table[log2a] - square_table[log2b]; - cum_diff += abs((long)diff); + int32_t diff = square_table[log2a] - square_table[log2b]; + cum_diff += abs(diff); } return cum_diff; } -static bool split_block(ENCODER_CONTEXT* context, uint32_t start, uint32_t end, uint32_t distance_to_end_at, uint32_t* split_at_literal, uint32_t* split_at_distance) { +static bool split_block(ENCODER_CONTEXT* context, uint32_t start, uint32_t end, int32_t distance_to_end_at, uint32_t* split_at_literal, int32_t* split_at_distance) { uint32_t i, j; uint32_t d = 0; int nd = 0; @@ -614,7 +622,7 @@ static bool split_block(ENCODER_CONTEXT* context, uint32_t start, uint32_t end, return false; } -static void count_len(ENCODER_CONTEXT* context, short i) { +static void count_len(ENCODER_CONTEXT* context, uint16_t i) { if (i < context->tree_n) { context->tree_len_cnt[(context->depth < 16) ? context->depth : 16]++; } @@ -625,8 +633,8 @@ static void count_len(ENCODER_CONTEXT* context, short i) { context->depth--; } } -static void make_len(ENCODER_CONTEXT* context, short root) { - short k; +static void make_len(ENCODER_CONTEXT* context, uint16_t root) { + int16_t k; uint16_t cum; uint8_t i; @@ -662,9 +670,9 @@ static void make_len(ENCODER_CONTEXT* context, short root) { } } -static void down_heap(ENCODER_CONTEXT* context, short i) { - short k = context->tree_heap[i]; - short j; +static void down_heap(ENCODER_CONTEXT* context, uint32_t i) { + uint32_t k = context->tree_heap[i]; + uint32_t j; while ((j = (i << 1)) <= context->tree_heapsize) { if (j < context->tree_heapsize && context->tree_freq[context->tree_heap[j]] > context->tree_freq[context->tree_heap[j + 1]]) j++; @@ -676,9 +684,10 @@ static void down_heap(ENCODER_CONTEXT* context, short i) { i = j; } - context->tree_heap[i] = k; + context->tree_heap[i] = (short)(k & 0xFFFF); } -static void make_code(ENCODER_CONTEXT* context, int n, char len[], uint16_t code[]) { + +static void make_code(ENCODER_CONTEXT* context, int n, const uint8_t len[], uint16_t code[]) { int i; uint16_t start[18] = { 0 }; for (i = 1; i <= 16; i++) @@ -688,8 +697,9 @@ static void make_code(ENCODER_CONTEXT* context, int n, char len[], uint16_t code code[i] = start[len[i]]++; } } -static void make_tree2(ENCODER_CONTEXT* context, short avail, uint16_t freqparm[], uint16_t codeparm[]) { - short i, j, k; + +static void make_tree2(ENCODER_CONTEXT* context, uint32_t avail, uint16_t freqparm[], uint16_t codeparm[]) { + uint32_t i, j, k; for (i = context->tree_heapsize >> 1; i >= 1; i--) down_heap(context, i); @@ -719,10 +729,10 @@ static void make_tree2(ENCODER_CONTEXT* context, short avail, uint16_t freqparm[ } while (context->tree_heapsize > 1); context->tree_sortptr = codeparm; - make_len(context, k); + make_len(context, (short)(k & 0xFFFF)); } static void make_tree(ENCODER_CONTEXT* context, int nparm, uint16_t* freqparm, uint8_t* lenparm, uint16_t* codeparm, bool make_codes) { - short i, avail; + uint32_t i, avail; RedoTree: context->tree_n = nparm; context->tree_freq = freqparm; @@ -735,7 +745,7 @@ static void make_tree(ENCODER_CONTEXT* context, int nparm, uint16_t* freqparm, u for (i = 0; i < nparm; i++) { context->len[i] = 0; if (freqparm[i]) - context->tree_heap[++context->tree_heapsize] = i; + context->tree_heap[++context->tree_heapsize] = (short)(i & 0xFFFF); } if (context->tree_heapsize < 2) { @@ -755,7 +765,7 @@ static void make_tree(ENCODER_CONTEXT* context, int nparm, uint16_t* freqparm, u make_tree2(context, avail, freqparm, codeparm); if (make_codes) - make_code(context, nparm, (char*)lenparm, codeparm); + make_code(context, nparm, lenparm, codeparm); } static void create_trees(ENCODER_CONTEXT* context, bool generate_codes) { make_tree(context, NUM_CHARS + (context->num_position_slots * (LZX_NUM_PRIMARY_LEN + 1)), context->main_tree_freq, context->main_tree_len, context->main_tree_code, generate_codes); @@ -810,11 +820,13 @@ static void fix_tree_cost_estimates(ENCODER_CONTEXT* context) { prevent_far_matches(context); } + static uint32_t get_block_stats(ENCODER_CONTEXT* context, uint32_t start, uint32_t start_at, uint32_t end) { memset(context->main_tree_freq, 0, LZX_MAIN_TREE_ELEMENTS(context->num_position_slots) * sizeof(context->main_tree_freq[0])); memset(context->secondary_tree_freq, 0, LZX_NUM_SECONDARY_LEN * sizeof(context->secondary_tree_freq[0])); return tally_frequency(context, start, start_at, end); } + static void update_tree_estimates(ENCODER_CONTEXT* context) { if (context->literals) { if (context->need_to_recalc_stats) { @@ -848,6 +860,7 @@ static void tally_aligned_bits(ENCODER_CONTEXT* context, uint32_t end_at) { context->aligned_tree_freq[match_pos & 7]++; } } + static int get_aligned_stats(ENCODER_CONTEXT* context, uint32_t end_at) { uint8_t i; uint32_t total_L3 = 0; @@ -870,7 +883,7 @@ static int get_aligned_stats(ENCODER_CONTEXT* context, uint32_t end_at) { static uint32_t estimate_compressed_block_size(ENCODER_CONTEXT* context) { uint32_t block_size = 0; uint32_t i; - uint8_t mpslot; + uint32_t mpslot; block_size = 150 * 8; for (i = 0; i < NUM_CHARS; i++) { @@ -878,7 +891,7 @@ static uint32_t estimate_compressed_block_size(ENCODER_CONTEXT* context) { } for (mpslot = 0; mpslot < context->num_position_slots; mpslot++) { - long element = NUM_CHARS + (mpslot << NL_SHIFT); + uint32_t element = NUM_CHARS + (mpslot << NL_SHIFT); for (int primary = 0; primary <= LZX_NUM_PRIMARY_LEN; primary++) { block_size += ((context->main_tree_len[element] + lzx_extra_bits[mpslot]) * context->main_tree_freq[element]); element++; @@ -892,15 +905,15 @@ static uint32_t estimate_compressed_block_size(ENCODER_CONTEXT* context) { return (block_size + 7) >> 3; } -static void write_rep_tree(ENCODER_CONTEXT* context, uint8_t* pLen, uint8_t* pLastLen, int Num) { +static void write_rep_tree(ENCODER_CONTEXT* context, uint8_t* pLen, uint8_t* pLastLen, uint32_t Num) { int i; int j; int same; uint16_t small_freq[2 * 24] = {0}; uint16_t mini_code[24] = {0}; - char mini_len[24] = {0}; + uint8_t mini_len[24] = {0}; - char k; + uint8_t k; uint8_t temp_store; temp_store = pLen[Num]; @@ -965,7 +978,7 @@ static void write_rep_tree(ENCODER_CONTEXT* context, uint8_t* pLen, uint8_t* pLa } } else { - k = (pLastLen[i] - pLen[i] + 17) % 17; + k = (uint8_t)((pLastLen[i] - pLen[i] + 17) % 17); } output_bits(context, mini_len[k], mini_code[k]); @@ -980,7 +993,7 @@ static void write_rep_tree(ENCODER_CONTEXT* context, uint8_t* pLen, uint8_t* pLa } else if (k == 19) { output_bits(context, TREE_ENC_REP_SAME_EXTRA_BITS, same - TREE_ENC_REP_MIN); - k = (pLastLen[i] - pLen[i] + 17) % 17; + k = (uint8_t)((pLastLen[i] - pLen[i] + 17) % 17); output_bits(context, mini_len[k], mini_code[k]); i += same - 1; } @@ -1093,10 +1106,10 @@ static void encode_uncompressed_block(ENCODER_CONTEXT* context, uint32_t bufpos, bool block_size_odd; uint32_t val; - output_bits(context, context->bitcount - 16, 0); + output_bits(context, (context->bitcount - 16) & 0xFF, 0); for (int i = 0; i < NUM_REPEATED_OFFSETS; i++) { val = context->repeated_offset_at_literal_zero[i]; - for (int j = 0; j < sizeof(long); j++) { + for (int j = 0; j < sizeof(uint32_t); j++) { *context->output_buffer_curpos++ = (uint8_t)val; val >>= 8; } @@ -1123,7 +1136,7 @@ static void encode_uncompressed_block(ENCODER_CONTEXT* context, uint32_t bufpos, context->bitbuf = 0; } -static long binary_search_findmatch(ENCODER_CONTEXT* context, long buf_pos) { +static uint32_t binary_search_findmatch(ENCODER_CONTEXT* context, uint32_t buf_pos) { uint32_t ptr; uint32_t a, b; uint32_t* small_ptr, * big_ptr; @@ -1137,7 +1150,9 @@ static long binary_search_findmatch(ENCODER_CONTEXT* context, long buf_pos) { int i, best_repeated_offset; uint16_t tree_to_use; - tree_to_use = *((uint16_t*)&context->mem_window[buf_pos]); + memset(context->matchpos_table, 0, sizeof(uint32_t) * (LZX_MAX_MATCH + 1)); + + memcpy(&tree_to_use, &context->mem_window[buf_pos], sizeof(uint16_t)); ptr = context->tree_root[tree_to_use]; context->tree_root[tree_to_use] = buf_pos; @@ -1147,7 +1162,7 @@ static long binary_search_findmatch(ENCODER_CONTEXT* context, long buf_pos) { context->left[buf_pos] = context->right[buf_pos] = 0; return 0; } - + clen = 2; match_length = 2; small_len = 2; @@ -1173,7 +1188,7 @@ static long binary_search_findmatch(ENCODER_CONTEXT* context, long buf_pos) { long_match: do { context->matchpos_table[++match_length] = buf_pos - ptr + (NUM_REPEATED_OFFSETS - 1); - } + } while (match_length < same); if (same >= BREAK_LENGTH) { @@ -1196,7 +1211,7 @@ static long binary_search_findmatch(ENCODER_CONTEXT* context, long buf_pos) { if (same > match_length) { do { context->matchpos_table[++match_length] = buf_pos - ptr + (NUM_REPEATED_OFFSETS - 1); - } + } while (match_length < same); if (same >= BREAK_LENGTH) { @@ -1232,7 +1247,7 @@ static long binary_search_findmatch(ENCODER_CONTEXT* context, long buf_pos) { if (i >= LZX_MIN_MATCH) { do { context->matchpos_table[i] = 0; - } + } while (--i >= LZX_MIN_MATCH); if (best_repeated_offset > BREAK_LENGTH) @@ -1258,7 +1273,7 @@ static long binary_search_findmatch(ENCODER_CONTEXT* context, long buf_pos) { if (i > best_repeated_offset) { do { context->matchpos_table[++best_repeated_offset] = 2; - } + } while (best_repeated_offset < i); } @@ -1273,11 +1288,14 @@ static long binary_search_findmatch(ENCODER_CONTEXT* context, long buf_pos) { match_length = 0; } - return (long)match_length; + return match_length; } -static void binary_search_remove_node(ENCODER_CONTEXT* context, long buf_pos, uint32_t end_pos) { - - uint16_t tree_to_use = *((uint16_t*)&context->mem_window[buf_pos]); + +static void binary_search_remove_node(ENCODER_CONTEXT* context, uint32_t buf_pos, uint32_t end_pos) { + + uint16_t tree_to_use; + memcpy(&tree_to_use, &context->mem_window[buf_pos], sizeof(uint16_t)); + if (context->tree_root[tree_to_use] != (uint32_t)buf_pos) { return; } @@ -1325,7 +1343,7 @@ static void binary_search_remove_node(ENCODER_CONTEXT* context, long buf_pos, ui } } } -static void quick_insert_bsearch_findmatch(ENCODER_CONTEXT* context, long buf_pos, long end_pos) { +static void quick_insert_bsearch_findmatch(ENCODER_CONTEXT* context, uint32_t buf_pos, uint32_t end_pos) { uint32_t a, b; uint32_t* small_ptr; uint32_t* big_ptr; @@ -1335,8 +1353,9 @@ static void quick_insert_bsearch_findmatch(ENCODER_CONTEXT* context, long buf_po int same; int clen; - uint16_t tree_to_use = *((uint16_t*)&context->mem_window[buf_pos]); - long ptr = context->tree_root[tree_to_use]; + uint16_t tree_to_use; + memcpy(&tree_to_use, &context->mem_window[buf_pos], sizeof(uint16_t)); + uint32_t ptr = context->tree_root[tree_to_use]; context->tree_root[tree_to_use] = buf_pos; if (ptr <= end_pos) { @@ -1356,7 +1375,7 @@ static void quick_insert_bsearch_findmatch(ENCODER_CONTEXT* context, long buf_po a = ptr + clen; b = buf_pos + clen; - while ((val = ((int)context->mem_window[a++]) - ((int)context->mem_window[b++])) == 0) { + while ((val = ((int32_t)context->mem_window[a++]) - ((int32_t)context->mem_window[b++])) == 0) { if (++same >= BREAK_LENGTH) break; } @@ -1394,16 +1413,16 @@ static void quick_insert_bsearch_findmatch(ENCODER_CONTEXT* context, long buf_po small_ptr = &context->right[ptr]; ptr = *small_ptr; } - } + } while (ptr > end_pos); *small_ptr = 0; *big_ptr = 0; } -static void get_final_repeated_offset_states(ENCODER_CONTEXT* context, uint32_t distances) { +static void get_final_repeated_offset_states(ENCODER_CONTEXT* context, int32_t distances) { uint8_t consecutive = 0; - long d = distances - 1; + int32_t d = distances - 1; for (; d >= 0; d--) { if (context->dist_data[d] > 2) @@ -1423,7 +1442,7 @@ static void get_final_repeated_offset_states(ENCODER_CONTEXT* context, uint32_t } uint32_t match_pos; - for (; d < (long)distances; d++) { + for (; d < (uint32_t)distances; d++) { match_pos = context->dist_data[d]; if (match_pos == 0) { @@ -1442,7 +1461,8 @@ static void get_final_repeated_offset_states(ENCODER_CONTEXT* context, uint32_t } } } -static void do_block_output(ENCODER_CONTEXT* context, long end, long distance_to_end_at) { + +static void do_block_output(ENCODER_CONTEXT* context, uint32_t end, int32_t distance_to_end_at) { uint32_t bytes_compressed = get_block_stats(context, 0, 0, end); int block_type = get_aligned_stats(context, distance_to_end_at); @@ -1480,7 +1500,7 @@ static void do_block_output(ENCODER_CONTEXT* context, long end, long distance_to } static void output_block(ENCODER_CONTEXT* context) { uint32_t where_to_split; - uint32_t distances; + int32_t distances; context->first_block = 0; @@ -1505,7 +1525,7 @@ static void output_block(ENCODER_CONTEXT* context) { fix_tree_cost_estimates(context); } -static void block_end(ENCODER_CONTEXT* context, long buf_pos) { +static void block_end(ENCODER_CONTEXT* context, uint32_t buf_pos) { context->first_block = false; context->need_to_recalc_stats = true; @@ -1522,11 +1542,11 @@ static void block_end(ENCODER_CONTEXT* context, long buf_pos) { } static bool redo_first_block(ENCODER_CONTEXT* context, uint32_t* bufpos_ptr) { - long start_at; - long earliest_can_start_at; - long pos_in_file; - long history_needed; - long history_avail; + uint32_t start_at; + uint32_t earliest_can_start_at; + uint32_t pos_in_file; + uint32_t history_needed; + uint32_t history_avail; uint32_t split_at_literal; uint32_t buf_pos; @@ -1541,7 +1561,7 @@ static bool redo_first_block(ENCODER_CONTEXT* context, uint32_t* bufpos_ptr) { else history_needed += context->window_size; - history_avail = (long)(&context->mem_window[buf_pos] - &context->real_mem_window[0]); + history_avail = (uint32_t)(&context->mem_window[buf_pos] - &context->real_mem_window[0]); if (history_needed <= history_avail) { earliest_can_start_at = context->bufpos_last_output_block; @@ -1584,13 +1604,13 @@ static bool redo_first_block(ENCODER_CONTEXT* context, uint32_t* bufpos_ptr) { return true; } -static void opt_encode_top(ENCODER_CONTEXT* context, long bytes_read) { +static void opt_encode_top(ENCODER_CONTEXT* context, uint32_t bytes_read) { uint32_t real_buf_pos; uint32_t buf_pos_end_this_chunk; uint32_t match_pos; uint32_t i; uint32_t end_pos; - int enc_match_len; + uint32_t enc_match_len; uint32_t buf_pos = context->bufpos; uint32_t buf_pos_end = context->bufpos + bytes_read; @@ -1611,7 +1631,7 @@ static void opt_encode_top(ENCODER_CONTEXT* context, long bytes_read) { } else { for (i = BREAK_LENGTH; i > 0; --i) { - quick_insert_bsearch_findmatch(context, (buf_pos - (long)i), (buf_pos - context->window_size + 4)); + quick_insert_bsearch_findmatch(context, (buf_pos - (uint32_t)i), (buf_pos - context->window_size + 4)); } } @@ -1644,7 +1664,7 @@ static void opt_encode_top(ENCODER_CONTEXT* context, long bytes_read) { if (enc_match_len < FAST_DECISION_THRESHOLD) { uint32_t span, epos, bpos, NextPrevPos; DECISION_NODE* decision_node_ptr; - long iterations; + uint32_t iterations; span = buf_pos + enc_match_len; epos = buf_pos + LOOK; @@ -1664,7 +1684,7 @@ static void opt_encode_top(ENCODER_CONTEXT* context, long bytes_read) { context->decision_node[0].repeated_offset[1] = context->last_matchpos_offset[1]; context->decision_node[0].repeated_offset[2] = context->last_matchpos_offset[2]; - decision_node_ptr = &context->decision_node[-(long)bpos]; + decision_node_ptr = &context->decision_node[-(int32_t)bpos]; #define rpt_offset_ptr(where,which_offset) decision_node_ptr[(where)].repeated_offset[(which_offset)] @@ -1744,8 +1764,8 @@ static void opt_encode_top(ENCODER_CONTEXT* context, long bytes_read) { if (enc_match_len > 2 || (enc_match_len == 2 && context->matchpos_table[2] < BREAK_MAX_LENGTH_TWO_OFFSET)) { if (span < (uint32_t)(buf_pos + enc_match_len)) { - long end = min(buf_pos + enc_match_len - bpos, LOOK - 1); - for (long j = span - bpos + 1; j <= end; j++) + uint32_t end = min(buf_pos + enc_match_len - bpos, LOOK - 1); + for (uint32_t j = span - bpos + 1; j <= end; j++) context->decision_node[j].numbits = (uint32_t)-1; span = buf_pos + enc_match_len; } @@ -1781,7 +1801,7 @@ static void opt_encode_top(ENCODER_CONTEXT* context, long bytes_read) { decision_node_ptr[PrevPos].path = buf_pos; buf_pos = PrevPos; iterations++; - } + } while (buf_pos != bpos); while (context->literals + iterations >= (MAX_LITERAL_ITEMS - 8) || context->distances + iterations >= (MAX_DIST_ITEMS - 8)) { @@ -1814,7 +1834,7 @@ static void opt_encode_top(ENCODER_CONTEXT* context, long bytes_read) { quick_insert_bsearch_findmatch(context, buf_pos + 1, buf_pos - context->window_size + 5); } else { - for (i = 1; i < (uint32_t)enc_match_len; i++) + for (i = 1; i < (uint32_t)enc_match_len; i++) quick_insert_bsearch_findmatch(context, buf_pos + i, buf_pos + i - context->window_size + 4); } @@ -1879,33 +1899,33 @@ static void opt_encode_top(ENCODER_CONTEXT* context, long bytes_read) { } static void encode_flush(ENCODER_CONTEXT* context) { - long output_size = 0; + uint32_t output_size = 0; LZX_BLOCK block; if (context->input_running_total > 0) { // output the bit buffer if (context->bitcount < 32) { - output_bits(context, (context->bitcount - 16), 0); + output_bits(context, context->bitcount - 16, 0); } - output_size = (long)(context->output_buffer_curpos - context->output_buffer_start); + output_size = (uint32_t)(context->output_buffer_curpos - context->output_buffer_start); - if (output_size > 0) { + if (output_size > 0) { block.compressed_size = (uint16_t)(context->output_buffer_curpos - context->output_buffer_start); block.uncompressed_size = (uint16_t)context->input_running_total; - + context->output_buffer_size += sizeof(LZX_BLOCK) + block.compressed_size; context->output_buffer_block_count++; // write block header memcpy(context->output_buffer, &block, sizeof(LZX_BLOCK)); context->output_buffer += sizeof(LZX_BLOCK); - + // write compressed data memcpy(context->output_buffer, context->output_buffer_start, block.compressed_size); context->output_buffer += block.compressed_size; - //printf("block %d: %5d -> %d\n", context->output_buffer_block_count, block.uncompressedSize, block.compressedSize); + //printf("block %d: %5d -> %d\n", context->output_buffer_block_count, block.uncompressed_size, block.compressed_size); } } @@ -1915,13 +1935,15 @@ static void encode_flush(ENCODER_CONTEXT* context) { context->bitcount = 32; context->bitbuf = 0; } + static void encode_start(ENCODER_CONTEXT* context) { - long buf_pos = context->bufpos - (long)(context->real_mem_window - context->mem_window); - long bytes_read = read_input(context, buf_pos, LZX_CHUNK_SIZE); + uint32_t buf_pos = context->bufpos - (uint32_t)(context->real_mem_window - context->mem_window); + uint32_t bytes_read = read_input(context, buf_pos, LZX_CHUNK_SIZE); if (bytes_read > 0) opt_encode_top(context, bytes_read); } -static long encode_data(ENCODER_CONTEXT* context, long input_size) { + +static int encode_data(ENCODER_CONTEXT* context, uint32_t input_size) { context->input_ptr = context->input_buffer; context->input_left = input_size; context->file_size_for_translation = DEFAULT_FILE_XLAT_SIZE; @@ -1956,8 +1978,8 @@ void lzx_flush_compression(ENCODER_CONTEXT* context) { encode_flush(context); } -ENCODER_CONTEXT* lzx_create_compression(uint8_t* dest) { - ENCODER_CONTEXT* context = (ENCODER_CONTEXT*)malloc(sizeof(ENCODER_CONTEXT)); +ENCODER_CONTEXT* lzx_create_compression(uint8_t* dest) { + ENCODER_CONTEXT* context = (ENCODER_CONTEXT*)calloc(1, sizeof(ENCODER_CONTEXT)); if (context == NULL) return NULL; @@ -1975,14 +1997,14 @@ void lzx_destroy_compression(ENCODER_CONTEXT* context) { } } -int lzx_compress_block(ENCODER_CONTEXT* context, const uint8_t* src, uint32_t bytes_read) { +int lzx_compress_block(ENCODER_CONTEXT* context, const uint8_t* src, uint32_t bytes_read) { if (bytes_read > LZX_CHUNK_SIZE) { return LZX_ERROR_INVALID_DATA; } - memcpy(context->input_buffer, src, bytes_read); + memcpy(context->input_buffer, src, bytes_read); return encode_data(context, bytes_read); } -int lzx_compress_next_block(ENCODER_CONTEXT* context, const uint8_t** src, uint32_t bytes_read, uint32_t* bytes_remaining) { +int lzx_compress_next_block(ENCODER_CONTEXT* context, const uint8_t** src, uint32_t bytes_read, uint32_t* bytes_remaining) { int result = lzx_compress_block(context, *src, bytes_read); *src += bytes_read; if (bytes_remaining != NULL) { @@ -2001,7 +2023,8 @@ int lzx_compress(const uint8_t* src, const uint32_t src_size, uint8_t** dest, ui // Allocate a buffer if one was not provided if (*dest == NULL) { - *dest = (uint8_t*)malloc(src_size); + // Compression may expand the block, so extra room is allocated. + *dest = (uint8_t*)malloc(src_size + (src_size >> 3) + 1024); if (*dest == NULL) { result = LZX_ERROR_OUT_OF_MEMORY; goto Cleanup; @@ -2017,7 +2040,7 @@ int lzx_compress(const uint8_t* src, const uint32_t src_size, uint8_t** dest, ui bytes_remaining = src_size; src_ptr = src; - + lzx_flush_compression(context); for (;;) { @@ -2043,7 +2066,7 @@ int lzx_compress(const uint8_t* src, const uint32_t src_size, uint8_t** dest, ui } Cleanup: - + if (context != NULL) { lzx_destroy_compression(context); context = NULL; diff --git a/src/mem_tracking.c b/src/mem_tracking.cpp similarity index 73% rename from src/mem_tracking.c rename to src/mem_tracking.cpp index 0d40a51..688f661 100644 --- a/src/mem_tracking.c +++ b/src/mem_tracking.cpp @@ -18,15 +18,20 @@ // Author: tommojphillips // GitHub: https:\\github.com\tommojphillips +#if !__APPLE__ #include -#include +#endif +#include +#include //#define MEM_TRACKING_PRINT -long memtrack_allocatedBytes = 0; -int memtrack_allocations = 0; +static long memtrack_allocatedBytes = 0; +static int memtrack_allocations = 0; + +static std::map allocation_map; -void* memtrack_malloc(size_t size) +extern "C" void* memtrack_malloc(size_t size) { void* ptr = malloc(size); if (ptr == NULL) { @@ -36,6 +41,7 @@ void* memtrack_malloc(size_t size) return NULL; } + allocation_map[ptr] = size; memtrack_allocations++; memtrack_allocatedBytes += size; @@ -45,7 +51,7 @@ void* memtrack_malloc(size_t size) return ptr; } -void memtrack_free(void* ptr) +extern "C" void memtrack_free(void* ptr) { #ifdef MEM_TRACKING_PRINT if (ptr == NULL) { @@ -54,8 +60,13 @@ void memtrack_free(void* ptr) } #endif - size_t size = _msize(ptr); + auto entry = allocation_map.find(ptr); + if (entry == allocation_map.end()) { + printf("Error untracked free 0x%p.\n", ptr); + } + size_t size = entry->second; free(ptr); + allocation_map.erase(entry); memtrack_allocations--; memtrack_allocatedBytes -= size; @@ -73,10 +84,16 @@ void memtrack_free(void* ptr) #endif } -void* memtrack_realloc(void* ptr, size_t size) +extern "C" void* memtrack_realloc(void* ptr, size_t size) { - size_t oldSize = _msize(ptr); + auto entry = allocation_map.find(ptr); + if (entry == allocation_map.end()) { + printf("Error untracked free 0x%p.\n", ptr); + } + size_t oldSize = entry->second; void* newPtr = realloc(ptr, size); + allocation_map.erase(entry); + allocation_map.insert(std::make_pair(newPtr, size)); if (newPtr == NULL) { #ifdef MEM_TRACKING_PRINT @@ -95,7 +112,7 @@ void* memtrack_realloc(void* ptr, size_t size) return newPtr; } -void* memtrack_calloc(size_t count, size_t size) +extern "C" void* memtrack_calloc(size_t count, size_t size) { if (count == 0 || size == 0) return NULL; @@ -108,6 +125,7 @@ void* memtrack_calloc(size_t count, size_t size) return NULL; } + allocation_map[ptr] = size; memtrack_allocations++; memtrack_allocatedBytes += size; @@ -118,7 +136,7 @@ void* memtrack_calloc(size_t count, size_t size) return ptr; } -int memtrack_report() +extern "C" int memtrack_report() { if (memtrack_allocatedBytes != 0 || memtrack_allocations != 0) { printf("\nLEAK DETECTED: %ld bytes in %d allocations\n", memtrack_allocatedBytes, memtrack_allocations); diff --git a/src/nt_headers.c b/src/nt_headers.c index e31d77c..456e31d 100644 --- a/src/nt_headers.c +++ b/src/nt_headers.c @@ -1,4 +1,4 @@ -// nt_headers.c +// nt_headers.c /* Copyright(C) 2024 tommojphillips * @@ -32,7 +32,7 @@ void print_image_dos_header(IMAGE_DOS_HEADER* dos_header) { char magic[3] = { 0 }; memcpy(magic, &dos_header->e_magic, 2); - + printf("Magic:\t\t%s ( %02X )\n" \ "cblp:\t\t0x%02x\n" \ "cp:\t\t0x%02x\n" \ @@ -43,16 +43,16 @@ void print_image_dos_header(IMAGE_DOS_HEADER* dos_header) "sp:\t\t0x%02x\n" \ "ip:\t\t0x%02x\n" \ "cs:\t\t0x%02x\n" \ - + "\nchecksum:\t0x%02x\n" \ "lfarlc:\t\t0x%02x\n" \ "ovno:\t\t0x%02x\n" \ - + "oem id:\t\t0x%02x\n" \ "oem info:\t0x%02x\n" \ - + "nt header ptr:\t0x%02x\n", \ - &magic, dos_header->e_magic, dos_header->e_cblp, dos_header->e_cp, dos_header->e_crlc, dos_header->e_cparhdr, + magic, dos_header->e_magic, dos_header->e_cblp, dos_header->e_cp, dos_header->e_crlc, dos_header->e_cparhdr, dos_header->e_minalloc, dos_header->e_maxalloc, dos_header->e_ss, dos_header->e_sp, dos_header->e_ip, dos_header->e_cs, dos_header->e_csum, dos_header->e_lfarlc, dos_header->e_ovno, dos_header->e_oemid, dos_header->e_oeminfo, dos_header->e_lfanew); @@ -82,7 +82,7 @@ void print_krnl_data_section_header(IMAGE_DOS_HEADER* dos_header) data_section->uninitializedDataSize, data_section->initializedDataSize, data_section->rawDataPtr, data_section->virtualAddr); } void print_image_file_header(COFF_FILE_HEADER* file_header, bool basic) -{ +{ char datetime[28] = { 0 }; const char* machine_str = { 0 }; diff --git a/src/util.c b/src/util.c index 45eb9d5..1da59b9 100644 --- a/src/util.c +++ b/src/util.c @@ -242,7 +242,7 @@ void uprinthl(const uint8_t* data, const size_t size, uint32_t per_line, const c uint32_t j = 0; for (uint32_t i = 0; i < size; i += per_line) { if (prefix != NULL) { - printf(prefix); + printf("%s", prefix); } for (j = 0; j < per_line; ++j) { if (i + j >= size) { diff --git a/tests/.clang-format b/tests/.clang-format new file mode 100644 index 0000000..0ca0998 --- /dev/null +++ b/tests/.clang-format @@ -0,0 +1,4 @@ +--- +Language: Cpp +BasedOnStyle: Google + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..0d723ba --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.30) +project(xbox_bios_tool_tests) + +set(CMAKE_VERBOSE_MAKEFILE TRUE) +set(CMAKE_CXX_STANDARD 17) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Og") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Og") + +enable_testing() +find_package(Boost 1.70.0 REQUIRED COMPONENTS unit_test_framework) + +# Tests ---------------------------------------------- + +add_executable( + compressor_tests + compress/test_main.cpp +) + +target_link_libraries( + compressor_tests + PRIVATE + compressor_lib + Boost::unit_test_framework +) + +add_test( + NAME + compressor_tests + COMMAND + compressor_tests +) diff --git a/tests/compress/test_main.cpp b/tests/compress/test_main.cpp new file mode 100644 index 0000000..3ef86db --- /dev/null +++ b/tests/compress/test_main.cpp @@ -0,0 +1,214 @@ +#define BOOST_TEST_MODULE CompressorTests + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lzx.h" + +struct Fixture { + Fixture() { + for (auto i = 0; i < 32; ++i) { + small_simple.push_back(i); + } + + for (auto i = 0; i < 32 * 1024; ++i) { + block_sized_simple.push_back(i & 0xFF); + } + + for (auto i = 0; i < 32 * 1024 + 1; ++i) { + block_sized_plus_one_simple.push_back(i & 0xFF); + } + + for (auto i = 0; i < 128 * 1024; ++i) { + large_simple.push_back(i & 0xFF); + } + + + constexpr size_t VECTOR_SIZE_BYTES = 128 * 1024; + constexpr uint32_t SEED = 0x44556677; + + large_noise.resize(VECTOR_SIZE_BYTES); + std::mt19937 engine(SEED); + std::uniform_int_distribution distribution; + std::generate(large_noise.begin(), large_noise.end(), [&]() { + return distribution(engine); + }); + } + + std::vector small_simple; + std::vector block_sized_simple; + std::vector block_sized_plus_one_simple; + std::vector large_simple; + + std::vector large_noise; +}; + +std::string byte_to_hex_str(uint8_t b) { + std::ostringstream oss; + oss << "0x" << std::hex << std::setw(2) << std::setfill('0') + << static_cast(b); + return oss.str(); +} + +bool check_decompressed(const std::vector &expected, + const uint8_t *actual, uint32_t actual_size, + std::string &diff_message) { + if (expected.size() != actual_size) { + std::ostringstream oss; + oss << "Vectors differ in size. expected_size: " << expected.size() + << ", vec2_size: " << actual_size << "."; + + size_t common_length = + std::min(expected.size(), static_cast(actual_size)); + for (size_t i = 0; i < common_length; ++i) { + if (expected[i] != actual[i]) { + oss << " First differing element before size mismatch at Location: " + << i << ", expected_byte: " << byte_to_hex_str(expected[i]) + << ", vec2_byte: " << byte_to_hex_str(actual[i]); + diff_message = oss.str(); + return false; + } + } + diff_message = oss.str(); + return false; + } + + for (size_t i = 0; i < expected.size(); ++i) { + if (expected[i] != actual[i]) { + std::ostringstream oss; + oss << "Location: " << i + << ", expected_byte: " << byte_to_hex_str(expected[i]) + << ", vec2_byte: " << byte_to_hex_str(actual[i]); + diff_message = oss.str(); + return false; + } + } + + return true; +} + +BOOST_FIXTURE_TEST_SUITE(compressor_suite, Fixture) + +// Compression of buffers < 1 block crashes. +// BOOST_AUTO_TEST_CASE(small_simple_round_trip) { +// uint8_t *compressed = nullptr; +// uint32_t compressed_size = 0; +// auto result = lzx_compress(small_simple.data(), small_simple.size(), +// &compressed, &compressed_size); BOOST_TEST(!result, "lzx_compress must +// return success"); +// +// uint8_t *decompressed = nullptr; +// uint32_t decompressed_buffer_size = 0; +// uint32_t decompressed_size = 0; +// result = lzx_decompress(compressed, compressed_size, &decompressed, +// &decompressed_buffer_size, &decompressed_size); BOOST_TEST(!result, +// "lzx_decompress must return success"); +// +//// std::string diff; +//// BOOST_CHECK_MESSAGE( +//// check_decompressed(small_simple, decompressed, diff), +//// diff); +//} + +BOOST_AUTO_TEST_CASE(block_sized_simple_round_trip) { + uint8_t *compressed = nullptr; + uint32_t compressed_size = 0; + auto result = + lzx_compress(block_sized_simple.data(), block_sized_simple.size(), + &compressed, &compressed_size); + BOOST_TEST(!result, "lzx_compress must return success"); + + uint8_t *decompressed = nullptr; + uint32_t decompressed_buffer_size = 0; + uint32_t decompressed_size = 0; + result = lzx_decompress(compressed, compressed_size, &decompressed, + &decompressed_buffer_size, &decompressed_size); + BOOST_TEST(!result, "lzx_decompress must return success"); + + std::string diff; + BOOST_TEST(check_decompressed(block_sized_simple, decompressed, + decompressed_size, diff), + diff); + free(decompressed); + free(compressed); +} + +BOOST_AUTO_TEST_CASE(block_sized_plus_one_simple_round_trip) { + uint8_t *compressed = nullptr; + uint32_t compressed_size = 0; + auto result = lzx_compress(block_sized_plus_one_simple.data(), + block_sized_plus_one_simple.size(), &compressed, + &compressed_size); + BOOST_TEST(!result, "lzx_compress must return success"); + + uint8_t *decompressed = nullptr; + uint32_t decompressed_buffer_size = 0; + uint32_t decompressed_size = 0; + result = lzx_decompress(compressed, compressed_size, &decompressed, + &decompressed_buffer_size, &decompressed_size); + BOOST_TEST(!result, "lzx_decompress must return success"); + + std::string diff; + BOOST_TEST(check_decompressed(block_sized_plus_one_simple, decompressed, + decompressed_size, diff), + diff); + + free(decompressed); + free(compressed); +} + +BOOST_AUTO_TEST_CASE(large_simple_round_trip) { + uint8_t *compressed = nullptr; + uint32_t compressed_size = 0; + auto result = lzx_compress(large_simple.data(), large_simple.size(), + &compressed, &compressed_size); + BOOST_TEST(!result, "lzx_compress must return success"); + + uint8_t *decompressed = nullptr; + uint32_t decompressed_buffer_size = 0; + uint32_t decompressed_size = 0; + result = lzx_decompress(compressed, compressed_size, &decompressed, + &decompressed_buffer_size, &decompressed_size); + BOOST_TEST(!result, "lzx_decompress must return success"); + + std::string diff; + BOOST_TEST( + check_decompressed(large_simple, decompressed, decompressed_size, diff), + diff); + + free(decompressed); + free(compressed); +} + + +BOOST_AUTO_TEST_CASE(large_noise_round_trip) { + uint8_t *compressed = nullptr; + uint32_t compressed_size = 0; + auto result = lzx_compress(large_noise.data(), large_noise.size(), + &compressed, &compressed_size); + BOOST_TEST(!result, "lzx_compress must return success"); + + uint8_t *decompressed = nullptr; + uint32_t decompressed_buffer_size = 0; + uint32_t decompressed_size = 0; + result = lzx_decompress(compressed, compressed_size, &decompressed, + &decompressed_buffer_size, &decompressed_size); + BOOST_TEST(!result, "lzx_decompress must return success"); + + std::string diff; + BOOST_TEST( + check_decompressed(large_noise, decompressed, decompressed_size, diff), + diff); + + free(decompressed); + free(compressed); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/vc/XboxBiosTools.vcxproj b/vc/XboxBiosTools.vcxproj index eed8ca1..af871fa 100644 --- a/vc/XboxBiosTools.vcxproj +++ b/vc/XboxBiosTools.vcxproj @@ -266,7 +266,7 @@ - +