Files
scc/libs/target/pe/src/scc_pe_idata.c
zzy 5a9f816ccf fix(abi): 修复void类型的ABI计算缺少break语句
在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相关的头文件和源文件,这些组件
将在后续重构中重新设计或替换。
2026-04-15 14:52:11 +08:00

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;
}