refactored testing utility

- factored out common parts in tests into T_BeginTest and T_EndTest
- separated radlink and DWARF tests
This commit is contained in:
Nikita Smith
2026-02-05 19:45:34 -08:00
parent d363c30e95
commit 8b729d4588
9 changed files with 4404 additions and 5301 deletions
+3 -1
View File
@@ -73,6 +73,8 @@ set cl_link= /link /MANIFEST:EMBED /INCREMENTAL:NO /pdbaltpath:%%%%_PDB%%%
set cl_out= /out: set cl_out= /out:
set cl_linker= set cl_linker=
set clang_common= -I..\src\ -I..\local\ -fdiagnostics-absolute-paths -Wall -Wno-unknown-warning-option -Wno-missing-braces -Wno-unused-function -Wno-unused-parameter -Wno-writable-strings -Wno-missing-field-initializers -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -ferror-limit=10000 -mcx16 -msha set clang_common= -I..\src\ -I..\local\ -fdiagnostics-absolute-paths -Wall -Wno-unknown-warning-option -Wno-missing-braces -Wno-unused-function -Wno-unused-parameter -Wno-writable-strings -Wno-missing-field-initializers -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -ferror-limit=10000 -mcx16 -msha
set clang_debug= call clang -g -O0 -DBUILD_DEBUG=1 %clang_common% %auto_compile_flags%
set clang_release= call clang -g -O2 -DBUILD_DEBUG=0 %clang_common% %auto_compile_flags%
set clang_debug= call clang -g -O0 -DBUILD_DEBUG=1 -D_DEBUG %clang_common% %auto_compile_flags% set clang_debug= call clang -g -O0 -DBUILD_DEBUG=1 -D_DEBUG %clang_common% %auto_compile_flags%
set clang_release= call clang -g -O2 -DBUILD_DEBUG=0 -DNDEBUG %clang_common% %auto_compile_flags% set clang_release= call clang -g -O2 -DBUILD_DEBUG=0 -DNDEBUG %clang_common% %auto_compile_flags%
set clang_link= -fuse-ld=lld -Xlinker /MANIFEST:EMBED -Xlinker /pdbaltpath:%%%%_PDB%%%% -Xlinker /NATVIS:"%~dp0\src\natvis\base.natvis" -Xlinker /opt:ref -Xlinker /opt:icf set clang_link= -fuse-ld=lld -Xlinker /MANIFEST:EMBED -Xlinker /pdbaltpath:%%%%_PDB%%%% -Xlinker /NATVIS:"%~dp0\src\natvis\base.natvis" -Xlinker /opt:ref -Xlinker /opt:icf
@@ -144,7 +146,7 @@ if "%strip_lib_debug%"=="1" set didbuild=1 && %compile% ..\src\strip_
if "%mule_main%"=="1" set didbuild=1 && del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1 if "%mule_main%"=="1" set didbuild=1 && del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1
if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1 if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1
if "%mule_hotload%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1 if "%mule_hotload%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1
if "%torture%"=="1" set didbuild=1 && %compile% ..\src\torture\torture.c %compile_link% %out%torture.exe || exit /b1 if "%torture%"=="1" set didbuild=1 && %compile% ..\src\torture\torture_main.c %compile_link% %out%torture.exe || exit /b1
if "%dwarf_expr_test%"=="1" set didbuild=1 && %compile% ..\src\torture\dwarf_expr_test.c %compile_link% %out%dwarf_expr_test.exe || exit /b1 if "%dwarf_expr_test%"=="1" set didbuild=1 && %compile% ..\src\torture\dwarf_expr_test.c %compile_link% %out%dwarf_expr_test.exe || exit /b1
if "%mule_peb_trample%"=="1" ( if "%mule_peb_trample%"=="1" (
set didbuild=1 set didbuild=1
+35 -2
View File
@@ -127,12 +127,45 @@ coff_section_table_from_data(Arena *arena, String8 data, Rng1U64 section_table_r
U64 section_count = dim_1u64(section_table_range) / sizeof(COFF_SectionHeader); U64 section_count = dim_1u64(section_table_range) / sizeof(COFF_SectionHeader);
COFF_SectionHeader **section_table = push_array_no_zero(arena, COFF_SectionHeader *, section_count+1); COFF_SectionHeader **section_table = push_array_no_zero(arena, COFF_SectionHeader *, section_count+1);
section_table[0] = push_array(arena, COFF_SectionHeader, 1); section_table[0] = push_array(arena, COFF_SectionHeader, 1);
for (U64 i = 0; i < section_count; ++i) { for EachIndex(sect_idx, section_count) {
section_table[i+1] = str8_deserial_get_raw_ptr(data, section_table_range.min + i*sizeof(COFF_SectionHeader), sizeof(COFF_SectionHeader)); section_table[sect_idx + 1] = str8_deserial_get_raw_ptr(data, section_table_range.min + sect_idx*sizeof(COFF_SectionHeader), sizeof(COFF_SectionHeader));
} }
return section_table; return section_table;
} }
internal COFF_SectionHeader *
coff_section_header_from_name(String8 string_table, COFF_SectionHeader *section_table, U64 section_count, String8 name)
{
for EachIndex(sect_idx, section_count) {
if (str8_match(coff_name_from_section_header(string_table, &section_table[sect_idx]), name, 0)) {
return &section_table[sect_idx];
}
}
return 0;
}
internal COFF_SectionHeaderArray
coff_section_header_array_from_name(Arena *arena, String8 string_table, COFF_SectionHeader *section_table, U64 section_count, String8 name)
{
U64 match_count = 0;
for EachIndex(sect_idx, section_count) {
if (str8_match(coff_name_from_section_header(string_table, &section_table[sect_idx]), name, 0)) {
match_count += 1;
}
}
COFF_SectionHeader *matches = push_array(arena, COFF_SectionHeader, match_count);
for (U64 sect_idx = 0, match_idx = 0; sect_idx < section_count; sect_idx += 1) {
if (str8_match(coff_name_from_section_header(string_table, &section_table[sect_idx]), name, 0)) {
matches[match_idx] = section_table[sect_idx];
match_idx += 1;
}
}
return (COFF_SectionHeaderArray){ .count = match_count, .v = matches };
}
internal COFF_ParsedSymbol internal COFF_ParsedSymbol
coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32) coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32)
{ {
+5 -2
View File
@@ -251,14 +251,17 @@ internal COFF_FileHeaderInfo coff_file_header_info_from_data(String8 raw_coff);
//////////////////////////////// ////////////////////////////////
// Section // Section
internal COFF_SectionHeader ** coff_section_table_from_data(Arena *arena, String8 data, Rng1U64 section_table_range); internal COFF_SectionHeader ** coff_section_table_from_data (Arena *arena, String8 data, Rng1U64 section_table_range);
internal COFF_SectionHeader * coff_section_header_from_name (String8 string_table, COFF_SectionHeader *section_table, U64 section_count, String8 name);
internal COFF_SectionHeaderArray coff_section_header_array_from_name(Arena *arena, String8 string_table, COFF_SectionHeader *section_table, U64 section_count, String8 name);
internal String8 coff_name_from_section_header (String8 string_table, COFF_SectionHeader *header);
//////////////////////////////// ////////////////////////////////
// Symbol // Symbol
internal COFF_ParsedSymbol coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32); internal COFF_ParsedSymbol coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32);
internal COFF_ParsedSymbol coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16); internal COFF_ParsedSymbol coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16);
internal COFF_ParsedSymbol coff_parse_symbol(COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx); internal COFF_ParsedSymbol coff_parse_symbol (COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx);
internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count); internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
internal COFF_Symbol32Array coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count); internal COFF_Symbol32Array coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
+115 -5296
View File
File diff suppressed because it is too large Load Diff
+94
View File
@@ -0,0 +1,94 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#pragma once
////////////////////////////////
typedef enum
{
T_RunStatus_Fail,
T_RunStatus_Crash,
T_RunStatus_Pass,
} T_RunStatus;
typedef struct
{
T_RunStatus status;
char *fail_file;
int fail_line;
char *fail_cond;
} T_RunResult;
typedef T_RunResult (*T_Run)(void);
typedef struct
{
T_Run run;
T_RunResult result;
} T_RunCtx;
typedef struct
{
char *group;
char *label;
int decl_line;
T_Run r;
} T_Test;
extern U64 g_torture_test_count;
extern T_Test g_torture_tests[0xffffff];
#define T_AddTest(name, l, ...) \
T_RunResult t_##name(void); \
__VA_ARGS__ void t_add_test_##name(void) \
{ \
g_torture_tests[g_torture_test_count].group = T_Group; \
g_torture_tests[g_torture_test_count].label = Stringify(name); \
g_torture_tests[g_torture_test_count].r = &t_##name; \
g_torture_tests[g_torture_test_count].decl_line = l; \
g_torture_test_count += 1; \
}
#if COMPILER_MSVC
#pragma section(".CRT$XCU", read)
# define T_BeginTest_(name) \
T_AddTest(name, __LINE__) \
__declspec(allocate(".CRT$XCU")) void(*r_##name)(void) = t_add_test_##name; \
__pragma(comment(linker, "/include:" Stringify(r_##name)))
#else
# define T_BeginTest_(name) \
T_AddTest(name, __LINE__, __attribute__((constructor)))
#endif
#define T_BeginTest(name) \
T_BeginTest_(name) \
T_RunResult t_##name(void) { \
Temp scratch = scratch_begin(0,0); \
T_RunResult result = { .status = T_RunStatus_Fail };
#define T_EndTest \
result.status = T_RunStatus_Pass; \
exit__:; \
scratch_end(scratch); \
return result; \
}
#define T_Ok(c) do { if (!(c)) { result.fail_file = __FILE__; result.fail_line = __LINE__; result.fail_cond = Stringify(c); goto exit__; } } while(0)
////////////////////////////////
// output directory
internal B32 t_write_file_list(String8 name, String8List data);
internal B32 t_write_file(String8 name, String8 data);
internal String8 t_read_file(Arena *arena, String8 name);
internal String8 t_make_file_path(Arena *arena, String8 name);
// test runner
internal void t_run_caller(void *raw_ctx);
internal void t_run_fail_handler(void *raw_ctx);
internal T_RunResult t_run(T_Run run);
internal B32 t_invoke(String8 exe, String8 cmdline, U64 timeout);
+190
View File
@@ -0,0 +1,190 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#define T_Group "Dwarf"
T_BeginTest(value_in_register)
{
// setup register context
REGS_RegBlockX64 regs = {0};
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, DW_ExprOp_Reg3 - DW_ExprOp_Reg0);
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
U64 value = 0xc0ffee;
MemoryCopy((U8 *)&regs + reg_range.min, &value, sizeof(value));
// compile a simple program which reads the value from register 3
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Reg3) };
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
// evaluate the program
DW_ExprValue expr_value;
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, &regs, 0, 0, &expr_value);
// validate eval result
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
T_Ok(expr_value.type == DW_ExprValueType_U64);
T_Ok(expr_value.u64 == value);
}
T_EndTest;
T_BeginTest(value_in_x_register)
{
// setup register context
REGS_RegBlockX64 regs = {0};
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, DW_RegX64_FsBase);
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
U64 value = 0xc0ffee;
MemoryCopy((U8 *)&regs + reg_range.min, &value, sizeof(value));
// compile a simple program which reads the value from register 3
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(RegX), DW_ExprEnc_ULEB128(DW_RegX64_FsBase) };
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
// evaluate the program
DW_ExprValue expr_value;
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, &regs, 0, 0, &expr_value);
// validate eval result
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
T_Ok(expr_value.type == DW_ExprValueType_U64);
T_Ok(expr_value.u64 == value);
}
T_EndTest;
T_BeginTest(address_of_value)
{
// compile a simple program which reads address
U64 addr = 0xdeadbeef;
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Addr), DW_ExprEnc_U64(addr) };
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
// evaluate the program
DW_ExprValue expr_value;
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, 0, 0, 0, 0, &expr_value);
// validate eval result
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
T_Ok(expr_value.type == DW_ExprValueType_Addr);
T_Ok(expr_value.addr == addr);
}
T_EndTest;
T_BeginTest(register_relative_variable)
{
// setup register context
REGS_RegBlockX64 regs = {0};
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, DW_ExprOp_BReg11 - DW_ExprOp_BReg0);
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
U64 value = 1;
MemoryCopy((U8 *)&regs + reg_range.min, &value, sizeof(value));
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(BReg11), DW_ExprEnc_SLEB128(44) };
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
DW_ExprValue expr_value;
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, &regs, 0, 0, &expr_value);
// validate eval result
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
T_Ok(expr_value.type == DW_ExprValueType_Addr);
T_Ok(expr_value.addr == (1 + 44));
}
T_EndTest;
T_BeginTest(frame_relative_variable)
{
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(FBReg), DW_ExprEnc_SLEB128(-50) };
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
U64 frame_base = 123;
DW_ExprValue expr_value;
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, frame_base, 0, 0, max_U64, expr, 0, 0, 0, 0, &expr_value);
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
T_Ok(expr_value.type == DW_ExprValueType_Addr);
T_Ok(expr_value.addr == frame_base -50);
}
T_EndTest;
internal
MACHINE_OP_MEM_READ(t_machine_op_mem_read)
{
MemoryCopy(buffer, PtrFromInt(addr), buffer_size);
return MachineOpResult_Ok;
}
T_BeginTest(call_by_reference)
{
U8 *memory = push_array(scratch.arena, U8, 128);
U64 value = 0xc0ffee;
MemoryCopy(memory + 32, &value, sizeof(value));
REGS_RegBlockX64 regs = {0};
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, 58); // fsbase
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
U64 memory_ptr = IntFromPtr(memory);
MemoryCopy((U8 *)&regs + reg_range.min, &memory_ptr, sizeof(memory_ptr));
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(BRegX), DW_ExprEnc_ULEB128(58), DW_ExprEnc_SLEB128(32), DW_ExprEnc_Op(Deref) };
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
DW_ExprValue expr_value = { 0 };
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, &regs, t_machine_op_mem_read, 0, &expr_value);
T_Ok(expr_value.type == DW_ExprValueType_Generic);
T_Ok(expr_value.generic.size == sizeof(U64));
T_Ok(*(U64 *)expr_value.generic.str == value);
}
T_EndTest;
T_BeginTest(plus_uconst)
{
U64 struct_addr = 0x123;
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Addr), DW_ExprEnc_Addr(struct_addr), DW_ExprEnc_Op(PlusUConst), DW_ExprEnc_ULEB128(4) };
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
DW_ExprValue expr_value;
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, 0, 0, t_machine_op_mem_read, 0, &expr_value);
T_Ok(expr_value.type == DW_ExprValueType_Addr);
T_Ok(expr_value.addr == 0x123 + 4);
}
T_EndTest;
#if 0
T_BeginTest(reg_split_spill)
{
// setup register context
REGS_RegBlockX64 regs = {0};
{
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, DW_ExprOp_BReg3 - DW_ExprOp_BReg0);
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
U64 value = 0xaaaa;
MemoryCopy((U8 *)&regs + reg_range.min, &value, sizeof(value));
}
{
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, DW_ExprOp_BReg10 - DW_ExprOp_BReg0);
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
U64 value = 0xbbbb;
MemoryCopy((U8 *)&regs + reg_range.min, &value, sizeof(value));
}
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Reg3), DW_ExprEnc_Op(Piece), DW_ExprEnc_ULEB128(4), DW_ExprEnc_Op(Reg10), DW_ExprEnc_Op(Piece), DW_ExprEnc_ULEB128(2) };
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
DW_ExprValue expr_value;
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, &regs, 0, 0, &expr_value);
}
T_EndTest;
#endif
#undef T_Group
+62
View File
@@ -0,0 +1,62 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
// Build Options
#define BUILD_CONSOLE_INTERFACE 1
#define BUILD_TITLE "TORTURE"
////////////////////////////////
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "linker/base_ext/base_core.h"
#include "linker/base_ext/base_arena.h"
#include "linker/base_ext/base_arrays.h"
#include "linker/hash_table.h"
#include "coff/coff.h"
#include "coff/coff_parse.h"
#include "coff/coff_obj_writer.h"
#include "coff/coff_lib_writer.h"
#include "pe/pe.h"
#include "pe/pe_section_flags.h"
#include "elf/elf.h"
#include "elf/elf_parse.h"
#include "dwarf/dwarf_inc.h"
#include "regs/regs.h"
#include "regs/dwarf/regs_dwarf.h"
#include "linker/lnk_cmd_line.h"
#include "linker/lnk_cmd_line.c"
#include "linker/lnk_error.h"
#include "torture.h"
#include "torture_radlink.h"
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "linker/hash_table.c"
#include "linker/base_ext/base_core.c"
#include "linker/base_ext/base_arena.c"
#include "linker/base_ext/base_arrays.c"
#include "coff/coff.c"
#include "coff/coff_parse.c"
#include "coff/coff_obj_writer.c"
#include "coff/coff_lib_writer.c"
#include "pe/pe.c"
#include "elf/elf.c"
#include "elf/elf_parse.c"
#include "dwarf/dwarf_inc.c"
#include "regs/regs.c"
#include "regs/dwarf/regs_dwarf.c"
#include "torture.c"
#include "torture_radlink.c"
#include "torture_dwarf.c"
////////////////////////////////
internal void
entry_point(CmdLine *cmdline)
{
t_entry_point(cmdline);
}
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#pragma once
////////////////////////////////
typedef enum
{
T_Linker_Null,
T_Linker_RAD,
T_Linker_MSVC,
T_Linker_LLVM
} T_Linker;
typedef enum
{
T_MsvcLinkExitCode_UnresolvedExternals = 1120,
T_MsvcLinkExitCode_CorruptOrInvalidSymbolTable = 1235,
T_MsvcLinkExitCode_SectionsFoundWithDifferentAttributes = 4078,
} T_MsvcLinkExitCode;
////////////////////////////////
#define t_invoke_linker_timeout(c, t) T_Ok(t_invoke(g_linker, c, t))
#define t_invoke_linker_timeoutf(t, f, ...) t_invoke_linker_timeout(push_str8f(scratch.arena, f, ##__VA_ARGS__), t)
#define t_invoke_linker(c) t_invoke_linker_timeout(c, max_U64)
#define t_invoke_linkerf(f, ...) t_invoke_linker(push_str8f(scratch.arena, f, ##__VA_ARGS__))
internal T_Linker t_id_linker(void);
internal COFF_ObjSection * t_push_text_section(COFF_ObjWriter *obj_writer, String8 data);
internal COFF_ObjSection * t_push_data_section(COFF_ObjWriter *obj_writer, String8 data);
internal COFF_ObjSection * t_push_rdata_section(COFF_ObjWriter *obj_writer, String8 data);
internal String8 t_make_entry_obj(Arena *arena);
internal String8 t_make_sec_defn_obj(Arena *arena, String8 payload);
internal B32 t_write_entry_obj(void);