Files
scc/libs/sccf/src/sccf_builder.c
zzy 4144f7841c refactor(argparse): 将null替换为nullptr以提高C++兼容性
- 在argparse库中将所有null指针常量替换为nullptr
- 更新头文件和源文件中的指针初始化和比较操作
- 修改测试文件中的相关断言检查
- 更新AST定义文件中的注释说明
2026-04-05 20:18:09 +08:00

151 lines
5.2 KiB
C

#include <sccf_builder.h>
void sccf_builder_init(sccf_builder_t *builder) {
builder->aligned = 64;
sccf_init(&builder->sccf);
scc_hashtable_init(&builder->str2offset,
(scc_hashtable_hash_func_t)scc_strhash32,
(scc_hashtable_equal_func_t)scc_strcmp);
scc_hashtable_init(&builder->str2sym,
(scc_hashtable_hash_func_t)scc_strhash32,
(scc_hashtable_equal_func_t)scc_strcmp);
scc_vec_init(builder->strtab);
scc_vec_init(builder->relocs);
scc_vec_init(builder->symtab);
builder->entry_symbol_name = nullptr;
///< Push nullptr
scc_vec_push(builder->strtab, (char)'\0');
///< Push nullptr
scc_vec_push(builder->symtab, (sccf_sym_t){0});
}
usize sccf_builder_add_symbol(sccf_builder_t *builder, const char *name,
sccf_sym_t *sym) {
usize offset = 0;
offset = (usize)scc_hashtable_get(&builder->str2offset, name);
const char *key = name;
if (offset == 0) {
offset = scc_vec_size(builder->strtab);
while (*name) {
scc_vec_push(builder->strtab, *name);
name++;
}
scc_vec_push(builder->strtab, '\0');
scc_hashtable_set(&builder->str2offset, key, (void *)offset);
}
sym->name_offset = offset;
usize sym_idx = scc_vec_size(builder->symtab);
offset = (usize)scc_hashtable_get(&builder->str2sym, key);
if (offset == 0) {
scc_hashtable_set(&builder->str2sym, key, (void *)sym_idx);
} else {
LOG_ERROR("symbol %s already exists", key);
}
scc_vec_push(builder->symtab, *sym);
return sym_idx;
}
usize sccf_builder_get_symbol_idx(sccf_builder_t *builder, const char *name) {
usize offset = (usize)scc_hashtable_get(&builder->str2sym, name);
return offset;
}
void sccf_builder_add_reloc(sccf_builder_t *builder, sccf_reloc_t reloc) {
scc_vec_push(builder->relocs, reloc);
}
void sccf_builder_add_section(sccf_builder_t *builder,
sccf_sect_header_t *sect_header,
sccf_sect_data_t *sect_data) {
Assert((usize)(sect_header->size) == scc_vec_size(*sect_data));
builder->sccf.header.sect_header_num += 1;
scc_vec_push(builder->sccf.sect_headers, *sect_header);
scc_vec_push(builder->sccf.sect_datas, *sect_data);
}
const sccf_t *sccf_builder_to_sccf(sccf_builder_t *builder) {
if (builder->entry_symbol_name == nullptr) {
builder->sccf.header.entry_point = 0;
} else {
sccf_sym_t *sym =
sccf_builder_get_symbol_unsafe(builder, builder->entry_symbol_name);
if (sym == nullptr || sym->sccf_sect_type != SCCF_SECT_CODE) {
LOG_ERROR("entry symbol %s not found");
builder->sccf.header.entry_point = 0;
} else {
builder->sccf.header.entry_point = sym->sccf_sect_offset;
}
}
sccf_sect_header_t sect_header;
if (scc_vec_size(builder->strtab)) {
sect_header = (sccf_sect_header_t){
.name = ".strtab",
.info = 0,
.data_size = scc_vec_size(builder->strtab),
.addralign = 1,
.size = scc_vec_size(builder->strtab),
.sccf_sect_type = SCCF_SECT_STRTAB,
};
sccf_builder_add_section(builder, &sect_header,
(void *)&builder->strtab);
}
if (scc_vec_size(builder->symtab)) {
sect_header = (sccf_sect_header_t){
.name = ".symtab",
.info = 0,
.data_size = scc_vec_size(builder->symtab),
.addralign = 1,
.size = scc_vec_size(builder->symtab),
.sccf_sect_type = SCCF_SECT_SYMTAB,
};
sccf_builder_add_section(builder, &sect_header,
(void *)&builder->symtab);
}
if (scc_vec_size(builder->relocs)) {
sect_header = (sccf_sect_header_t){
.name = ".relocs",
.info = 0,
.data_size = scc_vec_size(builder->relocs),
.addralign = 1,
.size = scc_vec_size(builder->relocs),
.sccf_sect_type = SCCF_SECT_RELOCS,
};
sccf_builder_add_section(builder, &sect_header,
(void *)&builder->relocs);
}
return &builder->sccf;
}
void sccf_builder_to_buffer(sccf_builder_t *builder, sccf_buffer_t *buffer) {
Assert(builder != nullptr && buffer != nullptr);
sccf_write(sccf_builder_to_sccf(builder), buffer);
}
void sccf_builder_to_file(sccf_builder_t *builder, const char *file_path) {
Assert(builder != nullptr && file_path != nullptr);
scc_file_t fp = scc_fopen(file_path, SCC_FILE_WRITE);
if (fp == nullptr) {
LOG_ERROR("file can't open %s", file_path);
return;
}
sccf_buffer_t buffer;
scc_vec_init(buffer);
sccf_builder_to_buffer(builder, &buffer);
usize write_size =
scc_fwrite(fp, scc_vec_unsafe_get_data(buffer), scc_vec_size(buffer));
if (write_size != scc_vec_size(buffer)) {
LOG_ERROR("file write failed expect write %zu but got %zu",
scc_vec_size(buffer), write_size);
}
scc_vec_free(buffer);
scc_fclose(fp);
}