kit

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

link_inputs.h (9741B)


      1 #ifndef KIT_DRIVER_LINK_INPUTS_H
      2 #define KIT_DRIVER_LINK_INPUTS_H
      3 
      4 #include <kit/compile.h>
      5 #include <stddef.h>
      6 #include <stdint.h>
      7 
      8 #include "cflags.h"
      9 #include "driver.h"
     10 #include "hosted.h"
     11 #include "link_flags.h"
     12 #include "runtime.h"
     13 
     14 /* Shared link-input model for the `cc` and `build-*` drivers.
     15  *
     16  * Both drivers classify positionals (and resolved `-l` names, runtime
     17  * archives, and hosted crt/libc files) into an ordered list of link items
     18  * backed by parallel object / archive / dso arrays, then resolve pending `-l`
     19  * names and replay the items into the linker. The two had byte-identical copies
     20  * of that model and its bookkeeping; this module owns the single
     21  * implementation. Each driver embeds a DriverLinkInputSet (by value, like the
     22  * shared DriverCflags / DriverLinkFlags) and keeps only its tool-specific state
     23  * (cc: sources/deps/probes; build: groups/scopes). */
     24 
     25 /* Kind of a link item. SOURCE / SOURCE_MEMORY index into the *driver's own*
     26  * source arrays (interpreted by the driver, never by this module); OBJECT /
     27  * ARCHIVE / DSO / LIB index into this set's parallel arrays. */
     28 typedef enum DriverLinkKind {
     29   DRIVER_LINK_SOURCE = 0,    /* index into the driver's source array        */
     30   DRIVER_LINK_SOURCE_MEMORY, /* cc: index into in-memory (stdin) sources    */
     31   DRIVER_LINK_OBJECT,        /* index into object_files                     */
     32   DRIVER_LINK_ARCHIVE,       /* index into archives                         */
     33   DRIVER_LINK_DSO,           /* index into dsos                             */
     34   DRIVER_LINK_LIB,           /* index into pending_libs (resolved later)    */
     35   DRIVER_LINK_FRAMEWORK,     /* index into pending_frameworks               */
     36 } DriverLinkKind;
     37 
     38 typedef struct DriverLinkItem {
     39   uint8_t kind; /* DriverLinkKind */
     40   uint8_t pad[3];
     41   uint32_t index;
     42 } DriverLinkItem;
     43 
     44 typedef struct DriverArchiveInput {
     45   const char* path;
     46   int owned;
     47   size_t owned_size;
     48   uint8_t whole_archive;
     49   uint8_t link_mode;
     50   uint8_t group_id;
     51   uint8_t pad;
     52 } DriverArchiveInput;
     53 
     54 typedef struct DriverDsoInput {
     55   const char* path;
     56   int owned;
     57   size_t owned_size;
     58 } DriverDsoInput;
     59 
     60 typedef struct DriverPendingLib {
     61   const char* name;
     62   uint8_t whole_archive;
     63   uint8_t link_mode;
     64   uint8_t group_id;
     65   uint8_t resolved_kind; /* DriverLinkKind: ARCHIVE or DSO */
     66   uint32_t resolved_index;
     67 } DriverPendingLib;
     68 
     69 typedef struct DriverPendingFramework {
     70   const char* name;
     71   uint32_t resolved_index;
     72 } DriverPendingFramework;
     73 
     74 typedef struct DriverLinkInputSet {
     75   DriverEnv* env;
     76   const char* tool;
     77   size_t bound; /* per-array capacity (for fini) */
     78 
     79   /* Positional / resolved inputs, split by kind. */
     80   const char** object_files; /* .o/.obj paths */
     81   uint32_t nobject_files;
     82   DriverArchiveInput* archives; /* .a paths + resolved -l names */
     83   uint32_t narchives;
     84   DriverDsoInput* dsos;
     85   uint32_t ndsos;
     86   const char** lib_search_paths; /* -L dirs (+ hosted/sysroot dirs) */
     87   uint32_t nlib_search_paths;
     88   const char** framework_search_paths; /* -F dirs (+ SDK framework dirs) */
     89   uint32_t nframework_search_paths;
     90   DriverPendingLib* pending_libs; /* -l names, resolved at end-of-parse */
     91   uint32_t npending_libs;
     92   DriverPendingFramework* pending_frameworks; /* -framework names */
     93   uint32_t npending_frameworks;
     94   DriverLinkItem* link_items; /* ordered link sequence */
     95   uint32_t nlink_items;
     96 
     97   /* Attributes applied to the next archive positional, driven by
     98    * -Wl,--whole-archive / -Bstatic|-Bdynamic / --start-group. */
     99   uint8_t cur_whole_archive;
    100   uint8_t cur_link_mode;
    101   uint8_t cur_group_id;
    102 
    103   /* Owned `<sysroot>/lib` slot appended for Windows targets when a sysroot is
    104    * in effect (see driver_link_inputs_append_windows_lib_dirs). */
    105   char* owned_sysroot_lib_dir;
    106   size_t owned_sysroot_lib_dir_size;
    107   char* owned_sysroot_framework_dirs[2];
    108   size_t owned_sysroot_framework_dir_sizes[2];
    109   uint32_t nowned_sysroot_framework_dirs;
    110 } DriverLinkInputSet;
    111 
    112 /* Allocate the parallel arrays (each sized `bound`) and seed defaults
    113  * (cur_link_mode = KIT_LM_DEFAULT). Returns 0, or 1 on OOM (diagnostic via
    114  * `tool`). */
    115 int driver_link_inputs_init(DriverLinkInputSet* set, DriverEnv* env,
    116                             const char* tool, size_t bound);
    117 
    118 /* Free owned archive/dso paths, the owned sysroot lib dir, and the arrays. */
    119 void driver_link_inputs_fini(DriverLinkInputSet* set);
    120 
    121 /* True for a `.so` / `.dylib` / `.tbd` shared-object path. */
    122 int driver_is_dso_path(const char* s);
    123 
    124 /* Append / insert a link item referencing array slot `index`. */
    125 void driver_link_inputs_push(DriverLinkInputSet* set, uint8_t kind,
    126                              uint32_t index);
    127 void driver_link_inputs_insert(DriverLinkInputSet* set, uint32_t pos,
    128                                uint8_t kind, uint32_t index);
    129 
    130 /* Record one hosted crt/libc input (object/archive/dso) into the set and order
    131  * it: insert at `insert_pos` when `insert`, else append. Returns 0/1. */
    132 int driver_link_inputs_append_hosted(DriverLinkInputSet* set,
    133                                      const DriverHostedInput* in,
    134                                      uint32_t insert_pos, int insert);
    135 
    136 /* Move a runtime archive (ownership transferred out of `rt`) into the set and
    137  * insert its link item at `insert_pos`. */
    138 void driver_link_inputs_insert_runtime_archive(DriverLinkInputSet* set,
    139                                                DriverRuntimeArchive* rt,
    140                                                uint32_t insert_pos);
    141 
    142 /* Insert the compiler runtime archive `rt` (ownership transferred out) at the
    143  * position(s) that satisfy the target's link order. For Windows this is a
    144  * two-position insert (a strong-_setjmp entry before the hosted `after` group
    145  * plus a late ___chkstk_ms entry before crtend; see the implementation), so a
    146  * second owned copy of the path is allocated. For every other target it is the
    147  * single end-insert (before the `nfinal` crt-end group). `nfinal` / `nafter`
    148  * are the hosted plan's final / after group sizes. */
    149 void driver_link_inputs_insert_runtime_archives(DriverLinkInputSet* set,
    150                                                 DriverRuntimeArchive* rt,
    151                                                 KitTargetSpec target,
    152                                                 uint32_t nfinal,
    153                                                 uint32_t nafter);
    154 
    155 /* Translate the recorded link-item sequence into the engine's public
    156  * KitLinkInputOrder list, writing into `order` (sized >= set->nlink_items) and
    157  * returning the count produced. SOURCE / SOURCE_MEMORY items index the caller's
    158  * parallel `source_obj_index` / `source_order_keep` arrays — the latter gates
    159  * whether a compiled source survived DCE; dropped sources are skipped.
    160  * SOURCE_MEMORY (cc stdin sources) indexes past `nsource_files` into those same
    161  * arrays; build records no SOURCE_MEMORY items, so it may pass any
    162  * nsource_files. OBJECT / ARCHIVE / DSO map straight through; LIB resolves via
    163  * its pending-lib slot's resolved kind/index. */
    164 uint32_t driver_link_inputs_build_order(const DriverLinkInputSet* set,
    165                                         const uint32_t* source_obj_index,
    166                                         const uint8_t* source_order_keep,
    167                                         uint32_t nsource_files,
    168                                         KitLinkInputOrder* order);
    169 
    170 /* Resolve every pending `-l` name against lib_search_paths into a concrete
    171  * archive or dso slot, filling each pending lib's resolved_kind/index. Returns
    172  * 0, or 1 with a diagnostic on not-found. */
    173 int driver_link_inputs_resolve_pending(DriverLinkInputSet* set,
    174                                        KitTargetSpec target, int static_link);
    175 
    176 /* For Windows targets, append `<sysroot>/lib` to the search path. The sysroot
    177  * is `*sysroot` if set, else KIT_SYSROOT (which is then written back through
    178  * `*sysroot`). No-op for non-Windows targets or when no sysroot applies.
    179  * Returns 0/1. */
    180 int driver_link_inputs_append_windows_lib_dirs(DriverLinkInputSet* set,
    181                                                const char** sysroot,
    182                                                KitTargetSpec target);
    183 
    184 /* True when the target uses Mach-O framework search dirs (Apple SDK): obj is
    185  * Mach-O and the target OS's hosted ops set uses_framework_dirs. Shared between
    186  * the cc/build link-input path and the `ld` driver. */
    187 int driver_target_uses_framework_dirs(KitTargetSpec target);
    188 
    189 /* For Mach-O SDK targets, append `<sysroot>/System/Library/Frameworks` and
    190  * `<sysroot>/System/Library/PrivateFrameworks` to the framework search path.
    191  * The sysroot is `*sysroot` if set, else KIT_SYSROOT (which is written back
    192  * through `*sysroot`). No-op for non-Apple-Mach-O targets or no sysroot. */
    193 int driver_link_inputs_append_sysroot_framework_dirs(DriverLinkInputSet* set,
    194                                                      const char** sysroot,
    195                                                      KitTargetSpec target);
    196 
    197 /* Apply a hosted libc profile: resolve `plan` for the target/sysroot, add its
    198  * system includes + defines to `cf`, add its lib search dirs to the set, and
    199  * (when `link_action`) insert its crt inputs and adopt its interpreter into
    200  * `link`. The wants-hosted / -nostdlib guard belongs to the caller. Returns
    201  * 0/1. */
    202 int driver_link_inputs_apply_hosted(DriverLinkInputSet* set,
    203                                     DriverHostedPlan* plan, DriverCflags* cf,
    204                                     DriverLinkFlags* link, KitTargetSpec target,
    205                                     const char* sysroot, int static_link,
    206                                     int shared_link, int no_startfiles,
    207                                     int link_action);
    208 
    209 #endif