LCOV - code coverage report
Current view: top level - src - link.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 545 1330 41.0 %
Date: 1970-01-01 00:00:01 Functions: 26 43 60.5 %
Branches: 224 734 30.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2015 Andrew Kelley
       3                 :            :  *
       4                 :            :  * This file is part of zig, which is MIT licensed.
       5                 :            :  * See http://opensource.org/licenses/MIT
       6                 :            :  */
       7                 :            : 
       8                 :            : #include "os.hpp"
       9                 :            : #include "config.h"
      10                 :            : #include "codegen.hpp"
      11                 :            : #include "analyze.hpp"
      12                 :            : #include "compiler.hpp"
      13                 :            : #include "install_files.h"
      14                 :            : #include "glibc.hpp"
      15                 :            : 
      16                 :            : static const char *msvcrt_common_src[] = {
      17                 :            :     "misc" OS_SEP "onexit_table.c",
      18                 :            :     "misc" OS_SEP "register_tls_atexit.c",
      19                 :            :     "stdio" OS_SEP "acrt_iob_func.c",
      20                 :            :     "misc" OS_SEP "_configthreadlocale.c",
      21                 :            :     "misc" OS_SEP "_get_current_locale.c",
      22                 :            :     "misc" OS_SEP "invalid_parameter_handler.c",
      23                 :            :     "misc" OS_SEP "output_format.c",
      24                 :            :     "misc" OS_SEP "purecall.c",
      25                 :            :     "secapi" OS_SEP "_access_s.c",
      26                 :            :     "secapi" OS_SEP "_cgets_s.c",
      27                 :            :     "secapi" OS_SEP "_cgetws_s.c",
      28                 :            :     "secapi" OS_SEP "_chsize_s.c",
      29                 :            :     "secapi" OS_SEP "_controlfp_s.c",
      30                 :            :     "secapi" OS_SEP "_cprintf_s.c",
      31                 :            :     "secapi" OS_SEP "_cprintf_s_l.c",
      32                 :            :     "secapi" OS_SEP "_ctime32_s.c",
      33                 :            :     "secapi" OS_SEP "_ctime64_s.c",
      34                 :            :     "secapi" OS_SEP "_cwprintf_s.c",
      35                 :            :     "secapi" OS_SEP "_cwprintf_s_l.c",
      36                 :            :     "secapi" OS_SEP "_gmtime32_s.c",
      37                 :            :     "secapi" OS_SEP "_gmtime64_s.c",
      38                 :            :     "secapi" OS_SEP "_localtime32_s.c",
      39                 :            :     "secapi" OS_SEP "_localtime64_s.c",
      40                 :            :     "secapi" OS_SEP "_mktemp_s.c",
      41                 :            :     "secapi" OS_SEP "_sopen_s.c",
      42                 :            :     "secapi" OS_SEP "_strdate_s.c",
      43                 :            :     "secapi" OS_SEP "_strtime_s.c",
      44                 :            :     "secapi" OS_SEP "_umask_s.c",
      45                 :            :     "secapi" OS_SEP "_vcprintf_s.c",
      46                 :            :     "secapi" OS_SEP "_vcprintf_s_l.c",
      47                 :            :     "secapi" OS_SEP "_vcwprintf_s.c",
      48                 :            :     "secapi" OS_SEP "_vcwprintf_s_l.c",
      49                 :            :     "secapi" OS_SEP "_vscprintf_p.c",
      50                 :            :     "secapi" OS_SEP "_vscwprintf_p.c",
      51                 :            :     "secapi" OS_SEP "_vswprintf_p.c",
      52                 :            :     "secapi" OS_SEP "_waccess_s.c",
      53                 :            :     "secapi" OS_SEP "_wasctime_s.c",
      54                 :            :     "secapi" OS_SEP "_wctime32_s.c",
      55                 :            :     "secapi" OS_SEP "_wctime64_s.c",
      56                 :            :     "secapi" OS_SEP "_wstrtime_s.c",
      57                 :            :     "secapi" OS_SEP "_wmktemp_s.c",
      58                 :            :     "secapi" OS_SEP "_wstrdate_s.c",
      59                 :            :     "secapi" OS_SEP "asctime_s.c",
      60                 :            :     "secapi" OS_SEP "memcpy_s.c",
      61                 :            :     "secapi" OS_SEP "memmove_s.c",
      62                 :            :     "secapi" OS_SEP "rand_s.c",
      63                 :            :     "secapi" OS_SEP "sprintf_s.c",
      64                 :            :     "secapi" OS_SEP "strerror_s.c",
      65                 :            :     "secapi" OS_SEP "vsprintf_s.c",
      66                 :            :     "secapi" OS_SEP "wmemcpy_s.c",
      67                 :            :     "secapi" OS_SEP "wmemmove_s.c",
      68                 :            :     "stdio" OS_SEP "mingw_lock.c",
      69                 :            : };
      70                 :            : 
      71                 :            : static const char *msvcrt_i386_src[] = {
      72                 :            :     "misc" OS_SEP "lc_locale_func.c",
      73                 :            : 
      74                 :            : };
      75                 :            : 
      76                 :            : static const char *msvcrt_other_src[] = {
      77                 :            :     "misc" OS_SEP "__p___argv.c",
      78                 :            :     "misc" OS_SEP "__p__acmdln.c",
      79                 :            :     "misc" OS_SEP "__p__fmode.c",
      80                 :            :     "misc" OS_SEP "__p__wcmdln.c",
      81                 :            : };
      82                 :            : 
      83                 :            : static const char *mingwex_generic_src[] = {
      84                 :            :     "complex" OS_SEP "_cabs.c",
      85                 :            :     "complex" OS_SEP "cabs.c",
      86                 :            :     "complex" OS_SEP "cabsf.c",
      87                 :            :     "complex" OS_SEP "cabsl.c",
      88                 :            :     "complex" OS_SEP "cacos.c",
      89                 :            :     "complex" OS_SEP "cacosf.c",
      90                 :            :     "complex" OS_SEP "cacosl.c",
      91                 :            :     "complex" OS_SEP "carg.c",
      92                 :            :     "complex" OS_SEP "cargf.c",
      93                 :            :     "complex" OS_SEP "cargl.c",
      94                 :            :     "complex" OS_SEP "casin.c",
      95                 :            :     "complex" OS_SEP "casinf.c",
      96                 :            :     "complex" OS_SEP "casinl.c",
      97                 :            :     "complex" OS_SEP "catan.c",
      98                 :            :     "complex" OS_SEP "catanf.c",
      99                 :            :     "complex" OS_SEP "catanl.c",
     100                 :            :     "complex" OS_SEP "ccos.c",
     101                 :            :     "complex" OS_SEP "ccosf.c",
     102                 :            :     "complex" OS_SEP "ccosl.c",
     103                 :            :     "complex" OS_SEP "cexp.c",
     104                 :            :     "complex" OS_SEP "cexpf.c",
     105                 :            :     "complex" OS_SEP "cexpl.c",
     106                 :            :     "complex" OS_SEP "cimag.c",
     107                 :            :     "complex" OS_SEP "cimagf.c",
     108                 :            :     "complex" OS_SEP "cimagl.c",
     109                 :            :     "complex" OS_SEP "clog.c",
     110                 :            :     "complex" OS_SEP "clog10.c",
     111                 :            :     "complex" OS_SEP "clog10f.c",
     112                 :            :     "complex" OS_SEP "clog10l.c",
     113                 :            :     "complex" OS_SEP "clogf.c",
     114                 :            :     "complex" OS_SEP "clogl.c",
     115                 :            :     "complex" OS_SEP "conj.c",
     116                 :            :     "complex" OS_SEP "conjf.c",
     117                 :            :     "complex" OS_SEP "conjl.c",
     118                 :            :     "complex" OS_SEP "cpow.c",
     119                 :            :     "complex" OS_SEP "cpowf.c",
     120                 :            :     "complex" OS_SEP "cpowl.c",
     121                 :            :     "complex" OS_SEP "cproj.c",
     122                 :            :     "complex" OS_SEP "cprojf.c",
     123                 :            :     "complex" OS_SEP "cprojl.c",
     124                 :            :     "complex" OS_SEP "creal.c",
     125                 :            :     "complex" OS_SEP "crealf.c",
     126                 :            :     "complex" OS_SEP "creall.c",
     127                 :            :     "complex" OS_SEP "csin.c",
     128                 :            :     "complex" OS_SEP "csinf.c",
     129                 :            :     "complex" OS_SEP "csinl.c",
     130                 :            :     "complex" OS_SEP "csqrt.c",
     131                 :            :     "complex" OS_SEP "csqrtf.c",
     132                 :            :     "complex" OS_SEP "csqrtl.c",
     133                 :            :     "complex" OS_SEP "ctan.c",
     134                 :            :     "complex" OS_SEP "ctanf.c",
     135                 :            :     "complex" OS_SEP "ctanl.c",
     136                 :            :     "crt" OS_SEP "dllentry.c",
     137                 :            :     "crt" OS_SEP "dllmain.c",
     138                 :            :     "gdtoa" OS_SEP "arithchk.c",
     139                 :            :     "gdtoa" OS_SEP "dmisc.c",
     140                 :            :     "gdtoa" OS_SEP "dtoa.c",
     141                 :            :     "gdtoa" OS_SEP "g__fmt.c",
     142                 :            :     "gdtoa" OS_SEP "g_dfmt.c",
     143                 :            :     "gdtoa" OS_SEP "g_ffmt.c",
     144                 :            :     "gdtoa" OS_SEP "g_xfmt.c",
     145                 :            :     "gdtoa" OS_SEP "gdtoa.c",
     146                 :            :     "gdtoa" OS_SEP "gethex.c",
     147                 :            :     "gdtoa" OS_SEP "gmisc.c",
     148                 :            :     "gdtoa" OS_SEP "hd_init.c",
     149                 :            :     "gdtoa" OS_SEP "hexnan.c",
     150                 :            :     "gdtoa" OS_SEP "misc.c",
     151                 :            :     "gdtoa" OS_SEP "qnan.c",
     152                 :            :     "gdtoa" OS_SEP "smisc.c",
     153                 :            :     "gdtoa" OS_SEP "strtodg.c",
     154                 :            :     "gdtoa" OS_SEP "strtodnrp.c",
     155                 :            :     "gdtoa" OS_SEP "strtof.c",
     156                 :            :     "gdtoa" OS_SEP "strtopx.c",
     157                 :            :     "gdtoa" OS_SEP "sum.c",
     158                 :            :     "gdtoa" OS_SEP "ulp.c",
     159                 :            :     "math" OS_SEP "abs64.c",
     160                 :            :     "math" OS_SEP "cbrt.c",
     161                 :            :     "math" OS_SEP "cbrtf.c",
     162                 :            :     "math" OS_SEP "cbrtl.c",
     163                 :            :     "math" OS_SEP "cephes_emath.c",
     164                 :            :     "math" OS_SEP "copysign.c",
     165                 :            :     "math" OS_SEP "copysignf.c",
     166                 :            :     "math" OS_SEP "coshf.c",
     167                 :            :     "math" OS_SEP "coshl.c",
     168                 :            :     "math" OS_SEP "erfl.c",
     169                 :            :     "math" OS_SEP "expf.c",
     170                 :            :     "math" OS_SEP "fabs.c",
     171                 :            :     "math" OS_SEP "fabsf.c",
     172                 :            :     "math" OS_SEP "fabsl.c",
     173                 :            :     "math" OS_SEP "fdim.c",
     174                 :            :     "math" OS_SEP "fdimf.c",
     175                 :            :     "math" OS_SEP "fdiml.c",
     176                 :            :     "math" OS_SEP "fma.c",
     177                 :            :     "math" OS_SEP "fmaf.c",
     178                 :            :     "math" OS_SEP "fmal.c",
     179                 :            :     "math" OS_SEP "fmax.c",
     180                 :            :     "math" OS_SEP "fmaxf.c",
     181                 :            :     "math" OS_SEP "fmaxl.c",
     182                 :            :     "math" OS_SEP "fmin.c",
     183                 :            :     "math" OS_SEP "fminf.c",
     184                 :            :     "math" OS_SEP "fminl.c",
     185                 :            :     "math" OS_SEP "fp_consts.c",
     186                 :            :     "math" OS_SEP "fp_constsf.c",
     187                 :            :     "math" OS_SEP "fp_constsl.c",
     188                 :            :     "math" OS_SEP "fpclassify.c",
     189                 :            :     "math" OS_SEP "fpclassifyf.c",
     190                 :            :     "math" OS_SEP "fpclassifyl.c",
     191                 :            :     "math" OS_SEP "frexpf.c",
     192                 :            :     "math" OS_SEP "hypot.c",
     193                 :            :     "math" OS_SEP "hypotf.c",
     194                 :            :     "math" OS_SEP "hypotl.c",
     195                 :            :     "math" OS_SEP "isnan.c",
     196                 :            :     "math" OS_SEP "isnanf.c",
     197                 :            :     "math" OS_SEP "isnanl.c",
     198                 :            :     "math" OS_SEP "ldexpf.c",
     199                 :            :     "math" OS_SEP "lgamma.c",
     200                 :            :     "math" OS_SEP "lgammaf.c",
     201                 :            :     "math" OS_SEP "lgammal.c",
     202                 :            :     "math" OS_SEP "llrint.c",
     203                 :            :     "math" OS_SEP "llrintf.c",
     204                 :            :     "math" OS_SEP "llrintl.c",
     205                 :            :     "math" OS_SEP "llround.c",
     206                 :            :     "math" OS_SEP "llroundf.c",
     207                 :            :     "math" OS_SEP "llroundl.c",
     208                 :            :     "math" OS_SEP "log10f.c",
     209                 :            :     "math" OS_SEP "logf.c",
     210                 :            :     "math" OS_SEP "lrint.c",
     211                 :            :     "math" OS_SEP "lrintf.c",
     212                 :            :     "math" OS_SEP "lrintl.c",
     213                 :            :     "math" OS_SEP "lround.c",
     214                 :            :     "math" OS_SEP "lroundf.c",
     215                 :            :     "math" OS_SEP "lroundl.c",
     216                 :            :     "math" OS_SEP "modf.c",
     217                 :            :     "math" OS_SEP "modff.c",
     218                 :            :     "math" OS_SEP "modfl.c",
     219                 :            :     "math" OS_SEP "nextafterf.c",
     220                 :            :     "math" OS_SEP "nextafterl.c",
     221                 :            :     "math" OS_SEP "nexttoward.c",
     222                 :            :     "math" OS_SEP "nexttowardf.c",
     223                 :            :     "math" OS_SEP "powf.c",
     224                 :            :     "math" OS_SEP "powi.c",
     225                 :            :     "math" OS_SEP "powif.c",
     226                 :            :     "math" OS_SEP "powil.c",
     227                 :            :     "math" OS_SEP "rint.c",
     228                 :            :     "math" OS_SEP "rintf.c",
     229                 :            :     "math" OS_SEP "rintl.c",
     230                 :            :     "math" OS_SEP "round.c",
     231                 :            :     "math" OS_SEP "roundf.c",
     232                 :            :     "math" OS_SEP "roundl.c",
     233                 :            :     "math" OS_SEP "s_erf.c",
     234                 :            :     "math" OS_SEP "sf_erf.c",
     235                 :            :     "math" OS_SEP "signbit.c",
     236                 :            :     "math" OS_SEP "signbitf.c",
     237                 :            :     "math" OS_SEP "signbitl.c",
     238                 :            :     "math" OS_SEP "signgam.c",
     239                 :            :     "math" OS_SEP "sinhf.c",
     240                 :            :     "math" OS_SEP "sinhl.c",
     241                 :            :     "math" OS_SEP "sqrt.c",
     242                 :            :     "math" OS_SEP "sqrtf.c",
     243                 :            :     "math" OS_SEP "sqrtl.c",
     244                 :            :     "math" OS_SEP "tanhf.c",
     245                 :            :     "math" OS_SEP "tanhl.c",
     246                 :            :     "math" OS_SEP "tgamma.c",
     247                 :            :     "math" OS_SEP "tgammaf.c",
     248                 :            :     "math" OS_SEP "tgammal.c",
     249                 :            :     "math" OS_SEP "truncl.c",
     250                 :            :     "misc" OS_SEP "alarm.c",
     251                 :            :     "misc" OS_SEP "assert.c",
     252                 :            :     "misc" OS_SEP "basename.c",
     253                 :            :     "misc" OS_SEP "btowc.c",
     254                 :            :     "misc" OS_SEP "delay-f.c",
     255                 :            :     "misc" OS_SEP "delay-n.c",
     256                 :            :     "misc" OS_SEP "delayimp.c",
     257                 :            :     "misc" OS_SEP "difftime.c",
     258                 :            :     "misc" OS_SEP "difftime32.c",
     259                 :            :     "misc" OS_SEP "difftime64.c",
     260                 :            :     "misc" OS_SEP "dirent.c",
     261                 :            :     "misc" OS_SEP "dirname.c",
     262                 :            :     "misc" OS_SEP "execv.c",
     263                 :            :     "misc" OS_SEP "execve.c",
     264                 :            :     "misc" OS_SEP "execvp.c",
     265                 :            :     "misc" OS_SEP "execvpe.c",
     266                 :            :     "misc" OS_SEP "feclearexcept.c",
     267                 :            :     "misc" OS_SEP "fegetenv.c",
     268                 :            :     "misc" OS_SEP "fegetexceptflag.c",
     269                 :            :     "misc" OS_SEP "fegetround.c",
     270                 :            :     "misc" OS_SEP "feholdexcept.c",
     271                 :            :     "misc" OS_SEP "feraiseexcept.c",
     272                 :            :     "misc" OS_SEP "fesetenv.c",
     273                 :            :     "misc" OS_SEP "fesetexceptflag.c",
     274                 :            :     "misc" OS_SEP "fesetround.c",
     275                 :            :     "misc" OS_SEP "fetestexcept.c",
     276                 :            :     "misc" OS_SEP "feupdateenv.c",
     277                 :            :     "misc" OS_SEP "ftruncate.c",
     278                 :            :     "misc" OS_SEP "ftw.c",
     279                 :            :     "misc" OS_SEP "ftw64.c",
     280                 :            :     "misc" OS_SEP "fwide.c",
     281                 :            :     "misc" OS_SEP "getlogin.c",
     282                 :            :     "misc" OS_SEP "getopt.c",
     283                 :            :     "misc" OS_SEP "gettimeofday.c",
     284                 :            :     "misc" OS_SEP "imaxabs.c",
     285                 :            :     "misc" OS_SEP "imaxdiv.c",
     286                 :            :     "misc" OS_SEP "isblank.c",
     287                 :            :     "misc" OS_SEP "iswblank.c",
     288                 :            :     "misc" OS_SEP "mbrtowc.c",
     289                 :            :     "misc" OS_SEP "mbsinit.c",
     290                 :            :     "misc" OS_SEP "mempcpy.c",
     291                 :            :     "misc" OS_SEP "mingw-aligned-malloc.c",
     292                 :            :     "misc" OS_SEP "mingw-fseek.c",
     293                 :            :     "misc" OS_SEP "mingw_getsp.S",
     294                 :            :     "misc" OS_SEP "mingw_matherr.c",
     295                 :            :     "misc" OS_SEP "mingw_mbwc_convert.c",
     296                 :            :     "misc" OS_SEP "mingw_usleep.c",
     297                 :            :     "misc" OS_SEP "mingw_wcstod.c",
     298                 :            :     "misc" OS_SEP "mingw_wcstof.c",
     299                 :            :     "misc" OS_SEP "mingw_wcstold.c",
     300                 :            :     "misc" OS_SEP "mkstemp.c",
     301                 :            :     "misc" OS_SEP "seterrno.c",
     302                 :            :     "misc" OS_SEP "sleep.c",
     303                 :            :     "misc" OS_SEP "spawnv.c",
     304                 :            :     "misc" OS_SEP "spawnve.c",
     305                 :            :     "misc" OS_SEP "spawnvp.c",
     306                 :            :     "misc" OS_SEP "spawnvpe.c",
     307                 :            :     "misc" OS_SEP "strnlen.c",
     308                 :            :     "misc" OS_SEP "strsafe.c",
     309                 :            :     "misc" OS_SEP "strtoimax.c",
     310                 :            :     "misc" OS_SEP "strtold.c",
     311                 :            :     "misc" OS_SEP "strtoumax.c",
     312                 :            :     "misc" OS_SEP "tdelete.c",
     313                 :            :     "misc" OS_SEP "tfind.c",
     314                 :            :     "misc" OS_SEP "tsearch.c",
     315                 :            :     "misc" OS_SEP "twalk.c",
     316                 :            :     "misc" OS_SEP "uchar_c16rtomb.c",
     317                 :            :     "misc" OS_SEP "uchar_c32rtomb.c",
     318                 :            :     "misc" OS_SEP "uchar_mbrtoc16.c",
     319                 :            :     "misc" OS_SEP "uchar_mbrtoc32.c",
     320                 :            :     "misc" OS_SEP "wassert.c",
     321                 :            :     "misc" OS_SEP "wcrtomb.c",
     322                 :            :     "misc" OS_SEP "wcsnlen.c",
     323                 :            :     "misc" OS_SEP "wcstof.c",
     324                 :            :     "misc" OS_SEP "wcstoimax.c",
     325                 :            :     "misc" OS_SEP "wcstold.c",
     326                 :            :     "misc" OS_SEP "wcstoumax.c",
     327                 :            :     "misc" OS_SEP "wctob.c",
     328                 :            :     "misc" OS_SEP "wctrans.c",
     329                 :            :     "misc" OS_SEP "wctype.c",
     330                 :            :     "misc" OS_SEP "wdirent.c",
     331                 :            :     "misc" OS_SEP "winbs_uint64.c",
     332                 :            :     "misc" OS_SEP "winbs_ulong.c",
     333                 :            :     "misc" OS_SEP "winbs_ushort.c",
     334                 :            :     "misc" OS_SEP "wmemchr.c",
     335                 :            :     "misc" OS_SEP "wmemcmp.c",
     336                 :            :     "misc" OS_SEP "wmemcpy.c",
     337                 :            :     "misc" OS_SEP "wmemmove.c",
     338                 :            :     "misc" OS_SEP "wmempcpy.c",
     339                 :            :     "misc" OS_SEP "wmemset.c",
     340                 :            :     "stdio" OS_SEP "_Exit.c",
     341                 :            :     "stdio" OS_SEP "_findfirst64i32.c",
     342                 :            :     "stdio" OS_SEP "_findnext64i32.c",
     343                 :            :     "stdio" OS_SEP "_fstat.c",
     344                 :            :     "stdio" OS_SEP "_fstat64i32.c",
     345                 :            :     "stdio" OS_SEP "_ftime.c",
     346                 :            :     "stdio" OS_SEP "_getc_nolock.c",
     347                 :            :     "stdio" OS_SEP "_getwc_nolock.c",
     348                 :            :     "stdio" OS_SEP "_putc_nolock.c",
     349                 :            :     "stdio" OS_SEP "_putwc_nolock.c",
     350                 :            :     "stdio" OS_SEP "_stat.c",
     351                 :            :     "stdio" OS_SEP "_stat64i32.c",
     352                 :            :     "stdio" OS_SEP "_wfindfirst64i32.c",
     353                 :            :     "stdio" OS_SEP "_wfindnext64i32.c",
     354                 :            :     "stdio" OS_SEP "_wstat.c",
     355                 :            :     "stdio" OS_SEP "_wstat64i32.c",
     356                 :            :     "stdio" OS_SEP "asprintf.c",
     357                 :            :     "stdio" OS_SEP "atoll.c",
     358                 :            :     "stdio" OS_SEP "fgetpos64.c",
     359                 :            :     "stdio" OS_SEP "fopen64.c",
     360                 :            :     "stdio" OS_SEP "fseeko32.c",
     361                 :            :     "stdio" OS_SEP "fseeko64.c",
     362                 :            :     "stdio" OS_SEP "fsetpos64.c",
     363                 :            :     "stdio" OS_SEP "ftello.c",
     364                 :            :     "stdio" OS_SEP "ftello64.c",
     365                 :            :     "stdio" OS_SEP "ftruncate64.c",
     366                 :            :     "stdio" OS_SEP "lltoa.c",
     367                 :            :     "stdio" OS_SEP "lltow.c",
     368                 :            :     "stdio" OS_SEP "lseek64.c",
     369                 :            :     "stdio" OS_SEP "mingw_asprintf.c",
     370                 :            :     "stdio" OS_SEP "mingw_fprintf.c",
     371                 :            :     "stdio" OS_SEP "mingw_fprintfw.c",
     372                 :            :     "stdio" OS_SEP "mingw_fscanf.c",
     373                 :            :     "stdio" OS_SEP "mingw_fwscanf.c",
     374                 :            :     "stdio" OS_SEP "mingw_pformat.c",
     375                 :            :     "stdio" OS_SEP "mingw_pformatw.c",
     376                 :            :     "stdio" OS_SEP "mingw_printf.c",
     377                 :            :     "stdio" OS_SEP "mingw_printfw.c",
     378                 :            :     "stdio" OS_SEP "mingw_scanf.c",
     379                 :            :     "stdio" OS_SEP "mingw_snprintf.c",
     380                 :            :     "stdio" OS_SEP "mingw_snprintfw.c",
     381                 :            :     "stdio" OS_SEP "mingw_sprintf.c",
     382                 :            :     "stdio" OS_SEP "mingw_sprintfw.c",
     383                 :            :     "stdio" OS_SEP "mingw_sscanf.c",
     384                 :            :     "stdio" OS_SEP "mingw_swscanf.c",
     385                 :            :     "stdio" OS_SEP "mingw_vasprintf.c",
     386                 :            :     "stdio" OS_SEP "mingw_vfprintf.c",
     387                 :            :     "stdio" OS_SEP "mingw_vfprintfw.c",
     388                 :            :     "stdio" OS_SEP "mingw_vfscanf.c",
     389                 :            :     "stdio" OS_SEP "mingw_vprintf.c",
     390                 :            :     "stdio" OS_SEP "mingw_vprintfw.c",
     391                 :            :     "stdio" OS_SEP "mingw_vsnprintf.c",
     392                 :            :     "stdio" OS_SEP "mingw_vsnprintfw.c",
     393                 :            :     "stdio" OS_SEP "mingw_vsprintf.c",
     394                 :            :     "stdio" OS_SEP "mingw_vsprintfw.c",
     395                 :            :     "stdio" OS_SEP "mingw_wscanf.c",
     396                 :            :     "stdio" OS_SEP "mingw_wvfscanf.c",
     397                 :            :     "stdio" OS_SEP "scanf.S",
     398                 :            :     "stdio" OS_SEP "snprintf.c",
     399                 :            :     "stdio" OS_SEP "snwprintf.c",
     400                 :            :     "stdio" OS_SEP "strtof.c",
     401                 :            :     "stdio" OS_SEP "strtok_r.c",
     402                 :            :     "stdio" OS_SEP "truncate.c",
     403                 :            :     "stdio" OS_SEP "ulltoa.c",
     404                 :            :     "stdio" OS_SEP "ulltow.c",
     405                 :            :     "stdio" OS_SEP "vasprintf.c",
     406                 :            :     "stdio" OS_SEP "vfscanf.c",
     407                 :            :     "stdio" OS_SEP "vfscanf2.S",
     408                 :            :     "stdio" OS_SEP "vfwscanf.c",
     409                 :            :     "stdio" OS_SEP "vfwscanf2.S",
     410                 :            :     "stdio" OS_SEP "vscanf.c",
     411                 :            :     "stdio" OS_SEP "vscanf2.S",
     412                 :            :     "stdio" OS_SEP "vsnprintf.c",
     413                 :            :     "stdio" OS_SEP "vsnwprintf.c",
     414                 :            :     "stdio" OS_SEP "vsscanf.c",
     415                 :            :     "stdio" OS_SEP "vsscanf2.S",
     416                 :            :     "stdio" OS_SEP "vswscanf.c",
     417                 :            :     "stdio" OS_SEP "vswscanf2.S",
     418                 :            :     "stdio" OS_SEP "vwscanf.c",
     419                 :            :     "stdio" OS_SEP "vwscanf2.S",
     420                 :            :     "stdio" OS_SEP "wtoll.c",
     421                 :            : };
     422                 :            : 
     423                 :            : static const char *mingwex_x86_src[] = {
     424                 :            :     "math" OS_SEP "x86" OS_SEP "acosf.c",
     425                 :            :     "math" OS_SEP "x86" OS_SEP "acosh.c",
     426                 :            :     "math" OS_SEP "x86" OS_SEP "acoshf.c",
     427                 :            :     "math" OS_SEP "x86" OS_SEP "acoshl.c",
     428                 :            :     "math" OS_SEP "x86" OS_SEP "acosl.c",
     429                 :            :     "math" OS_SEP "x86" OS_SEP "asinf.c",
     430                 :            :     "math" OS_SEP "x86" OS_SEP "asinh.c",
     431                 :            :     "math" OS_SEP "x86" OS_SEP "asinhf.c",
     432                 :            :     "math" OS_SEP "x86" OS_SEP "asinhl.c",
     433                 :            :     "math" OS_SEP "x86" OS_SEP "asinl.c",
     434                 :            :     "math" OS_SEP "x86" OS_SEP "atan2.c",
     435                 :            :     "math" OS_SEP "x86" OS_SEP "atan2f.c",
     436                 :            :     "math" OS_SEP "x86" OS_SEP "atan2l.c",
     437                 :            :     "math" OS_SEP "x86" OS_SEP "atanf.c",
     438                 :            :     "math" OS_SEP "x86" OS_SEP "atanh.c",
     439                 :            :     "math" OS_SEP "x86" OS_SEP "atanhf.c",
     440                 :            :     "math" OS_SEP "x86" OS_SEP "atanhl.c",
     441                 :            :     "math" OS_SEP "x86" OS_SEP "atanl.c",
     442                 :            :     "math" OS_SEP "x86" OS_SEP "ceilf.S",
     443                 :            :     "math" OS_SEP "x86" OS_SEP "ceill.S",
     444                 :            :     "math" OS_SEP "x86" OS_SEP "ceil.S",
     445                 :            :     "math" OS_SEP "x86" OS_SEP "_chgsignl.S",
     446                 :            :     "math" OS_SEP "x86" OS_SEP "copysignl.S",
     447                 :            :     "math" OS_SEP "x86" OS_SEP "cos.c",
     448                 :            :     "math" OS_SEP "x86" OS_SEP "cosf.c",
     449                 :            :     "math" OS_SEP "x86" OS_SEP "cosl.c",
     450                 :            :     "math" OS_SEP "x86" OS_SEP "cosl_internal.S",
     451                 :            :     "math" OS_SEP "x86" OS_SEP "cossin.c",
     452                 :            :     "math" OS_SEP "x86" OS_SEP "exp2f.S",
     453                 :            :     "math" OS_SEP "x86" OS_SEP "exp2l.S",
     454                 :            :     "math" OS_SEP "x86" OS_SEP "exp2.S",
     455                 :            :     "math" OS_SEP "x86" OS_SEP "exp.c",
     456                 :            :     "math" OS_SEP "x86" OS_SEP "expl.c",
     457                 :            :     "math" OS_SEP "x86" OS_SEP "expm1.c",
     458                 :            :     "math" OS_SEP "x86" OS_SEP "expm1f.c",
     459                 :            :     "math" OS_SEP "x86" OS_SEP "expm1l.c",
     460                 :            :     "math" OS_SEP "x86" OS_SEP "floorf.S",
     461                 :            :     "math" OS_SEP "x86" OS_SEP "floorl.S",
     462                 :            :     "math" OS_SEP "x86" OS_SEP "floor.S",
     463                 :            :     "math" OS_SEP "x86" OS_SEP "fmod.c",
     464                 :            :     "math" OS_SEP "x86" OS_SEP "fmodf.c",
     465                 :            :     "math" OS_SEP "x86" OS_SEP "fmodl.c",
     466                 :            :     "math" OS_SEP "x86" OS_SEP "frexpl.S",
     467                 :            :     "math" OS_SEP "x86" OS_SEP "fucom.c",
     468                 :            :     "math" OS_SEP "x86" OS_SEP "ilogbf.S",
     469                 :            :     "math" OS_SEP "x86" OS_SEP "ilogbl.S",
     470                 :            :     "math" OS_SEP "x86" OS_SEP "ilogb.S",
     471                 :            :     "math" OS_SEP "x86" OS_SEP "internal_logl.S",
     472                 :            :     "math" OS_SEP "x86" OS_SEP "ldexp.c",
     473                 :            :     "math" OS_SEP "x86" OS_SEP "ldexpl.c",
     474                 :            :     "math" OS_SEP "x86" OS_SEP "log10l.S",
     475                 :            :     "math" OS_SEP "x86" OS_SEP "log1pf.S",
     476                 :            :     "math" OS_SEP "x86" OS_SEP "log1pl.S",
     477                 :            :     "math" OS_SEP "x86" OS_SEP "log1p.S",
     478                 :            :     "math" OS_SEP "x86" OS_SEP "log2f.S",
     479                 :            :     "math" OS_SEP "x86" OS_SEP "log2l.S",
     480                 :            :     "math" OS_SEP "x86" OS_SEP "log2.S",
     481                 :            :     "math" OS_SEP "x86" OS_SEP "logb.c",
     482                 :            :     "math" OS_SEP "x86" OS_SEP "logbf.c",
     483                 :            :     "math" OS_SEP "x86" OS_SEP "logbl.c",
     484                 :            :     "math" OS_SEP "x86" OS_SEP "log.c",
     485                 :            :     "math" OS_SEP "x86" OS_SEP "logl.c",
     486                 :            :     "math" OS_SEP "x86" OS_SEP "nearbyintf.S",
     487                 :            :     "math" OS_SEP "x86" OS_SEP "nearbyintl.S",
     488                 :            :     "math" OS_SEP "x86" OS_SEP "nearbyint.S",
     489                 :            :     "math" OS_SEP "x86" OS_SEP "pow.c",
     490                 :            :     "math" OS_SEP "x86" OS_SEP "powl.c",
     491                 :            :     "math" OS_SEP "x86" OS_SEP "remainderf.S",
     492                 :            :     "math" OS_SEP "x86" OS_SEP "remainderl.S",
     493                 :            :     "math" OS_SEP "x86" OS_SEP "remainder.S",
     494                 :            :     "math" OS_SEP "x86" OS_SEP "remquof.S",
     495                 :            :     "math" OS_SEP "x86" OS_SEP "remquol.S",
     496                 :            :     "math" OS_SEP "x86" OS_SEP "remquo.S",
     497                 :            :     "math" OS_SEP "x86" OS_SEP "scalbnf.S",
     498                 :            :     "math" OS_SEP "x86" OS_SEP "scalbnl.S",
     499                 :            :     "math" OS_SEP "x86" OS_SEP "scalbn.S",
     500                 :            :     "math" OS_SEP "x86" OS_SEP "sin.c",
     501                 :            :     "math" OS_SEP "x86" OS_SEP "sinf.c",
     502                 :            :     "math" OS_SEP "x86" OS_SEP "sinl.c",
     503                 :            :     "math" OS_SEP "x86" OS_SEP "sinl_internal.S",
     504                 :            :     "math" OS_SEP "x86" OS_SEP "tanf.c",
     505                 :            :     "math" OS_SEP "x86" OS_SEP "tanl.S",
     506                 :            :     "math" OS_SEP "x86" OS_SEP "truncf.S",
     507                 :            :     "math" OS_SEP "x86" OS_SEP "trunc.S",
     508                 :            : };
     509                 :            : 
     510                 :            : static const char *mingwex_arm32_src[] = {
     511                 :            :     "math" OS_SEP "arm" OS_SEP "_chgsignl.S",
     512                 :            :     "math" OS_SEP "arm" OS_SEP "ceil.S",
     513                 :            :     "math" OS_SEP "arm" OS_SEP "ceilf.S",
     514                 :            :     "math" OS_SEP "arm" OS_SEP "ceill.S",
     515                 :            :     "math" OS_SEP "arm" OS_SEP "copysignl.c",
     516                 :            :     "math" OS_SEP "arm" OS_SEP "exp2.c",
     517                 :            :     "math" OS_SEP "arm" OS_SEP "floor.S",
     518                 :            :     "math" OS_SEP "arm" OS_SEP "floorf.S",
     519                 :            :     "math" OS_SEP "arm" OS_SEP "floorl.S",
     520                 :            :     "math" OS_SEP "arm" OS_SEP "ldexpl.c",
     521                 :            :     "math" OS_SEP "arm" OS_SEP "log2.c",
     522                 :            :     "math" OS_SEP "arm" OS_SEP "nearbyint.S",
     523                 :            :     "math" OS_SEP "arm" OS_SEP "nearbyintf.S",
     524                 :            :     "math" OS_SEP "arm" OS_SEP "nearbyintl.S",
     525                 :            :     "math" OS_SEP "arm" OS_SEP "scalbn.c",
     526                 :            :     "math" OS_SEP "arm" OS_SEP "sincos.c",
     527                 :            :     "math" OS_SEP "arm" OS_SEP "trunc.S",
     528                 :            :     "math" OS_SEP "arm" OS_SEP "truncf.S",
     529                 :            : };
     530                 :            : 
     531                 :            : static const char *mingwex_arm64_src[] = {
     532                 :            :     "math" OS_SEP "arm64" OS_SEP "ceilf.S",
     533                 :            :     "math" OS_SEP "arm64" OS_SEP "ceill.S",
     534                 :            :     "math" OS_SEP "arm64" OS_SEP "ceil.S",
     535                 :            :     "math" OS_SEP "arm64" OS_SEP "_chgsignl.S",
     536                 :            :     "math" OS_SEP "arm64" OS_SEP "copysignl.c",
     537                 :            :     "math" OS_SEP "arm64" OS_SEP "exp2f.S",
     538                 :            :     "math" OS_SEP "arm64" OS_SEP "exp2.S",
     539                 :            :     "math" OS_SEP "arm64" OS_SEP "floorf.S",
     540                 :            :     "math" OS_SEP "arm64" OS_SEP "floorl.S",
     541                 :            :     "math" OS_SEP "arm64" OS_SEP "floor.S",
     542                 :            :     "math" OS_SEP "arm64" OS_SEP "ldexpl.c",
     543                 :            :     "math" OS_SEP "arm64" OS_SEP "log2.c",
     544                 :            :     "math" OS_SEP "arm64" OS_SEP "nearbyintf.S",
     545                 :            :     "math" OS_SEP "arm64" OS_SEP "nearbyintl.S",
     546                 :            :     "math" OS_SEP "arm64" OS_SEP "nearbyint.S",
     547                 :            :     "math" OS_SEP "arm64" OS_SEP "scalbn.c",
     548                 :            :     "math" OS_SEP "arm64" OS_SEP "sincos.c",
     549                 :            :     "math" OS_SEP "arm64" OS_SEP "truncf.S",
     550                 :            :     "math" OS_SEP "arm64" OS_SEP "trunc.S",
     551                 :            : };
     552                 :            : 
     553                 :            : struct MinGWDef {
     554                 :            :     const char *name;
     555                 :            :     const char *path;
     556                 :            :     bool always_link;
     557                 :            : };
     558                 :            : static const MinGWDef mingw_def_list[] = {
     559                 :            :     {"msvcrt", "lib-common" OS_SEP "msvcrt.def.in", true},
     560                 :            :     {"setupapi", "libarm32" OS_SEP "setupapi.def", false},
     561                 :            :     {"setupapi", "libarm64" OS_SEP "setupapi.def", false},
     562                 :            :     {"setupapi", "lib32" OS_SEP "setupapi.def", false},
     563                 :            :     {"setupapi", "lib64" OS_SEP "setupapi.def", false},
     564                 :            :     {"winmm", "lib-common" OS_SEP "winmm.def", false},
     565                 :            :     {"gdi32", "lib-common" OS_SEP "gdi32.def", false},
     566                 :            :     {"imm32", "lib-common" OS_SEP "imm32.def", false},
     567                 :            :     {"version", "lib-common" OS_SEP "version.def", false},
     568                 :            :     {"advapi32", "lib-common" OS_SEP "advapi32.def.in", true},
     569                 :            :     {"oleaut32", "lib-common" OS_SEP "oleaut32.def.in", false},
     570                 :            :     {"ole32", "lib-common" OS_SEP "ole32.def.in", false},
     571                 :            :     {"shell32", "lib-common" OS_SEP "shell32.def", true},
     572                 :            :     {"user32", "lib-common" OS_SEP "user32.def.in", true},
     573                 :            :     {"kernel32", "lib-common" OS_SEP "kernel32.def.in", true},
     574                 :            :     {"ntdll", "libarm32" OS_SEP "ntdll.def", true},
     575                 :            :     {"ntdll", "lib32" OS_SEP "ntdll.def", true},
     576                 :            :     {"ntdll", "lib64" OS_SEP "ntdll.def", true},
     577                 :            : };
     578                 :            : 
     579                 :            : struct LinkJob {
     580                 :            :     CodeGen *codegen;
     581                 :            :     ZigList<const char *> args;
     582                 :            :     bool link_in_crt;
     583                 :            :     HashMap<Buf *, bool, buf_hash, buf_eql_buf> rpath_table;
     584                 :            : };
     585                 :            : 
     586                 :         38 : static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFile *c_file) {
     587                 :         38 :     CodeGen *child_gen = create_child_codegen(parent_gen, nullptr, OutTypeObj, nullptr);
     588                 :         38 :     codegen_set_out_name(child_gen, buf_create_from_str(name));
     589                 :         38 :     ZigList<CFile *> c_source_files = {0};
     590                 :         38 :     c_source_files.append(c_file);
     591                 :         38 :     child_gen->c_source_files = c_source_files;
     592                 :         38 :     codegen_build_and_link(child_gen);
     593                 :         38 :     return buf_ptr(&child_gen->output_file_path);
     594                 :            : }
     595                 :            : 
     596                 :        674 : static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) {
     597                 :        674 :     Buf *dir1 = buf_alloc();
     598                 :        674 :     os_path_join(g->zig_lib_dir, buf_create_from_str(dir), dir1);
     599                 :        674 :     Buf *result = buf_alloc();
     600                 :        674 :     os_path_join(dir1, buf_create_from_str(subpath), result);
     601                 :        674 :     return buf_ptr(result);
     602                 :            : }
     603                 :            : 
     604                 :        636 : static const char *path_from_libc(CodeGen *g, const char *subpath) {
     605                 :        636 :     return path_from_zig_lib(g, "libc", subpath);
     606                 :            : }
     607                 :            : 
     608                 :         32 : static const char *path_from_libunwind(CodeGen *g, const char *subpath) {
     609                 :         32 :     return path_from_zig_lib(g, "libunwind", subpath);
     610                 :            : }
     611                 :            : 
     612                 :          2 : static const char *build_libunwind(CodeGen *parent) {
     613                 :          2 :     CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
     614                 :          2 :     codegen_set_out_name(child_gen, buf_create_from_str("unwind"));
     615                 :          2 :     LinkLib *new_link_lib = codegen_add_link_lib(child_gen, buf_create_from_str("c"));
     616                 :          2 :     new_link_lib->provided_explicitly = false;
     617                 :            :     enum SrcKind {
     618                 :            :         SrcCpp,
     619                 :            :         SrcC,
     620                 :            :         SrcAsm,
     621                 :            :     };
     622                 :            :     static const struct {
     623                 :            :         const char *path;
     624                 :            :         SrcKind kind;
     625                 :            :     } unwind_src[] = {
     626                 :            :         {"src" OS_SEP "libunwind.cpp", SrcCpp},
     627                 :            :         {"src" OS_SEP "Unwind-EHABI.cpp", SrcCpp},
     628                 :            :         {"src" OS_SEP "Unwind-seh.cpp", SrcCpp},
     629                 :            : 
     630                 :            :         {"src" OS_SEP "UnwindLevel1.c", SrcC},
     631                 :            :         {"src" OS_SEP "UnwindLevel1-gcc-ext.c", SrcC},
     632                 :            :         {"src" OS_SEP "Unwind-sjlj.c", SrcC},
     633                 :            : 
     634                 :            :         {"src" OS_SEP "UnwindRegistersRestore.S", SrcAsm},
     635                 :            :         {"src" OS_SEP "UnwindRegistersSave.S", SrcAsm},
     636                 :            :     };
     637                 :          2 :     ZigList<CFile *> c_source_files = {0};
     638         [ +  + ]:         18 :     for (size_t i = 0; i < array_length(unwind_src); i += 1) {
     639                 :         16 :         CFile *c_file = allocate<CFile>(1);
     640                 :         16 :         c_file->source_path = path_from_libunwind(parent, unwind_src[i].path);
     641   [ +  +  +  - ]:         16 :         switch (unwind_src[i].kind) {
     642                 :          6 :             case SrcC:
     643                 :          6 :                 c_file->args.append("-std=c99");
     644                 :          6 :                 break;
     645                 :          6 :             case SrcCpp:
     646                 :          6 :                 c_file->args.append("-fno-rtti");
     647                 :          6 :                 c_file->args.append("-I");
     648                 :          6 :                 c_file->args.append(path_from_zig_lib(parent, "libcxx", "include"));
     649                 :          6 :                 break;
     650                 :          4 :             case SrcAsm:
     651                 :          4 :                 break;
     652                 :            :         }
     653                 :         16 :         c_file->args.append("-I");
     654                 :         16 :         c_file->args.append(path_from_libunwind(parent, "include"));
     655                 :         16 :         c_file->args.append("-fPIC");
     656                 :         16 :         c_file->args.append("-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS");
     657                 :         16 :         c_file->args.append("-Wa,--noexecstack");
     658         [ +  - ]:         16 :         if (parent->zig_target->is_native) {
     659                 :         16 :             c_file->args.append("-D_LIBUNWIND_IS_NATIVE_ONLY");
     660                 :            :         }
     661         [ +  - ]:         16 :         if (parent->build_mode == BuildModeDebug) {
     662                 :         16 :             c_file->args.append("-D_DEBUG");
     663                 :            :         }
     664         [ +  + ]:         16 :         if (parent->is_single_threaded) {
     665                 :          8 :             c_file->args.append("-D_LIBUNWIND_HAS_NO_THREADS");
     666                 :            :         }
     667                 :         16 :         c_source_files.append(c_file);
     668                 :            :     }
     669                 :          2 :     child_gen->c_source_files = c_source_files;
     670                 :          2 :     codegen_build_and_link(child_gen);
     671                 :          2 :     return buf_ptr(&child_gen->output_file_path);
     672                 :            : }
     673                 :            : 
     674                 :          0 : static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) {
     675                 :          0 :     c_file->args.append("-DHAVE_CONFIG_H");
     676                 :            : 
     677                 :          0 :     c_file->args.append("-I");
     678                 :          0 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "include",
     679                 :            :                     buf_ptr(parent->zig_lib_dir))));
     680                 :            : 
     681                 :          0 :     c_file->args.append("-isystem");
     682                 :          0 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "any-windows-any",
     683                 :            :                     buf_ptr(parent->zig_lib_dir))));
     684                 :            : 
     685         [ #  # ]:          0 :     if (target_is_arm(parent->zig_target) &&
           [ #  #  #  # ]
     686                 :          0 :         target_arch_pointer_bit_width(parent->zig_target->arch) == 32)
     687                 :            :     {
     688                 :          0 :         c_file->args.append("-mfpu=vfp");
     689                 :            :     }
     690                 :            : 
     691                 :          0 :     c_file->args.append("-std=gnu11");
     692                 :          0 :     c_file->args.append("-D_CRTBLD");
     693                 :          0 :     c_file->args.append("-D_WIN32_WINNT=0x0f00");
     694                 :          0 :     c_file->args.append("-D__MSVCRT_VERSION__=0x700");
     695                 :          0 : }
     696                 :            : 
     697                 :        152 : static void glibc_add_include_dirs_arch(CFile *c_file, ZigLLVM_ArchType arch, const char *nptl, const char *dir) {
     698 [ +  - ][ +  - ]:        152 :     bool is_x86 = arch == ZigLLVM_x86 || arch == ZigLLVM_x86_64;
     699 [ +  - ][ -  + ]:        152 :     bool is_aarch64 = arch == ZigLLVM_aarch64 || arch == ZigLLVM_aarch64_be;
     700 [ +  - ][ +  - ]:        152 :     bool is_mips = arch == ZigLLVM_mips || arch == ZigLLVM_mipsel ||
     701 [ +  - ][ -  + ]:        304 :         arch == ZigLLVM_mips64el || arch == ZigLLVM_mips64;
     702 [ +  - ][ -  + ]:        152 :     bool is_arm = arch == ZigLLVM_arm || arch == ZigLLVM_armeb;
     703 [ +  - ][ +  - ]:        152 :     bool is_ppc = arch == ZigLLVM_ppc || arch == ZigLLVM_ppc64 || arch == ZigLLVM_ppc64le;
                 [ -  + ]
     704 [ +  - ][ -  + ]:        152 :     bool is_riscv = arch == ZigLLVM_riscv32 || arch == ZigLLVM_riscv64;
     705 [ +  - ][ +  - ]:        152 :     bool is_sparc = arch == ZigLLVM_sparc || arch == ZigLLVM_sparcel || arch == ZigLLVM_sparcv9;
                 [ -  + ]
     706                 :        152 :     bool is_64 = target_arch_pointer_bit_width(arch) == 64;
     707                 :            : 
     708         [ +  - ]:        152 :     if (is_x86) {
     709         [ +  - ]:        152 :         if (arch == ZigLLVM_x86_64) {
     710         [ +  + ]:        152 :             if (nptl != nullptr) {
     711                 :         38 :                 c_file->args.append("-I");
     712                 :         38 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86_64" OS_SEP "%s", dir, nptl)));
     713                 :            :             } else {
     714                 :        114 :                 c_file->args.append("-I");
     715                 :        152 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86_64", dir)));
     716                 :            :             }
     717         [ #  # ]:          0 :         } else if (arch == ZigLLVM_x86) {
     718         [ #  # ]:          0 :             if (nptl != nullptr) {
     719                 :          0 :                 c_file->args.append("-I");
     720                 :          0 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "i386" OS_SEP "%s", dir, nptl)));
     721                 :            :             } else {
     722                 :          0 :                 c_file->args.append("-I");
     723                 :          0 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "i386", dir)));
     724                 :            :             }
     725                 :            :         }
     726         [ +  + ]:        152 :         if (nptl != nullptr) {
     727                 :         38 :             c_file->args.append("-I");
     728                 :         38 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86" OS_SEP "%s", dir, nptl)));
     729                 :            :         } else {
     730                 :        114 :             c_file->args.append("-I");
     731                 :        152 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86", dir)));
     732                 :            :         }
     733         [ #  # ]:          0 :     } else if (is_arm) {
     734         [ #  # ]:          0 :         if (nptl != nullptr) {
     735                 :          0 :             c_file->args.append("-I");
     736                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "arm" OS_SEP "%s", dir, nptl)));
     737                 :            :         } else {
     738                 :          0 :             c_file->args.append("-I");
     739                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "arm", dir)));
     740                 :            :         }
     741         [ #  # ]:          0 :     } else if (is_mips) {
     742         [ #  # ]:          0 :         if (nptl != nullptr) {
     743                 :          0 :             c_file->args.append("-I");
     744                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips" OS_SEP "%s", dir, nptl)));
     745                 :            :         } else {
     746         [ #  # ]:          0 :             if (is_64) {
     747                 :          0 :                 c_file->args.append("-I");
     748                 :          0 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips" OS_SEP "mips64", dir)));
     749                 :            :             } else {
     750                 :          0 :                 c_file->args.append("-I");
     751                 :          0 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips" OS_SEP "mips32", dir)));
     752                 :            :             }
     753                 :          0 :             c_file->args.append("-I");
     754                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips", dir)));
     755                 :            :         }
     756         [ #  # ]:          0 :     } else if (is_sparc) {
     757         [ #  # ]:          0 :         if (nptl != nullptr) {
     758                 :          0 :             c_file->args.append("-I");
     759                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc" OS_SEP "%s", dir, nptl)));
     760                 :            :         } else {
     761         [ #  # ]:          0 :             if (is_64) {
     762                 :          0 :                 c_file->args.append("-I");
     763                 :          0 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc" OS_SEP "sparc64", dir)));
     764                 :            :             } else {
     765                 :          0 :                 c_file->args.append("-I");
     766                 :          0 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc" OS_SEP "sparc32", dir)));
     767                 :            :             }
     768                 :          0 :             c_file->args.append("-I");
     769                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc", dir)));
     770                 :            :         }
     771         [ #  # ]:          0 :     } else if (is_aarch64) {
     772         [ #  # ]:          0 :         if (nptl != nullptr) {
     773                 :          0 :             c_file->args.append("-I");
     774                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "aarch64" OS_SEP "%s", dir, nptl)));
     775                 :            :         } else {
     776                 :          0 :             c_file->args.append("-I");
     777                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "aarch64", dir)));
     778                 :            :         }
     779         [ #  # ]:          0 :     } else if (is_ppc) {
     780         [ #  # ]:          0 :         if (nptl != nullptr) {
     781                 :          0 :             c_file->args.append("-I");
     782                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc" OS_SEP "%s", dir, nptl)));
     783                 :            :         } else {
     784         [ #  # ]:          0 :             if (is_64) {
     785                 :          0 :                 c_file->args.append("-I");
     786                 :          0 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc" OS_SEP "powerpc64", dir)));
     787                 :            :             } else {
     788                 :          0 :                 c_file->args.append("-I");
     789                 :          0 :                 c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc" OS_SEP "powerpc32", dir)));
     790                 :            :             }
     791                 :          0 :             c_file->args.append("-I");
     792                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc", dir)));
     793                 :            :         }
     794         [ #  # ]:          0 :     } else if (is_riscv) {
     795         [ #  # ]:          0 :         if (nptl != nullptr) {
     796                 :          0 :             c_file->args.append("-I");
     797                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "riscv" OS_SEP "%s", dir, nptl)));
     798                 :            :         } else {
     799                 :          0 :             c_file->args.append("-I");
     800                 :          0 :             c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "riscv", dir)));
     801                 :            :         }
     802                 :            :     }
     803                 :        152 : }
     804                 :            : 
     805                 :         38 : static void glibc_add_include_dirs(CodeGen *parent, CFile *c_file) {
     806                 :         38 :     ZigLLVM_ArchType arch = parent->zig_target->arch;
     807         [ +  - ]:         38 :     const char *nptl = (parent->zig_target->os == OsLinux) ? "nptl" : "htl";
     808                 :         38 :     const char *glibc = path_from_libc(parent, "glibc");
     809                 :            : 
     810                 :         38 :     c_file->args.append("-I");
     811                 :         38 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "include", glibc)));
     812                 :            : 
     813         [ +  - ]:         38 :     if (parent->zig_target->os == OsLinux) {
     814                 :         38 :         glibc_add_include_dirs_arch(c_file, arch, nullptr,
     815                 :            :             path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix" OS_SEP "sysv" OS_SEP "linux"));
     816                 :            :     }
     817                 :            : 
     818         [ +  - ]:         38 :     if (nptl != nullptr) {
     819                 :         38 :         glibc_add_include_dirs_arch(c_file, arch, nptl, path_from_libc(parent, "glibc" OS_SEP "sysdeps"));
     820                 :            :     }
     821                 :            : 
     822         [ +  - ]:         38 :     if (parent->zig_target->os == OsLinux) {
     823                 :         38 :         c_file->args.append("-I");
     824                 :         38 :         c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP
     825                 :            :                     "unix" OS_SEP "sysv" OS_SEP "linux" OS_SEP "include"));
     826                 :         38 :         c_file->args.append("-I");
     827                 :         38 :         c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP
     828                 :            :                     "unix" OS_SEP "sysv" OS_SEP "linux"));
     829                 :            :     }
     830         [ +  - ]:         38 :     if (nptl != nullptr) {
     831                 :         38 :         c_file->args.append("-I");
     832                 :         38 :         c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sysdeps" OS_SEP "%s", glibc, nptl)));
     833                 :            :     }
     834                 :            : 
     835                 :         38 :     c_file->args.append("-I");
     836                 :         38 :     c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "pthread"));
     837                 :            : 
     838                 :         38 :     c_file->args.append("-I");
     839                 :         38 :     c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix" OS_SEP "sysv"));
     840                 :            : 
     841                 :         38 :     glibc_add_include_dirs_arch(c_file, arch, nullptr,
     842                 :            :             path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix"));
     843                 :            : 
     844                 :         38 :     c_file->args.append("-I");
     845                 :         38 :     c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix"));
     846                 :            : 
     847                 :         38 :     glibc_add_include_dirs_arch(c_file, arch, nullptr, path_from_libc(parent, "glibc" OS_SEP "sysdeps"));
     848                 :            : 
     849                 :         38 :     c_file->args.append("-I");
     850                 :         38 :     c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "generic"));
     851                 :            : 
     852                 :         38 :     c_file->args.append("-I");
     853                 :         38 :     c_file->args.append(path_from_libc(parent, "glibc"));
     854                 :            : 
     855                 :         38 :     c_file->args.append("-I");
     856                 :         38 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-%s",
     857                 :         38 :                     buf_ptr(parent->zig_lib_dir), target_arch_name(parent->zig_target->arch),
     858                 :         76 :                     target_os_name(parent->zig_target->os), target_abi_name(parent->zig_target->abi))));
     859                 :            : 
     860                 :         38 :     c_file->args.append("-I");
     861                 :         38 :     c_file->args.append(path_from_libc(parent, "include" OS_SEP "generic-glibc"));
     862                 :            : 
     863                 :         38 :     c_file->args.append("-I");
     864                 :         38 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-linux-any",
     865                 :         38 :                     buf_ptr(parent->zig_lib_dir), target_arch_name(parent->zig_target->arch))));
     866                 :            : 
     867                 :         38 :     c_file->args.append("-I");
     868                 :         38 :     c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-linux-any"));
     869                 :         38 : }
     870                 :            : 
     871                 :          6 : static const char *glibc_start_asm_path(CodeGen *parent, const char *file) {
     872                 :          6 :     ZigLLVM_ArchType arch = parent->zig_target->arch;
     873 [ +  - ][ -  + ]:          6 :     bool is_aarch64 = arch == ZigLLVM_aarch64 || arch == ZigLLVM_aarch64_be;
     874 [ +  - ][ +  - ]:          6 :     bool is_mips = arch == ZigLLVM_mips || arch == ZigLLVM_mipsel ||
     875 [ +  - ][ -  + ]:         12 :         arch == ZigLLVM_mips64el || arch == ZigLLVM_mips64;
     876 [ +  - ][ -  + ]:          6 :     bool is_arm = arch == ZigLLVM_arm || arch == ZigLLVM_armeb;
     877 [ +  - ][ +  - ]:          6 :     bool is_ppc = arch == ZigLLVM_ppc || arch == ZigLLVM_ppc64 || arch == ZigLLVM_ppc64le;
                 [ -  + ]
     878 [ +  - ][ -  + ]:          6 :     bool is_riscv = arch == ZigLLVM_riscv32 || arch == ZigLLVM_riscv64;
     879 [ +  - ][ +  - ]:          6 :     bool is_sparc = arch == ZigLLVM_sparc || arch == ZigLLVM_sparcel || arch == ZigLLVM_sparcv9;
                 [ -  + ]
     880                 :          6 :     bool is_64 = target_arch_pointer_bit_width(arch) == 64;
     881                 :            : 
     882                 :          6 :     Buf result = BUF_INIT;
     883                 :          6 :     buf_resize(&result, 0);
     884                 :          6 :     buf_append_buf(&result, parent->zig_lib_dir);
     885                 :          6 :     buf_append_str(&result, OS_SEP "libc" OS_SEP "glibc" OS_SEP "sysdeps" OS_SEP);
     886         [ -  + ]:          6 :     if (is_sparc) {
     887         [ #  # ]:          0 :         if (is_64) {
     888                 :          0 :             buf_append_str(&result, "sparc" OS_SEP "sparc64");
     889                 :            :         } else {
     890                 :          0 :             buf_append_str(&result, "sparc" OS_SEP "sparc32");
     891                 :            :         }
     892         [ -  + ]:          6 :     } else if (is_arm) {
     893                 :          0 :         buf_append_str(&result, "arm");
     894         [ -  + ]:          6 :     } else if (is_mips) {
     895                 :          0 :         buf_append_str(&result, "mips");
     896         [ +  - ]:          6 :     } else if (arch == ZigLLVM_x86_64) {
     897                 :          6 :         buf_append_str(&result, "x86_64");
     898         [ #  # ]:          0 :     } else if (arch == ZigLLVM_x86) {
     899                 :          0 :         buf_append_str(&result, "i386");
     900         [ #  # ]:          0 :     } else if (is_aarch64) {
     901                 :          0 :         buf_append_str(&result, "aarch64");
     902         [ #  # ]:          0 :     } else if (is_riscv) {
     903                 :          0 :         buf_append_str(&result, "riscv");
     904         [ #  # ]:          0 :     } else if (is_ppc) {
     905         [ #  # ]:          0 :         if (is_64) {
     906                 :          0 :             buf_append_str(&result, "powerpc" OS_SEP "powerpc64");
     907                 :            :         } else {
     908                 :          0 :             buf_append_str(&result, "powerpc" OS_SEP "powerpc32");
     909                 :            :         }
     910                 :            :     }
     911                 :            : 
     912                 :          6 :     buf_append_str(&result, OS_SEP);
     913                 :          6 :     buf_append_str(&result, file);
     914                 :          6 :     return buf_ptr(&result);
     915                 :            : }
     916                 :            : 
     917                 :          0 : static const char *musl_start_asm_path(CodeGen *parent, const char *file) {
     918                 :          0 :     Buf *result = buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "crt" OS_SEP "%s" OS_SEP "%s",
     919                 :          0 :                    buf_ptr(parent->zig_lib_dir), target_arch_musl_name(parent->zig_target->arch), file);
     920                 :          0 :     return buf_ptr(result);
     921                 :            : }
     922                 :            : 
     923                 :          0 : static void musl_add_cc_args(CodeGen *parent, CFile *c_file, bool want_O3) {
     924                 :          0 :     c_file->args.append("-std=c99");
     925                 :          0 :     c_file->args.append("-ffreestanding");
     926                 :            :     // Musl adds these args to builds with gcc but clang does not support them. 
     927                 :            :     //c_file->args.append("-fexcess-precision=standard");
     928                 :            :     //c_file->args.append("-frounding-math");
     929                 :          0 :     c_file->args.append("-Wa,--noexecstack");
     930                 :          0 :     c_file->args.append("-D_XOPEN_SOURCE=700");
     931                 :            : 
     932                 :          0 :     c_file->args.append("-I");
     933                 :          0 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "arch" OS_SEP "%s",
     934                 :          0 :             buf_ptr(parent->zig_lib_dir), target_arch_musl_name(parent->zig_target->arch))));
     935                 :            : 
     936                 :          0 :     c_file->args.append("-I");
     937                 :          0 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "arch" OS_SEP "generic",
     938                 :            :             buf_ptr(parent->zig_lib_dir))));
     939                 :            : 
     940                 :          0 :     c_file->args.append("-I");
     941                 :          0 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "src" OS_SEP "include",
     942                 :            :             buf_ptr(parent->zig_lib_dir)))); 
     943                 :            : 
     944                 :          0 :     c_file->args.append("-I");
     945                 :          0 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "src" OS_SEP "internal",
     946                 :            :             buf_ptr(parent->zig_lib_dir))));
     947                 :            : 
     948                 :          0 :     c_file->args.append("-I");
     949                 :          0 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "include",
     950                 :            :             buf_ptr(parent->zig_lib_dir))));
     951                 :            : 
     952                 :          0 :     c_file->args.append("-I");
     953                 :          0 :     c_file->args.append(buf_ptr(buf_sprintf(
     954                 :            :             "%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-%s",
     955                 :            :         buf_ptr(parent->zig_lib_dir),
     956                 :          0 :         target_arch_name(parent->zig_target->arch),
     957                 :          0 :         target_os_name(parent->zig_target->os),
     958                 :          0 :         target_abi_name(parent->zig_target->abi))));
     959                 :            : 
     960                 :          0 :     c_file->args.append("-I");
     961                 :          0 :     c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "generic-musl",
     962                 :            :             buf_ptr(parent->zig_lib_dir))));
     963                 :            : 
     964         [ #  # ]:          0 :     if (want_O3)
     965                 :          0 :         c_file->args.append("-O3");
     966                 :            :     else
     967                 :          0 :         c_file->args.append("-Os");
     968                 :            : 
     969                 :          0 :     c_file->args.append("-fomit-frame-pointer");
     970                 :          0 :     c_file->args.append("-fno-unwind-tables");
     971                 :          0 :     c_file->args.append("-fno-asynchronous-unwind-tables");
     972                 :          0 :     c_file->args.append("-ffunction-sections");
     973                 :          0 :     c_file->args.append("-fdata-sections");
     974                 :          0 : }
     975                 :            : 
     976                 :            : static const char *musl_arch_names[] = {
     977                 :            :     "aarch64",
     978                 :            :     "arm",
     979                 :            :     "generic",
     980                 :            :     "i386",
     981                 :            :     "m68k",
     982                 :            :     "microblaze",
     983                 :            :     "mips",
     984                 :            :     "mips64",
     985                 :            :     "mipsn32",
     986                 :            :     "or1k",
     987                 :            :     "powerpc",
     988                 :            :     "powerpc64",
     989                 :            :     "riscv64",
     990                 :            :     "s390x",
     991                 :            :     "sh",
     992                 :            :     "x32",
     993                 :            :     "x86_64",
     994                 :            : };
     995                 :            : 
     996                 :          0 : static bool is_musl_arch_name(const char *name) {
     997         [ #  # ]:          0 :     for (size_t i = 0; i < array_length(musl_arch_names); i += 1) {
     998         [ #  # ]:          0 :         if (strcmp(name, musl_arch_names[i]) == 0)
     999                 :          0 :             return true;
    1000                 :            :     }
    1001                 :          0 :     return false;
    1002                 :            : }
    1003                 :            : 
    1004                 :          0 : static const char *build_musl(CodeGen *parent) {
    1005                 :          0 :     CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
    1006                 :          0 :     codegen_set_out_name(child_gen, buf_create_from_str("c"));
    1007                 :            : 
    1008                 :            :     // When there is a src/<arch>/foo.* then it should substitute for src/foo.*
    1009                 :            :     // Even a .s file can substitute for a .c file.
    1010                 :            : 
    1011                 :            :     enum MuslSrc {
    1012                 :            :         MuslSrcAsm,
    1013                 :            :         MuslSrcNormal,
    1014                 :            :         MuslSrcO3,
    1015                 :            :     };
    1016                 :            : 
    1017                 :          0 :     const char *target_musl_arch_name = target_arch_musl_name(parent->zig_target->arch);
    1018                 :            : 
    1019                 :          0 :     HashMap<Buf *, MuslSrc, buf_hash, buf_eql_buf> source_table = {};
    1020                 :          0 :     source_table.init(1800);
    1021                 :            : 
    1022         [ #  # ]:          0 :     for (size_t i = 0; i < array_length(ZIG_MUSL_SRC_FILES); i += 1) {
    1023                 :          0 :         Buf *src_file = buf_create_from_str(ZIG_MUSL_SRC_FILES[i]);
    1024                 :            : 
    1025                 :            :         MuslSrc src_kind;
    1026         [ #  # ]:          0 :         if (buf_ends_with_str(src_file, ".c")) {
    1027                 :          0 :             assert(buf_starts_with_str(src_file, "musl/src/"));
    1028         [ #  # ]:          0 :             bool want_O3 = buf_starts_with_str(src_file, "musl/src/malloc/") ||
    1029 [ #  # ][ #  # ]:          0 :                 buf_starts_with_str(src_file, "musl/src/string/") ||
    1030                 :          0 :                 buf_starts_with_str(src_file, "musl/src/internal/");
    1031         [ #  # ]:          0 :             src_kind = want_O3 ? MuslSrcO3 : MuslSrcNormal;
    1032 [ #  # ][ #  # ]:          0 :         } else if (buf_ends_with_str(src_file, ".s") || buf_ends_with_str(src_file, ".S")) {
                 [ #  # ]
    1033                 :          0 :             src_kind = MuslSrcAsm;
    1034                 :            :         } else {
    1035                 :          0 :             continue;
    1036                 :            :         }
    1037                 :            :         if (ZIG_OS_SEP_CHAR != '/') {
    1038                 :            :             buf_replace(src_file, '/', ZIG_OS_SEP_CHAR);
    1039                 :            :         }
    1040                 :          0 :         source_table.put_unique(src_file, src_kind);
    1041                 :            :     }
    1042                 :            : 
    1043                 :          0 :     ZigList<CFile *> c_source_files = {0};
    1044                 :            : 
    1045                 :          0 :     Buf dirname = BUF_INIT;
    1046                 :          0 :     Buf basename = BUF_INIT;
    1047                 :          0 :     Buf noextbasename = BUF_INIT;
    1048                 :          0 :     Buf dirbasename = BUF_INIT;
    1049                 :          0 :     Buf before_arch_dir = BUF_INIT;
    1050                 :            : 
    1051                 :          0 :     auto source_it = source_table.entry_iterator();
    1052                 :            :     for (;;) {
    1053                 :          0 :         auto *entry = source_it.next();
    1054         [ #  # ]:          0 :         if (!entry) break;
    1055                 :            : 
    1056                 :          0 :         Buf *src_file = entry->key;
    1057                 :          0 :         MuslSrc src_kind = entry->value;
    1058                 :            : 
    1059                 :          0 :         os_path_split(src_file, &dirname, &basename);
    1060                 :          0 :         os_path_extname(&basename, &noextbasename, nullptr);
    1061                 :          0 :         os_path_split(&dirname, &before_arch_dir, &dirbasename);
    1062                 :            : 
    1063                 :          0 :         bool is_arch_specific = false;
    1064                 :            :         // Architecture-specific implementations are under a <arch>/ folder.
    1065         [ #  # ]:          0 :         if (is_musl_arch_name(buf_ptr(&dirbasename))) {
    1066                 :            :             // Not the architecture we're compiling for.
    1067         [ #  # ]:          0 :             if (strcmp(buf_ptr(&dirbasename), target_musl_arch_name) != 0)
    1068                 :          0 :                 continue;
    1069                 :          0 :             is_arch_specific = true;
    1070                 :            :         }
    1071                 :            : 
    1072         [ #  # ]:          0 :         if (!is_arch_specific) {
    1073                 :          0 :             Buf override_path = BUF_INIT;
    1074                 :            : 
    1075                 :            :             // Look for an arch specific override.
    1076                 :          0 :             buf_resize(&override_path, 0);
    1077                 :          0 :             buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.s",
    1078                 :            :                         buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
    1079         [ #  # ]:          0 :             if (source_table.maybe_get(&override_path) != nullptr)
    1080                 :          0 :                 continue;
    1081                 :            : 
    1082                 :          0 :             buf_resize(&override_path, 0);
    1083                 :          0 :             buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.S",
    1084                 :            :                         buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
    1085         [ #  # ]:          0 :             if (source_table.maybe_get(&override_path) != nullptr)
    1086                 :          0 :                 continue;
    1087                 :            : 
    1088                 :          0 :             buf_resize(&override_path, 0);
    1089                 :          0 :             buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.c",
    1090                 :            :                         buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
    1091         [ #  # ]:          0 :             if (source_table.maybe_get(&override_path) != nullptr)
    1092                 :          0 :                 continue;
    1093                 :            :         }
    1094                 :            : 
    1095                 :          0 :         Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s",
    1096                 :          0 :                 buf_ptr(parent->zig_lib_dir), buf_ptr(src_file));
    1097                 :            : 
    1098                 :          0 :         CFile *c_file = allocate<CFile>(1);
    1099                 :          0 :         c_file->source_path = buf_ptr(full_path);
    1100                 :            : 
    1101                 :          0 :         musl_add_cc_args(parent, c_file, src_kind == MuslSrcO3);
    1102                 :          0 :         c_file->args.append("-Qunused-arguments");
    1103                 :          0 :         c_file->args.append("-w"); // disable all warnings
    1104                 :            : 
    1105                 :          0 :         c_source_files.append(c_file);
    1106                 :          0 :     }
    1107                 :            : 
    1108                 :          0 :     child_gen->c_source_files = c_source_files;
    1109                 :          0 :     codegen_build_and_link(child_gen);
    1110                 :          0 :     return buf_ptr(&child_gen->output_file_path);
    1111                 :            : }
    1112                 :            : 
    1113                 :          0 : static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
    1114                 :          0 :     CFile *c_file = allocate<CFile>(1);
    1115                 :          0 :     c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s",
    1116                 :            :             buf_ptr(parent->zig_lib_dir), src_path));
    1117                 :          0 :     c_file->args.append("-DHAVE_CONFIG_H");
    1118                 :          0 :     c_file->args.append("-D__LIBMSVCRT__");
    1119                 :            : 
    1120                 :          0 :     c_file->args.append("-I");
    1121                 :          0 :     c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include"));
    1122                 :            : 
    1123                 :          0 :     c_file->args.append("-std=gnu99");
    1124                 :          0 :     c_file->args.append("-D_CRTBLD");
    1125                 :          0 :     c_file->args.append("-D_WIN32_WINNT=0x0f00");
    1126                 :          0 :     c_file->args.append("-D__MSVCRT_VERSION__=0x700");
    1127                 :            : 
    1128                 :          0 :     c_file->args.append("-isystem");
    1129                 :          0 :     c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any"));
    1130                 :            : 
    1131                 :          0 :     c_file->args.append("-g");
    1132                 :          0 :     c_file->args.append("-O2");
    1133                 :            : 
    1134                 :          0 :     child_gen->c_source_files.append(c_file);
    1135                 :          0 : }
    1136                 :            : 
    1137                 :          0 : static void add_mingwex_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
    1138                 :          0 :     CFile *c_file = allocate<CFile>(1);
    1139                 :          0 :     c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s",
    1140                 :            :             buf_ptr(parent->zig_lib_dir), src_path));
    1141                 :          0 :     c_file->args.append("-DHAVE_CONFIG_H");
    1142                 :            : 
    1143                 :          0 :     c_file->args.append("-I");
    1144                 :          0 :     c_file->args.append(path_from_libc(parent, "mingw"));
    1145                 :            : 
    1146                 :          0 :     c_file->args.append("-I");
    1147                 :          0 :     c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include"));
    1148                 :            : 
    1149                 :          0 :     c_file->args.append("-std=gnu99");
    1150                 :          0 :     c_file->args.append("-D_CRTBLD");
    1151                 :          0 :     c_file->args.append("-D_WIN32_WINNT=0x0f00");
    1152                 :          0 :     c_file->args.append("-D__MSVCRT_VERSION__=0x700");
    1153                 :          0 :     c_file->args.append("-g");
    1154                 :          0 :     c_file->args.append("-O2");
    1155                 :            : 
    1156                 :          0 :     c_file->args.append("-isystem");
    1157                 :          0 :     c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any"));
    1158                 :            : 
    1159                 :          0 :     child_gen->c_source_files.append(c_file);
    1160                 :          0 : }
    1161                 :            : 
    1162                 :         12 : static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
    1163 [ +  - ][ -  + ]:         12 :     if (parent->libc == nullptr && parent->zig_target->os == OsWindows) {
    1164         [ #  # ]:          0 :         if (strcmp(file, "crt2.o") == 0) {
    1165                 :          0 :             CFile *c_file = allocate<CFile>(1);
    1166                 :          0 :             c_file->source_path = buf_ptr(buf_sprintf(
    1167                 :            :                 "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "crt" OS_SEP "crtexe.c", buf_ptr(parent->zig_lib_dir)));
    1168                 :          0 :             mingw_add_cc_args(parent, c_file);
    1169                 :          0 :             c_file->args.append("-U__CRTDLL__");
    1170                 :          0 :             c_file->args.append("-D__MSVCRT__");
    1171                 :            :             // Uncomment these 3 things for crtu
    1172                 :            :             //c_file->args.append("-DUNICODE");
    1173                 :            :             //c_file->args.append("-D_UNICODE");
    1174                 :            :             //c_file->args.append("-DWPRFLAG=1");
    1175                 :          0 :             return build_libc_object(parent, "crt2", c_file);
    1176         [ #  # ]:          0 :         } else if (strcmp(file, "dllcrt2.o") == 0) {
    1177                 :          0 :             CFile *c_file = allocate<CFile>(1);
    1178                 :          0 :             c_file->source_path = buf_ptr(buf_sprintf(
    1179                 :            :                 "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "crt" OS_SEP "crtdll.c", buf_ptr(parent->zig_lib_dir)));
    1180                 :          0 :             mingw_add_cc_args(parent, c_file);
    1181                 :          0 :             c_file->args.append("-U__CRTDLL__");
    1182                 :          0 :             c_file->args.append("-D__MSVCRT__");
    1183                 :          0 :             return build_libc_object(parent, "dllcrt2", c_file);
    1184         [ #  # ]:          0 :         } else if (strcmp(file, "mingw32.lib") == 0) {
    1185                 :          0 :             CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
    1186                 :          0 :             codegen_set_out_name(child_gen, buf_create_from_str("mingw32"));
    1187                 :            : 
    1188                 :            :             static const char *deps[] = {
    1189                 :            :                 "mingw" OS_SEP "crt" OS_SEP "crt0_c.c",
    1190                 :            :                 "mingw" OS_SEP "crt" OS_SEP "dll_argv.c",
    1191                 :            :                 "mingw" OS_SEP "crt" OS_SEP "gccmain.c",
    1192                 :            :                 "mingw" OS_SEP "crt" OS_SEP "natstart.c",
    1193                 :            :                 "mingw" OS_SEP "crt" OS_SEP "pseudo-reloc-list.c",
    1194                 :            :                 "mingw" OS_SEP "crt" OS_SEP "wildcard.c",
    1195                 :            :                 "mingw" OS_SEP "crt" OS_SEP "charmax.c",
    1196                 :            :                 "mingw" OS_SEP "crt" OS_SEP "crt0_w.c",
    1197                 :            :                 "mingw" OS_SEP "crt" OS_SEP "dllargv.c",
    1198                 :            :                 "mingw" OS_SEP "crt" OS_SEP "gs_support.c",
    1199                 :            :                 "mingw" OS_SEP "crt" OS_SEP "_newmode.c",
    1200                 :            :                 "mingw" OS_SEP "crt" OS_SEP "tlssup.c",
    1201                 :            :                 "mingw" OS_SEP "crt" OS_SEP "xncommod.c",
    1202                 :            :                 "mingw" OS_SEP "crt" OS_SEP "cinitexe.c",
    1203                 :            :                 "mingw" OS_SEP "crt" OS_SEP "merr.c",
    1204                 :            :                 "mingw" OS_SEP "crt" OS_SEP "pesect.c",
    1205                 :            :                 "mingw" OS_SEP "crt" OS_SEP "udllargc.c",
    1206                 :            :                 "mingw" OS_SEP "crt" OS_SEP "xthdloc.c",
    1207                 :            :                 "mingw" OS_SEP "crt" OS_SEP "CRT_fp10.c",
    1208                 :            :                 "mingw" OS_SEP "crt" OS_SEP "mingw_helpers.c",
    1209                 :            :                 "mingw" OS_SEP "crt" OS_SEP "pseudo-reloc.c",
    1210                 :            :                 "mingw" OS_SEP "crt" OS_SEP "udll_argv.c",
    1211                 :            :                 "mingw" OS_SEP "crt" OS_SEP "xtxtmode.c",
    1212                 :            :                 "mingw" OS_SEP "crt" OS_SEP "crt_handler.c",
    1213                 :            :                 "mingw" OS_SEP "crt" OS_SEP "tlsthrd.c",
    1214                 :            :                 "mingw" OS_SEP "crt" OS_SEP "tlsmthread.c",
    1215                 :            :                 "mingw" OS_SEP "crt" OS_SEP "tlsmcrt.c",
    1216                 :            :                 "mingw" OS_SEP "crt" OS_SEP "cxa_atexit.c",
    1217                 :            :             };
    1218         [ #  # ]:          0 :             for (size_t i = 0; i < array_length(deps); i += 1) {
    1219                 :          0 :                 CFile *c_file = allocate<CFile>(1);
    1220                 :          0 :                 c_file->source_path = path_from_libc(parent, deps[i]);
    1221                 :          0 :                 c_file->args.append("-DHAVE_CONFIG_H");
    1222                 :          0 :                 c_file->args.append("-D_SYSCRT=1");
    1223                 :          0 :                 c_file->args.append("-DCRTDLL=1");
    1224                 :            : 
    1225                 :          0 :                 c_file->args.append("-isystem");
    1226                 :          0 :                 c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any"));
    1227                 :            : 
    1228                 :          0 :                 c_file->args.append("-isystem");
    1229                 :          0 :                 c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include"));
    1230                 :            : 
    1231                 :          0 :                 c_file->args.append("-std=gnu99");
    1232                 :          0 :                 c_file->args.append("-D_CRTBLD");
    1233                 :          0 :                 c_file->args.append("-D_WIN32_WINNT=0x0f00");
    1234                 :          0 :                 c_file->args.append("-D__MSVCRT_VERSION__=0x700");
    1235                 :          0 :                 c_file->args.append("-g");
    1236                 :          0 :                 c_file->args.append("-O2");
    1237                 :            : 
    1238                 :          0 :                 child_gen->c_source_files.append(c_file);
    1239                 :            :             }
    1240                 :          0 :             codegen_build_and_link(child_gen);
    1241                 :          0 :             return buf_ptr(&child_gen->output_file_path);
    1242         [ #  # ]:          0 :         } else if (strcmp(file, "msvcrt-os.lib") == 0) {
    1243                 :          0 :             CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
    1244                 :          0 :             codegen_set_out_name(child_gen, buf_create_from_str("msvcrt-os"));
    1245                 :            : 
    1246         [ #  # ]:          0 :             for (size_t i = 0; i < array_length(msvcrt_common_src); i += 1) {
    1247                 :          0 :                 add_msvcrt_os_dep(parent, child_gen, msvcrt_common_src[i]);
    1248                 :            :             }
    1249         [ #  # ]:          0 :             if (parent->zig_target->arch == ZigLLVM_x86) {
    1250         [ #  # ]:          0 :                 for (size_t i = 0; i < array_length(msvcrt_i386_src); i += 1) {
    1251                 :          0 :                     add_msvcrt_os_dep(parent, child_gen, msvcrt_i386_src[i]);
    1252                 :            :                 }
    1253                 :            :             } else {
    1254         [ #  # ]:          0 :                 for (size_t i = 0; i < array_length(msvcrt_other_src); i += 1) {
    1255                 :          0 :                     add_msvcrt_os_dep(parent, child_gen, msvcrt_other_src[i]);
    1256                 :            :                 }
    1257                 :            :             }
    1258                 :          0 :             codegen_build_and_link(child_gen);
    1259                 :          0 :             return buf_ptr(&child_gen->output_file_path);
    1260         [ #  # ]:          0 :         } else if (strcmp(file, "mingwex.lib") == 0) {
    1261                 :          0 :             CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
    1262                 :          0 :             codegen_set_out_name(child_gen, buf_create_from_str("mingwex"));
    1263                 :            : 
    1264         [ #  # ]:          0 :             for (size_t i = 0; i < array_length(mingwex_generic_src); i += 1) {
    1265                 :          0 :                 add_mingwex_os_dep(parent, child_gen, mingwex_generic_src[i]);
    1266                 :            :             }
    1267 [ #  # ][ #  # ]:          0 :             if (parent->zig_target->arch == ZigLLVM_x86 || parent->zig_target->arch == ZigLLVM_x86_64) {
    1268         [ #  # ]:          0 :                 for (size_t i = 0; i < array_length(mingwex_x86_src); i += 1) {
    1269                 :          0 :                     add_mingwex_os_dep(parent, child_gen, mingwex_x86_src[i]);
    1270                 :          0 :                 }
    1271         [ #  # ]:          0 :             } else if (target_is_arm(parent->zig_target)) {
    1272         [ #  # ]:          0 :                 if (target_arch_pointer_bit_width(parent->zig_target->arch) == 32) {
    1273         [ #  # ]:          0 :                     for (size_t i = 0; i < array_length(mingwex_arm32_src); i += 1) {
    1274                 :          0 :                         add_mingwex_os_dep(parent, child_gen, mingwex_arm32_src[i]);
    1275                 :            :                     }
    1276                 :            :                 } else {
    1277         [ #  # ]:          0 :                     for (size_t i = 0; i < array_length(mingwex_arm64_src); i += 1) {
    1278                 :          0 :                         add_mingwex_os_dep(parent, child_gen, mingwex_arm64_src[i]);
    1279                 :            :                     }
    1280                 :            :                 }
    1281                 :            :             } else {
    1282                 :          0 :                 zig_unreachable();
    1283                 :            :             }
    1284                 :          0 :             codegen_build_and_link(child_gen);
    1285                 :          0 :             return buf_ptr(&child_gen->output_file_path);
    1286                 :            :         } else {
    1287                 :          0 :             zig_unreachable();
    1288                 :            :         }
    1289 [ +  - ][ +  - ]:         12 :     } else if (parent->libc == nullptr && target_is_glibc(parent->zig_target)) {
                 [ +  - ]
    1290         [ +  + ]:         12 :         if (strcmp(file, "crti.o") == 0) {
    1291                 :          2 :             CFile *c_file = allocate<CFile>(1);
    1292                 :          2 :             c_file->source_path = glibc_start_asm_path(parent, "crti.S");
    1293                 :          2 :             glibc_add_include_dirs(parent, c_file);
    1294                 :          2 :             c_file->args.append("-D_LIBC_REENTRANT");
    1295                 :          2 :             c_file->args.append("-include");
    1296                 :          2 :             c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
    1297                 :          2 :             c_file->args.append("-DMODULE_NAME=libc");
    1298                 :          2 :             c_file->args.append("-include");
    1299                 :          2 :             c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
    1300                 :          2 :             c_file->args.append("-DTOP_NAMESPACE=glibc");
    1301                 :          2 :             c_file->args.append("-DASSEMBLER");
    1302                 :          2 :             c_file->args.append("-g");
    1303                 :          2 :             c_file->args.append("-Wa,--noexecstack");
    1304                 :          2 :             return build_libc_object(parent, "crti", c_file);
    1305         [ +  + ]:         10 :         } else if (strcmp(file, "crtn.o") == 0) {
    1306                 :          2 :             CFile *c_file = allocate<CFile>(1);
    1307                 :          2 :             c_file->source_path = glibc_start_asm_path(parent, "crtn.S");
    1308                 :          2 :             glibc_add_include_dirs(parent, c_file);
    1309                 :          2 :             c_file->args.append("-D_LIBC_REENTRANT");
    1310                 :          2 :             c_file->args.append("-DMODULE_NAME=libc");
    1311                 :          2 :             c_file->args.append("-DTOP_NAMESPACE=glibc");
    1312                 :          2 :             c_file->args.append("-DASSEMBLER");
    1313                 :          2 :             c_file->args.append("-g");
    1314                 :          2 :             c_file->args.append("-Wa,--noexecstack");
    1315                 :          2 :             return build_libc_object(parent, "crtn", c_file);
    1316         [ +  + ]:          8 :         } else if (strcmp(file, "start.os") == 0) {
    1317                 :          2 :             CFile *c_file = allocate<CFile>(1);
    1318                 :          2 :             c_file->source_path = glibc_start_asm_path(parent, "start.S");
    1319                 :          2 :             glibc_add_include_dirs(parent, c_file);
    1320                 :          2 :             c_file->args.append("-D_LIBC_REENTRANT");
    1321                 :          2 :             c_file->args.append("-include");
    1322                 :          2 :             c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
    1323                 :          2 :             c_file->args.append("-DMODULE_NAME=libc");
    1324                 :          2 :             c_file->args.append("-include");
    1325                 :          2 :             c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
    1326                 :          2 :             c_file->args.append("-DPIC");
    1327                 :          2 :             c_file->args.append("-DSHARED");
    1328                 :          2 :             c_file->args.append("-DTOP_NAMESPACE=glibc");
    1329                 :          2 :             c_file->args.append("-DASSEMBLER");
    1330                 :          2 :             c_file->args.append("-g");
    1331                 :          2 :             c_file->args.append("-Wa,--noexecstack");
    1332                 :          2 :             return build_libc_object(parent, "start", c_file);
    1333         [ +  + ]:          6 :         } else if (strcmp(file, "abi-note.o") == 0) {
    1334                 :          2 :             CFile *c_file = allocate<CFile>(1);
    1335                 :          2 :             c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "abi-note.S");
    1336                 :          2 :             c_file->args.append("-I");
    1337                 :          2 :             c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "csu"));
    1338                 :          2 :             glibc_add_include_dirs(parent, c_file);
    1339                 :          2 :             c_file->args.append("-D_LIBC_REENTRANT");
    1340                 :          2 :             c_file->args.append("-DMODULE_NAME=libc");
    1341                 :          2 :             c_file->args.append("-DTOP_NAMESPACE=glibc");
    1342                 :          2 :             c_file->args.append("-DASSEMBLER");
    1343                 :          2 :             c_file->args.append("-g");
    1344                 :          2 :             c_file->args.append("-Wa,--noexecstack");
    1345                 :          2 :             return build_libc_object(parent, "abi-note", c_file);
    1346         [ +  + ]:          4 :         } else if (strcmp(file, "Scrt1.o") == 0) {
    1347                 :          2 :             const char *start_os = get_libc_crt_file(parent, "start.os");
    1348                 :          2 :             const char *abi_note_o = get_libc_crt_file(parent, "abi-note.o");
    1349                 :          2 :             CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeObj, nullptr);
    1350                 :          2 :             codegen_set_out_name(child_gen, buf_create_from_str("Scrt1"));
    1351                 :          2 :             codegen_add_object(child_gen, buf_create_from_str(start_os));
    1352                 :          2 :             codegen_add_object(child_gen, buf_create_from_str(abi_note_o));
    1353                 :          2 :             codegen_build_and_link(child_gen);
    1354                 :          2 :             return buf_ptr(&child_gen->output_file_path);
    1355         [ +  - ]:          2 :         } else if (strcmp(file, "libc_nonshared.a") == 0) {
    1356                 :          2 :             CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
    1357                 :          2 :             codegen_set_out_name(child_gen, buf_create_from_str("c_nonshared"));
    1358                 :            :             {
    1359                 :          2 :                 CFile *c_file = allocate<CFile>(1);
    1360                 :          2 :                 c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "elf-init.c");
    1361                 :          2 :                 c_file->args.append("-std=gnu11");
    1362                 :          2 :                 c_file->args.append("-fgnu89-inline");
    1363                 :          2 :                 c_file->args.append("-g");
    1364                 :          2 :                 c_file->args.append("-O2");
    1365                 :          2 :                 c_file->args.append("-fmerge-all-constants");
    1366                 :          2 :                 c_file->args.append("-fno-stack-protector");
    1367                 :          2 :                 c_file->args.append("-fmath-errno");
    1368                 :          2 :                 c_file->args.append("-fno-stack-protector");
    1369                 :          2 :                 c_file->args.append("-I");
    1370                 :          2 :                 c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "csu"));
    1371                 :          2 :                 glibc_add_include_dirs(parent, c_file);
    1372                 :          2 :                 c_file->args.append("-DSTACK_PROTECTOR_LEVEL=0");
    1373                 :          2 :                 c_file->args.append("-fPIC");
    1374                 :          2 :                 c_file->args.append("-fno-stack-protector");
    1375                 :          2 :                 c_file->args.append("-ftls-model=initial-exec");
    1376                 :          2 :                 c_file->args.append("-D_LIBC_REENTRANT");
    1377                 :          2 :                 c_file->args.append("-include");
    1378                 :          2 :                 c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
    1379                 :          2 :                 c_file->args.append("-DMODULE_NAME=libc");
    1380                 :          2 :                 c_file->args.append("-include");
    1381                 :          2 :                 c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
    1382                 :          2 :                 c_file->args.append("-DPIC");
    1383                 :          2 :                 c_file->args.append("-DLIBC_NONSHARED=1");
    1384                 :          2 :                 c_file->args.append("-DTOP_NAMESPACE=glibc");
    1385                 :          2 :                 codegen_add_object(child_gen, buf_create_from_str(build_libc_object(parent, "elf-init", c_file)));
    1386                 :            :             }
    1387                 :            :             static const struct {
    1388                 :            :                 const char *name;
    1389                 :            :                 const char *path;
    1390                 :            :             } deps[] = {
    1391                 :            :                 {"atexit", "glibc" OS_SEP "stdlib" OS_SEP "atexit.c"},
    1392                 :            :                 {"at_quick_exit", "glibc" OS_SEP "stdlib" OS_SEP "at_quick_exit.c"},
    1393                 :            :                 {"stat", "glibc" OS_SEP "io" OS_SEP "stat.c"},
    1394                 :            :                 {"fstat", "glibc" OS_SEP "io" OS_SEP "fstat.c"},
    1395                 :            :                 {"lstat", "glibc" OS_SEP "io" OS_SEP "lstat.c"},
    1396                 :            :                 {"stat64", "glibc" OS_SEP "io" OS_SEP "stat64.c"},
    1397                 :            :                 {"fstat64", "glibc" OS_SEP "io" OS_SEP "fstat64.c"},
    1398                 :            :                 {"lstat64", "glibc" OS_SEP "io" OS_SEP "lstat64.c"},
    1399                 :            :                 {"fstatat", "glibc" OS_SEP "io" OS_SEP "fstatat.c"},
    1400                 :            :                 {"fstatat64", "glibc" OS_SEP "io" OS_SEP "fstatat64.c"},
    1401                 :            :                 {"mknod", "glibc" OS_SEP "io" OS_SEP "mknod.c"},
    1402                 :            :                 {"mknodat", "glibc" OS_SEP "io" OS_SEP "mknodat.c"},
    1403                 :            :                 {"pthread_atfork", "glibc" OS_SEP "nptl" OS_SEP "pthread_atfork.c"},
    1404                 :            :                 {"stack_chk_fail_local", "glibc" OS_SEP "debug" OS_SEP "stack_chk_fail_local.c"},
    1405                 :            :             };
    1406         [ +  + ]:         30 :             for (size_t i = 0; i < array_length(deps); i += 1) {
    1407                 :         28 :                 CFile *c_file = allocate<CFile>(1);
    1408                 :         28 :                 c_file->source_path = path_from_libc(parent, deps[i].path);
    1409                 :         28 :                 c_file->args.append("-std=gnu11");
    1410                 :         28 :                 c_file->args.append("-fgnu89-inline");
    1411                 :         28 :                 c_file->args.append("-g");
    1412                 :         28 :                 c_file->args.append("-O2");
    1413                 :         28 :                 c_file->args.append("-fmerge-all-constants");
    1414                 :         28 :                 c_file->args.append("-fno-stack-protector");
    1415                 :         28 :                 c_file->args.append("-fmath-errno");
    1416                 :         28 :                 c_file->args.append("-ftls-model=initial-exec");
    1417                 :         28 :                 c_file->args.append("-Wno-ignored-attributes");
    1418                 :         28 :                 glibc_add_include_dirs(parent, c_file);
    1419                 :         28 :                 c_file->args.append("-D_LIBC_REENTRANT");
    1420                 :         28 :                 c_file->args.append("-include");
    1421                 :         28 :                 c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
    1422                 :         28 :                 c_file->args.append("-DMODULE_NAME=libc");
    1423                 :         28 :                 c_file->args.append("-include");
    1424                 :         28 :                 c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
    1425                 :         28 :                 c_file->args.append("-DPIC");
    1426                 :         28 :                 c_file->args.append("-DLIBC_NONSHARED=1");
    1427                 :         28 :                 c_file->args.append("-DTOP_NAMESPACE=glibc");
    1428                 :         28 :                 codegen_add_object(child_gen, buf_create_from_str(build_libc_object(parent, deps[i].name, c_file)));
    1429                 :            :             }
    1430                 :          2 :             codegen_build_and_link(child_gen);
    1431                 :          2 :             return buf_ptr(&child_gen->output_file_path);
    1432                 :            :         } else {
    1433                 :          0 :             zig_unreachable();
    1434                 :            :         }
    1435 [ #  # ][ #  # ]:          0 :     } else if (parent->libc == nullptr && target_is_musl(parent->zig_target)) {
                 [ #  # ]
    1436         [ #  # ]:          0 :         if (strcmp(file, "crti.o") == 0) {
    1437                 :          0 :             CFile *c_file = allocate<CFile>(1);
    1438                 :          0 :             c_file->source_path = musl_start_asm_path(parent, "crti.s");
    1439                 :          0 :             musl_add_cc_args(parent, c_file, false);
    1440                 :          0 :             c_file->args.append("-Qunused-arguments");
    1441                 :          0 :             return build_libc_object(parent, "crti", c_file);
    1442         [ #  # ]:          0 :         } else if (strcmp(file, "crtn.o") == 0) {
    1443                 :          0 :             CFile *c_file = allocate<CFile>(1);
    1444                 :          0 :             c_file->source_path = musl_start_asm_path(parent, "crtn.s");
    1445                 :          0 :             c_file->args.append("-Qunused-arguments");
    1446                 :          0 :             musl_add_cc_args(parent, c_file, false);
    1447                 :          0 :             return build_libc_object(parent, "crtn", c_file);
    1448         [ #  # ]:          0 :         } else if (strcmp(file, "crt1.o") == 0) {
    1449                 :          0 :             CFile *c_file = allocate<CFile>(1);
    1450                 :          0 :             c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c");
    1451                 :          0 :             musl_add_cc_args(parent, c_file, false);
    1452                 :          0 :             c_file->args.append("-fno-stack-protector");
    1453                 :          0 :             c_file->args.append("-DCRT");
    1454                 :          0 :             return build_libc_object(parent, "crt1", c_file);
    1455         [ #  # ]:          0 :         } else if (strcmp(file, "Scrt1.o") == 0) {
    1456                 :          0 :             CFile *c_file = allocate<CFile>(1);
    1457                 :          0 :             c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c");
    1458                 :          0 :             musl_add_cc_args(parent, c_file, false);
    1459                 :          0 :             c_file->args.append("-fPIC");
    1460                 :          0 :             c_file->args.append("-fno-stack-protector");
    1461                 :          0 :             c_file->args.append("-DCRT");
    1462                 :          0 :             return build_libc_object(parent, "Scrt1", c_file);
    1463                 :            :         } else {
    1464                 :          0 :             zig_unreachable();
    1465                 :            :         }
    1466                 :            :     } else {
    1467                 :          0 :         assert(parent->libc != nullptr);
    1468                 :          0 :         Buf *out_buf = buf_alloc();
    1469                 :          0 :         os_path_join(&parent->libc->crt_dir, buf_create_from_str(file), out_buf);
    1470                 :          0 :         return buf_ptr(out_buf);
    1471                 :            :     }
    1472                 :            : }
    1473                 :            : 
    1474                 :         14 : static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type) {
    1475                 :         14 :     CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type,
    1476                 :         14 :             parent_gen->libc);
    1477                 :         14 :     codegen_set_out_name(child_gen, buf_create_from_str(aname));
    1478                 :            : 
    1479                 :            :     // This is so that compiler_rt and libc.zig libraries know whether they
    1480                 :            :     // will eventually be linked with libc. They make different decisions
    1481                 :            :     // about what to export depending on whether libc is linked.
    1482         [ +  + ]:         14 :     if (parent_gen->libc_link_lib != nullptr) {
    1483                 :          4 :         LinkLib *new_link_lib = codegen_add_link_lib(child_gen, parent_gen->libc_link_lib->name);
    1484                 :          4 :         new_link_lib->provided_explicitly = parent_gen->libc_link_lib->provided_explicitly;
    1485                 :            :     }
    1486                 :            : 
    1487                 :         14 :     child_gen->function_sections = true;
    1488                 :         14 :     child_gen->want_stack_check = WantStackCheckDisabled;
    1489                 :            : 
    1490                 :         14 :     codegen_build_and_link(child_gen);
    1491                 :         14 :     return &child_gen->output_file_path;
    1492                 :            : }
    1493                 :            : 
    1494                 :          9 : static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) {
    1495                 :          9 :     Buf *full_path = buf_alloc();
    1496                 :          9 :     os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path);
    1497                 :            : 
    1498                 :          9 :     return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type);
    1499                 :            : }
    1500                 :            : 
    1501                 :          5 : static Buf *build_c(CodeGen *parent_gen, OutType child_out_type) {
    1502                 :          5 :     Buf *full_path = buf_alloc();
    1503                 :          5 :     os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("c.zig"), full_path);
    1504                 :            : 
    1505                 :          5 :     return build_a_raw(parent_gen, "c", full_path, child_out_type);
    1506                 :            : }
    1507                 :            : 
    1508                 :          2 : static const char *get_darwin_arch_string(const ZigTarget *t) {
    1509   [ -  -  -  -  :          2 :     switch (t->arch) {
                   -  + ]
    1510                 :          0 :         case ZigLLVM_aarch64:
    1511                 :          0 :             return "arm64";
    1512                 :          0 :         case ZigLLVM_thumb:
    1513                 :            :         case ZigLLVM_arm:
    1514                 :          0 :             return "arm";
    1515                 :          0 :         case ZigLLVM_ppc:
    1516                 :          0 :             return "ppc";
    1517                 :          0 :         case ZigLLVM_ppc64:
    1518                 :          0 :             return "ppc64";
    1519                 :          0 :         case ZigLLVM_ppc64le:
    1520                 :          0 :             return "ppc64le";
    1521                 :          2 :         default:
    1522                 :          2 :             return ZigLLVMGetArchTypeName(t->arch);
    1523                 :            :     }
    1524                 :            : }
    1525                 :            : 
    1526                 :            : 
    1527                 :         11 : static const char *getLDMOption(const ZigTarget *t) {
    1528   [ -  -  -  -  :         11 :     switch (t->arch) {
          -  -  -  -  -  
          -  -  -  -  -  
             +  -  -  - ]
    1529                 :          0 :         case ZigLLVM_x86:
    1530                 :          0 :             return "elf_i386";
    1531                 :          0 :         case ZigLLVM_aarch64:
    1532                 :          0 :             return "aarch64linux";
    1533                 :          0 :         case ZigLLVM_aarch64_be:
    1534                 :          0 :             return "aarch64_be_linux";
    1535                 :          0 :         case ZigLLVM_arm:
    1536                 :            :         case ZigLLVM_thumb:
    1537                 :          0 :             return "armelf_linux_eabi";
    1538                 :          0 :         case ZigLLVM_armeb:
    1539                 :            :         case ZigLLVM_thumbeb:
    1540                 :          0 :             return "armebelf_linux_eabi";
    1541                 :          0 :         case ZigLLVM_ppc:
    1542                 :          0 :             return "elf32ppclinux";
    1543                 :          0 :         case ZigLLVM_ppc64:
    1544                 :          0 :             return "elf64ppc";
    1545                 :          0 :         case ZigLLVM_ppc64le:
    1546                 :          0 :             return "elf64lppc";
    1547                 :          0 :         case ZigLLVM_sparc:
    1548                 :            :         case ZigLLVM_sparcel:
    1549                 :          0 :             return "elf32_sparc";
    1550                 :          0 :         case ZigLLVM_sparcv9:
    1551                 :          0 :             return "elf64_sparc";
    1552                 :          0 :         case ZigLLVM_mips:
    1553                 :          0 :             return "elf32btsmip";
    1554                 :          0 :         case ZigLLVM_mipsel:
    1555                 :          0 :             return "elf32ltsmip";
    1556                 :            :             return "elf64btsmip";
    1557                 :          0 :         case ZigLLVM_mips64el:
    1558                 :          0 :             return "elf64ltsmip";
    1559                 :          0 :         case ZigLLVM_systemz:
    1560                 :          0 :             return "elf64_s390";
    1561                 :         11 :         case ZigLLVM_x86_64:
    1562         [ -  + ]:         11 :             if (t->abi == ZigLLVM_GNUX32) {
    1563                 :          0 :                 return "elf32_x86_64";
    1564                 :            :             }
    1565                 :            :             // Any target elf will use the freebsd osabi if suffixed with "_fbsd".
    1566         [ -  + ]:         11 :             if (t->os == OsFreeBSD) {
    1567                 :          0 :                 return "elf_x86_64_fbsd";
    1568                 :            :             }
    1569                 :         11 :             return "elf_x86_64";
    1570                 :          0 :         case ZigLLVM_riscv32:
    1571                 :          0 :             return "elf32lriscv";
    1572                 :          0 :         case ZigLLVM_riscv64:
    1573                 :          0 :             return "elf64lriscv";
    1574                 :          0 :         default:
    1575                 :          0 :             zig_unreachable();
    1576                 :            :     }
    1577                 :            : }
    1578                 :            : 
    1579                 :          0 : static void add_rpath(LinkJob *lj, Buf *rpath) {
    1580         [ #  # ]:          0 :     if (lj->rpath_table.maybe_get(rpath) != nullptr)
    1581                 :          0 :         return;
    1582                 :            : 
    1583                 :          0 :     lj->args.append("-rpath");
    1584                 :          0 :     lj->args.append(buf_ptr(rpath));
    1585                 :            : 
    1586                 :          0 :     lj->rpath_table.put(rpath, true);
    1587                 :            : }
    1588                 :            : 
    1589                 :          2 : static void add_glibc_libs(LinkJob *lj) {
    1590                 :            :     Error err;
    1591                 :            :     ZigGLibCAbi *glibc_abi;
    1592         [ -  + ]:          2 :     if ((err = glibc_load_metadata(&glibc_abi, lj->codegen->zig_lib_dir, true))) {
    1593                 :          0 :         fprintf(stderr, "%s\n", err_str(err));
    1594                 :          0 :         exit(1);
    1595                 :            :     }
    1596                 :            : 
    1597                 :            :     Buf *artifact_dir;
    1598         [ -  + ]:          2 :     if ((err = glibc_build_dummies_and_maps(lj->codegen, glibc_abi, lj->codegen->zig_target,
    1599                 :          2 :                     &artifact_dir, true)))
    1600                 :            :     {
    1601                 :          0 :         fprintf(stderr, "%s\n", err_str(err));
    1602                 :          0 :         exit(1);
    1603                 :            :     }
    1604                 :            : 
    1605                 :          2 :     size_t lib_count = glibc_lib_count();
    1606         [ +  + ]:         12 :     for (size_t i = 0; i < lib_count; i += 1) {
    1607                 :         10 :         const ZigGLibCLib *lib = glibc_lib_enum(i);
    1608                 :         10 :         Buf *so_path = buf_sprintf("%s" OS_SEP "lib%s.so.%d.0.0", buf_ptr(artifact_dir), lib->name, lib->sover);
    1609                 :         10 :         lj->args.append(buf_ptr(so_path));
    1610                 :            :     }
    1611                 :          2 : }
    1612                 :            : 
    1613                 :         11 : static void construct_linker_job_elf(LinkJob *lj) {
    1614                 :         11 :     CodeGen *g = lj->codegen;
    1615                 :            : 
    1616                 :         11 :     lj->args.append("-error-limit=0");
    1617                 :            : 
    1618         [ -  + ]:         11 :     if (g->linker_script) {
    1619                 :          0 :         lj->args.append("-T");
    1620                 :          0 :         lj->args.append(g->linker_script);
    1621                 :            :     }
    1622                 :            : 
    1623         [ +  + ]:         11 :     if (g->out_type != OutTypeObj) {
    1624                 :         10 :         lj->args.append("--gc-sections");
    1625                 :            :     }
    1626                 :            : 
    1627                 :         11 :     lj->args.append("-m");
    1628                 :         11 :     lj->args.append(getLDMOption(g->zig_target));
    1629                 :            : 
    1630                 :         11 :     bool is_lib = g->out_type == OutTypeLib;
    1631 [ +  - ][ +  + ]:         11 :     bool is_dyn_lib = g->is_dynamic && is_lib;
    1632                 :         11 :     Buf *soname = nullptr;
    1633         [ +  + ]:         11 :     if (!g->have_dynamic_link) {
    1634 [ +  - ][ +  - ]:          4 :         if (g->zig_target->arch == ZigLLVM_arm || g->zig_target->arch == ZigLLVM_armeb ||
                 [ +  - ]
    1635         [ -  + ]:          4 :             g->zig_target->arch == ZigLLVM_thumb || g->zig_target->arch == ZigLLVM_thumbeb)
    1636                 :            :         {
    1637                 :          0 :             lj->args.append("-Bstatic");
    1638                 :            :         } else {
    1639                 :          4 :             lj->args.append("-static");
    1640                 :            :         }
    1641         [ +  + ]:          7 :     } else if (is_dyn_lib) {
    1642                 :          5 :         lj->args.append("-shared");
    1643                 :            : 
    1644                 :          5 :         assert(buf_len(&g->output_file_path) != 0);
    1645                 :          5 :         soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);
    1646                 :            :     }
    1647                 :            : 
    1648                 :         11 :     lj->args.append("-o");
    1649                 :         11 :     lj->args.append(buf_ptr(&g->output_file_path));
    1650                 :            : 
    1651         [ +  + ]:         11 :     if (lj->link_in_crt) {
    1652                 :            :         const char *crt1o;
    1653         [ -  + ]:          2 :         if (g->zig_target->os == OsNetBSD) {
    1654                 :          0 :             crt1o = "crt0.o";
    1655         [ -  + ]:          2 :         } else if (!g->have_dynamic_link) {
    1656                 :          0 :             crt1o = "crt1.o";
    1657                 :            :         } else {
    1658                 :          2 :             crt1o = "Scrt1.o";
    1659                 :            :         }
    1660                 :          2 :         lj->args.append(get_libc_crt_file(g, crt1o));
    1661                 :          2 :         lj->args.append(get_libc_crt_file(g, "crti.o"));
    1662                 :            :     }
    1663                 :            : 
    1664         [ -  + ]:         11 :     for (size_t i = 0; i < g->rpath_list.length; i += 1) {
    1665                 :          0 :         Buf *rpath = g->rpath_list.at(i);
    1666                 :          0 :         add_rpath(lj, rpath);
    1667                 :            :     }
    1668         [ +  - ]:         11 :     if (g->each_lib_rpath) {
    1669         [ -  + ]:         11 :         for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
    1670                 :          0 :             const char *lib_dir = g->lib_dirs.at(i);
    1671         [ #  # ]:          0 :             for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
    1672                 :          0 :                 LinkLib *link_lib = g->link_libs_list.at(i);
    1673         [ #  # ]:          0 :                 if (buf_eql_str(link_lib->name, "c")) {
    1674                 :          0 :                     continue;
    1675                 :            :                 }
    1676                 :            :                 bool does_exist;
    1677                 :          0 :                 Buf *test_path = buf_sprintf("%s/lib%s.so", lib_dir, buf_ptr(link_lib->name));
    1678         [ #  # ]:          0 :                 if (os_file_exists(test_path, &does_exist) != ErrorNone) {
    1679                 :          0 :                     zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path));
    1680                 :            :                 }
    1681         [ #  # ]:          0 :                 if (does_exist) {
    1682                 :          0 :                     add_rpath(lj, buf_create_from_str(lib_dir));
    1683                 :          0 :                     break;
    1684                 :            :                 }
    1685                 :            :             }
    1686                 :            :         }
    1687                 :            :     }
    1688                 :            : 
    1689         [ -  + ]:         11 :     for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
    1690                 :          0 :         const char *lib_dir = g->lib_dirs.at(i);
    1691                 :          0 :         lj->args.append("-L");
    1692                 :          0 :         lj->args.append(lib_dir);
    1693                 :            :     }
    1694                 :            : 
    1695         [ +  + ]:         11 :     if (g->libc_link_lib != nullptr) {
    1696         [ -  + ]:          2 :         if (g->libc != nullptr) {
    1697                 :          0 :             lj->args.append("-L");
    1698                 :          0 :             lj->args.append(buf_ptr(&g->libc->crt_dir));
    1699                 :            :         }
    1700                 :            : 
    1701 [ +  - ][ +  - ]:          2 :         if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {
                 [ +  - ]
    1702                 :          2 :             assert(g->dynamic_linker_path != nullptr);
    1703                 :          2 :             lj->args.append("-dynamic-linker");
    1704                 :          2 :             lj->args.append(buf_ptr(g->dynamic_linker_path));
    1705                 :            :         }
    1706                 :            :     }
    1707                 :            : 
    1708         [ +  + ]:         11 :     if (is_dyn_lib) {
    1709                 :          5 :         lj->args.append("-soname");
    1710                 :          5 :         lj->args.append(buf_ptr(soname));
    1711                 :            : 
    1712         [ +  - ]:          5 :         if (g->version_script_path != nullptr) {
    1713                 :          5 :             lj->args.append("-version-script");
    1714                 :          5 :             lj->args.append(buf_ptr(g->version_script_path));
    1715                 :            :         }
    1716                 :            :     }
    1717                 :            : 
    1718                 :            :     // .o files
    1719         [ +  + ]:         23 :     for (size_t i = 0; i < g->link_objects.length; i += 1) {
    1720                 :         12 :         lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
    1721                 :            :     }
    1722                 :            : 
    1723 [ +  + ][ +  + ]:         11 :     if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) {
                 [ -  + ]
    1724         [ +  + ]:          5 :         if (g->libc_link_lib == nullptr) {
    1725                 :          3 :             Buf *libc_a_path = build_c(g, OutTypeLib);
    1726                 :          3 :             lj->args.append(buf_ptr(libc_a_path));
    1727                 :            :         }
    1728                 :            : 
    1729                 :          5 :         Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
    1730                 :          5 :         lj->args.append(buf_ptr(compiler_rt_o_path));
    1731                 :            :     }
    1732                 :            : 
    1733         [ +  + ]:         13 :     for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
    1734                 :          2 :         LinkLib *link_lib = g->link_libs_list.at(i);
    1735         [ +  - ]:          2 :         if (buf_eql_str(link_lib->name, "c")) {
    1736                 :            :             // libc is linked specially
    1737                 :          2 :             continue;
    1738                 :            :         }
    1739 [ #  # ][ #  # ]:          0 :         if (g->libc == nullptr && target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) {
                 [ #  # ]
    1740                 :            :             // these libraries are always linked below when targeting glibc
    1741                 :          0 :             continue;
    1742                 :            :         }
    1743                 :            :         Buf *arg;
    1744         [ #  # ]:          0 :         if (buf_starts_with_str(link_lib->name, "/") || buf_ends_with_str(link_lib->name, ".a") ||
           [ #  #  #  # ]
                 [ #  # ]
    1745                 :          0 :             buf_ends_with_str(link_lib->name, ".so"))
    1746                 :            :         {
    1747                 :          0 :             arg = link_lib->name;
    1748                 :            :         } else {
    1749                 :          0 :             arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
    1750                 :            :         }
    1751                 :          0 :         lj->args.append(buf_ptr(arg));
    1752                 :            :     }
    1753                 :            : 
    1754                 :            : 
    1755                 :            :     // libc dep
    1756 [ +  + ][ +  - ]:         11 :     if (g->libc_link_lib != nullptr && g->out_type != OutTypeObj) {
    1757         [ -  + ]:          2 :         if (g->libc != nullptr) {
    1758         [ #  # ]:          0 :             if (!g->have_dynamic_link) {
    1759                 :          0 :                 lj->args.append("--start-group");
    1760                 :          0 :                 lj->args.append("-lgcc");
    1761                 :          0 :                 lj->args.append("-lgcc_eh");
    1762                 :          0 :                 lj->args.append("-lc");
    1763                 :          0 :                 lj->args.append("-lm");
    1764                 :          0 :                 lj->args.append("--end-group");
    1765                 :            :             } else {
    1766                 :          0 :                 lj->args.append("-lgcc");
    1767                 :          0 :                 lj->args.append("--as-needed");
    1768                 :          0 :                 lj->args.append("-lgcc_s");
    1769                 :          0 :                 lj->args.append("--no-as-needed");
    1770                 :          0 :                 lj->args.append("-lc");
    1771                 :          0 :                 lj->args.append("-lm");
    1772                 :          0 :                 lj->args.append("-lgcc");
    1773                 :          0 :                 lj->args.append("--as-needed");
    1774                 :          0 :                 lj->args.append("-lgcc_s");
    1775                 :          0 :                 lj->args.append("--no-as-needed");
    1776                 :            :             }
    1777         [ +  - ]:          2 :         } else if (target_is_glibc(g->zig_target)) {
    1778         [ +  - ]:          2 :             if (target_supports_libunwind(g->zig_target)) {
    1779                 :          2 :                 lj->args.append(build_libunwind(g));
    1780                 :            :             }
    1781                 :          2 :             add_glibc_libs(lj);
    1782                 :          2 :             lj->args.append(get_libc_crt_file(g, "libc_nonshared.a"));
    1783         [ #  # ]:          0 :         } else if (target_is_musl(g->zig_target)) {
    1784         [ #  # ]:          0 :             if (target_supports_libunwind(g->zig_target)) {
    1785                 :          0 :                 lj->args.append(build_libunwind(g));
    1786                 :            :             }
    1787                 :          0 :             lj->args.append(build_musl(g));
    1788                 :            :         } else {
    1789                 :          0 :             zig_unreachable();
    1790                 :            :         }
    1791                 :            :     }
    1792                 :            : 
    1793                 :            :     // crt end
    1794         [ +  + ]:         11 :     if (lj->link_in_crt) {
    1795                 :          2 :         lj->args.append(get_libc_crt_file(g, "crtn.o"));
    1796                 :            :     }
    1797                 :            : 
    1798         [ -  + ]:         11 :     if (!g->zig_target->is_native) {
    1799                 :          0 :         lj->args.append("--allow-shlib-undefined");
    1800                 :            :     }
    1801                 :            : 
    1802         [ -  + ]:         11 :     if (g->zig_target->os == OsZen) {
    1803                 :          0 :         lj->args.append("-e");
    1804                 :          0 :         lj->args.append("_start");
    1805                 :            : 
    1806                 :          0 :         lj->args.append("--image-base=0x10000000");
    1807                 :            :     }
    1808                 :         11 : }
    1809                 :            : 
    1810                 :          0 : static void construct_linker_job_wasm(LinkJob *lj) {
    1811                 :          0 :     CodeGen *g = lj->codegen;
    1812                 :            : 
    1813                 :          0 :     lj->args.append("-error-limit=0");
    1814                 :            : 
    1815         [ #  # ]:          0 :     if (g->out_type != OutTypeExe) {
    1816                 :          0 :         lj->args.append("--no-entry"); // So lld doesn't look for _start.
    1817                 :            : 
    1818                 :            :         // If there are any C source files we cannot rely on individual exports.
    1819         [ #  # ]:          0 :         if (g->c_source_files.length != 0) {
    1820                 :          0 :             lj->args.append("--export-all");
    1821                 :            :         } else {
    1822                 :          0 :             auto export_it = g->exported_symbol_names.entry_iterator();
    1823                 :          0 :             decltype(g->exported_symbol_names)::Entry *curr_entry = nullptr;
    1824         [ #  # ]:          0 :             while ((curr_entry = export_it.next()) != nullptr) {
    1825                 :          0 :                 Buf *arg = buf_sprintf("--export=%s", buf_ptr(curr_entry->key));
    1826                 :          0 :                 lj->args.append(buf_ptr(arg));
    1827                 :            :             }
    1828                 :            :         }
    1829                 :            :     }
    1830                 :          0 :     lj->args.append("--allow-undefined");
    1831                 :          0 :     lj->args.append("-o");
    1832                 :          0 :     lj->args.append(buf_ptr(&g->output_file_path));
    1833                 :            : 
    1834                 :            :     // .o files
    1835         [ #  # ]:          0 :     for (size_t i = 0; i < g->link_objects.length; i += 1) {
    1836                 :          0 :         lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
    1837                 :            :     }
    1838                 :            : 
    1839         [ #  # ]:          0 :     if (g->out_type != OutTypeObj) {
    1840                 :          0 :         Buf *libc_o_path = build_c(g, OutTypeObj);
    1841                 :          0 :         lj->args.append(buf_ptr(libc_o_path));
    1842                 :            : 
    1843                 :          0 :         Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj);
    1844                 :          0 :         lj->args.append(buf_ptr(compiler_rt_o_path));
    1845                 :            :     }
    1846                 :          0 : }
    1847                 :            : 
    1848                 :          6 : static void coff_append_machine_arg(CodeGen *g, ZigList<const char *> *list) {
    1849         [ -  + ]:          6 :     if (g->zig_target->arch == ZigLLVM_x86) {
    1850                 :          0 :         list->append("-MACHINE:X86");
    1851         [ +  - ]:          6 :     } else if (g->zig_target->arch == ZigLLVM_x86_64) {
    1852                 :          6 :         list->append("-MACHINE:X64");
    1853         [ #  # ]:          0 :     } else if (target_is_arm(g->zig_target)) {
    1854         [ #  # ]:          0 :         if (target_arch_pointer_bit_width(g->zig_target->arch) == 32) {
    1855                 :          0 :             list->append("-MACHINE:ARM");
    1856                 :            :         } else {
    1857                 :          0 :             list->append("-MACHINE:ARM64");
    1858                 :            :         }
    1859                 :            :     }
    1860                 :          6 : }
    1861                 :            : 
    1862                 :          0 : static void link_diag_callback(void *context, const char *ptr, size_t len) {
    1863                 :          0 :     Buf *diag = reinterpret_cast<Buf *>(context);
    1864                 :          0 :     buf_append_mem(diag, ptr, len);
    1865                 :          0 : }
    1866                 :            : 
    1867                 :         19 : static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag) {
    1868                 :         19 :     buf_resize(diag, 0);
    1869                 :         19 :     return ZigLLDLink(oformat, args, arg_count, link_diag_callback, diag);
    1870                 :            : }
    1871                 :            : 
    1872                 :          0 : static void add_uefi_link_args(LinkJob *lj) {
    1873                 :          0 :     lj->args.append("-BASE:0");
    1874                 :          0 :     lj->args.append("-ENTRY:EfiMain");
    1875                 :          0 :     lj->args.append("-OPT:REF");
    1876                 :          0 :     lj->args.append("-SAFESEH:NO");
    1877                 :          0 :     lj->args.append("-MERGE:.rdata=.data");
    1878                 :          0 :     lj->args.append("-ALIGN:32");
    1879                 :          0 :     lj->args.append("-NODEFAULTLIB");
    1880                 :          0 :     lj->args.append("-SECTION:.xdata,D");
    1881                 :          0 : }
    1882                 :            : 
    1883                 :          0 : static void add_msvc_link_args(LinkJob *lj, bool is_library) {
    1884                 :          0 :     CodeGen *g = lj->codegen;
    1885                 :            : 
    1886                 :          0 :     bool is_dynamic = g->is_dynamic;
    1887         [ #  # ]:          0 :     const char *lib_str = is_dynamic ? "" : "lib";
    1888         [ #  # ]:          0 :     const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : "";
    1889                 :            : 
    1890         [ #  # ]:          0 :     if (!is_dynamic) {
    1891                 :          0 :         Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str);
    1892                 :          0 :         lj->args.append(buf_ptr(cmt_lib_name));
    1893                 :            :     } else {
    1894                 :          0 :         Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str);
    1895                 :          0 :         lj->args.append(buf_ptr(msvcrt_lib_name));
    1896                 :            :     }
    1897                 :            : 
    1898                 :          0 :     Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str);
    1899                 :          0 :     lj->args.append(buf_ptr(vcruntime_lib_name));
    1900                 :            : 
    1901                 :          0 :     Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str);
    1902                 :          0 :     lj->args.append(buf_ptr(crt_lib_name));
    1903                 :            : 
    1904                 :            :     //Visual C++ 2015 Conformance Changes
    1905                 :            :     //https://msdn.microsoft.com/en-us/library/bb531344.aspx
    1906                 :          0 :     lj->args.append("legacy_stdio_definitions.lib");
    1907                 :            : 
    1908                 :            :     // msvcrt depends on kernel32 and ntdll
    1909                 :          0 :     lj->args.append("kernel32.lib");
    1910                 :          0 :     lj->args.append("ntdll.lib");
    1911                 :          0 : }
    1912                 :            : 
    1913                 :          0 : static void print_zig_cc_cmd(ZigList<const char *> *args) {
    1914         [ #  # ]:          0 :     for (size_t arg_i = 0; arg_i < args->length; arg_i += 1) {
    1915         [ #  # ]:          0 :         const char *space_str = (arg_i == 0) ? "" : " ";
    1916                 :          0 :         fprintf(stderr, "%s%s", space_str, args->at(arg_i));
    1917                 :            :     }
    1918                 :          0 :     fprintf(stderr, "\n");
    1919                 :          0 : }
    1920                 :            : 
    1921                 :          0 : static const char *get_def_lib(CodeGen *parent, const char *name, Buf *def_in_rel_path) {
    1922                 :            :     Error err;
    1923                 :            : 
    1924                 :          0 :     Buf *self_exe_path = buf_alloc();
    1925         [ #  # ]:          0 :     if ((err = os_self_exe_path(self_exe_path))) {
    1926                 :          0 :         fprintf(stderr, "Unable to get self exe path: %s\n", err_str(err));
    1927                 :          0 :         exit(1);
    1928                 :            :     }
    1929                 :            :     Buf *compiler_id;
    1930         [ #  # ]:          0 :     if ((err = get_compiler_id(&compiler_id))) {
    1931                 :          0 :         fprintf(stderr, "Unable to get compiler id: %s\n", err_str(err));
    1932                 :          0 :         exit(1);
    1933                 :            :     }
    1934                 :            : 
    1935                 :          0 :     Buf *cache_dir = get_stage1_cache_path();
    1936                 :          0 :     Buf *o_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR, buf_ptr(cache_dir));
    1937                 :          0 :     Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(cache_dir));
    1938                 :            : 
    1939                 :          0 :     Buf *def_in_file = buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s",
    1940                 :          0 :             buf_ptr(parent->zig_lib_dir), buf_ptr(def_in_rel_path));
    1941                 :          0 :     Buf *def_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "def-include",
    1942                 :          0 :             buf_ptr(parent->zig_lib_dir));
    1943                 :            : 
    1944                 :          0 :     CacheHash *cache_hash = allocate<CacheHash>(1);
    1945                 :          0 :     cache_init(cache_hash, manifest_dir);
    1946                 :            : 
    1947                 :          0 :     cache_buf(cache_hash, compiler_id);
    1948                 :          0 :     cache_file(cache_hash, def_in_file);
    1949                 :          0 :     cache_buf(cache_hash, def_include_dir);
    1950                 :          0 :     cache_int(cache_hash, parent->zig_target->arch);
    1951                 :            : 
    1952                 :          0 :     Buf digest = BUF_INIT;
    1953                 :          0 :     buf_resize(&digest, 0);
    1954         [ #  # ]:          0 :     if ((err = cache_hit(cache_hash, &digest))) {
    1955         [ #  # ]:          0 :         if (err != ErrorInvalidFormat) {
    1956         [ #  # ]:          0 :             if (err == ErrorCacheUnavailable) {
    1957                 :            :                 // already printed error
    1958                 :            :             } else {
    1959                 :          0 :                 fprintf(stderr, "unable to check cache when processing .def.in file: %s\n", err_str(err));
    1960                 :            :             }
    1961                 :          0 :             exit(1);
    1962                 :            :         }
    1963                 :            :     }
    1964                 :            : 
    1965                 :            :     Buf *artifact_dir;
    1966                 :            :     Buf *lib_final_path;
    1967                 :          0 :     Buf *final_lib_basename = buf_sprintf("%s.lib", name);
    1968                 :            : 
    1969                 :          0 :     bool is_cache_miss = (buf_len(&digest) == 0);
    1970         [ #  # ]:          0 :     if (is_cache_miss) {
    1971         [ #  # ]:          0 :         if ((err = cache_final(cache_hash, &digest))) {
    1972                 :          0 :             fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
    1973                 :          0 :             exit(1);
    1974                 :            :         }
    1975                 :          0 :         artifact_dir = buf_alloc();
    1976                 :          0 :         os_path_join(o_dir, &digest, artifact_dir);
    1977         [ #  # ]:          0 :         if ((err = os_make_path(artifact_dir))) {
    1978                 :          0 :             fprintf(stderr, "Unable to create output directory '%s': %s",
    1979                 :            :                     buf_ptr(artifact_dir), err_str(err));
    1980                 :          0 :             exit(1);
    1981                 :            :         }
    1982                 :          0 :         Buf *final_def_basename = buf_sprintf("%s.def", name);
    1983                 :          0 :         Buf *def_final_path = buf_alloc();
    1984                 :          0 :         os_path_join(artifact_dir, final_def_basename, def_final_path);
    1985                 :            : 
    1986                 :          0 :         ZigList<const char *> args = {};
    1987                 :          0 :         args.append(buf_ptr(self_exe_path));
    1988                 :          0 :         args.append("cc");
    1989                 :          0 :         args.append("-x");
    1990                 :          0 :         args.append("c");
    1991                 :          0 :         args.append(buf_ptr(def_in_file));
    1992                 :          0 :         args.append("-Wp,-w");
    1993                 :          0 :         args.append("-undef");
    1994                 :          0 :         args.append("-P");
    1995                 :          0 :         args.append("-I");
    1996                 :          0 :         args.append(buf_ptr(def_include_dir));
    1997         [ #  # ]:          0 :         if (target_is_arm(parent->zig_target)) {
    1998         [ #  # ]:          0 :             if (target_arch_pointer_bit_width(parent->zig_target->arch) == 32) {
    1999                 :          0 :                 args.append("-DDEF_ARM32");
    2000                 :            :             } else {
    2001                 :          0 :                 args.append("-DDEF_ARM64");
    2002                 :            :             }
    2003         [ #  # ]:          0 :         } else if (parent->zig_target->arch == ZigLLVM_x86) {
    2004                 :          0 :             args.append("-DDEF_I386");
    2005         [ #  # ]:          0 :         } else if (parent->zig_target->arch == ZigLLVM_x86_64) {
    2006                 :          0 :             args.append("-DDEF_X64");
    2007                 :            :         } else {
    2008                 :          0 :             zig_unreachable();
    2009                 :            :         }
    2010                 :          0 :         args.append("-E");
    2011                 :          0 :         args.append("-o");
    2012                 :          0 :         args.append(buf_ptr(def_final_path));
    2013                 :            : 
    2014         [ #  # ]:          0 :         if (parent->verbose_cc) {
    2015                 :          0 :             print_zig_cc_cmd(&args);
    2016                 :            :         }
    2017                 :            :         Termination term;
    2018                 :          0 :         os_spawn_process(args, &term);
    2019 [ #  # ][ #  # ]:          0 :         if (term.how != TerminationIdClean || term.code != 0) {
    2020                 :          0 :             fprintf(stderr, "\nThe following command failed:\n");
    2021                 :          0 :             print_zig_cc_cmd(&args);
    2022                 :          0 :             exit(1);
    2023                 :            :         }
    2024                 :            : 
    2025                 :          0 :         lib_final_path = buf_alloc();
    2026                 :          0 :         os_path_join(artifact_dir, final_lib_basename, lib_final_path);
    2027                 :            : 
    2028                 :          0 :         args.resize(0);
    2029                 :          0 :         args.append("link");
    2030                 :          0 :         coff_append_machine_arg(parent, &args);
    2031                 :            : 
    2032                 :          0 :         args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_final_path))));
    2033                 :          0 :         args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(lib_final_path))));
    2034                 :            : 
    2035                 :          0 :         Buf diag = BUF_INIT;
    2036                 :          0 :         ZigLLVM_ObjectFormatType target_ofmt = target_object_format(parent->zig_target);
    2037         [ #  # ]:          0 :         if (!zig_lld_link(target_ofmt, args.items, args.length, &diag)) {
    2038                 :          0 :             fprintf(stderr, "%s\n", buf_ptr(&diag));
    2039                 :          0 :             exit(1);
    2040                 :            :         }
    2041                 :            :     } else {
    2042                 :            :         // cache hit
    2043                 :          0 :         artifact_dir = buf_alloc();
    2044                 :          0 :         os_path_join(o_dir, &digest, artifact_dir);
    2045                 :          0 :         lib_final_path = buf_alloc();
    2046                 :          0 :         os_path_join(artifact_dir, final_lib_basename, lib_final_path);
    2047                 :            :     }
    2048                 :          0 :     parent->caches_to_release.append(cache_hash);
    2049                 :            : 
    2050                 :          0 :     return buf_ptr(lib_final_path);
    2051                 :            : }
    2052                 :            : 
    2053                 :          0 : static bool is_linking_system_lib(CodeGen *g, const char *name) {
    2054         [ #  # ]:          0 :     for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
    2055                 :          0 :         LinkLib *link_lib = g->link_libs_list.at(lib_i);
    2056         [ #  # ]:          0 :         if (buf_eql_str(link_lib->name, name)) {
    2057                 :          0 :             return true;
    2058                 :            :         }
    2059                 :            :     }
    2060                 :          0 :     return false;
    2061                 :            : }
    2062                 :            : 
    2063                 :          0 : static void add_mingw_link_args(LinkJob *lj, bool is_library) {
    2064                 :          0 :     CodeGen *g = lj->codegen;
    2065                 :            : 
    2066                 :          0 :     lj->args.append("-lldmingw");
    2067                 :            : 
    2068 [ #  # ][ #  # ]:          0 :     bool is_dll = g->out_type == OutTypeLib && g->is_dynamic;
    2069                 :            : 
    2070         [ #  # ]:          0 :     if (g->zig_target->arch == ZigLLVM_x86) {
    2071                 :          0 :         lj->args.append("-ALTERNATENAME:__image_base__=___ImageBase");
    2072                 :            :     } else {
    2073                 :          0 :         lj->args.append("-ALTERNATENAME:__image_base__=__ImageBase");
    2074                 :            :     }
    2075                 :            : 
    2076         [ #  # ]:          0 :     if (is_dll) {
    2077                 :          0 :         lj->args.append(get_libc_crt_file(g, "dllcrt2.o"));
    2078                 :            :     } else {
    2079                 :          0 :         lj->args.append(get_libc_crt_file(g, "crt2.o"));
    2080                 :            :     }
    2081                 :            : 
    2082                 :          0 :     lj->args.append(get_libc_crt_file(g, "mingw32.lib"));
    2083                 :          0 :     lj->args.append(get_libc_crt_file(g, "mingwex.lib"));
    2084                 :          0 :     lj->args.append(get_libc_crt_file(g, "msvcrt-os.lib"));
    2085                 :            : 
    2086         [ #  # ]:          0 :     for (size_t def_i = 0; def_i < array_length(mingw_def_list); def_i += 1) {
    2087                 :          0 :         const char *name = mingw_def_list[def_i].name;
    2088                 :          0 :         Buf *path = buf_create_from_str(mingw_def_list[def_i].path);
    2089                 :          0 :         bool always_link = mingw_def_list[def_i].always_link;
    2090                 :          0 :         bool is_this_arch = false;
    2091         [ #  # ]:          0 :         if (buf_starts_with_str(path, "lib-common" OS_SEP)) {
    2092                 :          0 :             is_this_arch = true;
    2093         [ #  # ]:          0 :         } else if (target_is_arm(g->zig_target)) {
    2094         [ #  # ]:          0 :             if (target_arch_pointer_bit_width(g->zig_target->arch) == 32) {
    2095                 :          0 :                 is_this_arch = buf_starts_with_str(path, "libarm32" OS_SEP);
    2096                 :            :             } else {
    2097                 :          0 :                 is_this_arch = buf_starts_with_str(path, "libarm64" OS_SEP);
    2098                 :            :             }
    2099         [ #  # ]:          0 :         } else if (g->zig_target->arch == ZigLLVM_x86) {
    2100                 :          0 :             is_this_arch = buf_starts_with_str(path, "lib32" OS_SEP);
    2101         [ #  # ]:          0 :         } else if (g->zig_target->arch == ZigLLVM_x86_64) {
    2102                 :          0 :             is_this_arch = buf_starts_with_str(path, "lib64" OS_SEP);
    2103                 :            :         }
    2104 [ #  # ][ #  # ]:          0 :         if (is_this_arch && (always_link || is_linking_system_lib(g, name))) {
         [ #  # ][ #  # ]
    2105                 :          0 :             lj->args.append(get_def_lib(g, name, path));
    2106                 :            :         }
    2107                 :            :     }
    2108                 :          0 : }
    2109                 :            : 
    2110                 :          2 : static void add_win_link_args(LinkJob *lj, bool is_library, bool *have_windows_dll_import_libs) {
    2111         [ -  + ]:          2 :     if (lj->link_in_crt) {
    2112         [ #  # ]:          0 :         if (target_abi_is_gnu(lj->codegen->zig_target->abi)) {
    2113                 :          0 :             *have_windows_dll_import_libs = true;
    2114                 :          0 :             add_mingw_link_args(lj, is_library);
    2115                 :            :         } else {
    2116                 :          0 :             add_msvc_link_args(lj, is_library);
    2117                 :            :         }
    2118                 :            :     } else {
    2119                 :          2 :         lj->args.append("-NODEFAULTLIB");
    2120         [ +  - ]:          2 :         if (!is_library) {
    2121         [ -  + ]:          2 :             if (lj->codegen->have_winmain) {
    2122                 :          0 :                 lj->args.append("-ENTRY:WinMain");
    2123                 :            :             } else {
    2124                 :          2 :                 lj->args.append("-ENTRY:WinMainCRTStartup");
    2125                 :            :             }
    2126                 :            :         }
    2127                 :            :     }
    2128                 :          2 : }
    2129                 :            : 
    2130                 :          4 : static bool is_mingw_link_lib(Buf *name) {
    2131         [ +  - ]:         62 :     for (size_t def_i = 0; def_i < array_length(mingw_def_list); def_i += 1) {
    2132         [ +  + ]:         62 :         if (buf_eql_str_ignore_case(name, mingw_def_list[def_i].name)) {
    2133                 :          4 :             return true;
    2134                 :            :         }
    2135                 :            :     }
    2136                 :          0 :     return false;
    2137                 :            : }
    2138                 :          2 : static void construct_linker_job_coff(LinkJob *lj) {
    2139                 :            :     Error err;
    2140                 :          2 :     CodeGen *g = lj->codegen;
    2141                 :            : 
    2142                 :          2 :     lj->args.append("-ERRORLIMIT:0");
    2143                 :            : 
    2144                 :          2 :     lj->args.append("-NOLOGO");
    2145                 :            : 
    2146         [ +  - ]:          2 :     if (!g->strip_debug_symbols) {
    2147                 :          2 :         lj->args.append("-DEBUG");
    2148                 :            :     }
    2149                 :            : 
    2150         [ +  - ]:          2 :     if (g->out_type == OutTypeExe) {
    2151                 :            :         // TODO compile time stack upper bound detection
    2152                 :          2 :         lj->args.append("-STACK:16777216");
    2153                 :            :     }
    2154                 :            : 
    2155                 :          2 :     coff_append_machine_arg(g, &lj->args);
    2156                 :            : 
    2157                 :          2 :     bool is_library = g->out_type == OutTypeLib;
    2158 [ #  # ][ -  + ]:          2 :     if (is_library && g->is_dynamic) {
    2159                 :          0 :         lj->args.append("-DLL");
    2160                 :            :     }
    2161                 :            : 
    2162                 :          2 :     lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
    2163                 :            : 
    2164 [ #  # ][ -  + ]:          2 :     if (g->libc_link_lib != nullptr && g->libc != nullptr) {
    2165                 :          0 :         lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir))));
    2166                 :            : 
    2167         [ #  # ]:          0 :         if (target_abi_is_gnu(g->zig_target->abi)) {
    2168                 :          0 :             lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->sys_include_dir))));
    2169                 :          0 :             lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->include_dir))));
    2170                 :            :         } else {
    2171                 :          0 :             lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));
    2172                 :          0 :             lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));
    2173                 :            :         }
    2174                 :            :     }
    2175                 :            : 
    2176         [ -  + ]:          2 :     for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
    2177                 :          0 :         const char *lib_dir = g->lib_dirs.at(i);
    2178                 :          0 :         lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));
    2179                 :            :     }
    2180                 :            : 
    2181         [ +  + ]:          4 :     for (size_t i = 0; i < g->link_objects.length; i += 1) {
    2182                 :          2 :         lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
    2183                 :            :     }
    2184                 :            : 
    2185                 :          2 :     bool have_windows_dll_import_libs = false;
    2186   [ -  +  -  -  :          2 :     switch (detect_subsystem(g)) {
          -  -  -  -  -  
                      - ]
    2187                 :          0 :         case TargetSubsystemAuto:
    2188         [ #  # ]:          0 :             if (g->zig_target->os == OsUefi) {
    2189                 :          0 :                 add_uefi_link_args(lj);
    2190                 :            :             } else {
    2191                 :          0 :                 add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
    2192                 :            :             }
    2193                 :          0 :             break;
    2194                 :          2 :         case TargetSubsystemConsole:
    2195                 :          2 :             lj->args.append("-SUBSYSTEM:console");
    2196                 :          2 :             add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
    2197                 :          2 :             break;
    2198                 :          0 :         case TargetSubsystemEfiApplication:
    2199                 :          0 :             lj->args.append("-SUBSYSTEM:efi_application");
    2200                 :          0 :             add_uefi_link_args(lj);
    2201                 :          0 :             break;
    2202                 :          0 :         case TargetSubsystemEfiBootServiceDriver:
    2203                 :          0 :             lj->args.append("-SUBSYSTEM:efi_boot_service_driver");
    2204                 :          0 :             add_uefi_link_args(lj);
    2205                 :          0 :             break;
    2206                 :          0 :         case TargetSubsystemEfiRom:
    2207                 :          0 :             lj->args.append("-SUBSYSTEM:efi_rom");
    2208                 :          0 :             add_uefi_link_args(lj);
    2209                 :          0 :             break;
    2210                 :          0 :         case TargetSubsystemEfiRuntimeDriver:
    2211                 :          0 :             lj->args.append("-SUBSYSTEM:efi_runtime_driver");
    2212                 :          0 :             add_uefi_link_args(lj);
    2213                 :          0 :             break;
    2214                 :          0 :         case TargetSubsystemNative:
    2215                 :          0 :             lj->args.append("-SUBSYSTEM:native");
    2216                 :          0 :             add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
    2217                 :          0 :             break;
    2218                 :          0 :         case TargetSubsystemPosix:
    2219                 :          0 :             lj->args.append("-SUBSYSTEM:posix");
    2220                 :          0 :             add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
    2221                 :          0 :             break;
    2222                 :          0 :         case TargetSubsystemWindows:
    2223                 :          0 :             lj->args.append("-SUBSYSTEM:windows");
    2224                 :          0 :             add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
    2225                 :          0 :             break;
    2226                 :            :     }
    2227                 :            : 
    2228 [ -  + ][ #  # ]:          2 :     if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {
                 [ #  # ]
    2229 [ +  - ][ +  - ]:          2 :         if (g->libc_link_lib == nullptr && !g->is_dummy_so) {
    2230                 :          2 :             Buf *libc_a_path = build_c(g, OutTypeLib);
    2231                 :          2 :             lj->args.append(buf_ptr(libc_a_path));
    2232                 :            :         }
    2233                 :            : 
    2234                 :            :         // msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage
    2235                 :          2 :         Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
    2236                 :          2 :         lj->args.append(buf_ptr(compiler_rt_o_path));
    2237                 :            :     }
    2238                 :            : 
    2239                 :          2 :     Buf *def_contents = buf_alloc();
    2240                 :          2 :     ZigList<const char *> gen_lib_args = {0};
    2241         [ +  + ]:          6 :     for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
    2242                 :          4 :         LinkLib *link_lib = g->link_libs_list.at(lib_i);
    2243         [ -  + ]:          4 :         if (buf_eql_str(link_lib->name, "c")) {
    2244                 :          0 :             continue;
    2245                 :            :         }
    2246                 :          4 :         bool is_sys_lib = is_mingw_link_lib(link_lib->name);
    2247 [ #  # ][ -  + ]:          4 :         if (have_windows_dll_import_libs && is_sys_lib) {
    2248                 :          0 :             continue;
    2249                 :            :         }
    2250                 :            :         // If we're linking in the CRT or the libs are provided explictly we don't want to generate def/libs
    2251 [ -  + ][ #  # ]:          4 :         if ((lj->link_in_crt && is_sys_lib) || link_lib->provided_explicitly) {
                 [ -  + ]
    2252         [ #  # ]:          0 :             if (target_abi_is_gnu(lj->codegen->zig_target->abi)) {
    2253                 :          0 :                 Buf* lib_name = buf_sprintf("lib%s.a", buf_ptr(link_lib->name));
    2254                 :          0 :                 lj->args.append(buf_ptr(lib_name));
    2255                 :            :             }
    2256                 :            :             else {
    2257                 :          0 :                 Buf* lib_name = buf_sprintf("%s.lib", buf_ptr(link_lib->name));
    2258                 :          0 :                 lj->args.append(buf_ptr(lib_name));
    2259                 :            :             }
    2260                 :          0 :             continue;
    2261                 :            :         }
    2262                 :            : 
    2263                 :          4 :         buf_resize(def_contents, 0);
    2264                 :          4 :         buf_appendf(def_contents, "LIBRARY %s\nEXPORTS\n", buf_ptr(link_lib->name));
    2265         [ +  + ]:         54 :         for (size_t exp_i = 0; exp_i < link_lib->symbols.length; exp_i += 1) {
    2266                 :         50 :             Buf *symbol_name = link_lib->symbols.at(exp_i);
    2267                 :         50 :             buf_appendf(def_contents, "%s\n", buf_ptr(symbol_name));
    2268                 :            :         }
    2269                 :          4 :         buf_appendf(def_contents, "\n");
    2270                 :            : 
    2271                 :          4 :         Buf *def_path = buf_alloc();
    2272                 :          4 :         os_path_join(g->output_dir, buf_sprintf("%s.def", buf_ptr(link_lib->name)), def_path);
    2273         [ -  + ]:          4 :         if ((err = os_write_file(def_path, def_contents))) {
    2274                 :          0 :             zig_panic("error writing def file: %s", err_str(err));
    2275                 :            :         }
    2276                 :            : 
    2277                 :          4 :         Buf *generated_lib_path = buf_alloc();
    2278                 :          4 :         os_path_join(g->output_dir, buf_sprintf("%s.lib", buf_ptr(link_lib->name)), generated_lib_path);
    2279                 :            : 
    2280                 :          4 :         gen_lib_args.resize(0);
    2281                 :          4 :         gen_lib_args.append("link");
    2282                 :            : 
    2283                 :          4 :         coff_append_machine_arg(g, &gen_lib_args);
    2284                 :          4 :         gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
    2285                 :          4 :         gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path))));
    2286                 :          4 :         Buf diag = BUF_INIT;
    2287                 :          4 :         ZigLLVM_ObjectFormatType target_ofmt = target_object_format(g->zig_target);
    2288         [ -  + ]:          4 :         if (!zig_lld_link(target_ofmt, gen_lib_args.items, gen_lib_args.length, &diag)) {
    2289                 :          0 :             fprintf(stderr, "%s\n", buf_ptr(&diag));
    2290                 :          0 :             exit(1);
    2291                 :            :         }
    2292                 :          4 :         lj->args.append(buf_ptr(generated_lib_path));
    2293                 :            :     }
    2294                 :          2 : }
    2295                 :            : 
    2296                 :            : 
    2297                 :            : // Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the
    2298                 :            : // grouped values as integers. Numbers which are not provided are set to 0.
    2299                 :            : // return true if the entire string was parsed (9.2), or all groups were
    2300                 :            : // parsed (10.3.5extrastuff).
    2301                 :          2 : static bool darwin_get_release_version(const char *str, int *major, int *minor, int *micro, bool *had_extra) {
    2302                 :          2 :     *had_extra = false;
    2303                 :            : 
    2304                 :          2 :     *major = 0;
    2305                 :          2 :     *minor = 0;
    2306                 :          2 :     *micro = 0;
    2307                 :            : 
    2308         [ -  + ]:          2 :     if (*str == '\0')
    2309                 :          0 :         return false;
    2310                 :            : 
    2311                 :            :     char *end;
    2312                 :          2 :     *major = (int)strtol(str, &end, 10);
    2313 [ -  + ][ +  - ]:          2 :     if (*str != '\0' && *end == '\0')
    2314                 :          0 :         return true;
    2315         [ -  + ]:          2 :     if (*end != '.')
    2316                 :          0 :         return false;
    2317                 :            : 
    2318                 :          2 :     str = end + 1;
    2319                 :          2 :     *minor = (int)strtol(str, &end, 10);
    2320 [ +  - ][ +  - ]:          2 :     if (*str != '\0' && *end == '\0')
    2321                 :          2 :         return true;
    2322         [ #  # ]:          0 :     if (*end != '.')
    2323                 :          0 :         return false;
    2324                 :            : 
    2325                 :          0 :     str = end + 1;
    2326                 :          0 :     *micro = (int)strtol(str, &end, 10);
    2327 [ #  # ][ #  # ]:          0 :     if (*str != '\0' && *end == '\0')
    2328                 :          0 :         return true;
    2329         [ #  # ]:          0 :     if (str == end)
    2330                 :          0 :         return false;
    2331                 :          0 :     *had_extra = true;
    2332                 :          2 :     return true;
    2333                 :            : }
    2334                 :            : 
    2335                 :            : enum DarwinPlatformKind {
    2336                 :            :     MacOS,
    2337                 :            :     IPhoneOS,
    2338                 :            :     IPhoneOSSimulator,
    2339                 :            : };
    2340                 :            : 
    2341                 :            : struct DarwinPlatform {
    2342                 :            :     DarwinPlatformKind kind;
    2343                 :            :     int major;
    2344                 :            :     int minor;
    2345                 :            :     int micro;
    2346                 :            : };
    2347                 :            : 
    2348                 :          2 : static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
    2349                 :          2 :     CodeGen *g = lj->codegen;
    2350                 :            : 
    2351         [ -  + ]:          2 :     if (g->mmacosx_version_min) {
    2352                 :          0 :         platform->kind = MacOS;
    2353         [ -  + ]:          2 :     } else if (g->mios_version_min) {
    2354                 :          0 :         platform->kind = IPhoneOS;
    2355         [ +  - ]:          2 :     } else if (g->zig_target->os == OsMacOSX) {
    2356                 :          2 :         platform->kind = MacOS;
    2357                 :          2 :         g->mmacosx_version_min = buf_create_from_str("10.14");
    2358                 :            :     } else {
    2359                 :          0 :         zig_panic("unable to infer -mmacosx-version-min or -mios-version-min");
    2360                 :            :     }
    2361                 :            : 
    2362                 :            :     bool had_extra;
    2363         [ +  - ]:          2 :     if (platform->kind == MacOS) {
    2364         [ -  + ]:          4 :         if (!darwin_get_release_version(buf_ptr(g->mmacosx_version_min),
    2365         [ +  - ]:          2 :                     &platform->major, &platform->minor, &platform->micro, &had_extra) ||
    2366 [ +  - ][ +  - ]:          4 :                 had_extra || platform->major != 10 || platform->minor >= 100 || platform->micro >= 100)
         [ -  + ][ +  - ]
    2367                 :            :         {
    2368                 :          0 :             zig_panic("invalid -mmacosx-version-min");
    2369                 :            :         }
    2370         [ #  # ]:          0 :     } else if (platform->kind == IPhoneOS) {
    2371         [ #  # ]:          0 :         if (!darwin_get_release_version(buf_ptr(g->mios_version_min),
    2372         [ #  # ]:          0 :                     &platform->major, &platform->minor, &platform->micro, &had_extra) ||
    2373 [ #  # ][ #  # ]:          0 :                 had_extra || platform->major >= 10 || platform->minor >= 100 || platform->micro >= 100)
         [ #  # ][ #  # ]
    2374                 :            :         {
    2375                 :          0 :             zig_panic("invalid -mios-version-min");
    2376                 :            :         }
    2377                 :            :     } else {
    2378                 :          0 :         zig_unreachable();
    2379                 :            :     }
    2380                 :            : 
    2381 [ -  + ][ #  # ]:          2 :     if (platform->kind == IPhoneOS &&
    2382         [ #  # ]:          0 :         (g->zig_target->arch == ZigLLVM_x86 ||
    2383                 :          0 :          g->zig_target->arch == ZigLLVM_x86_64))
    2384                 :            :     {
    2385                 :          0 :         platform->kind = IPhoneOSSimulator;
    2386                 :            :     }
    2387                 :          2 : }
    2388                 :            : 
    2389                 :          2 : static void construct_linker_job_macho(LinkJob *lj) {
    2390                 :          2 :     CodeGen *g = lj->codegen;
    2391                 :            : 
    2392                 :            :     // LLD MACH-O has no error limit option.
    2393                 :            :     //lj->args.append("-error-limit=0");
    2394                 :          2 :     lj->args.append("-demangle");
    2395                 :            : 
    2396         [ -  + ]:          2 :     if (g->linker_rdynamic) {
    2397                 :          0 :         lj->args.append("-export_dynamic");
    2398                 :            :     }
    2399                 :            : 
    2400                 :          2 :     bool is_lib = g->out_type == OutTypeLib;
    2401 [ -  + ][ #  # ]:          2 :     bool is_dyn_lib = g->is_dynamic && is_lib;
    2402 [ -  + ][ #  # ]:          2 :     if (is_lib && !g->is_dynamic) {
    2403                 :          0 :         lj->args.append("-static");
    2404                 :            :     } else {
    2405                 :          2 :         lj->args.append("-dynamic");
    2406                 :            :     }
    2407                 :            : 
    2408         [ -  + ]:          2 :     if (is_dyn_lib) {
    2409                 :          0 :         lj->args.append("-dylib");
    2410                 :            : 
    2411                 :          0 :         Buf *compat_vers = buf_sprintf("%" ZIG_PRI_usize ".0.0", g->version_major);
    2412                 :          0 :         lj->args.append("-compatibility_version");
    2413                 :          0 :         lj->args.append(buf_ptr(compat_vers));
    2414                 :            : 
    2415                 :          0 :         Buf *cur_vers = buf_sprintf("%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize,
    2416                 :          0 :             g->version_major, g->version_minor, g->version_patch);
    2417                 :          0 :         lj->args.append("-current_version");
    2418                 :          0 :         lj->args.append(buf_ptr(cur_vers));
    2419                 :            : 
    2420                 :            :         // TODO getting an error when running an executable when doing this rpath thing
    2421                 :            :         //Buf *dylib_install_name = buf_sprintf("@rpath/lib%s.%" ZIG_PRI_usize ".dylib",
    2422                 :            :         //    buf_ptr(g->root_out_name), g->version_major);
    2423                 :            :         //lj->args.append("-install_name");
    2424                 :            :         //lj->args.append(buf_ptr(dylib_install_name));
    2425                 :            : 
    2426                 :          0 :         assert(buf_len(&g->output_file_path) != 0);
    2427                 :            :     }
    2428                 :            : 
    2429                 :          2 :     lj->args.append("-arch");
    2430                 :          2 :     lj->args.append(get_darwin_arch_string(g->zig_target));
    2431                 :            : 
    2432                 :            :     DarwinPlatform platform;
    2433                 :          2 :     get_darwin_platform(lj, &platform);
    2434   [ +  -  -  - ]:          2 :     switch (platform.kind) {
    2435                 :          2 :         case MacOS:
    2436                 :          2 :             lj->args.append("-macosx_version_min");
    2437                 :          2 :             break;
    2438                 :          0 :         case IPhoneOS:
    2439                 :          0 :             lj->args.append("-iphoneos_version_min");
    2440                 :          0 :             break;
    2441                 :          0 :         case IPhoneOSSimulator:
    2442                 :          0 :             lj->args.append("-ios_simulator_version_min");
    2443                 :          0 :             break;
    2444                 :            :     }
    2445                 :          2 :     Buf *version_string = buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro);
    2446                 :          2 :     lj->args.append(buf_ptr(version_string));
    2447                 :            : 
    2448                 :          2 :     lj->args.append("-sdk_version");
    2449                 :          2 :     lj->args.append(buf_ptr(version_string));
    2450                 :            : 
    2451                 :            : 
    2452         [ +  - ]:          2 :     if (g->out_type == OutTypeExe) {
    2453                 :          2 :         lj->args.append("-pie");
    2454                 :            :     }
    2455                 :            : 
    2456                 :          2 :     lj->args.append("-o");
    2457                 :          2 :     lj->args.append(buf_ptr(&g->output_file_path));
    2458                 :            : 
    2459         [ -  + ]:          2 :     for (size_t i = 0; i < g->rpath_list.length; i += 1) {
    2460                 :          0 :         Buf *rpath = g->rpath_list.at(i);
    2461                 :          0 :         add_rpath(lj, rpath);
    2462                 :            :     }
    2463         [ -  + ]:          2 :     if (is_dyn_lib) {
    2464                 :          0 :         add_rpath(lj, &g->output_file_path);
    2465                 :            :     }
    2466                 :            : 
    2467         [ -  + ]:          2 :     if (is_dyn_lib) {
    2468         [ #  # ]:          0 :         if (g->system_linker_hack) {
    2469                 :          0 :             lj->args.append("-headerpad_max_install_names");
    2470                 :            :         }
    2471                 :            :     }
    2472                 :            : 
    2473         [ -  + ]:          2 :     for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
    2474                 :          0 :         const char *lib_dir = g->lib_dirs.at(i);
    2475                 :          0 :         lj->args.append("-L");
    2476                 :          0 :         lj->args.append(lib_dir);
    2477                 :            :     }
    2478                 :            : 
    2479         [ +  + ]:          4 :     for (size_t i = 0; i < g->link_objects.length; i += 1) {
    2480                 :          2 :         lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
    2481                 :            :     }
    2482                 :            : 
    2483                 :            :     // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce
    2484 [ -  + ][ #  # ]:          2 :     if (g->out_type == OutTypeExe || is_dyn_lib) {
    2485                 :          2 :         Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
    2486                 :          2 :         lj->args.append(buf_ptr(compiler_rt_o_path));
    2487                 :            :     }
    2488                 :            : 
    2489         [ -  + ]:          2 :     if (g->zig_target->is_native) {
    2490         [ #  # ]:          0 :         for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
    2491                 :          0 :             LinkLib *link_lib = g->link_libs_list.at(lib_i);
    2492         [ #  # ]:          0 :             if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) {
    2493                 :            :                 // handled by libSystem
    2494                 :          0 :                 continue;
    2495                 :            :             }
    2496         [ #  # ]:          0 :             if (strchr(buf_ptr(link_lib->name), '/') == nullptr) {
    2497                 :          0 :                 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
    2498                 :          0 :                 lj->args.append(buf_ptr(arg));
    2499                 :            :             } else {
    2500                 :          0 :                 lj->args.append(buf_ptr(link_lib->name));
    2501                 :            :             }
    2502                 :            :         }
    2503                 :            :         // on Darwin, libSystem has libc in it, but also you have to use it
    2504                 :            :         // to make syscalls because the syscall numbers are not documented
    2505                 :            :         // and change between versions.
    2506                 :            :         // so we always link against libSystem
    2507                 :          0 :         lj->args.append("-lSystem");
    2508                 :            :     } else {
    2509                 :          2 :         lj->args.append("-undefined");
    2510                 :          2 :         lj->args.append("dynamic_lookup");
    2511                 :            :     }
    2512                 :            : 
    2513         [ -  + ]:          2 :     for (size_t i = 0; i < g->framework_dirs.length; i += 1) {
    2514                 :          0 :         const char *framework_dir = g->framework_dirs.at(i);
    2515                 :          0 :         lj->args.append("-F");
    2516                 :          0 :         lj->args.append(framework_dir);
    2517                 :            :     }
    2518                 :            : 
    2519         [ -  + ]:          2 :     for (size_t i = 0; i < g->darwin_frameworks.length; i += 1) {
    2520                 :          0 :         lj->args.append("-framework");
    2521                 :          0 :         lj->args.append(buf_ptr(g->darwin_frameworks.at(i)));
    2522                 :            :     }
    2523                 :            : 
    2524                 :          2 : }
    2525                 :            : 
    2526                 :         15 : static void construct_linker_job(LinkJob *lj) {
    2527   [ -  +  +  +  :         15 :     switch (target_object_format(lj->codegen->zig_target)) {
                   -  - ]
    2528                 :          0 :         case ZigLLVM_UnknownObjectFormat:
    2529                 :          0 :             zig_unreachable();
    2530                 :            : 
    2531                 :          2 :         case ZigLLVM_COFF:
    2532                 :          2 :             return construct_linker_job_coff(lj);
    2533                 :         11 :         case ZigLLVM_ELF:
    2534                 :         11 :             return construct_linker_job_elf(lj);
    2535                 :          2 :         case ZigLLVM_MachO:
    2536                 :          2 :             return construct_linker_job_macho(lj);
    2537                 :          0 :         case ZigLLVM_Wasm:
    2538                 :          0 :             return construct_linker_job_wasm(lj);
    2539                 :            :     }
    2540                 :            : }
    2541                 :            : 
    2542                 :          0 : void zig_link_add_compiler_rt(CodeGen *g) {
    2543                 :          0 :     Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj);
    2544                 :          0 :     g->link_objects.append(compiler_rt_o_path);
    2545                 :          0 : }
    2546                 :            : 
    2547                 :         24 : void codegen_link(CodeGen *g) {
    2548                 :         24 :     codegen_add_time_event(g, "Build Dependencies");
    2549                 :            : 
    2550                 :         24 :     LinkJob lj = {0};
    2551                 :            : 
    2552                 :            :     // even though we're calling LLD as a library it thinks the first
    2553                 :            :     // argument is its own exe name
    2554                 :         24 :     lj.args.append("lld");
    2555                 :            : 
    2556                 :         24 :     lj.rpath_table.init(4);
    2557                 :         24 :     lj.codegen = g;
    2558                 :            : 
    2559         [ -  + ]:         24 :     if (g->verbose_llvm_ir) {
    2560                 :          0 :         fprintf(stderr, "\nOptimization:\n");
    2561                 :          0 :         fprintf(stderr, "---------------\n");
    2562                 :          0 :         fflush(stderr);
    2563                 :          0 :         LLVMDumpModule(g->module);
    2564                 :            :     }
    2565                 :            : 
    2566         [ +  + ]:         24 :     if (g->out_type == OutTypeObj) {
    2567                 :          1 :         lj.args.append("-r");
    2568                 :            :     }
    2569                 :            : 
    2570 [ +  + ][ +  + ]:         24 :     if (g->out_type == OutTypeLib && !g->is_dynamic && !target_is_wasm(g->zig_target)) {
         [ +  - ][ +  + ]
    2571                 :          9 :         ZigList<const char *> file_names = {};
    2572         [ +  + ]:         46 :         for (size_t i = 0; i < g->link_objects.length; i += 1) {
    2573                 :         37 :             file_names.append(buf_ptr(g->link_objects.at(i)));
    2574                 :            :         }
    2575                 :          9 :         ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os);
    2576                 :          9 :         codegen_add_time_event(g, "LLVM Link");
    2577         [ -  + ]:          9 :         if (g->verbose_link) {
    2578                 :          0 :             fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));
    2579         [ #  # ]:          0 :             for (size_t i = 0; i < file_names.length; i += 1) {
    2580                 :          0 :                 fprintf(stderr, " %s", file_names.at(i));
    2581                 :            :             }
    2582                 :          0 :             fprintf(stderr, "\n");
    2583                 :            :         }
    2584         [ -  + ]:          9 :         if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {
    2585                 :          0 :             fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));
    2586                 :          0 :             exit(1);
    2587                 :            :         }
    2588                 :          9 :         return;
    2589                 :            :     }
    2590                 :            : 
    2591 [ +  + ][ +  - ]:         15 :     lj.link_in_crt = (g->libc_link_lib != nullptr && g->out_type == OutTypeExe);
    2592                 :            : 
    2593                 :         15 :     construct_linker_job(&lj);
    2594                 :            : 
    2595                 :            : 
    2596         [ -  + ]:         15 :     if (g->verbose_link) {
    2597         [ #  # ]:          0 :         for (size_t i = 0; i < lj.args.length; i += 1) {
    2598         [ #  # ]:          0 :             const char *space = (i != 0) ? " " : "";
    2599                 :          0 :             fprintf(stderr, "%s%s", space, lj.args.at(i));
    2600                 :            :         }
    2601                 :          0 :         fprintf(stderr, "\n");
    2602                 :            :     }
    2603                 :            : 
    2604                 :         15 :     Buf diag = BUF_INIT;
    2605                 :            : 
    2606                 :         15 :     codegen_add_time_event(g, "LLVM Link");
    2607 [ #  # ][ -  + ]:         15 :     if (g->system_linker_hack && g->zig_target->os == OsMacOSX) {
    2608                 :            :         Termination term;
    2609                 :          0 :         ZigList<const char *> args = {};
    2610                 :          0 :         args.append("ld");
    2611         [ #  # ]:          0 :         for (size_t i = 1; i < lj.args.length; i += 1) {
    2612                 :          0 :             args.append(lj.args.at(i));
    2613                 :            :         }
    2614                 :          0 :         os_spawn_process(args, &term);
    2615 [ #  # ][ #  # ]:          0 :         if (term.how != TerminationIdClean || term.code != 0) {
    2616                 :          0 :             exit(1);
    2617                 :          0 :         }
    2618         [ -  + ]:         15 :     } else if (!zig_lld_link(target_object_format(g->zig_target), lj.args.items, lj.args.length, &diag)) {
    2619                 :          0 :         fprintf(stderr, "%s\n", buf_ptr(&diag));
    2620                 :         15 :         exit(1);
    2621                 :            :     }
    2622                 :            : }
    2623                 :            : 

Generated by: LCOV version 1.14