diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index 0b8811cb..6fa63320 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -840,59 +840,12 @@ di_parse_thread__entry_point(void *p) RDI_Parsed rdi_parsed = rdi_parsed_maybe_compressed; if(got_task) { - U64 decompressed_size = file_props.size; - for(U64 dsec_idx = 0; dsec_idx < rdi_parsed_maybe_compressed.dsec_count; dsec_idx += 1) - { - decompressed_size += (rdi_parsed_maybe_compressed.dsecs[dsec_idx].unpacked_size - rdi_parsed_maybe_compressed.dsecs[dsec_idx].encoded_size); - } + U64 decompressed_size = rdi_decompressed_size_from_parsed(&rdi_parsed_maybe_compressed); if(decompressed_size > file_props.size) { rdi_parsed_arena = arena_alloc(); U8 *decompressed_data = push_array_no_zero(rdi_parsed_arena, U8, decompressed_size); - - // rjf: copy header - RDI_Header *src_header = (RDI_Header *)file_base; - RDI_Header *dst_header = (RDI_Header *)decompressed_data; - { - MemoryCopy(dst_header, src_header, sizeof(RDI_Header)); - } - - // rjf: copy & adjust sections for decompressed version - if(rdi_parsed_maybe_compressed.dsec_count != 0) - { - RDI_DataSection *dsec_base = (RDI_DataSection *)(decompressed_data + dst_header->data_section_off); - MemoryCopy(dsec_base, (U8 *)file_base + src_header->data_section_off, sizeof(RDI_DataSection) * rdi_parsed_maybe_compressed.dsec_count); - U64 off = dst_header->data_section_off + sizeof(RDI_DataSection) * rdi_parsed_maybe_compressed.dsec_count; - off += 7; - off -= off%8; - for(U64 idx = 0; idx < rdi_parsed_maybe_compressed.dsec_count; idx += 1) - { - dsec_base[idx].encoding = RDI_DataSectionEncoding_Unpacked; - dsec_base[idx].off = off; - dsec_base[idx].encoded_size = dsec_base[idx].unpacked_size; - off += dsec_base[idx].unpacked_size; - off += 7; - off -= off%8; - } - } - - // rjf: decompress sections into new decompressed file buffer - if(rdi_parsed_maybe_compressed.dsec_count != 0) - { - RDI_DataSection *src_first = rdi_parsed_maybe_compressed.dsecs; - RDI_DataSection *dst_first = (RDI_DataSection *)(decompressed_data + dst_header->data_section_off); - RDI_DataSection *src_opl = src_first + rdi_parsed_maybe_compressed.dsec_count; - RDI_DataSection *dst_opl = dst_first + rdi_parsed_maybe_compressed.dsec_count; - for(RDI_DataSection *src = src_first, *dst = dst_first; - src < src_opl && dst < dst_opl; - src += 1, dst += 1) - { - rr_lzb_simple_decode((U8*)file_base + src->off, src->encoded_size, - decompressed_data + dst->off, dst->unpacked_size); - } - } - - // rjf: re-parse + rdi_decompress_parsed(decompressed_data, decompressed_size, &rdi_parsed_maybe_compressed); RDI_ParseStatus parse_status = rdi_parse(decompressed_data, decompressed_size, &rdi_parsed); (void)parse_status; } diff --git a/src/lib_rdi_format/rdi_format_parse.c b/src/lib_rdi_format/rdi_format_parse.c index 3b3c2f61..dafce68b 100644 --- a/src/lib_rdi_format/rdi_format_parse.c +++ b/src/lib_rdi_format/rdi_format_parse.c @@ -221,6 +221,17 @@ rdi_parse(RDI_U8 *data, RDI_U64 size, RDI_Parsed *out) return(result); } +RDI_PROC RDI_U64 +rdi_decompressed_size_from_parsed(RDI_Parsed *rdi) +{ + RDI_U64 decompressed_size = rdi->raw_data_size; + for(RDI_U64 dsec_idx = 0; dsec_idx < rdi->dsec_count; dsec_idx += 1) + { + decompressed_size += (rdi->dsecs[dsec_idx].unpacked_size - rdi->dsecs[dsec_idx].encoded_size); + } + return decompressed_size; +} + RDI_PROC RDI_U8* rdi_string_from_idx(RDI_Parsed *parsed, RDI_U32 idx, RDI_U64 *len_out){ RDI_U8 *result = 0; diff --git a/src/lib_rdi_format/rdi_format_parse.h b/src/lib_rdi_format/rdi_format_parse.h index 9e97bcb3..66b29019 100644 --- a/src/lib_rdi_format/rdi_format_parse.h +++ b/src/lib_rdi_format/rdi_format_parse.h @@ -153,6 +153,9 @@ static RDI_Local rdi_local_nil = {0}; RDI_PROC RDI_ParseStatus rdi_parse(RDI_U8 *data, RDI_U64 size, RDI_Parsed *out); +RDI_PROC RDI_U64 +rdi_decompressed_size_from_parsed(RDI_Parsed *rdi); + RDI_PROC RDI_U8* rdi_string_from_idx(RDI_Parsed *parsed, RDI_U32 idx, RDI_U64 *len_out); diff --git a/src/raddbg/raddbg_main.cpp b/src/raddbg/raddbg_main.cpp index 70c881b6..85f5830a 100644 --- a/src/raddbg/raddbg_main.cpp +++ b/src/raddbg/raddbg_main.cpp @@ -22,10 +22,6 @@ //~ rjf: Includes //- rjf: [lib] -#include "lib_rdi_format/rdi_format.h" -#include "lib_rdi_format/rdi_format.c" -#include "lib_rdi_format/rdi_format_parse.h" -#include "lib_rdi_format/rdi_format_parse.c" #include "third_party/rad_lzb_simple/rad_lzb_simple.h" #include "third_party/rad_lzb_simple/rad_lzb_simple.c" @@ -34,6 +30,7 @@ #include "os/os_inc.h" #include "task_system/task_system.h" #include "ico/ico.h" +#include "rdi_format_local/rdi_format_local.h" #include "rdi_make_local/rdi_make_local.h" #include "mdesk/mdesk.h" #include "hash_store/hash_store.h" @@ -73,6 +70,7 @@ #include "os/os_inc.c" #include "task_system/task_system.c" #include "ico/ico.c" +#include "rdi_format_local/rdi_format_local.c" #include "rdi_make_local/rdi_make_local.c" #include "mdesk/mdesk.c" #include "hash_store/hash_store.c" diff --git a/src/rdi_dump/rdi_dump_main.c b/src/rdi_dump/rdi_dump_main.c index 315850e9..c6ad215d 100644 --- a/src/rdi_dump/rdi_dump_main.c +++ b/src/rdi_dump/rdi_dump_main.c @@ -15,25 +15,19 @@ //~ rjf: Includes //- rjf: [lib] -#include "lib_rdi_format/rdi_format.h" -#include "lib_rdi_format/rdi_format_parse.h" -#include "lib_rdi_format/rdi_format.c" -#include "lib_rdi_format/rdi_format_parse.c" #include "third_party/rad_lzb_simple/rad_lzb_simple.h" #include "third_party/rad_lzb_simple/rad_lzb_simple.c" //- rjf: [h] #include "base/base_inc.h" #include "os/os_inc.h" -#include "path/path.h" -#include "dbgi/dbgi.h" +#include "rdi_format_local/rdi_format_local.h" #include "rdi_dump.h" //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" -#include "path/path.c" -#include "dbgi/dbgi.c" +#include "rdi_format_local/rdi_format_local.c" #include "rdi_dump.c" //////////////////////////////// @@ -46,7 +40,6 @@ entry_point(CmdLine *cmd_line) //- rjf: set up // Arena *arena = arena_alloc(); - DI_Scope *di_scope = di_scope_open(); String8List errors = {0}; ////////////////////////////// @@ -74,7 +67,6 @@ entry_point(CmdLine *cmd_line) DumpFlag_Strings = (1<<16), }; String8 input_name = {0}; - String8 input_data = {0}; DumpFlags dump_flags = (U32)0xffffffff; { // rjf: extract input file path @@ -111,24 +103,46 @@ entry_point(CmdLine *cmd_line) } ////////////////////////////// - //- rjf: obtain rdi parse + //- rjf: load file // - RDI_Parsed *rdi = &di_rdi_parsed_nil; + String8 input_data = os_data_from_file_path(arena, input_name); if(input_name.size == 0) { str8_list_pushf(arena, &errors, "error (input): No input RDI file specified."); } - else - { - DI_Key key = {input_name}; - di_open(&key); - rdi = di_rdi_from_key(di_scope, &key, max_U64); - } - if(rdi == &di_rdi_parsed_nil) + else if(input_data.size == 0) { str8_list_pushf(arena, &errors, "error (input): No input RDI file successfully loaded; either the path or file contents are invalid."); } + ////////////////////////////// + //- rjf: obtain initial rdi parse + // + RDI_Parsed rdi_ = {0}; + RDI_Parsed *rdi = &rdi_; + RDI_ParseStatus status = rdi_parse(input_data.str, input_data.size, rdi); + + ////////////////////////////// + //- rjf: decompress rdi if necessary + // + { + U64 decompressed_size = rdi_decompressed_size_from_parsed(rdi); + if(decompressed_size > input_data.size) + { + U8 *decompressed_data = push_array_no_zero(arena, U8, decompressed_size); + rdi_decompress_parsed(decompressed_data, decompressed_size, rdi); + status = rdi_parse(decompressed_data, decompressed_size, rdi); + } + } + + ////////////////////////////// + //- rjf: error on bad parse status + // + if(status != RDI_ParseStatus_Good) + { + str8_list_pushf(arena, &errors, "error (input): RDI file could not be successfully decoded."); + } + ////////////////////////////// //- rjf: output error strings to stderr // @@ -142,7 +156,7 @@ entry_point(CmdLine *cmd_line) //- rjf: build dump strings // String8List dump = {0}; - if(rdi != &di_rdi_parsed_nil) + if(errors.node_count != 0) { //- rjf: DATA SECTIONS if(dump_flags & DumpFlag_DataSections) @@ -437,6 +451,4 @@ entry_point(CmdLine *cmd_line) { fwrite(n->string.str, 1, n->string.size, stdout); } - - di_scope_close(di_scope); } diff --git a/src/rdi_format_local/rdi_format_local.c b/src/rdi_format_local/rdi_format_local.c new file mode 100644 index 00000000..6fae2eb3 --- /dev/null +++ b/src/rdi_format_local/rdi_format_local.c @@ -0,0 +1,52 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#include "lib_rdi_format/rdi_format.c" +#include "lib_rdi_format/rdi_format_parse.c" + +internal void +rdi_decompress_parsed(U8 *decompressed_data, U64 decompressed_size, RDI_Parsed *og_rdi) +{ + // rjf: copy header + RDI_Header *src_header = (RDI_Header *)og_rdi->raw_data; + RDI_Header *dst_header = (RDI_Header *)decompressed_data; + { + MemoryCopy(dst_header, src_header, sizeof(RDI_Header)); + } + + // rjf: copy & adjust sections for decompressed version + if(og_rdi->dsec_count != 0) + { + RDI_DataSection *dsec_base = (RDI_DataSection *)(decompressed_data + dst_header->data_section_off); + MemoryCopy(dsec_base, (U8 *)og_rdi->raw_data + src_header->data_section_off, sizeof(RDI_DataSection) * og_rdi->dsec_count); + U64 off = dst_header->data_section_off + sizeof(RDI_DataSection) * og_rdi->dsec_count; + off += 7; + off -= off%8; + for(U64 idx = 0; idx < og_rdi->dsec_count; idx += 1) + { + dsec_base[idx].encoding = RDI_DataSectionEncoding_Unpacked; + dsec_base[idx].off = off; + dsec_base[idx].encoded_size = dsec_base[idx].unpacked_size; + off += dsec_base[idx].unpacked_size; + off += 7; + off -= off%8; + } + } + + // rjf: decompress sections into new decompressed file buffer + if(og_rdi->dsec_count != 0) + { + RDI_DataSection *src_first = og_rdi->dsecs; + RDI_DataSection *dst_first = (RDI_DataSection *)(decompressed_data + dst_header->data_section_off); + RDI_DataSection *src_opl = src_first + og_rdi->dsec_count; + RDI_DataSection *dst_opl = dst_first + og_rdi->dsec_count; + for(RDI_DataSection *src = src_first, *dst = dst_first; + src < src_opl && dst < dst_opl; + src += 1, dst += 1) + { + rr_lzb_simple_decode((U8*)og_rdi->raw_data + src->off, src->encoded_size, + decompressed_data + dst->off, dst->unpacked_size); + } + } +} + diff --git a/src/rdi_format_local/rdi_format_local.h b/src/rdi_format_local/rdi_format_local.h new file mode 100644 index 00000000..48f7eea3 --- /dev/null +++ b/src/rdi_format_local/rdi_format_local.h @@ -0,0 +1,12 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RDI_FORMAT_LOCAL_H +#define RDI_FORMAT_LOCAL_H + +#include "lib_rdi_format/rdi_format.h" +#include "lib_rdi_format/rdi_format_parse.h" + +internal void rdi_decompress_parsed(U8 *decompressed_data, U64 decompressed_size, RDI_Parsed *og_rdi); + +#endif // RDI_FORMAT_LOCAL_H