U0 AsmResolve(CCompCtrl *cc, CAsmUnresolvedRef *tmpu, U8 *label, Bool undefined) { CAOTImportExport *tmpie; CAsmUndefHash *tmpauh; I64 res = Call(tmpu->machine_code); if (undefined) { tmpauh = tmpu->asm_undef_hash; while (tmpauh) { if (tmpauh->hash->type & HTF_UNRESOLVED) { tmpie = CAlloc(sizeof(CAOTImportExport)); tmpie->next = tmpauh->hash->ie_list; tmpauh->hash->ie_list = tmpie; tmpie->rip = tmpu->rip; tmpie->aot = cc->aot; tmpie->type = tmpu->type; } tmpauh = tmpauh->next; //Technically, more than one won't work. } } else if (!(tmpu->type & IEF_IMM_NOT_REL)) { res -= tmpu->rel_rip; if (tmpu->type == IET_REL_I8 && !(I8_MIN <= res <= I8_MAX) || tmpu->type == IET_REL_I16 && !(I16_MIN <= res <= I16_MAX)) { PrintErr("Branch out of range at line:%04d %s\n", tmpu->line_num, label); LexExcept(cc); } if (tmpu->U8_avail && tmpu->type > IET_IMM_U8 && -124 <= res <= 123) PrintWarn("could use I8 displacement at line:%04d %s %s\n", tmpu->line_num, cc->aotc->last_label, label); } AOTStoreCodeU8At(cc, tmpu->rip, res.u8[0]); if (tmpu->type >= IET_REL_I16) { AOTStoreCodeU8At(cc, tmpu->rip + 1, res.u8[1]); if (tmpu->type >= IET_REL_I32) { AOTStoreCodeU8At(cc, tmpu->rip + 2, res.u8[2], res.u8[3]); if (tmpu->type >= IET_REL_I64) AOTStoreCodeU8At(cc, tmpu->rip + 4, res.u8[4], res.u8[5], res.u8[6], res.u8[7]); } } } U0 AOTLocalsResolve(CCompCtrl *cc) { CAOTCtrl *aotc = cc->aotc; CAsmUnresolvedRef *tmpu = aotc->local_unresolved, *tmpu1; CAsmUndefHash *tmpauh; Bool undefined; U8 *label = NULL; while (tmpu) { undefined = FALSE; tmpu1 = tmpu->next; tmpauh = tmpu->asm_undef_hash; while (tmpauh) { if (tmpauh->hash->type & HTF_UNRESOLVED) { PrintErr("Undefined sym at line:%04d %s %s\n", tmpu->line_num, aotc->last_label, tmpauh->hash->str); LexExcept(cc); } label = tmpauh->hash->str; tmpauh = tmpauh->next; } if (!undefined) AsmResolve(cc, tmpu, label, FALSE); Free(tmpu->machine_code); LinkedListDel(tmpu->asm_undef_hash); Free(tmpu); tmpu = tmpu1; } HashTableDel(cc->htc.local_hash_table); cc->htc.hash_table_list = cc->htc.local_hash_table = HashTableNew(16); cc->htc.local_hash_table->next = cc->htc.global_hash_table; aotc->local_unresolved = NULL; } U0 AOTGlobalsResolve(CCompCtrl *cc, CAOT *tmpaot) { CAOTCtrl *aotc = cc->aotc; CHashFun *tmpf; CAsmUnresolvedRef *tmpu = aotc->global_unresolved, *tmpu1; I64 i, j; CAOTImportExport *tmpie, *tmpie1; CAsmUndefHash *tmpauh; CHashExport *tmpex; U8 *label; Bool undefined; CExternUsage *tmpeu, *tmpeu8; while (tmpu) { label = NULL; undefined = FALSE; tmpu1 = tmpu->next; tmpauh = tmpu->asm_undef_hash; while (tmpauh) { if (tmpauh->hash->type & HTF_UNRESOLVED) { tmpex = tmpauh->hash; if (tmpex->type & HTT_EXPORT_SYS_SYM && tmpex->type & HTF_UNRESOLVED && !(tmpex->type & HTF_IMPORT) && (tmpf = HashFind(tmpex->str, cc->htc.hash_table_list, HTT_FUN)) && !Bt(&tmpf->flags, Cf_EXTERN)) { tmpex->val = tmpf->exe_addr; tmpex->type &= ~HTF_UNRESOLVED; label = tmpauh->hash->str; } else { if (!(tmpex->type & HTF_IMPORT)) { if (cc->htc.local_var_list) { tmpex->type |= HTF_GOTO_LABEL; tmpex->use_count++; } else { PrintErr("Undefined sym at line:%04d %s\n", tmpu->line_num, tmpex->str); LexExcept(cc); } } else if (undefined) { PrintErr("Two imports in same expression " "not allowed at line:%04d %s\n", tmpu->line_num, tmpex->str); LexExcept(cc); } undefined = TRUE; } } else label = tmpauh->hash->str; tmpauh = tmpauh->next; } AsmResolve(cc, tmpu, label, undefined); Free(tmpu->machine_code); LinkedListDel(tmpu->asm_undef_hash); Free(tmpu); tmpu = tmpu1; } for (i = 0; i <= cc->htc.global_hash_table->mask; i++) { tmpex = cc->htc.global_hash_table->body[i]; while (tmpex) { if (tmpex->type & (HTF_IMPORT | HTF_GOTO_LABEL)) { if (tmpex->use_count && (tmpie = tmpex->ie_list)) { if (tmpex->type & HTF_GOTO_LABEL) tmpie->flags |= IEF_GOTO_LABEL; if (tmpex->import_name) tmpie->str = StrNew(tmpex->import_name); else tmpie->str = StrNew(tmpex->str); do { tmpie1 = tmpie->next; QueueInsert(tmpie, tmpaot->last_ie); } while (tmpie = tmpie1); tmpex->ie_list = NULL; } } else if (tmpex->type & (HTF_EXPORT | HTF_RESOLVE)) { if (tmpex->type & HTF_UNRESOLVED) { PrintErr("Undefined sym at %s\n", tmpex->str); LexExcept(cc); } if (tmpex->type & HTF_RESOLVE) { tmpf = tmpex; tmpeu = tmpf->ext_list; while (tmpeu) { tmpeu8 = tmpeu->next; j = tmpf->exe_addr - (tmpeu->rip + 4); AOTStoreCodeU8At(cc, tmpeu->rip, j.u8[0], j.u8[1], j.u8[2], j.u8[3]); Free(tmpeu); tmpeu = tmpeu8; } } if (tmpex->type & HTF_EXPORT) { tmpie = CAlloc(sizeof(CAOTImportExport)); tmpie->type = IET_REL32_EXPORT; if (tmpex->type & HTT_FUN) tmpie->rip = tmpf->exe_addr; else if (tmpex->type & HTT_GLOBAL_VAR) tmpie->rip = tmpex(CHashGlobalVar *)->data_addr_rip; else tmpie->rip = tmpex->val; tmpie->aot = cc->aot; if (tmpex->type & HTF_IMM) tmpie->type++; tmpie->str = StrNew(tmpex->str); tmpie->src_link = StrNew(tmpex->src_link); QueueInsert(tmpie, tmpaot->last_ie); } } tmpex = tmpex->next; } } } U0 AsmUnresolvedAdd(CCompCtrl *cc, U8 *machine_code, I64 type, I64 rip, I64 rel_rip, CAsmUndefHash *local_asm_undef_hash, CAsmUndefHash *global_asm_undef_hash, I64 line_num, Bool U8_avail) { CAsmUnresolvedRef *tmpu = MAlloc(sizeof(CAsmUnresolvedRef)); tmpu->machine_code = machine_code; tmpu->type = type; tmpu->rip = rip; tmpu->rel_rip = rel_rip; tmpu->aot = cc->aot; tmpu->imm_flag = FALSE; tmpu->line_num = line_num; tmpu->U8_avail = U8_avail; tmpu->str = NULL; if (local_asm_undef_hash) { tmpu->asm_undef_hash = local_asm_undef_hash; tmpu->next = cc->aotc->local_unresolved; cc->aotc->local_unresolved = tmpu; } else { tmpu->asm_undef_hash = global_asm_undef_hash; tmpu->next = cc->aotc->global_unresolved; cc->aotc->global_unresolved = tmpu; if (global_asm_undef_hash->hash->type & HTF_IMPORT) { tmpu->str = StrNew(global_asm_undef_hash->hash->str); if (global_asm_undef_hash->hash->type & HTF_IMM) tmpu->imm_flag = TRUE; } } }