kit

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

hosted.c (8344B)


      1 #include "os/hosted_internal.h"
      2 
      3 static int hosted_add_linux_defines(KitOsHostedPlan* plan, int gnu) {
      4   if (kit_os_hosted_add_clang_compat_defines(plan) != 0 ||
      5       kit_os_hosted_add_define(plan, "__linux__", "1") != 0 ||
      6       kit_os_hosted_add_define(plan, "__linux", "1") != 0 ||
      7       kit_os_hosted_add_define(plan, "linux", "1") != 0 ||
      8       kit_os_hosted_add_define(plan, "__ELF__", "1") != 0)
      9     return 1;
     10   if (gnu && kit_os_hosted_add_define(plan, "__gnu_linux__", "1") != 0)
     11     return 1;
     12   return 0;
     13 }
     14 
     15 static const char* hosted_glibc_interp(KitArchKind arch) {
     16   switch (arch) {
     17     case KIT_ARCH_ARM_64:
     18       return "/lib/ld-linux-aarch64.so.1";
     19     case KIT_ARCH_X86_64:
     20       return "/lib64/ld-linux-x86-64.so.2";
     21     case KIT_ARCH_RV64:
     22       return "/lib/ld-linux-riscv64-lp64d.so.1";
     23     default:
     24       return NULL;
     25   }
     26 }
     27 
     28 static const char* hosted_musl_interp(KitArchKind arch) {
     29   switch (arch) {
     30     case KIT_ARCH_ARM_64:
     31       return "/lib/ld-musl-aarch64.so.1";
     32     case KIT_ARCH_X86_64:
     33       return "/lib/ld-musl-x86_64.so.1";
     34     case KIT_ARCH_RV64:
     35       return "/lib/ld-musl-riscv64.so.1";
     36     default:
     37       return NULL;
     38   }
     39 }
     40 
     41 static int hosted_resolve_linux_musl_static(const KitOsHostedRequest* req,
     42                                             const KitOsHostedDirs* dirs,
     43                                             KitOsHostedPlan* plan) {
     44   plan->profile_name = "linux-musl-static";
     45   if (hosted_add_linux_defines(plan, 0) != 0 ||
     46       kit_os_hosted_add_incdirs(plan, req->host, req->host_user, dirs) != 0) {
     47     kit_os_hosted_errf(req->host, req->host_user, req->tool, "out of memory");
     48     return 1;
     49   }
     50   if (!req->link_inputs) return 0;
     51   if (kit_os_hosted_add_required_search(
     52           plan->before, &plan->nbefore, KIT_OS_HOSTED_MAX_BEFORE, req, dirs,
     53           "crt1.o", KIT_OS_HOSTED_INPUT_OBJECT) != 0 ||
     54       kit_os_hosted_add_required_search(
     55           plan->before, &plan->nbefore, KIT_OS_HOSTED_MAX_BEFORE, req, dirs,
     56           "crti.o", KIT_OS_HOSTED_INPUT_OBJECT) != 0)
     57     return 1;
     58   if (kit_os_hosted_add_required_search(
     59           plan->after, &plan->nafter, KIT_OS_HOSTED_MAX_AFTER, req, dirs,
     60           "libc.a", KIT_OS_HOSTED_INPUT_ARCHIVE) != 0)
     61     return 1;
     62   if (kit_os_hosted_add_required_search(
     63           plan->final, &plan->nfinal, KIT_OS_HOSTED_MAX_FINAL, req, dirs,
     64           "crtn.o", KIT_OS_HOSTED_INPUT_OBJECT) != 0)
     65     return 1;
     66   return 0;
     67 }
     68 
     69 static int hosted_resolve_linux_musl_dynamic(const KitOsHostedRequest* req,
     70                                              const KitOsHostedDirs* dirs,
     71                                              KitOsHostedPlan* plan) {
     72   const char* interp = hosted_musl_interp(req->target.arch);
     73   if (!interp) {
     74     kit_os_hosted_errf(req->host, req->host_user, req->tool,
     75                        "no hosted musl profile for target architecture");
     76     return 1;
     77   }
     78   plan->profile_name = "linux-musl-dynamic";
     79   plan->interp_path = interp;
     80   if (hosted_add_linux_defines(plan, 0) != 0 ||
     81       kit_os_hosted_add_incdirs(plan, req->host, req->host_user, dirs) != 0) {
     82     kit_os_hosted_errf(req->host, req->host_user, req->tool, "out of memory");
     83     return 1;
     84   }
     85   if (!req->link_inputs) return 0;
     86   if (kit_os_hosted_add_required_search(
     87           plan->before, &plan->nbefore, KIT_OS_HOSTED_MAX_BEFORE, req, dirs,
     88           "Scrt1.o", KIT_OS_HOSTED_INPUT_OBJECT) != 0 ||
     89       kit_os_hosted_add_required_search(
     90           plan->before, &plan->nbefore, KIT_OS_HOSTED_MAX_BEFORE, req, dirs,
     91           "crti.o", KIT_OS_HOSTED_INPUT_OBJECT) != 0)
     92     return 1;
     93   if (kit_os_hosted_add_required_search(
     94           plan->after, &plan->nafter, KIT_OS_HOSTED_MAX_AFTER, req, dirs,
     95           "libc.so", KIT_OS_HOSTED_INPUT_DSO) != 0)
     96     return 1;
     97   if (kit_os_hosted_add_required_search(
     98           plan->final, &plan->nfinal, KIT_OS_HOSTED_MAX_FINAL, req, dirs,
     99           "crtn.o", KIT_OS_HOSTED_INPUT_OBJECT) != 0)
    100     return 1;
    101   return 0;
    102 }
    103 
    104 static int hosted_resolve_linux_glibc_dynamic(const KitOsHostedRequest* req,
    105                                               const KitOsHostedDirs* dirs,
    106                                               KitOsHostedPlan* plan) {
    107   const char* interp = hosted_glibc_interp(req->target.arch);
    108   if (!interp) {
    109     kit_os_hosted_errf(req->host, req->host_user, req->tool,
    110                        "no hosted glibc profile for target architecture");
    111     return 1;
    112   }
    113   plan->profile_name = "linux-glibc-dynamic";
    114   plan->interp_path = interp;
    115   if (hosted_add_linux_defines(plan, 1) != 0 ||
    116       kit_os_hosted_add_incdirs(plan, req->host, req->host_user, dirs) != 0) {
    117     kit_os_hosted_errf(req->host, req->host_user, req->tool, "out of memory");
    118     return 1;
    119   }
    120   if (!req->link_inputs) return 0;
    121   if (kit_os_hosted_add_required_search(
    122           plan->before, &plan->nbefore, KIT_OS_HOSTED_MAX_BEFORE, req, dirs,
    123           "Scrt1.o", KIT_OS_HOSTED_INPUT_OBJECT) != 0 ||
    124       kit_os_hosted_add_required_search(
    125           plan->before, &plan->nbefore, KIT_OS_HOSTED_MAX_BEFORE, req, dirs,
    126           "crti.o", KIT_OS_HOSTED_INPUT_OBJECT) != 0)
    127     return 1;
    128   if (kit_os_hosted_add_required_search(
    129           plan->after, &plan->nafter, KIT_OS_HOSTED_MAX_AFTER, req, dirs,
    130           "libc.so.6", KIT_OS_HOSTED_INPUT_DSO) != 0 ||
    131       kit_os_hosted_add_required_search(
    132           plan->after, &plan->nafter, KIT_OS_HOSTED_MAX_AFTER, req, dirs,
    133           "libc_nonshared.a", KIT_OS_HOSTED_INPUT_ARCHIVE) != 0)
    134     return 1;
    135   if (kit_os_hosted_add_required_search(
    136           plan->final, &plan->nfinal, KIT_OS_HOSTED_MAX_FINAL, req, dirs,
    137           "crtn.o", KIT_OS_HOSTED_INPUT_OBJECT) != 0)
    138     return 1;
    139   return 0;
    140 }
    141 
    142 static int hosted_resolve_linux(const KitOsHostedRequest* req,
    143                                 const KitOsHostedDirs* dirs,
    144                                 KitOsHostedPlan* plan) {
    145   int has_libc_a, has_libc_so, has_libc_so6, has_glibc_nonshared;
    146   if (dirs->nlibdirs == 0) {
    147     kit_os_hosted_errf(req->host, req->host_user, req->tool,
    148                        "Linux hosted profile requires --sysroot or "
    149                        "KIT_SYSROOT");
    150     return 1;
    151   }
    152   has_libc_a =
    153       kit_os_hosted_libdir_has(req->host, req->host_user, dirs, "libc.a");
    154   has_libc_so =
    155       kit_os_hosted_libdir_has(req->host, req->host_user, dirs, "libc.so");
    156   has_libc_so6 =
    157       kit_os_hosted_libdir_has(req->host, req->host_user, dirs, "libc.so.6");
    158   has_glibc_nonshared = kit_os_hosted_libdir_has(
    159       req->host, req->host_user, dirs, "libc_nonshared.a");
    160   if (!req->static_link && has_libc_so6 && has_glibc_nonshared)
    161     return hosted_resolve_linux_glibc_dynamic(req, dirs, plan);
    162   if (!req->static_link && has_libc_so)
    163     return hosted_resolve_linux_musl_dynamic(req, dirs, plan);
    164   if (has_libc_a && !(has_libc_so6 && has_glibc_nonshared))
    165     return hosted_resolve_linux_musl_static(req, dirs, plan);
    166   kit_os_hosted_errf(req->host, req->host_user, req->tool,
    167                      "no supported Linux hosted libc found (searched %u "
    168                      "library dir(s))",
    169                      (unsigned)dirs->nlibdirs);
    170   return 1;
    171 }
    172 
    173 static const char* hosted_linux_inc_triple_sub(KitArchKind arch) {
    174   switch (arch) {
    175     case KIT_ARCH_ARM_64:
    176       return "usr/include/aarch64-linux-gnu";
    177     case KIT_ARCH_X86_64:
    178       return "usr/include/x86_64-linux-gnu";
    179     case KIT_ARCH_RV64:
    180       return "usr/include/riscv64-linux-gnu";
    181     default:
    182       return NULL;
    183   }
    184 }
    185 
    186 static int hosted_sysroot_layout_linux(KitOsHostedDirs* dirs,
    187                                        KitTargetSpec target,
    188                                        const char* sysroot) {
    189   const char* triple = hosted_linux_inc_triple_sub(target.arch);
    190   if (kit_os_hosted_dirs_add_inc_join(dirs, sysroot, "usr/include") != 0)
    191     return 1;
    192   if (triple && kit_os_hosted_dirs_add_inc_join(dirs, sysroot, triple) != 0)
    193     return 1;
    194   if (kit_os_hosted_dirs_add_lib_join(dirs, sysroot, "usr/lib") != 0)
    195     return 1;
    196   if (kit_os_hosted_dirs_add_lib_join(dirs, sysroot, "lib") != 0) return 1;
    197   if (kit_os_hosted_dirs_add_lib_join(dirs, sysroot, "lib64") != 0) return 1;
    198   return 0;
    199 }
    200 
    201 const KitOsHostedOps kit_os_linux_hosted_ops = {
    202     .obj = KIT_OBJ_ELF,
    203     .default_profile = 0,
    204     .needs_sysroot_libdir = 0,
    205     .resolve = hosted_resolve_linux,
    206     .sysroot_layout = hosted_sysroot_layout_linux,
    207 };