link_engine.c (3555B)
1 #include "link_engine.h" 2 3 #include <string.h> 4 5 typedef struct DriverPreservedVec { 6 KitHeap* heap; 7 KitCgSym* syms; 8 uint32_t nsyms; 9 uint32_t cap; 10 int oom; 11 } DriverPreservedVec; 12 13 static void driver_preserved_vec_add(void* user, KitCgSym sym) { 14 DriverPreservedVec* v = (DriverPreservedVec*)user; 15 KitCgSym* ns; 16 uint32_t ncap; 17 if (!v || v->oom) return; 18 if (v->nsyms == v->cap) { 19 ncap = v->cap ? v->cap * 2u : 32u; 20 ns = (KitCgSym*)v->heap->realloc( 21 v->heap, v->syms, sizeof(*v->syms) * v->cap, sizeof(*v->syms) * ncap, 22 _Alignof(KitCgSym)); 23 if (!ns) { 24 v->oom = 1; 25 return; 26 } 27 v->syms = ns; 28 v->cap = ncap; 29 } 30 v->syms[v->nsyms++] = sym; 31 } 32 33 static KitStatus driver_link_engine_add_inputs(KitLinkSession* link, 34 const DriverLinkInputs* in) { 35 KitStatus st = KIT_OK; 36 uint32_t i; 37 if (!link || !in) return KIT_INVALID; 38 39 for (i = 0; i < in->norder && st == KIT_OK; ++i) { 40 const KitLinkInputOrder* ord = &in->order[i]; 41 switch ((KitLinkInputOrderKind)ord->kind) { 42 case KIT_LINK_INPUT_OBJ: 43 st = kit_link_session_add_obj(link, in->objs[ord->index]); 44 break; 45 case KIT_LINK_INPUT_OBJ_BYTES: 46 st = kit_link_session_add_obj_bytes(link, in->obj_names[ord->index], 47 &in->obj_bytes[ord->index]); 48 break; 49 case KIT_LINK_INPUT_ARCHIVE: 50 st = 51 kit_link_session_add_archive_bytes(link, &in->archives[ord->index]); 52 break; 53 case KIT_LINK_INPUT_DSO: 54 st = kit_link_session_add_dso_bytes(link, in->dso_names[ord->index], 55 &in->dso_bytes[ord->index]); 56 break; 57 } 58 } 59 return st; 60 } 61 62 KitStatus driver_link_engine_emit_with_lto( 63 KitCompiler* compiler, const KitLinkSessionOptions* lopts, 64 const DriverLinkInputs* in, DriverCompilePendingLto* pending_lto, 65 const DriverCompileBatchOptions* batch, KitWriter* out) { 66 KitLinkSession* link = NULL; 67 DriverPreservedVec preserved; 68 KitStatus st; 69 70 if (!compiler || !lopts || !in || !out) { 71 if (pending_lto && pending_lto->active) 72 driver_compile_pending_lto_abort(pending_lto); 73 return KIT_INVALID; 74 } 75 memset(&preserved, 0, sizeof preserved); 76 preserved.heap = kit_compiler_context(compiler)->heap; 77 st = kit_link_session_new(compiler, lopts, &link); 78 if (st == KIT_OK) st = driver_link_engine_add_inputs(link, in); 79 if (st == KIT_OK && pending_lto && pending_lto->active) { 80 st = kit_link_session_visit_lto_preserved( 81 link, pending_lto->obj, pending_lto->cg, driver_preserved_vec_add, 82 &preserved); 83 if (st == KIT_OK && preserved.oom) st = KIT_NOMEM; 84 if (st == KIT_OK) { 85 st = driver_compile_pending_lto_finish(pending_lto, batch, preserved.syms, 86 preserved.nsyms); 87 } 88 } 89 if (st == KIT_OK) st = kit_link_session_emit(link, out); 90 kit_link_session_free(link); 91 if (preserved.syms) 92 preserved.heap->free(preserved.heap, preserved.syms, 93 sizeof(*preserved.syms) * preserved.cap); 94 if (st != KIT_OK && pending_lto && pending_lto->active) 95 driver_compile_pending_lto_abort(pending_lto); 96 return st; 97 } 98 99 KitStatus driver_link_engine_emit(KitCompiler* compiler, 100 const KitLinkSessionOptions* lopts, 101 const DriverLinkInputs* in, KitWriter* out) { 102 return driver_link_engine_emit_with_lto(compiler, lopts, in, NULL, NULL, out); 103 }