/** * @file test_scf_x64.c * @brief SCF x64 architecture tests * * This test creates a simple x64 executable similar to the Rust example * provided by the user. */ #include #include #include int main() { printf("Testing SCF x64 format implementation...\n"); // Test 1: Initialize SCF for x64 architecture scf_t scf; scf_init(&scf); // Set architecture to x64 scf.header.arch = SCF_ARCH_X64; scf.header.flags = SCF_FLAG_EXE_RELOC; printf("Test 1 PASSED: x64 initialization successful\n"); // Test 2: Add .text section with x64 machine code // x64 machine code for: // sub rsp, 0x28 // lea rcx, [rip + data_offset] ; will be relocated // call [rip + printf_iat] ; will be relocated // add rsp, 0x28 // xor eax, eax // ret unsigned char x64_code[] = { 0x48, 0x83, 0xEC, 0x28, // sub rsp, 0x28 0x48, 0x8D, 0x0D, 0x00, 0x00, 0x00, 0x00, // lea rcx, [rip + 0] (to be relocated) 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, // call [rip + 0] (to be relocated) 0x48, 0x83, 0xC4, 0x28, // add rsp, 0x28 0x33, 0xC0, // xor eax, eax 0xC3 // ret }; // Add code to .text section for (usize i = 0; i < sizeof(x64_code); i++) { scc_vec_push(scf.text, x64_code[i]); } scf.header.code_size = (scf_size_t)scf.text.size; printf("Test 2 PASSED: x64 code added to .text section\n"); // Test 3: Add .data section with string const char hello_world[] = "Hello, World from SCF x64 Test!\n\0"; for (usize i = 0; i < sizeof(hello_world); i++) { scc_vec_push(scf.data, hello_world[i]); } scf.header.data_size = (scf_size_t)scf.data.size; printf("Test 3 PASSED: Data string added to .data section\n"); // Test 4: Add symbols scf_sym_t data_sym = {0}; data_sym.name_offset = 0; // Would need string table for actual names data_sym.scf_sym_type = SCF_SYM_TYPE_DATA; data_sym.scf_sym_bind = SCF_SYM_BIND_GLOBAL; data_sym.scf_sym_vis = SCF_SYM_VIS_DEFAULT; data_sym.scf_sect_type = SCF_SECT_DATA; data_sym.scf_sect_offset = 0; // Start of data section data_sym.scf_sym_size = sizeof(hello_world); if (!scf_add_sym(&scf, &data_sym)) { printf("FAIL: Cannot add data symbol\n"); return 1; } scf_sym_t code_sym = {0}; code_sym.name_offset = 0; code_sym.scf_sym_type = SCF_SYM_TYPE_FUNC; code_sym.scf_sym_bind = SCF_SYM_BIND_GLOBAL; code_sym.scf_sym_vis = SCF_SYM_VIS_DEFAULT; code_sym.scf_sect_type = SCF_SECT_CODE; code_sym.scf_sect_offset = 0; // Start of code section code_sym.scf_sym_size = sizeof(x64_code); if (!scf_add_sym(&scf, &code_sym)) { printf("FAIL: Cannot add code symbol\n"); return 1; } printf("Test 4 PASSED: Symbols added\n"); // Test 5: Add relocations // First relocation: data reference at offset 7 in code (lea rcx, [rip + // data_offset]) scf_reloc_t data_reloc = {0}; data_reloc.offset = 7; // Offset in code section data_reloc.sym_idx = 0; // Index of data symbol (first symbol added) data_reloc.type = SCF_RELOC_PC; // PC-relative relocation data_reloc.sect_type = SCF_SECT_CODE; data_reloc.addend = -4; // RIP-relative addressing adjustment if (!scf_add_reloc(&scf, &data_reloc)) { printf("FAIL: Cannot add data relocation\n"); return 1; } // Second relocation: external function reference at offset 13 in code (call // [rip + printf_iat]) scf_reloc_t func_reloc = {0}; func_reloc.offset = 13; // Offset in code section func_reloc.sym_idx = 1; // Index of code symbol (would be external in real case) func_reloc.type = SCF_RELOC_PC; // PC-relative relocation func_reloc.sect_type = SCF_SECT_CODE; func_reloc.addend = -4; // RIP-relative addressing adjustment if (!scf_add_reloc(&scf, &func_reloc)) { printf("FAIL: Cannot add function relocation\n"); return 1; } printf("Test 5 PASSED: Relocations added\n"); // Test 6: Apply relocations if (!scf_apply_relocations(&scf)) { printf("FAIL: Cannot apply relocations\n"); return 1; } printf("Test 6 PASSED: Relocations applied\n"); // Test 7: Prepare for writing (internal整理) if (!scf_write_done(&scf)) { printf("FAIL: Cannot prepare for writing\n"); return 1; } printf("Test 7 PASSED: Prepared for writing\n"); // Test 8: Write to buffer char buffer[4096]; if (!scf_write(&scf, buffer, sizeof(buffer))) { printf("FAIL: Cannot write to buffer\n"); return 1; } printf("Test 8 PASSED: Written to buffer\n"); // Test 9: Parse from buffer scf_t scf2; scf_init(&scf2); if (!scf_parse(&scf2, buffer, sizeof(buffer))) { printf("FAIL: Cannot parse from buffer\n"); return 1; } // Verify architecture if (scf2.header.arch != SCF_ARCH_X64) { printf("FAIL: Architecture not preserved\n"); return 1; } printf("Test 9 PASSED: Parsed from buffer, architecture preserved\n"); // Test 10: Verify structure if (!scf_check_valid(&scf2)) { printf("FAIL: Parsed structure invalid\n"); return 1; } printf("Test 10 PASSED: Parsed structure valid\n"); printf("\nAll x64 tests passed!\n"); printf("Created SCF file with:\n"); printf(" Architecture: x64\n"); printf(" Code size: %u bytes\n", scf.header.code_size); printf(" Data size: %u bytes\n", scf.header.data_size); printf(" Symbols: %u\n", scf.header.sym_count); printf(" Relocations: %u\n", scf.header.reloc_count); printf(" Flags: 0x%x\n", scf.header.flags); return 0; }