在scc_type_abi.c文件中,void类型的case分支缺少break语句, 导致执行流程错误地进入下一个case分支。 feat(ast): 为参数声明添加索引字段 在ast_def.h头文件中为参数声明结构体添加param_idx字段, 用于跟踪参数在函数参数列表中的位置索引。 feat(ast): 更新参数初始化函数以支持索引参数 修改scc_ast.h中的scc_ast_decl_param_init函数签名, 添加参数索引idx参数,并将该值存储到参数声明结构体中。 feat(ast2ir): 添加IR转换上下文的值使用提示选项 在ast2ir.h中为scc_ast2ir_ctx_t结构体添加hint_using_value字段, 控制参数转换时是使用值还是分配内存的方式。 fix(ast2ir): 正确处理void类型到IR的转换 当遇到大小为0的类型(如void)时,直接返回void类型, 而不是尝试匹配其他大小分支。 refactor(ast2ir): 统一基本块引用类型为value_ref 将逻辑表达式、条件语句、循环语句中的基本块引用类型 从bblock_ref_t改为value_ref_t,保持类型一致性。 fix(ast2ir): 修正函数引用空值检查 使用SCC_IR_REF_nullptr常量替代0进行函数引用的空值检查, 提高代码的可读性和正确性。 refactor(ast2ir): 简化参数处理逻辑 移除不必要的函数参数获取和命名设置逻辑, 通过递归调用scc_ast2ir_decl来处理参数声明。 feat(ast2ir): 实现参数声明到IR的转换 为参数声明添加完整的IR转换逻辑,包括类型转换、 参数引用创建和内存分配处理。 refactor(ast2ir): 更新哈希表初始化接口 适配新的哈希表初始化函数签名,添加userdata参数支持, 并初始化hint_using_value字段为false。 refactor(ir): 移除函数参数的预分配逻辑 删除IR构建器中函数参数的预分配和循环添加逻辑, 简化函数开始构建的处理流程。 refactor(ir): 更新类型哈希表键值处理 修改类型哈希表的哈希和比较函数以接受模块参数, 正确处理空引用情况并支持新的键值传递方式。 fix(ir): 修复IR转储中的字符串格式 移除IR函数转储时多余的换行符,确保输出格式正确。 refactor(ir): 更新模块哈希表初始化 适配哈希表初始化接口变更,添加userdata参数, 并为各种向量预留UID 0作为无效引用。 fix(ir): 修复模块清理中的循环起始索引 将模块清理循环的起始索引从0改为1,跳过预留的 无效引用项,避免访问空指针。 refactor(ir): 调整向量和哈希表操作顺序 调整模块中向量push和哈希表set的操作顺序, 确保数据一致性和正确的UID分配。 chore(build): 移除ir2mcode模块相关文件 移除ir2mcode相关的头文件和源文件,这些组件 将在后续重构中重新设计或替换。
169 lines
6.5 KiB
C
169 lines
6.5 KiB
C
#include <scc_pe_idata.h>
|
|
|
|
// RVA Relative Virtual Address
|
|
static inline IMAGE_IMPORT_DESCRIPTOR
|
|
image_import_descriptor_init(u32 import_lookup_table_rva, u32 name_rva,
|
|
u32 import_address_table_rva) {
|
|
IMAGE_IMPORT_DESCRIPTOR iid = {0};
|
|
iid.DUMMYUNIONNAME.OriginalFirstThunk = SCC_LE32(import_lookup_table_rva);
|
|
iid.TimeDateStamp = SCC_LE32(0);
|
|
iid.ForwarderChain = SCC_LE32(0);
|
|
iid.Name = SCC_LE32(name_rva);
|
|
iid.FirstThunk = SCC_LE32(import_address_table_rva);
|
|
return iid;
|
|
};
|
|
|
|
static void scc_winpe_hnt_builder_push(scc_pe_hnt_builder_t *builder,
|
|
const char *name, u16 hint);
|
|
static void scc_winpe_hnt_builder_init(scc_pe_hnt_builder_t *builder) {
|
|
scc_vec_init(builder->data);
|
|
builder->section_offset = 0;
|
|
scc_hashtable_cstr_init(&builder->str_map);
|
|
}
|
|
|
|
static void scc_winpe_hnt_builder_push(scc_pe_hnt_builder_t *builder,
|
|
const char *name, u16 hint) {
|
|
///< 可选哈希表去重
|
|
if (scc_hashtable_get(&builder->str_map, name)) {
|
|
return;
|
|
}
|
|
scc_hashtable_set(&builder->str_map, name, (void *)(u64)builder->data.size);
|
|
|
|
/// FIXME WARNING需要转换为little endian
|
|
scc_vec_push(builder->data, hint & 0xff);
|
|
scc_vec_push(builder->data, hint >> 8);
|
|
|
|
while (*name) {
|
|
scc_vec_push(builder->data, *name);
|
|
name++;
|
|
}
|
|
scc_vec_push(builder->data, 0);
|
|
|
|
if (scc_vec_size(builder->data) % 2 != 0) {
|
|
scc_vec_push(builder->data, 0);
|
|
}
|
|
|
|
// return scc_vec_size(builder->data);
|
|
Assert(scc_vec_size(builder->data) % 2 == 0);
|
|
}
|
|
|
|
static u64 scc_winpe_hnt_get_offset(scc_pe_hnt_builder_t *builder,
|
|
const char *name) {
|
|
return (u64)scc_hashtable_get(&builder->str_map, name);
|
|
}
|
|
|
|
void scc_pe_idata_builder_init(scc_pe_idata_builder_t *builder,
|
|
scc_pe_idata_lib_vec_t *idata_libs) {
|
|
scc_vec_init(builder->buffer);
|
|
builder->idata_libs = *idata_libs;
|
|
|
|
scc_winpe_hnt_builder_init(&builder->hnt_builder);
|
|
|
|
scc_hashtable_cstr_init(&builder->iat_map);
|
|
}
|
|
|
|
u32 scc_pe_reserve_idata(scc_pe_idata_builder_t *builder) {
|
|
u32 idata_size = (scc_vec_size(builder->idata_libs) + 1) *
|
|
sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
|
|
|
scc_vec_foreach(builder->idata_libs, i) {
|
|
scc_pe_idata_lib_t *lib = &scc_vec_at(builder->idata_libs, i);
|
|
idata_size += (scc_vec_size(lib->symbol_names) + 1) * 2 *
|
|
sizeof(IMAGE_THUNK_DATA64);
|
|
scc_winpe_hnt_builder_push(&builder->hnt_builder, lib->name, 0);
|
|
|
|
scc_vec_foreach(lib->symbol_names, j) {
|
|
scc_winpe_hnt_builder_push(&builder->hnt_builder,
|
|
scc_vec_at(lib->symbol_names, j), 0);
|
|
}
|
|
}
|
|
builder->hnt_builder.section_offset = idata_size;
|
|
idata_size += scc_vec_size(builder->hnt_builder.data);
|
|
|
|
scc_vec_realloc(builder->buffer, idata_size);
|
|
scc_vec_size(builder->buffer) = idata_size;
|
|
return idata_size;
|
|
}
|
|
|
|
scc_pe_buffer_t scc_pe_construct_idata(scc_pe_idata_builder_t *builder,
|
|
scc_pe_section_range *idata_range) {
|
|
u32 idata_rva = idata_range->virual_address;
|
|
u32 hnt_offset = builder->hnt_builder.section_offset;
|
|
|
|
usize import_file_count = scc_vec_size(builder->idata_libs);
|
|
usize current_offset =
|
|
(import_file_count + 1) * sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
|
scc_vec_foreach(builder->idata_libs, i) {
|
|
scc_pe_idata_lib_t *lib = &scc_vec_at(builder->idata_libs, i);
|
|
scc_winpe_lookup_table_vec_t lookup_table;
|
|
scc_vec_init(lookup_table);
|
|
|
|
scc_vec_foreach(lib->symbol_names, j) {
|
|
u64 name_offset = scc_winpe_hnt_get_offset(
|
|
&builder->hnt_builder, scc_vec_at(lib->symbol_names, j));
|
|
u64 name_rva = idata_rva + hnt_offset + name_offset;
|
|
|
|
IMAGE_THUNK_DATA64 lookup_table_entry = {.u1.AddressOfData =
|
|
name_rva};
|
|
scc_vec_push(lookup_table, lookup_table_entry);
|
|
}
|
|
scc_vec_push(lookup_table, (IMAGE_THUNK_DATA64){0});
|
|
usize table_size =
|
|
scc_vec_size(lookup_table) * sizeof(IMAGE_THUNK_DATA64);
|
|
|
|
usize ilt_offset = current_offset;
|
|
usize iat_offset = ilt_offset + table_size;
|
|
current_offset += table_size * 2;
|
|
|
|
scc_vec_foreach(lib->symbol_names, j) {
|
|
// 构造IAT链接
|
|
scc_hashtable_set(
|
|
&builder->iat_map, scc_vec_at(lib->symbol_names, j),
|
|
(void *)(usize)(idata_rva + j * sizeof(IMAGE_THUNK_DATA64)) +
|
|
iat_offset);
|
|
}
|
|
|
|
usize name_rva = idata_rva + hnt_offset +
|
|
scc_winpe_hnt_get_offset(&builder->hnt_builder,
|
|
lib->name); ///< hashtable get
|
|
|
|
// 构造并写入导入目录项
|
|
// The address of an ASCII string that contains the name of the DLL.
|
|
// This address is relative to the image base.
|
|
// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-directory-table
|
|
// so add 2 to skip the two bytes of the Hint
|
|
IMAGE_IMPORT_DESCRIPTOR dir_entry = image_import_descriptor_init(
|
|
ilt_offset + idata_rva, name_rva + 2, iat_offset + idata_rva);
|
|
scc_memcpy(
|
|
&scc_vec_at(builder->buffer, i * sizeof(IMAGE_IMPORT_DESCRIPTOR)),
|
|
&dir_entry,
|
|
sizeof(IMAGE_IMPORT_DESCRIPTOR)); // FIXME 大小端
|
|
|
|
Assert(table_size ==
|
|
scc_vec_size(lookup_table) * sizeof(IMAGE_THUNK_DATA64));
|
|
|
|
// 转换为字节序列并写入
|
|
// FIXME 大小端
|
|
// 写入ILT表
|
|
scc_memcpy(&scc_vec_at(builder->buffer, ilt_offset),
|
|
&scc_vec_at(lookup_table, 0), table_size);
|
|
// 写入IAT表
|
|
scc_memcpy(&scc_vec_at(builder->buffer, iat_offset),
|
|
&scc_vec_at(lookup_table, 0), table_size);
|
|
}
|
|
|
|
// 添加nullptr终止的目录项
|
|
IMAGE_IMPORT_DESCRIPTOR nullptr_entry =
|
|
image_import_descriptor_init(0, 0, 0);
|
|
scc_memcpy(&scc_vec_at(builder->buffer,
|
|
import_file_count * sizeof(IMAGE_IMPORT_DESCRIPTOR)),
|
|
&nullptr_entry, sizeof(IMAGE_IMPORT_DESCRIPTOR));
|
|
|
|
// 填充Hint/Name表
|
|
scc_memcpy(&scc_vec_at(builder->buffer, hnt_offset),
|
|
&scc_vec_at(builder->hnt_builder.data, 0),
|
|
scc_vec_size(builder->hnt_builder.data));
|
|
|
|
return builder->buffer;
|
|
}
|