From fdea12b2d9deaea6a90c7b1451df425e84b98099 Mon Sep 17 00:00:00 2001 From: nebulaeonline Date: Sun, 23 Dec 2018 22:44:02 -0500 Subject: msvc subsystem option handling; added uefi os type --- src/link.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 20 deletions(-) (limited to 'src/link.cpp') diff --git a/src/link.cpp b/src/link.cpp index 188f976a86..52ca2f2cd9 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -455,7 +455,7 @@ static void construct_linker_job_coff(LinkJob *lj) { lj->args.append("-NOLOGO"); - if (!g->strip_debug_symbols) { + if (!g->strip_debug_symbols && g->zig_target.os != Os::OsUefi) { lj->args.append("-DEBUG"); } @@ -466,11 +466,6 @@ static void construct_linker_job_coff(LinkJob *lj) { coff_append_machine_arg(g, &lj->args); - if (g->windows_subsystem_windows) { - lj->args.append("/SUBSYSTEM:windows"); - } else if (g->windows_subsystem_console) { - lj->args.append("/SUBSYSTEM:console"); - } // The commented out stuff is from when we linked with MinGW // Now that we're linking with LLD it remains to be determined // how to handle --target-environ gnu @@ -499,18 +494,47 @@ static void construct_linker_job_coff(LinkJob *lj) { // } //} - lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); - - if (g->libc_link_lib != nullptr) { - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir)))); - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir)))); - - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir)))); - if (g->libc_static_lib_dir != nullptr) { - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); - } - } + // These are n actual command lines from LINK.EXE UEFI builds (app & driver) to be used as guidance cleaning + // up a bit for building the COFF linker args: + // /OUT:"J:\coding\nebulae\k\x64\Release\k.efi" /LTCG:incremental /Driver /PDB:"J:\coding\nebulae\k\x64\Release\k.pdb" "UefiApplicationEntryPoint.lib" "UefiRuntimeLib.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\nebulae\k\x64\Release\k.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_APPLICATION /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" + // /OUT:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.efi" /LTCG:incremental /Driver /PDB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.pdb" "UefiDriverEntryPoint.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" + + // Sorry for the goto(s) :) + switch (g->msvc_subsystem) { + case ZigLLVM_MSVC_CONSOLE: + lj->args.append("/SUBSYSTEM:console"); + goto building_nt; + case ZigLLVM_MSVC_EFI_APPLICATION: + lj->args.append("/SUBSYSTEM:efi_application"); + goto building_uefi; + case ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER: + lj->args.append("/SUBSYSTEM:efi_boot_service_driver"); + goto building_uefi; + case ZigLLVM_MSVC_EFI_ROM: + lj->args.append("/SUBSYSTEM:efi_rom"); + goto building_uefi; + case ZigLLVM_MSVC_EFI_RUNTIME_DRIVER: + lj->args.append("/SUBSYSTEM:efi_runtime_driver"); + goto building_uefi; + case ZigLLVM_MSVC_NATIVE: + lj->args.append("/SUBSYSTEM:native"); + goto building_nt; + case ZigLLVM_MSVC_POSIX: + lj->args.append("/SUBSYSTEM:posix"); + goto building_nt; + case ZigLLVM_MSVC_WINDOWS: + lj->args.append("/SUBSYSTEM:windows"); + goto building_nt; + case ZigLLVM_MSVC_NONE: + goto continuing_build; + } + +building_uefi: + lj->args.append("/BASE:\"0\" /ENTRY:\"EfiMain\" /OPT:REF /SAFESEH:NO /MERGE:\".rdata=.data\" /ALIGN:32 /NODEFAULTLIB /SECTION:\".xdata,D\""); + goto continuing_build; + +building_nt: if (lj->link_in_crt) { const char *lib_str = g->is_static ? "lib" : ""; const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; @@ -547,16 +571,30 @@ static void construct_linker_job_coff(LinkJob *lj) { // msvcrt depends on kernel32 lj->args.append("kernel32.lib"); } else { - lj->args.append("-NODEFAULTLIB"); + lj->args.append("/NODEFAULTLIB"); if (!is_library) { if (g->have_winmain) { - lj->args.append("-ENTRY:WinMain"); + lj->args.append("/ENTRY:WinMain"); } else { - lj->args.append("-ENTRY:WinMainCRTStartup"); + lj->args.append("/ENTRY:WinMainCRTStartup"); } } } +continuing_build: + + lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); + + if (g->libc_link_lib != nullptr) { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir)))); + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir)))); + + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir)))); + if (g->libc_static_lib_dir != nullptr) { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); + } + } + if (is_library && !g->is_static) { lj->args.append("-DLL"); } -- cgit v1.2.3 From a918ce26b81b8e51c061d85631aa432a025c1ee2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 26 Dec 2018 15:25:54 -0500 Subject: fixups --- CMakeLists.txt | 2 +- README.md | 40 +++---- src/all_types.hpp | 2 +- src/analyze.cpp | 8 +- src/codegen.cpp | 6 +- src/ir.cpp | 8 +- src/link.cpp | 310 ++++++++++++++++++++++++++------------------------ src/main.cpp | 78 ++++++------- src/target.cpp | 5 +- src/target.hpp | 13 ++- src/translate_c.cpp | 2 +- src/zig_llvm.cpp | 7 +- src/zig_llvm.h | 18 +-- std/os/index.zig | 5 +- std/os/uefi.zig | 2 + std/os/uefi/index.zig | 0 std/special/panic.zig | 6 +- 17 files changed, 253 insertions(+), 259 deletions(-) create mode 100644 std/os/uefi.zig delete mode 100644 std/os/uefi/index.zig (limited to 'src/link.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b31f96562..807077476a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -590,7 +590,7 @@ set(ZIG_STD_FILES "os/freebsd/x86_64.zig" "os/path.zig" "os/time.zig" - "os/uefi/index.zig" + "os/uefi.zig" "os/windows/advapi32.zig" "os/windows/error.zig" "os/windows/index.zig" diff --git a/README.md b/README.md index c1eec599e5..e9756b404d 100644 --- a/README.md +++ b/README.md @@ -87,26 +87,26 @@ clarity. #### Support Table -| | freestanding | linux | macosx | windows | freebsd | other | -|--------|--------------|--------|--------|---------|---------|--------| -|x86_64 | Tier 2 | Tier 1 | Tier 1 | Tier 1 | Tier 2 | Tier 3 | -|i386 | Tier 2 | Tier 2 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | -|arm | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|arm64 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|hexagon | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|mips | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|powerpc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|r600 | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|amdgcn | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|sparc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|s390x | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|spir | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|lanai | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|wasm32 | Tier 4 | N/A | N/A | N/A | N/A | N/A | -|wasm64 | Tier 4 | N/A | N/A | N/A | N/A | N/A | -|riscv32 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | -|riscv64 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | +| | freestanding | linux | macosx | windows | freebsd | UEFI | other | +|--------|--------------|--------|--------|---------|---------|--------|--------| +|x86_64 | Tier 2 | Tier 1 | Tier 1 | Tier 1 | Tier 2 | Tier 2 | Tier 3 | +|i386 | Tier 2 | Tier 2 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | +|arm | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | +|arm64 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | +|bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|hexagon | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|mips | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|powerpc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|r600 | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|amdgcn | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|sparc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|s390x | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|spir | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|lanai | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|wasm32 | Tier 4 | N/A | N/A | N/A | N/A | N/A | N/A | +|wasm64 | Tier 4 | N/A | N/A | N/A | N/A | N/A | N/A | +|riscv32 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | +|riscv64 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | ## Community diff --git a/src/all_types.hpp b/src/all_types.hpp index 26e9edbab4..2b55f8ee2e 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1750,11 +1750,11 @@ struct CodeGen { BuildMode build_mode; OutType out_type; ZigTarget zig_target; + TargetSubsystem subsystem; bool is_static; bool strip_debug_symbols; bool is_test_build; bool is_native_target; - ZigLLVM_MSVCSubsystemType msvc_subsystem; bool linker_rdynamic; bool no_rosegment_workaround; bool each_lib_rpath; diff --git a/src/analyze.cpp b/src/analyze.cpp index 48d473fb37..04d957b626 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3203,22 +3203,20 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi if (ccc) { if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) { g->have_c_main = true; - g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; + g->subsystem = TargetSubsystemConsole; } else if (buf_eql_str(symbol_name, "WinMain") && g->zig_target.os == OsWindows) { g->have_winmain = true; - g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; + g->subsystem = TargetSubsystemWindows; } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && g->zig_target.os == OsWindows) { g->have_winmain_crt_startup = true; - g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") && g->zig_target.os == OsWindows) { g->have_dllmain_crt_startup = true; - g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } } @@ -4377,7 +4375,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r if (is_pub && ok_cc) { if (buf_eql_str(proto_name, "main")) { g->have_pub_main = true; - g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; + g->subsystem = TargetSubsystemConsole; } else if (buf_eql_str(proto_name, "panic")) { g->have_pub_panic = true; } diff --git a/src/codegen.cpp b/src/codegen.cpp index 30a4f8c2a4..bbf8ffa340 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7231,7 +7231,7 @@ static void init(CodeGen *g) { } if (g->is_test_build) { - g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; + g->subsystem = TargetSubsystemConsole; } assert(g->root_out_name); @@ -7513,7 +7513,7 @@ static void gen_root_source(CodeGen *g) { report_errors_and_maybe_exit(g); if (!g->is_test_build && g->zig_target.os != OsFreestanding && - g->zig_target.os != OsZen && g->zig_target.os != OsUefi && + g->zig_target.os != OsUefi && !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) { @@ -8070,11 +8070,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_int(ch, g->zig_target.os); cache_int(ch, g->zig_target.env_type); cache_int(ch, g->zig_target.oformat); + cache_int(ch, g->subsystem); cache_bool(ch, g->is_static); cache_bool(ch, g->strip_debug_symbols); cache_bool(ch, g->is_test_build); cache_bool(ch, g->is_native_target); - cache_int(ch, g->msvc_subsystem); cache_bool(ch, g->linker_rdynamic); cache_bool(ch, g->no_rosegment_workaround); cache_bool(ch, g->each_lib_rpath); diff --git a/src/ir.cpp b/src/ir.cpp index a1432c7b11..83960f2eee 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17872,13 +17872,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct if (type_is_invalid(cimport_result->value.type)) return ira->codegen->invalid_instruction; - if (ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_APPLICATION && - ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER && - ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_ROM && - ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_RUNTIME_DRIVER) { - - find_libc_include_path(ira->codegen); - } + find_libc_include_path(ira->codegen); ImportTableEntry *child_import = allocate(1); child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import); diff --git a/src/link.cpp b/src/link.cpp index 52ca2f2cd9..593f7f309f 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -444,97 +444,20 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si return ZigLLDLink(oformat, args, arg_count, link_diag_callback, diag); } -static void construct_linker_job_coff(LinkJob *lj) { - CodeGen *g = lj->codegen; - - lj->args.append("/ERRORLIMIT:0"); - - if (g->libc_link_lib != nullptr) { - find_libc_lib_path(g); - } - - lj->args.append("-NOLOGO"); - - if (!g->strip_debug_symbols && g->zig_target.os != Os::OsUefi) { - lj->args.append("-DEBUG"); - } - - if (g->out_type == OutTypeExe) { - // TODO compile time stack upper bound detection - lj->args.append("/STACK:16777216"); - } - - coff_append_machine_arg(g, &lj->args); - - // The commented out stuff is from when we linked with MinGW - // Now that we're linking with LLD it remains to be determined - // how to handle --target-environ gnu - // These comments are a clue - - bool is_library = g->out_type == OutTypeLib; - //bool dll = g->out_type == OutTypeLib; - //bool shared = !g->is_static && dll; - //if (g->is_static) { - // lj->args.append("-Bstatic"); - //} else { - // if (dll) { - // lj->args.append("--dll"); - // } else if (shared) { - // lj->args.append("--shared"); - // } - // lj->args.append("-Bdynamic"); - // if (dll || shared) { - // lj->args.append("-e"); - // if (g->zig_target.arch.arch == ZigLLVM_x86) { - // lj->args.append("_DllMainCRTStartup@12"); - // } else { - // lj->args.append("DllMainCRTStartup"); - // } - // lj->args.append("--enable-auto-image-base"); - // } - //} - - - // These are n actual command lines from LINK.EXE UEFI builds (app & driver) to be used as guidance cleaning - // up a bit for building the COFF linker args: - // /OUT:"J:\coding\nebulae\k\x64\Release\k.efi" /LTCG:incremental /Driver /PDB:"J:\coding\nebulae\k\x64\Release\k.pdb" "UefiApplicationEntryPoint.lib" "UefiRuntimeLib.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\nebulae\k\x64\Release\k.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_APPLICATION /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" - // /OUT:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.efi" /LTCG:incremental /Driver /PDB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.pdb" "UefiDriverEntryPoint.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" - - // Sorry for the goto(s) :) - switch (g->msvc_subsystem) { - case ZigLLVM_MSVC_CONSOLE: - lj->args.append("/SUBSYSTEM:console"); - goto building_nt; - case ZigLLVM_MSVC_EFI_APPLICATION: - lj->args.append("/SUBSYSTEM:efi_application"); - goto building_uefi; - case ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER: - lj->args.append("/SUBSYSTEM:efi_boot_service_driver"); - goto building_uefi; - case ZigLLVM_MSVC_EFI_ROM: - lj->args.append("/SUBSYSTEM:efi_rom"); - goto building_uefi; - case ZigLLVM_MSVC_EFI_RUNTIME_DRIVER: - lj->args.append("/SUBSYSTEM:efi_runtime_driver"); - goto building_uefi; - case ZigLLVM_MSVC_NATIVE: - lj->args.append("/SUBSYSTEM:native"); - goto building_nt; - case ZigLLVM_MSVC_POSIX: - lj->args.append("/SUBSYSTEM:posix"); - goto building_nt; - case ZigLLVM_MSVC_WINDOWS: - lj->args.append("/SUBSYSTEM:windows"); - goto building_nt; - case ZigLLVM_MSVC_NONE: - goto continuing_build; - } +static void add_uefi_link_args(LinkJob *lj) { + lj->args.append("/BASE:0"); + lj->args.append("/ENTRY:EfiMain"); + lj->args.append("/OPT:REF"); + lj->args.append("/SAFESEH:NO"); + lj->args.append("/MERGE:.rdata=.data"); + lj->args.append("/ALIGN:32"); + lj->args.append("/NODEFAULTLIB"); + lj->args.append("/SECTION:.xdata,D"); +} -building_uefi: - lj->args.append("/BASE:\"0\" /ENTRY:\"EfiMain\" /OPT:REF /SAFESEH:NO /MERGE:\".rdata=.data\" /ALIGN:32 /NODEFAULTLIB /SECTION:\".xdata,D\""); - goto continuing_build; +static void add_nt_link_args(LinkJob *lj, bool is_library) { + CodeGen *g = lj->codegen; -building_nt: if (lj->link_in_crt) { const char *lib_str = g->is_static ? "lib" : ""; const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; @@ -557,17 +480,6 @@ building_nt: //https://msdn.microsoft.com/en-us/library/bb531344.aspx lj->args.append("legacy_stdio_definitions.lib"); - //if (shared || dll) { - // lj->args.append(get_libc_file(g, "dllcrt2.o")); - //} else { - // if (g->windows_linker_unicode) { - // lj->args.append(get_libc_file(g, "crt2u.o")); - // } else { - // lj->args.append(get_libc_file(g, "crt2.o")); - // } - //} - //lj->args.append(get_libc_static_file(g, "crtbegin.o")); - // msvcrt depends on kernel32 lj->args.append("kernel32.lib"); } else { @@ -580,8 +492,156 @@ building_nt: } } } +} + +// These are n actual command lines from LINK.EXE UEFI builds (app & driver) to be used as guidance cleaning +// up a bit for building the COFF linker args: +// /OUT:"J:\coding\nebulae\k\x64\Release\k.efi" /LTCG:incremental /Driver /PDB:"J:\coding\nebulae\k\x64\Release\k.pdb" "UefiApplicationEntryPoint.lib" "UefiRuntimeLib.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\nebulae\k\x64\Release\k.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_APPLICATION /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" +// /OUT:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.efi" /LTCG:incremental /Driver /PDB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.pdb" "UefiDriverEntryPoint.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" +// This commented out stuff is from when we linked with MinGW +// Now that we're linking with LLD it remains to be determined +// how to handle --target-environ gnu +// These comments are a clue +//bool dll = g->out_type == OutTypeLib; +//bool shared = !g->is_static && dll; +//if (g->is_static) { +// lj->args.append("-Bstatic"); +//} else { +// if (dll) { +// lj->args.append("--dll"); +// } else if (shared) { +// lj->args.append("--shared"); +// } +// lj->args.append("-Bdynamic"); +// if (dll || shared) { +// lj->args.append("-e"); +// if (g->zig_target.arch.arch == ZigLLVM_x86) { +// lj->args.append("_DllMainCRTStartup@12"); +// } else { +// lj->args.append("DllMainCRTStartup"); +// } +// lj->args.append("--enable-auto-image-base"); +// } +//} +//if (shared || dll) { +// lj->args.append(get_libc_file(g, "dllcrt2.o")); +//} else { +// if (g->windows_linker_unicode) { +// lj->args.append(get_libc_file(g, "crt2u.o")); +// } else { +// lj->args.append(get_libc_file(g, "crt2.o")); +// } +//} +//lj->args.append(get_libc_static_file(g, "crtbegin.o")); +//if (g->libc_link_lib != nullptr) { +//if (g->is_static) { +// lj->args.append("--start-group"); +//} + +//lj->args.append("-lmingw32"); + +//lj->args.append("-lgcc"); +//bool is_android = (g->zig_target.env_type == ZigLLVM_Android); +//bool is_cyg_ming = is_target_cyg_mingw(&g->zig_target); +//if (!g->is_static && !is_android) { +// if (!is_cyg_ming) { +// lj->args.append("--as-needed"); +// } +// //lj->args.append("-lgcc_s"); +// if (!is_cyg_ming) { +// lj->args.append("--no-as-needed"); +// } +//} +//if (g->is_static && !is_android) { +// //lj->args.append("-lgcc_eh"); +//} +//if (is_android && !g->is_static) { +// lj->args.append("-ldl"); +//} + +//lj->args.append("-lmoldname"); +//lj->args.append("-lmingwex"); +//lj->args.append("-lmsvcrt"); + + +//if (g->windows_subsystem_windows) { +// lj->args.append("-lgdi32"); +// lj->args.append("-lcomdlg32"); +//} +//lj->args.append("-ladvapi32"); +//lj->args.append("-lshell32"); +//lj->args.append("-luser32"); +//lj->args.append("-lkernel32"); + +//if (g->is_static) { +// lj->args.append("--end-group"); +//} + +//if (lj->link_in_crt) { +// lj->args.append(get_libc_static_file(g, "crtend.o")); +//} +//} + + +static void construct_linker_job_coff(LinkJob *lj) { + CodeGen *g = lj->codegen; + + lj->args.append("/ERRORLIMIT:0"); + + if (g->libc_link_lib != nullptr) { + find_libc_lib_path(g); + } + + lj->args.append("/NOLOGO"); -continuing_build: + if (!g->strip_debug_symbols) { + lj->args.append("/DEBUG"); + } + + if (g->out_type == OutTypeExe) { + // TODO compile time stack upper bound detection + lj->args.append("/STACK:16777216"); + } + + coff_append_machine_arg(g, &lj->args); + + bool is_library = g->out_type == OutTypeLib; + switch (g->subsystem) { + case TargetSubsystemAuto: + break; + case TargetSubsystemConsole: + lj->args.append("/SUBSYSTEM:console"); + add_nt_link_args(lj, is_library); + break; + case TargetSubsystemEfiApplication: + lj->args.append("/SUBSYSTEM:efi_application"); + add_uefi_link_args(lj); + break; + case TargetSubsystemEfiBootServiceDriver: + lj->args.append("/SUBSYSTEM:efi_boot_service_driver"); + add_uefi_link_args(lj); + break; + case TargetSubsystemEfiRom: + lj->args.append("/SUBSYSTEM:efi_rom"); + add_uefi_link_args(lj); + break; + case TargetSubsystemEfiRuntimeDriver: + lj->args.append("/SUBSYSTEM:efi_runtime_driver"); + add_uefi_link_args(lj); + break; + case TargetSubsystemNative: + lj->args.append("/SUBSYSTEM:native"); + add_nt_link_args(lj, is_library); + break; + case TargetSubsystemPosix: + lj->args.append("/SUBSYSTEM:posix"); + add_nt_link_args(lj, is_library); + break; + case TargetSubsystemWindows: + lj->args.append("/SUBSYSTEM:windows"); + add_nt_link_args(lj, is_library); + break; + } lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); @@ -665,54 +725,6 @@ continuing_build: } } - //if (g->libc_link_lib != nullptr) { - //if (g->is_static) { - // lj->args.append("--start-group"); - //} - - //lj->args.append("-lmingw32"); - - //lj->args.append("-lgcc"); - //bool is_android = (g->zig_target.env_type == ZigLLVM_Android); - //bool is_cyg_ming = is_target_cyg_mingw(&g->zig_target); - //if (!g->is_static && !is_android) { - // if (!is_cyg_ming) { - // lj->args.append("--as-needed"); - // } - // //lj->args.append("-lgcc_s"); - // if (!is_cyg_ming) { - // lj->args.append("--no-as-needed"); - // } - //} - //if (g->is_static && !is_android) { - // //lj->args.append("-lgcc_eh"); - //} - //if (is_android && !g->is_static) { - // lj->args.append("-ldl"); - //} - - //lj->args.append("-lmoldname"); - //lj->args.append("-lmingwex"); - //lj->args.append("-lmsvcrt"); - - - //if (g->windows_subsystem_windows) { - // lj->args.append("-lgdi32"); - // lj->args.append("-lcomdlg32"); - //} - //lj->args.append("-ladvapi32"); - //lj->args.append("-lshell32"); - //lj->args.append("-luser32"); - //lj->args.append("-lkernel32"); - - //if (g->is_static) { - // lj->args.append("--end-group"); - //} - - //if (lj->link_in_crt) { - // lj->args.append(get_libc_static_file(g, "crtend.o")); - //} - //} } diff --git a/src/main.cpp b/src/main.cpp index faca9511dc..fd8e3db2fa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,13 +16,6 @@ #include -#ifdef __GNUC__ -#include -#define STRCASECMP strcasecmp -#else -#define STRCASECMP stricmp -#endif - static int print_error_usage(const char *arg0) { fprintf(stderr, "See `%s help` for detailed usage information\n", arg0); return EXIT_FAILURE; @@ -97,8 +90,8 @@ static int print_full_usage(const char *arg0) { " -rdynamic add all symbols to the dynamic symbol table\n" " -rpath [path] add directory to the runtime library search path\n" " --no-rosegment compromise security to workaround valgrind bug\n" - " --msvc-subsystem [subsystem] (windows/uefi) /SUBSYSTEM: to the linker\n" - " -framework [name] (darwin) link against framework\n" + " --subsystem [subsystem] (windows) /SUBSYSTEM: to the linker\n" + " -framework [name] (darwin) link against framework\n" " -mios-version-min [ver] (darwin) set iOS deployment target\n" " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n" " --ver-major [ver] dynamic library semver major version\n" @@ -377,8 +370,6 @@ int main(int argc, char **argv) { const char *target_arch = nullptr; const char *target_os = nullptr; const char *target_environ = nullptr; - bool mwindows = false; - bool mconsole = false; bool rdynamic = false; const char *mmacosx_version_min = nullptr; const char *mios_version_min = nullptr; @@ -401,7 +392,7 @@ int main(int argc, char **argv) { int runtime_args_start = -1; bool no_rosegment_workaround = false; bool system_linker_hack = false; - ZigLLVM_MSVCSubsystemType msvc_subsystem_type = ZigLLVM_MSVC_NONE; + TargetSubsystem subsystem = TargetSubsystemAuto; if (argc >= 2 && strcmp(argv[1], "build") == 0) { Buf zig_exe_path_buf = BUF_INIT; @@ -547,36 +538,6 @@ int main(int argc, char **argv) { verbose_llvm_ir = true; } else if (strcmp(arg, "--verbose-cimport") == 0) { verbose_cimport = true; - } else if (strcmp(arg, "--msvc-subsystem") == 0) { - if (i + 1 >= argc) { - fprintf(stderr, "Expected 1 argument after --msvc-subsystem\n"); - return print_error_usage(arg0); - } - i += 1; - if (STRCASECMP(argv[i], "CONSOLE") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_CONSOLE; - } else if (STRCASECMP(argv[i], "WINDOWS") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_WINDOWS; - } else if (STRCASECMP(argv[i], "POSIX") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_POSIX; - } else if (STRCASECMP(argv[i], "NATIVE") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_NATIVE; - } else if (STRCASECMP(argv[i], "EFI_APPLICATION") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_EFI_APPLICATION; - } else if (STRCASECMP(argv[i], "EFI_BOOT_SERVICE_DRIVER") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER; - } else if (STRCASECMP(argv[i], "EFI_ROM") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_EFI_ROM; - } else if (STRCASECMP(argv[i], "EFI_RUNTIME_DRIVER") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_EFI_RUNTIME_DRIVER; - } else { - fprintf(stderr, "Unknown format %s for --msvc-subsystem argument\n", argv[i]); - return EXIT_FAILURE; - } - } else if (strcmp(arg, "-mwindows") == 0) { - mwindows = true; - } else if (strcmp(arg, "-mconsole") == 0) { - mconsole = true; } else if (strcmp(arg, "-rdynamic") == 0) { rdynamic = true; } else if (strcmp(arg, "--no-rosegment") == 0) { @@ -720,6 +681,37 @@ int main(int argc, char **argv) { ver_patch = atoi(argv[i]); } else if (strcmp(arg, "--test-cmd") == 0) { test_exec_args.append(argv[i]); + } else if (strcmp(arg, "--subsystem") == 0) { + if (strcmp(argv[i], "console") == 0) { + subsystem = TargetSubsystemConsole; + } else if (strcmp(argv[i], "windows") == 0) { + subsystem = TargetSubsystemWindows; + } else if (strcmp(argv[i], "posix") == 0) { + subsystem = TargetSubsystemPosix; + } else if (strcmp(argv[i], "native") == 0) { + subsystem = TargetSubsystemNative; + } else if (strcmp(argv[i], "efi_application") == 0) { + subsystem = TargetSubsystemEfiApplication; + } else if (strcmp(argv[i], "efi_boot_service_driver") == 0) { + subsystem = TargetSubsystemEfiBootServiceDriver; + } else if (strcmp(argv[i], "efi_rom") == 0) { + subsystem = TargetSubsystemEfiRom; + } else if (strcmp(argv[i], "efi_runtime_driver") == 0) { + subsystem = TargetSubsystemEfiRuntimeDriver; + } else { + fprintf(stderr, "invalid: --subsystem %s\n" + "Options are:\n" + " console\n" + " windows\n" + " posix\n" + " native\n" + " efi_application\n" + " efi_boot_service_driver\n" + " efi_rom\n" + " efi_runtime_driver\n" + , argv[i]); + return EXIT_FAILURE; + } } else { fprintf(stderr, "Invalid argument: %s\n", arg); return print_error_usage(arg0); @@ -882,7 +874,7 @@ int main(int argc, char **argv) { buf_out_name = buf_create_from_str("run"); } CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir()); - g->msvc_subsystem = msvc_subsystem_type; + g->subsystem = subsystem; if (disable_pic) { if (out_type != OutTypeLib || !is_static) { diff --git a/src/target.cpp b/src/target.cpp index 61543c38d5..6fea79518c 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -283,6 +283,7 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) { case OsSolaris: return ZigLLVM_Solaris; case OsWindows: + case OsUefi: return ZigLLVM_Win32; case OsHaiku: return ZigLLVM_Haiku; @@ -316,8 +317,6 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) { return ZigLLVM_Contiki; case OsAMDPAL: return ZigLLVM_AMDPAL; - case OsUefi: - return ZigLLVM_Uefi; } zig_unreachable(); } @@ -809,7 +808,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { } const char *target_o_file_ext(ZigTarget *target) { - if (target->env_type == ZigLLVM_MSVC || (target->os == OsWindows || target->os == OsUefi)) { + if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) { return ".obj"; } else { return ".o"; diff --git a/src/target.hpp b/src/target.hpp index 62cc20711a..a87b12351a 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -54,13 +54,24 @@ enum Os { OsUefi, }; +enum TargetSubsystem { + TargetSubsystemAuto, // Zig should infer the subsystem + TargetSubsystemConsole, + TargetSubsystemWindows, + TargetSubsystemPosix, + TargetSubsystemNative, + TargetSubsystemEfiApplication, + TargetSubsystemEfiBootServiceDriver, + TargetSubsystemEfiRom, + TargetSubsystemEfiRuntimeDriver, +}; + struct ZigTarget { ArchType arch; ZigLLVM_VendorType vendor; Os os; ZigLLVM_EnvironmentType env_type; ZigLLVM_ObjectFormatType oformat; - ZigLLVM_MSVCSubsystemType msvc_subsystem = ZigLLVM_MSVC_NONE; }; enum CIntType { diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 0e56e29810..02fa3b24be 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4749,7 +4749,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList *errors, const clang_argv.append("-isystem"); clang_argv.append(buf_ptr(codegen->zig_c_headers_dir)); - if (codegen->libc_include_dir) { + if (codegen->libc_include_dir != nullptr) { clang_argv.append("-isystem"); clang_argv.append(buf_ptr(codegen->libc_include_dir)); } diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index bd63b7cbe5..bda8fa0adc 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -690,12 +690,7 @@ const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) { } const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) { - switch (os) { - case ZigLLVM_Uefi: - return "windows"; - default: - return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin(); - } + return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin(); } const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) { diff --git a/src/zig_llvm.h b/src/zig_llvm.h index bb7cb5c5ff..551a4a7448 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -358,8 +357,8 @@ enum ZigLLVM_OSType { ZigLLVM_Mesa3D, ZigLLVM_Contiki, ZigLLVM_AMDPAL, // AMD PAL Runtime - ZigLLVM_Uefi, - ZigLLVM_LastOSType = ZigLLVM_Uefi + + ZigLLVM_LastOSType = ZigLLVM_AMDPAL }; // Synchronize with target.cpp::environ_list @@ -398,19 +397,6 @@ enum ZigLLVM_ObjectFormatType { ZigLLVM_Wasm, }; -// For MSVC-supported subsystems -enum ZigLLVM_MSVCSubsystemType { - ZigLLVM_MSVC_NONE, - ZigLLVM_MSVC_CONSOLE, - ZigLLVM_MSVC_WINDOWS, - ZigLLVM_MSVC_POSIX, - ZigLLVM_MSVC_NATIVE, - ZigLLVM_MSVC_EFI_APPLICATION, - ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER, - ZigLLVM_MSVC_EFI_ROM, - ZigLLVM_MSVC_EFI_RUNTIME_DRIVER, -}; - ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch); ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch); ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor); diff --git a/std/os/index.zig b/std/os/index.zig index ce65667157..bb2eb76265 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -18,7 +18,7 @@ test "std.os" { _ = @import("test.zig"); _ = @import("time.zig"); _ = @import("windows/index.zig"); - _ = @import("uefi/index.zig"); + _ = @import("uefi.zig"); _ = @import("get_app_data_dir.zig"); } @@ -27,7 +27,7 @@ pub const darwin = @import("darwin.zig"); pub const linux = @import("linux/index.zig"); pub const freebsd = @import("freebsd/index.zig"); pub const zen = @import("zen.zig"); -pub const uefi = @import("uefi/index.zig"); +pub const uefi = @import("uefi.zig"); pub const posix = switch (builtin.os) { Os.linux => linux, @@ -192,6 +192,7 @@ pub fn abort() noreturn { windows.ExitProcess(3); }, Os.uefi => { + // TODO there's gotta be a better thing to do here than loop forever while (true) {} }, else => @compileError("Unsupported OS"), diff --git a/std/os/uefi.zig b/std/os/uefi.zig new file mode 100644 index 0000000000..8ed60d9c9b --- /dev/null +++ b/std/os/uefi.zig @@ -0,0 +1,2 @@ +// TODO this is where the extern declarations go. For example, see +// inc/efilib.h in gnu-efi-code diff --git a/std/os/uefi/index.zig b/std/os/uefi/index.zig deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/std/special/panic.zig b/std/special/panic.zig index fe1e020604..bd3ad971e0 100644 --- a/std/special/panic.zig +++ b/std/special/panic.zig @@ -10,9 +10,13 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn @setCold(true); switch (builtin.os) { // TODO: fix panic in zen. - builtin.Os.freestanding, builtin.Os.zen, builtin.Os.uefi => { + builtin.Os.freestanding, builtin.Os.zen => { while (true) {} }, + builtin.Os.uefi => { + // TODO look into using the debug info and logging helpful messages + std.os.abort(); + }, else => { const first_trace_addr = @ptrToInt(@returnAddress()); std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg); -- cgit v1.2.3 From d2602b442e7cdea2e74584f9529917d7a53625fd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 6 Feb 2019 14:32:20 -0500 Subject: require running std lib tests coherently this should actually improve CI times a bit too See the description at the top of std/os/startup.zig (deleted in this commit) for a more detailed understanding of what this commit does. --- CMakeLists.txt | 1 - src/codegen.cpp | 18 +++++++++++++----- src/codegen.hpp | 2 +- src/link.cpp | 2 +- src/main.cpp | 12 +++++++++--- std/build.zig | 10 ++++++++++ std/index.zig | 1 - std/os/index.zig | 31 +++++++++++++++++++++---------- std/os/startup.zig | 26 -------------------------- std/special/bootstrap.zig | 14 +++++++------- test/tests.zig | 3 +++ 11 files changed, 65 insertions(+), 55 deletions(-) delete mode 100644 std/os/startup.zig (limited to 'src/link.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index a093bfbfd9..4dd6a1dcfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -587,7 +587,6 @@ set(ZIG_STD_FILES "os/linux/vdso.zig" "os/linux/x86_64.zig" "os/path.zig" - "os/startup.zig" "os/time.zig" "os/uefi.zig" "os/windows/advapi32.zig" diff --git a/src/codegen.cpp b/src/codegen.cpp index d8fc077efc..5e282160d6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -88,7 +88,7 @@ static const char *symbols_that_llvm_depends_on[] = { }; CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode, - Buf *zig_lib_dir) + Buf *zig_lib_dir, Buf *override_std_dir) { CodeGen *g = allocate(1); @@ -96,8 +96,12 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out g->zig_lib_dir = zig_lib_dir; - g->zig_std_dir = buf_alloc(); - os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir); + if (override_std_dir == nullptr) { + g->zig_std_dir = buf_alloc(); + os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir); + } else { + g->zig_std_dir = override_std_dir; + } g->zig_c_headers_dir = buf_alloc(); os_path_join(zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir); @@ -8356,8 +8360,12 @@ static void add_cache_pkg(CodeGen *g, CacheHash *ch, PackageTableEntry *pkg) { if (!entry) break; - cache_buf(ch, entry->key); - add_cache_pkg(g, ch, entry->value); + // TODO: I think we need a more sophisticated detection of + // packages we have already seen + if (entry->value != pkg) { + cache_buf(ch, entry->key); + add_cache_pkg(g, ch, entry->value); + } } } diff --git a/src/codegen.hpp b/src/codegen.hpp index 6f1cdfb677..4bd8f2dcca 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -15,7 +15,7 @@ #include CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode, - Buf *zig_lib_dir); + Buf *zig_lib_dir, Buf *override_std_dir); void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len); diff --git a/src/link.cpp b/src/link.cpp index 593f7f309f..58221a99ea 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -42,7 +42,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) } CodeGen *child_gen = codegen_create(full_path, child_target, child_out_type, - parent_gen->build_mode, parent_gen->zig_lib_dir); + parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir); child_gen->out_h_path = nullptr; child_gen->verbose_tokenize = parent_gen->verbose_tokenize; diff --git a/src/main.cpp b/src/main.cpp index 81f49089be..73a1d75d42 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,6 +74,7 @@ static int print_full_usage(const char *arg0) { " -dirafter [dir] same as -isystem but do it last\n" " -isystem [dir] add additional search path for other .h files\n" " -mllvm [arg] forward an arg to LLVM's option processing\n" + " --override-std-dir [arg] use an alternate Zig standard library\n" "\n" "Link Options:\n" " --dynamic-linker [path] set the path to ld.so\n" @@ -395,6 +396,7 @@ int main(int argc, char **argv) { bool system_linker_hack = false; TargetSubsystem subsystem = TargetSubsystemAuto; bool is_single_threaded = false; + Buf *override_std_dir = nullptr; if (argc >= 2 && strcmp(argv[1], "build") == 0) { Buf zig_exe_path_buf = BUF_INIT; @@ -430,7 +432,8 @@ int main(int argc, char **argv) { Buf *build_runner_path = buf_alloc(); os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path); - CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir()); + CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(), + override_std_dir); g->enable_time_report = timing_info; buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name); codegen_set_out_name(g, buf_create_from_str("build")); @@ -645,6 +648,8 @@ int main(int argc, char **argv) { clang_argv.append(argv[i]); llvm_argv.append(argv[i]); + } else if (strcmp(arg, "--override-std-dir") == 0) { + override_std_dir = buf_create_from_str(argv[i]); } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) { lib_dirs.append(argv[i]); } else if (strcmp(arg, "--library") == 0) { @@ -819,7 +824,7 @@ int main(int argc, char **argv) { switch (cmd) { case CmdBuiltin: { - CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir()); + CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir(), override_std_dir); g->is_single_threaded = is_single_threaded; Buf *builtin_source = codegen_generate_builtin_source(g); if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) { @@ -878,7 +883,8 @@ int main(int argc, char **argv) { if (cmd == CmdRun && buf_out_name == nullptr) { buf_out_name = buf_create_from_str("run"); } - CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir()); + CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir(), + override_std_dir); g->subsystem = subsystem; if (disable_pic) { diff --git a/std/build.zig b/std/build.zig index 5246d97339..07efcec30d 100644 --- a/std/build.zig +++ b/std/build.zig @@ -1686,6 +1686,7 @@ pub const TestStep = struct { no_rosegment: bool, output_path: ?[]const u8, system_linker_hack: bool, + override_std_dir: ?[]const u8, pub fn init(builder: *Builder, root_src: []const u8) TestStep { const step_name = builder.fmt("test {}", root_src); @@ -1707,6 +1708,7 @@ pub const TestStep = struct { .no_rosegment = false, .output_path = null, .system_linker_hack = false, + .override_std_dir = null, }; } @@ -1737,6 +1739,10 @@ pub const TestStep = struct { self.build_mode = mode; } + pub fn overrideStdDir(self: *TestStep, dir_path: []const u8) void { + self.override_std_dir = dir_path; + } + pub fn setOutputPath(self: *TestStep, file_path: []const u8) void { self.output_path = file_path; @@ -1914,6 +1920,10 @@ pub const TestStep = struct { if (self.system_linker_hack) { try zig_args.append("--system-linker-hack"); } + if (self.override_std_dir) |dir| { + try zig_args.append("--override-std-dir"); + try zig_args.append(builder.pathFromRoot(dir)); + } try builder.spawnChild(zig_args.toSliceConst()); } diff --git a/std/index.zig b/std/index.zig index ef3988460f..2a63244004 100644 --- a/std/index.zig +++ b/std/index.zig @@ -45,7 +45,6 @@ pub const unicode = @import("unicode.zig"); pub const zig = @import("zig/index.zig"); pub const lazyInit = @import("lazy_init.zig").lazyInit; -pub const startup = @import("os/startup.zig"); test "std" { // run tests from these diff --git a/std/os/index.zig b/std/os/index.zig index 68b3409757..d17b6f4f40 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -8,8 +8,9 @@ const is_posix = switch (builtin.os) { }; const os = @This(); -// See the comment in startup.zig for why this does not use the `std` global above. -const startup = @import("std").startup; +comptime { + assert(@import("std") == std); // You have to run the std lib tests with --override-std-dir +} test "std.os" { _ = @import("child_process.zig"); @@ -670,11 +671,14 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError { } } +pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = null; +pub var posix_environ_raw: [][*]u8 = undefined; + /// See std.elf for the constants. pub fn linuxGetAuxVal(index: usize) usize { if (builtin.link_libc) { return usize(std.c.getauxval(index)); - } else if (startup.linux_elf_aux_maybe) |auxv| { + } else if (linux_elf_aux_maybe) |auxv| { var i: usize = 0; while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) { if (auxv[i].a_type == index) @@ -734,7 +738,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap { try result.setMove(key, value); } } else { - for (startup.posix_environ_raw) |ptr| { + for (posix_environ_raw) |ptr| { var line_i: usize = 0; while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {} const key = ptr[0..line_i]; @@ -756,7 +760,7 @@ test "os.getEnvMap" { /// TODO make this go through libc when we have it pub fn getEnvPosix(key: []const u8) ?[]const u8 { - for (startup.posix_environ_raw) |ptr| { + for (posix_environ_raw) |ptr| { var line_i: usize = 0; while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {} const this_key = ptr[0..line_i]; @@ -1937,14 +1941,14 @@ pub const ArgIteratorPosix = struct { pub fn init() ArgIteratorPosix { return ArgIteratorPosix{ .index = 0, - .count = startup.posix_argv_raw.len, + .count = raw.len, }; } pub fn next(self: *ArgIteratorPosix) ?[]const u8 { if (self.index == self.count) return null; - const s = startup.posix_argv_raw[self.index]; + const s = raw[self.index]; self.index += 1; return cstr.toSlice(s); } @@ -1955,6 +1959,10 @@ pub const ArgIteratorPosix = struct { self.index += 1; return true; } + + /// This is marked as public but actually it's only meant to be used + /// internally by zig's startup code. + pub var raw: [][*]u8 = undefined; }; pub const ArgIteratorWindows = struct { @@ -3000,6 +3008,9 @@ pub const SpawnThreadError = error{ Unexpected, }; +pub var linux_tls_phdr: ?*std.elf.Phdr = null; +pub var linux_tls_img_src: [*]const u8 = undefined; // defined if linux_tls_phdr is + /// caller must call wait on the returned thread /// fn startFn(@typeOf(context)) T /// where T is u8, noreturn, void, or !void @@ -3109,7 +3120,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread } // Finally, the Thread Local Storage, if any. if (!Thread.use_pthreads) { - if (startup.linux_tls_phdr) |tls_phdr| { + if (linux_tls_phdr) |tls_phdr| { l = mem.alignForward(l, tls_phdr.p_align); tls_start_offset = l; l += tls_phdr.p_memsz; @@ -3153,8 +3164,8 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread posix.CLONE_THREAD | posix.CLONE_SYSVSEM | posix.CLONE_PARENT_SETTID | posix.CLONE_CHILD_CLEARTID | posix.CLONE_DETACHED; var newtls: usize = undefined; - if (startup.linux_tls_phdr) |tls_phdr| { - @memcpy(@intToPtr([*]u8, mmap_addr + tls_start_offset), startup.linux_tls_img_src, tls_phdr.p_filesz); + if (linux_tls_phdr) |tls_phdr| { + @memcpy(@intToPtr([*]u8, mmap_addr + tls_start_offset), linux_tls_img_src, tls_phdr.p_filesz); thread_ptr.data.tls_end_addr = mmap_addr + mmap_len; newtls = @ptrToInt(&thread_ptr.data.tls_end_addr); flags |= posix.CLONE_SETTLS; diff --git a/std/os/startup.zig b/std/os/startup.zig deleted file mode 100644 index c54d274c5d..0000000000 --- a/std/os/startup.zig +++ /dev/null @@ -1,26 +0,0 @@ -// This file contains global variables that are initialized on startup from -// std/special/bootstrap.zig. There are a few things to be aware of here. -// -// First, when building an object or library, and no entry point is defined -// (such as pub fn main), std/special/bootstrap.zig is not included in the -// compilation. And so these global variables will remain set to the values -// you see here. -// -// Second, when using `zig test` to test the standard library, note that -// `zig test` is self-hosted. This means that it uses std/special/bootstrap.zig -// and an @import("std") from the install directory, which is distinct from -// the standard library files that we are directly testing with `zig test`. -// This means that these global variables would not get set. So the workaround -// here is that references to these globals from the standard library must -// use `@import("std").startup` rather than -// `@import("path/to/std/index.zig").startup` (and rather than the file path of -// this file directly). We also put "std" as a reference to itself in the -// standard library package so that this can work. - -const std = @import("../index.zig"); - -pub var linux_tls_phdr: ?*std.elf.Phdr = null; -pub var linux_tls_img_src: [*]const u8 = undefined; // defined when linux_tls_phdr is non-null -pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = null; -pub var posix_environ_raw: [][*]u8 = undefined; -pub var posix_argv_raw: [][*]u8 = undefined; diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig index 0e84f67481..97699e0cc5 100644 --- a/std/special/bootstrap.zig +++ b/std/special/bootstrap.zig @@ -64,7 +64,7 @@ fn posixCallMainAndExit() noreturn { if (builtin.os == builtin.Os.linux) { // Scan auxiliary vector. const auxv = @ptrCast([*]std.elf.Auxv, envp.ptr + envp_count + 1); - std.startup.linux_elf_aux_maybe = auxv; + std.os.linux_elf_aux_maybe = auxv; var i: usize = 0; var at_phdr: usize = 0; var at_phnum: usize = 0; @@ -87,8 +87,8 @@ fn posixCallMainAndExit() noreturn { // This is marked inline because for some reason LLVM in release mode fails to inline it, // and we want fewer call frames in stack traces. inline fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 { - std.startup.posix_argv_raw = argv[0..argc]; - std.startup.posix_environ_raw = envp; + std.os.ArgIteratorPosix.raw = argv[0..argc]; + std.os.posix_environ_raw = envp; return callMain(); } @@ -145,15 +145,15 @@ fn linuxInitializeThreadLocalStorage(at_phdr: usize, at_phnum: usize, at_phent: // TODO look for PT_DYNAMIC when we have https://github.com/ziglang/zig/issues/1917 switch (phdr.p_type) { std.elf.PT_PHDR => base = at_phdr - phdr.p_vaddr, - std.elf.PT_TLS => std.startup.linux_tls_phdr = phdr, + std.elf.PT_TLS => std.os.linux_tls_phdr = phdr, else => continue, } } - const tls_phdr = std.startup.linux_tls_phdr orelse return; - std.startup.linux_tls_img_src = @intToPtr([*]const u8, base + tls_phdr.p_vaddr); + const tls_phdr = std.os.linux_tls_phdr orelse return; + std.os.linux_tls_img_src = @intToPtr([*]const u8, base + tls_phdr.p_vaddr); assert(main_thread_tls_bytes.len >= tls_phdr.p_memsz); // not enough preallocated Thread Local Storage assert(main_thread_tls_align >= tls_phdr.p_align); // preallocated Thread Local Storage not aligned enough - @memcpy(&main_thread_tls_bytes, std.startup.linux_tls_img_src, tls_phdr.p_filesz); + @memcpy(&main_thread_tls_bytes, std.os.linux_tls_img_src, tls_phdr.p_filesz); tls_end_addr = @ptrToInt(&main_thread_tls_bytes) + tls_phdr.p_memsz; linuxSetThreadArea(@ptrToInt(&tls_end_addr)); } diff --git a/test/tests.zig b/test/tests.zig index 548496fa2f..fc188f5550 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -194,6 +194,9 @@ pub fn addPkgTests(b: *build.Builder, test_filter: ?[]const u8, root_src: []cons if (link_libc) { these_tests.linkSystemLibrary("c"); } + if (mem.eql(u8, name, "std")) { + these_tests.overrideStdDir("std"); + } step.dependOn(&these_tests.step); } } -- cgit v1.2.3