66 lines
2.2 KiB
C
66 lines
2.2 KiB
C
#include "header.h"
|
|
|
|
static u32_t text_addr = 0;
|
|
#define FOREACH_PROGS(progs) for (rv32_prog_t **pprog = progs, *prog = *progs; \
|
|
*pprog != NULL; prog = *(++pprog))
|
|
int append(const void *key, void *value, void *context) {
|
|
symtab_asm_t* symtab = (symtab_asm_t*) context;
|
|
symasm_entry_t* entry = (symasm_entry_t*) key;
|
|
u32_t* addr = (u32_t*) value;
|
|
*addr += text_addr; // size to index
|
|
salloc_alloc(16);
|
|
if (entry->attr == GLOBAL) {
|
|
symtab_asm_put(symtab, entry, *addr);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]) {
|
|
symtab_asm_t symtab;
|
|
init_symtab_asm(&symtab);
|
|
|
|
rv32_prog_t* exe = salloc_alloc(sizeof(rv32_prog_t));
|
|
init_rv32_prog(exe, NULL);
|
|
|
|
FOREACH_PROGS(progs) {
|
|
prog->text_base_address = text_addr;
|
|
text_addr += prog->text.size;
|
|
}
|
|
exe->text.data = salloc_alloc(text_addr * sizeof(u32_t));
|
|
exe->text.cap = text_addr;
|
|
exe->text.size = text_addr;
|
|
text_addr = 0;
|
|
FOREACH_PROGS(progs) {
|
|
rt_memcpy(exe->text.data + text_addr, prog->text.data, prog->text.size * sizeof(u32_t));
|
|
// FIXME
|
|
hashtable_foreach(&prog->symtab.symtab, append, &symtab);
|
|
text_addr += prog->text.size;
|
|
}
|
|
|
|
// find by self
|
|
FOREACH_PROGS(progs) {
|
|
for (int i = 0; i < prog->rinstrs.size; i++) {
|
|
u32_t* paddr;
|
|
u32_t addr;
|
|
paddr = symtab_asm_get(&prog->symtab, &prog->rinstrs.data[i].target);
|
|
if (paddr == NULL) {
|
|
paddr = symtab_asm_get(&symtab, &prog->rinstrs.data[i].target);
|
|
if (paddr == NULL) {
|
|
LOG_FATAL("linker: %s not found", prog->rinstrs.data[i].target.name);
|
|
}
|
|
addr = *paddr;
|
|
} else {
|
|
addr = *paddr;
|
|
// addr += prog->text_base_address;
|
|
}
|
|
// FIXME
|
|
int cur_idx = prog->text_base_address + prog->rinstrs.data[i].address;
|
|
prog->rinstrs.data[i].instr.imm += (addr - cur_idx) * sizeof(u32_t);
|
|
emit_rv32_instr(exe, &prog->rinstrs.data[i].instr, cur_idx, NULL);
|
|
|
|
// symtab_get(&prog->symtab, &prog->rinstrs.data[i].target);
|
|
}
|
|
}
|
|
return exe;
|
|
}
|