mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-06 22:08:41 +00:00
add tests for symbols with absolute address
This commit is contained in:
committed by
Ryan Fleury
parent
01c905dbbd
commit
f17ed8485d
+227
-20
@@ -103,11 +103,12 @@ t_invoke_linkerf(char *fmt, ...)
|
|||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(0,0);
|
Temp scratch = scratch_begin(0,0);
|
||||||
va_list args;
|
va_list args;
|
||||||
va_strat(args, fmt);
|
va_start(args, fmt);
|
||||||
String8 cmdline = push_str8fv(scratch.arena, fmt, args);
|
String8 cmdline = push_str8fv(scratch.arena, fmt, args);
|
||||||
|
int exit_code = t_invoke_linker(cmdline);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
return result;
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String8
|
internal String8
|
||||||
@@ -180,6 +181,24 @@ t_coff_section_header_from_name(String8 string_table, COFF_SectionHeader *sectio
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
internal COFF_ObjSection *
|
||||||
|
t_push_text_section(COFF_ObjWriter *obj_writer, String8 data)
|
||||||
|
{
|
||||||
|
return coff_obj_writer_push_section(obj_writer, str8_lit(".text"), COFF_SectionFlag_CntCode|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemExecute|COFF_SectionFlag_Align1Bytes, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal COFF_ObjSection *
|
||||||
|
t_push_data_section(COFF_ObjWriter *obj_writer, String8 data)
|
||||||
|
{
|
||||||
|
return coff_obj_writer_push_section(obj_writer, str8_lit(".data"), COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal COFF_ObjSection *
|
||||||
|
t_push_rdata_section(COFF_ObjWriter *obj_writer, String8 data)
|
||||||
|
{
|
||||||
|
return coff_obj_writer_push_section(obj_writer, str8_lit(".rdata"), COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead, data);
|
||||||
|
}
|
||||||
|
|
||||||
internal T_Result
|
internal T_Result
|
||||||
t_simple_link_test(void)
|
t_simple_link_test(void)
|
||||||
{
|
{
|
||||||
@@ -238,10 +257,10 @@ t_simple_link_test(void)
|
|||||||
// check section alignment
|
// check section alignment
|
||||||
for (U64 sect_idx = 0; sect_idx < pe.section_count; sect_idx += 1) {
|
for (U64 sect_idx = 0; sect_idx < pe.section_count; sect_idx += 1) {
|
||||||
COFF_SectionHeader *sect_header = §ion_table[sect_idx];
|
COFF_SectionHeader *sect_header = §ion_table[sect_idx];
|
||||||
if (AlignPadPow2(text_section->fsize, file_align) != 0) {
|
if (AlignPadPow2(sect_header->fsize, file_align) != 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (AlignPadPow2(text_section->voff, virt_align) != 0) {
|
if (AlignPadPow2(sect_header->voff, virt_align) != 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,23 +332,30 @@ t_abs_vs_weak(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int linker_exit_code = t_invoke_linker(str8_lit("/subsystem:console /entry:my_entry /out:a.exe abs.obj text.obj"));
|
int abs_vs_weak_exit_code = t_invoke_linker(str8_lit("/subsystem:console /entry:my_entry /out:a.exe abs.obj text.obj"));
|
||||||
if (linker_exit_code == 0) {
|
if (abs_vs_weak_exit_code != 0) {
|
||||||
String8 exe = t_read_file(scratch.arena, str8_lit("a.exe"));
|
goto exit;
|
||||||
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe);
|
}
|
||||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(exe, pe.section_table_range).str;
|
|
||||||
String8 string_table = str8_substr(exe, pe.string_table_range);
|
|
||||||
|
|
||||||
COFF_SectionHeader *text_section = t_coff_section_header_from_name(string_table, section_table, pe.section_count, str8_lit(".text"));
|
int weak_vs_abs_exit_code = t_invoke_linker(str8_lit("/subsystem:console /entry:my_entry /out:a.exe text.obj abs.obj"));
|
||||||
if (text_section) {
|
if (weak_vs_abs_exit_code != 0) {
|
||||||
String8 text_data = str8_substr(exe, rng_1u64(text_section->foff, text_section->foff + text_section->fsize));
|
goto exit;
|
||||||
String8 inst = str8_prefix(text_data, 2);
|
}
|
||||||
if (str8_match(inst, str8_array(text_code, 2), 0)) {
|
|
||||||
String8 imm = str8_prefix(str8_skip(text_data, 2), 8);
|
String8 exe = t_read_file(scratch.arena, str8_lit("a.exe"));
|
||||||
U64 expected_imm = abs_value;
|
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe);
|
||||||
if (str8_match(imm, str8_struct(&expected_imm), 0)) {
|
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(exe, pe.section_table_range).str;
|
||||||
result = T_Result_Pass;
|
String8 string_table = str8_substr(exe, pe.string_table_range);
|
||||||
}
|
|
||||||
|
COFF_SectionHeader *text_section = t_coff_section_header_from_name(string_table, section_table, pe.section_count, str8_lit(".text"));
|
||||||
|
if (text_section) {
|
||||||
|
String8 text_data = str8_substr(exe, rng_1u64(text_section->foff, text_section->foff + text_section->fsize));
|
||||||
|
String8 inst = str8_prefix(text_data, 2);
|
||||||
|
if (str8_match(inst, str8_array(text_code, 2), 0)) {
|
||||||
|
String8 imm = str8_prefix(str8_skip(text_data, 2), 8);
|
||||||
|
U64 expected_imm = abs_value;
|
||||||
|
if (str8_match(imm, str8_struct(&expected_imm), 0)) {
|
||||||
|
result = T_Result_Pass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,6 +365,125 @@ exit:;
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal T_Result
|
||||||
|
t_abs_vs_regular(void)
|
||||||
|
{
|
||||||
|
Temp scratch = scratch_begin(0,0);
|
||||||
|
|
||||||
|
T_Result result = T_Result_Fail;
|
||||||
|
|
||||||
|
String8 shared_symbol_name = str8_lit("foo");
|
||||||
|
|
||||||
|
U8 regular_payload[] = { 0xC0, 0xFF, 0xEE };
|
||||||
|
String8 regular_obj_name = str8_lit("regular.obj");
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
COFF_ObjSection *data_sect = t_push_data_section(obj_writer, str8_array_fixed(regular_payload));
|
||||||
|
coff_obj_writer_push_symbol_extern(obj_writer, shared_symbol_name, 0, data_sect);
|
||||||
|
String8 regular_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
|
||||||
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
if (!t_write_file(regular_obj_name, regular_obj)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 abs_obj_name = str8_lit("abs.obj");
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, shared_symbol_name, 0x1234, COFF_SymStorageClass_External);
|
||||||
|
String8 abs_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
|
||||||
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
if (!t_write_file(abs_obj_name, abs_obj)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U8 entry_text[] = { 0xC3 };
|
||||||
|
String8 entry_obj_name = str8_lit("entry.obj");
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
COFF_ObjSection *text_sect = t_push_text_section(obj_writer, str8_array_fixed(entry_text));
|
||||||
|
coff_obj_writer_push_symbol_extern(obj_writer, str8_lit("my_entry"), 0, text_sect);
|
||||||
|
String8 entry_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
|
||||||
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
if (!t_write_file(entry_obj_name, entry_obj)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: validate that linker issues multiply defined symbol error
|
||||||
|
int linker_exit_code = t_invoke_linkerf("/subsystem:console /entry:my_entry /out:a.exe abs.obj regular.obj entry.obj");
|
||||||
|
if (linker_exit_code != 0) {
|
||||||
|
int regular_vs_abs_exit_code = t_invoke_linkerf("/subsystem:console /entry:my_entry /out:a.exe regular.obj abs.obj entry.obj");
|
||||||
|
if (regular_vs_abs_exit_code != 0) {
|
||||||
|
result = T_Result_Pass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:;
|
||||||
|
scratch_end(scratch);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal T_Result
|
||||||
|
t_abs_vs_common(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
Temp scratch = scratch_begin(0,0);
|
||||||
|
|
||||||
|
T_Result result = T_Result_Fail;
|
||||||
|
|
||||||
|
String8 shared_symbol_name = str8_lit("foo");
|
||||||
|
|
||||||
|
String8 common_obj_name = str8_lit("common.obj");
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
coff_obj_writer_push_symbol_common(obj_writer, shared_symbol_name, 321);
|
||||||
|
String8 common_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
|
||||||
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
if (!t_write_file(common_obj_name, common_obj)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 abs_obj_name = str8_lit("abs.obj");
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, shared_symbol_name, 0x1234, COFF_SymStorageClass_External);
|
||||||
|
String8 abs_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
|
||||||
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
if (!t_write_file(abs_obj_name, abs_obj)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U8 entry_text[] = { 0xC3 };
|
||||||
|
String8 entry_obj_name = str8_lit("entry.obj");
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
COFF_ObjSection *text_sect = t_push_text_section(obj_writer, str8_array_fixed(entry_text));
|
||||||
|
coff_obj_writer_push_symbol_extern(obj_writer, str8_lit("my_entry"), 0, text_sect);
|
||||||
|
String8 entry_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
|
||||||
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
if (!t_write_file(entry_obj_name, entry_obj)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int linker_exit_code = t_invoke_linkerf("/subsystem:console /entry:my_entry /out:a.exe abs.obj common.obj entry.obj");
|
||||||
|
if (linker_exit_code == 0) {
|
||||||
|
// TODO: validate that linker issues multiply defined symbol error
|
||||||
|
int common_vs_abs = t_invoke_linkerf("/subsystem:console /entry:my_entry /out:a.exe common.obj abs.obj entry.obj");
|
||||||
|
if (common_vs_abs != 0) {
|
||||||
|
result = T_Result_Pass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:;
|
||||||
|
scratch_end(scratch);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
internal String8
|
internal String8
|
||||||
t_make_sec_defn_obj(Arena *arena, String8 payload)
|
t_make_sec_defn_obj(Arena *arena, String8 payload)
|
||||||
{
|
{
|
||||||
@@ -467,6 +612,65 @@ t_find_merged_pdata(void)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal T_Result
|
||||||
|
t_base_relocs(void)
|
||||||
|
{
|
||||||
|
Temp scratch = scratch_begin(0,0);
|
||||||
|
|
||||||
|
T_Result result = T_Result_Fail;
|
||||||
|
|
||||||
|
// main.obj
|
||||||
|
String8 entry_name = str8_lit("my_entry");
|
||||||
|
U64 mov_func_name64 = 2;
|
||||||
|
U64 mov_func_name32 = 16;
|
||||||
|
U8 main_text[] = {
|
||||||
|
0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax, func_name
|
||||||
|
0xff, 0xd0, // call rax
|
||||||
|
0x48, 0x31, 0xc0, // xor rax, rax
|
||||||
|
0xb8, 0x00, 0x00, 0x00, 0x00, // mov eax, func_name
|
||||||
|
0xff, 0xd0, // call rax
|
||||||
|
0xc3 // ret
|
||||||
|
};
|
||||||
|
|
||||||
|
// func.obj
|
||||||
|
String8 func_name = str8_lit("foo");
|
||||||
|
U8 func_text[] = { 0xc3 };
|
||||||
|
|
||||||
|
String8 main_obj_name = str8_lit("main.obj");
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
COFF_ObjSection *text_sect = t_push_text_section(obj_writer, str8_array_fixed(main_text));
|
||||||
|
COFF_ObjSymbol *func_undef = coff_obj_writer_push_symbol_undef(obj_writer, func_name);
|
||||||
|
coff_obj_writer_section_push_reloc(obj_writer, text_sect, mov_func_name64, func_undef, COFF_Reloc_X64_Addr64);
|
||||||
|
coff_obj_writer_section_push_reloc(obj_writer, text_sect, mov_func_name32, func_undef, COFF_Reloc_X64_Addr32);
|
||||||
|
coff_obj_writer_push_symbol_extern(obj_writer, entry_name, 0, text_sect);
|
||||||
|
String8 main_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
|
||||||
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
if (!t_write_file(main_obj_name, main_obj)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 func_obj_name = str8_lit("func.obj");
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
COFF_ObjSection *text_sect = t_push_text_section(obj_writer, str8_array_fixed(func_text));
|
||||||
|
coff_obj_writer_push_symbol_extern(obj_writer, func_name, 0, text_sect);
|
||||||
|
String8 func_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
|
||||||
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
if (!t_write_file(func_obj_name, func_obj)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 out_name = str8_lit("a.exe");
|
||||||
|
int linker_exit_code = t_invoke_linkerf("/subsystem:console /entry:%S /dynamicbase /dll /largeaddressaware:no /out:%S %S %S", entry_name, out_name, main_obj_name, func_obj_name);
|
||||||
|
|
||||||
|
exit:;
|
||||||
|
scratch_end(scratch);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
@@ -484,7 +688,10 @@ entry_point(CmdLine *cmdline)
|
|||||||
{ "simple_link_test", t_simple_link_test },
|
{ "simple_link_test", t_simple_link_test },
|
||||||
{ "undef_section", t_undef_section },
|
{ "undef_section", t_undef_section },
|
||||||
{ "abs_vs_weak", t_abs_vs_weak },
|
{ "abs_vs_weak", t_abs_vs_weak },
|
||||||
|
{ "abs_vs_regular", t_abs_vs_regular },
|
||||||
|
{ "abs_vs_common", t_abs_vs_common },
|
||||||
{ "find_merged_pdata", t_find_merged_pdata },
|
{ "find_merged_pdata", t_find_merged_pdata },
|
||||||
|
//{ "base_relocs", t_base_relocs },
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user