#ifndef __SCC_X86_PATCH_H__ #define __SCC_X86_PATCH_H__ #include "scc_x86_encode.h" // x86-64 重定位类型(由底层 patch 函数处理) typedef enum { SCC_X86_PATCH_NONE, SCC_X86_PATCH_PC32, // 32 位 PC 相对偏移(CALL/JMP/Jcc) SCC_X86_PATCH_ABS64, // 64 位绝对地址(MOV reg, imm64) SCC_X86_PATCH_ABS32, // 32 位绝对地址(MOV reg, imm32) SCC_X86_PATCH_DISP8, // 8 位内存位移([RIP+disp8] 或 [base+disp8]) SCC_X86_PATCH_DISP32, // 32 位内存位移([RIP+disp32]) } scc_x86_patch_type_t; static inline void patch_bytes(scc_mcode_t *mcode, usize offset, const void *data, usize size) { u8 *buf = (u8 *)scc_mcode_unsafe_data(mcode); usize total = scc_mcode_size(mcode); if (offset + size > total) { Panic("patch offset out of range: offset=%zu size=%zu total=%zu", offset, size, total); } scc_memcpy(buf + offset, data, size); } static inline int scc_x86_patch_disp(scc_mcode_t *mcode, usize offset, scc_x86_disp_t disp) { if (!mcode || disp.displacement_bits == 0) return -1; usize bytes = disp.displacement_bits / 8; if (bytes == 0) { bytes = 4; // RELBR 32 } if (bytes != 1 && bytes != 2 && bytes != 4 && bytes != 8) { Panic("invalid displacement bits: %u", disp.displacement_bits); } // 将 displacement 截断到对应宽度(小端写入) i64 val = disp.displacement; switch (bytes) { case 1: { u8 v = (u8)val; patch_bytes(mcode, offset, &v, 1); break; } case 2: { u16 v = (u16)val; patch_bytes(mcode, offset, &v, 2); break; } case 4: { u32 v = (u32)val; patch_bytes(mcode, offset, &v, 4); break; } case 8: patch_bytes(mcode, offset, &val, 8); break; } return 0; } static inline int scc_x86_patch_brdisp(scc_mcode_t *mcode, usize offset, scc_x86_operand_value_t disp) { if (disp.kind != SCC_X86_OPR_RELBR && disp.kind != SCC_X86_OPR_RELOC) { Panic("patch_brdisp called with non-branch operand kind %d", disp.kind); } i32 brdisp; if (disp.kind == SCC_X86_OPR_RELBR) brdisp = disp.brdisp; else brdisp = (i32)disp.reloc.imm; // 从重定位占位中获取值(上层会先填好) patch_bytes(mcode, offset, &brdisp, 4); return 0; } static inline int scc_x86_patch_imm0(scc_mcode_t *mcode, usize offset, scc_x86_operand_value_t imm0) { // 注意:原声明未提供大小参数,我们假定调用者保证了正确的宽度。 // 此处默认写入 8 字节(最常用)。若需要其他宽度,请使用扩展版本。 if (imm0.kind != SCC_X86_OPR_IMM && imm0.kind != SCC_X86_OPR_RELOC) { Panic("patch_imm0 called with non-immediate operand kind %d", imm0.kind); } u64 val; if (imm0.kind == SCC_X86_OPR_IMM) val = imm0.imm0; else val = (u64)imm0.reloc.imm; // 从重定位占位中获取 patch_bytes(mcode, offset, &val, 8); return 0; } /* ---------- 扩展:带大小的立即数 patch(推荐上层使用) ---------- */ static inline int scc_x86_patch_imm0_ex(scc_mcode_t *mcode, usize offset, u64 value, usize size) { if (size != 1 && size != 2 && size != 4 && size != 8) return -1; switch (size) { case 1: { u8 v = (u8)value; patch_bytes(mcode, offset, &v, 1); break; } case 2: { u16 v = (u16)value; patch_bytes(mcode, offset, &v, 2); break; } case 4: { u32 v = (u32)value; patch_bytes(mcode, offset, &v, 4); break; } case 8: patch_bytes(mcode, offset, &value, 8); break; } return 0; } static inline void scc_x86_patch(scc_mcode_t *mcode, scc_x86_patch_type_t patch_type, u64 offset, u64 value) { switch (patch_type) { case SCC_X86_PATCH_PC32: i32 rel = value - offset; scc_x86_patch_brdisp(mcode, offset - 4, scc_x86_op_relbr(rel)); break; default: TODO(); break; } } #endif /* __SCC_X86_PATCH_H__ */