kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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 }