inputs.h (5787B)
1 #ifndef KIT_DRIVER_INPUTS_H 2 #define KIT_DRIVER_INPUTS_H 3 4 #include <kit/compile.h> 5 #include <kit/link.h> 6 #include <kit/object.h> 7 8 #include "driver.h" 9 10 /* Shared input handling for tools that take a mixed list of C sources, 11 * stdin source, object files, and static archives — `kit run` and 12 * `kit dbg` today. Owns parallel arrays sized to the worst-case argv 13 * slot count plus an optional one-shot stdin slurp. 14 * 15 * Usage: 16 * DriverInputs in = {0}; 17 * if (driver_inputs_init(&in, env, TOOL, argc) != 0) return 1; 18 * for (i = 1; i < argc; ++i) { 19 * int r = driver_inputs_classify(&in, argv[i]); 20 * if (r < 0) { driver_inputs_release(&in); return 1; } 21 * if (r) continue; 22 * ... handle other flags / positionals ... 23 * } 24 * if (driver_inputs_count(&in) == 0) { ... no inputs ... } 25 * rc = driver_inputs_compile_and_jit(&in, compiler, host, &copts, &pp, entry, 26 * driver_dlsym_resolver, NULL, &jit); 27 * driver_inputs_release(&in); 28 * 29 * Path strings (`.c`, `.o`, `.a`) are borrowed from argv. The stdin 30 * buffer is heap-owned and freed by driver_inputs_release. */ 31 typedef struct DriverInputs { 32 DriverEnv* env; 33 const char* tool; 34 size_t bound; 35 36 const char** sources; /* .c .cc .cpp paths (borrowed) */ 37 uint32_t nsources; 38 KitSourceInput* source_memory; /* "-" stdin slurp; at most one entry */ 39 uint32_t nsource_memory; 40 uint8_t* stdin_buf; /* owning storage for the one stdin slurp */ 41 size_t stdin_size; 42 const char** object_files; /* .o .obj paths (borrowed) */ 43 uint32_t nobject_files; 44 const char** archives; /* .a paths (borrowed) */ 45 uint32_t narchives; 46 } DriverInputs; 47 48 /* Allocate the parallel arrays. `argc` is the worst-case input count 49 * (typically the program's argc). `tool` is the short name used in 50 * driver_errf messages. Returns 0 on success, 1 on allocation failure 51 * (already reported). */ 52 int driver_inputs_init(DriverInputs*, DriverEnv*, const char* tool, int argc); 53 54 /* Release every allocation held by *in, including the stdin buffer. 55 * Safe to call even after a failed init. */ 56 void driver_inputs_release(DriverInputs*); 57 58 /* Try to consume one positional input at `arg`. Recognized: 59 * "-" read C source from stdin (at most once) 60 * *.c *.toy *.s *.wat *.wasm 61 * source path 62 * *.o *.obj object-file path 63 * *.a static-archive path 64 * 65 * Returns: 66 * 1 arg matched and was recorded. 67 * 0 arg is not a recognized input shape (caller decides whether to 68 * treat it as an unknown flag, etc.). 69 * -1 arg matched a recognized shape but recording failed (duplicate 70 * stdin, stdin read failure, allocation failure); the error has 71 * already been reported via driver_errf. */ 72 int driver_inputs_classify(DriverInputs*, const char* arg); 73 74 /* Total recorded inputs across every kind. */ 75 uint32_t driver_inputs_count(const DriverInputs*); 76 77 /* Display name of the first recorded input (sources, then source_memory, 78 * then object_files, then archives — matches the order used by the 79 * link/compile loop). Used by callers to synthesize argv[0] for the 80 * JITed program. Returns NULL when no inputs are recorded. */ 81 const char* driver_inputs_first_name(const DriverInputs*); 82 83 /* Load every input through env.file_io, compile sources via `compiler` 84 * with `copts` (code/diagnostics) and `pp` (preprocessor settings, applied to 85 * preprocessor-enabled frontends), and JIT-link the result. `host` carries 86 * execmem/tls; `extern_resolver` populates the JIT link options. `pp` may be 87 * NULL for no preprocessor configuration. On success *out_jit owns the JIT 88 * image; on failure an error has already been reported. Returns 0 on success, 89 * 1 otherwise. */ 90 int driver_inputs_compile_and_jit(DriverInputs*, KitCompiler*, 91 const KitJitHost*, 92 const KitCCompileOptions* copts, 93 const KitPreprocessOptions* pp, 94 const char* entry, 95 void* (*extern_resolver)(void*, KitSlice), 96 void* extern_resolver_user, KitJit** out_jit); 97 98 /* ---------------------------------------------------------------------- 99 * Per-object global-symbol collection 100 * 101 * ar / ranlib / strip all need to enumerate the globally-defined symbols 102 * of an object file so the archive symbol index (ar/ranlib) or the 103 * --strip-unneeded keep-set (strip) can be populated. The shape is 104 * always the same: open the object, walk symbols, copy out the names 105 * of every SB_GLOBAL symbol with a defining section. 106 * 107 * driver_collect_obj_global_syms allocates a single heap block laid out 108 * as [KitSlice names[count]][NUL-separated name bytes]. The caller 109 * frees the block via driver_collect_obj_global_syms_free. Each name 110 * slice points into the name-byte region and is NUL-terminated there. 111 * 112 * Returns: 113 * 0 member parsed, output filled (count may be 0 if the object has 114 * no globally-defined symbols, or the member is not a recognized 115 * object file at all — in that case *blob_out is NULL). 116 * 1 fatal failure (out of memory, etc.); an error has been reported 117 * via driver_errf using the supplied tool tag. 118 */ 119 int driver_collect_obj_global_syms(DriverEnv* env, const KitContext* ctx, 120 const char* tool, const KitSlice* member, 121 void** blob_out, size_t* blob_size_out, 122 const KitSlice** names_out, 123 uint32_t* count_out); 124 125 void driver_collect_obj_global_syms_free(DriverEnv* env, void* blob, 126 size_t blob_size); 127 128 #endif