diff --git a/CMakeLists.txt b/CMakeLists.txt index 72c480cd40..d8e2d9ff7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,15 +47,20 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF) option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead of the embedded LLD" OFF) find_package(llvm) -include_directories(${LLVM_INCLUDE_DIRS}) - find_package(clang) -include_directories(${CLANG_INCLUDE_DIRS}) if(ZIG_FORCE_EXTERNAL_LLD) find_package(lld) + include_directories(${LLVM_INCLUDE_DIRS}) include_directories(${LLD_INCLUDE_DIRS}) + include_directories(${CLANG_INCLUDE_DIRS}) else() + # This goes first so that we find embedded LLD instead + # of system LLD. + include_directories("${CMAKE_SOURCE_DIR}/deps/lld/include") + + include_directories(${LLVM_INCLUDE_DIRS}) + include_directories(${CLANG_INCLUDE_DIRS}) set(EMBEDDED_LLD_LIB_SOURCES "${CMAKE_SOURCE_DIR}/deps/lld/lib/Driver/DarwinLdDriver.cpp" "${CMAKE_SOURCE_DIR}/deps/lld/lib/Config/Version.cpp" diff --git a/c_headers/avx512fintrin.h b/c_headers/avx512fintrin.h index 4ce6945311..4b66acc02f 100644 --- a/c_headers/avx512fintrin.h +++ b/c_headers/avx512fintrin.h @@ -267,21 +267,16 @@ _mm512_maskz_set1_epi32(__mmask16 __M, int __A) __M); } +#ifdef __x86_64__ static __inline __m512i __DEFAULT_FN_ATTRS _mm512_maskz_set1_epi64(__mmask8 __M, long long __A) { -#ifdef __x86_64__ return (__m512i) __builtin_ia32_pbroadcastq512_gpr_mask (__A, (__v8di) _mm512_setzero_si512 (), __M); -#else - return (__m512i) __builtin_ia32_pbroadcastq512_mem_mask (__A, - (__v8di) - _mm512_setzero_si512 (), - __M); -#endif } +#endif static __inline __m512 __DEFAULT_FN_ATTRS _mm512_setzero_ps(void) diff --git a/deps/lld-prebuilt/lld/Config/Version.inc b/deps/lld-prebuilt/lld/Config/Version.inc index 2fb8a16222..a3f6f44588 100644 --- a/deps/lld-prebuilt/lld/Config/Version.inc +++ b/deps/lld-prebuilt/lld/Config/Version.inc @@ -1,5 +1,5 @@ -#define LLD_VERSION 5.0.0 -#define LLD_VERSION_STRING "5.0.0" +#define LLD_VERSION 5.0.1 +#define LLD_VERSION_STRING "5.0.1" #define LLD_VERSION_MAJOR 5 #define LLD_VERSION_MINOR 0 #define LLD_REVISION_STRING "" diff --git a/deps/lld/COFF/Config.h b/deps/lld/COFF/Config.h index 7f8259d016..ffbd0715cf 100644 --- a/deps/lld/COFF/Config.h +++ b/deps/lld/COFF/Config.h @@ -157,6 +157,7 @@ struct Configuration { uint32_t MinorImageVersion = 0; uint32_t MajorOSVersion = 6; uint32_t MinorOSVersion = 0; + bool CanExitEarly = false; bool DynamicBase = true; bool NxCompat = true; bool AllowIsolation = true; diff --git a/deps/lld/COFF/Driver.cpp b/deps/lld/COFF/Driver.cpp index 0dabca6e37..868ff0aa1e 100644 --- a/deps/lld/COFF/Driver.cpp +++ b/deps/lld/COFF/Driver.cpp @@ -52,15 +52,21 @@ BumpPtrAllocator BAlloc; StringSaver Saver{BAlloc}; std::vector SpecificAllocBase::Instances; -bool link(ArrayRef Args, raw_ostream &Diag) { +bool link(ArrayRef Args, bool CanExitEarly, raw_ostream &Diag) { ErrorCount = 0; ErrorOS = &Diag; Config = make(); Config->Argv = {Args.begin(), Args.end()}; Config->ColorDiagnostics = (ErrorOS == &llvm::errs() && Process::StandardErrHasColors()); + Config->CanExitEarly = CanExitEarly; Driver = make(); Driver->link(Args); + + // Call exit() if we can to avoid calling destructors. + if (CanExitEarly) + exitLld(ErrorCount ? 1 : 0); + freeArena(); return !ErrorCount; } @@ -1123,7 +1129,7 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // This is useful because MSVC link.exe can generate complete PDBs. if (Args.hasArg(OPT_msvclto)) { invokeMSVC(Args); - exit(0); + return; } // Do LTO by compiling bitcode input files to a set of native COFF files then diff --git a/deps/lld/COFF/Error.cpp b/deps/lld/COFF/Error.cpp index 34abc280f6..550d9b9696 100644 --- a/deps/lld/COFF/Error.cpp +++ b/deps/lld/COFF/Error.cpp @@ -32,7 +32,7 @@ namespace coff { uint64_t ErrorCount; raw_ostream *ErrorOS; -static LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) { +LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) { // Dealloc/destroy ManagedStatic variables before calling // _exit(). In a non-LTO build, this is a nop. In an LTO // build allows us to get the output of -time-passes. @@ -78,7 +78,8 @@ void error(const Twine &Msg) { print("error: ", raw_ostream::RED); *ErrorOS << "too many errors emitted, stopping now" << " (use /ERRORLIMIT:0 to see all errors)\n"; - exitLld(1); + if (Config->CanExitEarly) + exitLld(1); } ++ErrorCount; diff --git a/deps/lld/COFF/Error.h b/deps/lld/COFF/Error.h index e1e4c1e521..1c1e2beab5 100644 --- a/deps/lld/COFF/Error.h +++ b/deps/lld/COFF/Error.h @@ -27,6 +27,8 @@ LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg); LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix); LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error &Err, const Twine &Prefix); +LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); + template T check(ErrorOr V, const Twine &Prefix) { if (auto EC = V.getError()) fatal(EC, Prefix); diff --git a/deps/lld/ELF/SyntheticSections.cpp b/deps/lld/ELF/SyntheticSections.cpp index 4bbec4ab34..a67b039ddf 100644 --- a/deps/lld/ELF/SyntheticSections.cpp +++ b/deps/lld/ELF/SyntheticSections.cpp @@ -427,10 +427,11 @@ CieRecord *EhFrameSection::addCie(EhSectionPiece &Piece, &Sec->template getFile()->getRelocTargetSym(Rels[FirstRelI]); // Search for an existing CIE by CIE contents/relocation target pair. - CieRecord *Cie = &CieMap[{Piece.data(), Personality}]; + CieRecord *&Cie = CieMap[{Piece.data(), Personality}]; // If not found, create a new one. - if (Cie->Piece == nullptr) { + if (!Cie) { + Cie = make(); Cie->Piece = &Piece; Cies.push_back(Cie); } @@ -522,9 +523,14 @@ template static void writeCieFde(uint8_t *Buf, ArrayRef D) { memcpy(Buf, D.data(), D.size()); + size_t Aligned = alignTo(D.size(), sizeof(typename ELFT::uint)); + + // Zero-clear trailing padding if it exists. + memset(Buf + D.size(), 0, Aligned - D.size()); + // Fix the size field. -4 since size does not include the size field itself. const endianness E = ELFT::TargetEndianness; - write32(Buf, alignTo(D.size(), sizeof(typename ELFT::uint)) - 4); + write32(Buf, Aligned - 4); } template void EhFrameSection::finalizeContents() { diff --git a/deps/lld/ELF/SyntheticSections.h b/deps/lld/ELF/SyntheticSections.h index ddd8ca99a6..ccf021ec95 100644 --- a/deps/lld/ELF/SyntheticSections.h +++ b/deps/lld/ELF/SyntheticSections.h @@ -103,7 +103,8 @@ private: std::vector Cies; // CIE records are uniquified by their contents and personality functions. - llvm::DenseMap, SymbolBody *>, CieRecord> CieMap; + llvm::DenseMap, SymbolBody *>, CieRecord *> + CieMap; }; class GotSection : public SyntheticSection { diff --git a/deps/lld/include/lld/Driver/Driver.h b/deps/lld/include/lld/Driver/Driver.h index 4ba0994e88..02c3c059d3 100644 --- a/deps/lld/include/lld/Driver/Driver.h +++ b/deps/lld/include/lld/Driver/Driver.h @@ -15,7 +15,7 @@ namespace lld { namespace coff { -bool link(llvm::ArrayRef Args, +bool link(llvm::ArrayRef Args, bool CanExitEarly, llvm::raw_ostream &Diag = llvm::errs()); } diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index efe23abb91..b207c85523 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -621,7 +621,6 @@ void ArchHandler_x86_64::applyFixupFinal( // Fall into llvm_unreachable(). break; } - return; } void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, diff --git a/deps/lld/test/ELF/eh-frame-padding-no-rosegment.s b/deps/lld/test/ELF/eh-frame-padding-no-rosegment.s new file mode 100644 index 0000000000..951fed0a56 --- /dev/null +++ b/deps/lld/test/ELF/eh-frame-padding-no-rosegment.s @@ -0,0 +1,64 @@ +// REQUIRES: x86 + +.cfi_startproc +.cfi_personality 0x1b, bar +.cfi_endproc + +.global bar +.hidden bar +bar: + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o + +// Check the size of the CIE (0x18 + 4) and FDE (0x10 + 4) +// RUN: llvm-readobj -s -section-data %t.o | FileCheck --check-prefix=OBJ %s + +// OBJ: Name: .eh_frame +// OBJ-NEXT: Type: +// OBJ-NEXT: Flags [ +// OBJ-NEXT: SHF_ALLOC +// OBJ-NEXT: ] +// OBJ-NEXT: Address: +// OBJ-NEXT: Offset: +// OBJ-NEXT: Size: +// OBJ-NEXT: Link: +// OBJ-NEXT: Info: +// OBJ-NEXT: AddressAlignment: +// OBJ-NEXT: EntrySize: +// OBJ-NEXT: SectionData ( +// OBJ-NEXT: 0000: 18000000 00000000 017A5052 00017810 +// OBJ-NEXT: 0010: 061B0000 00001B0C 07089001 10000000 +// OBJ-NEXT: 0020: 20000000 00000000 00000000 00000000 +// OBJ-NEXT: ) + +// RUN: ld.lld %t.o -no-rosegment -o %t -shared + +// Check that .eh_frame is in the same segment as .text +// RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=PHDR %s + +// PHDR: Segment Sections +// PHDR: .text +// PHDR-SAME: .eh_frame + +// Check that the CIE and FDE are padded with 0x00 and not 0xCC when the +// .eh_frame section is placed in the executable segment +// RUN: llvm-readobj -s -section-data %t | FileCheck %s + +// CHECK: Name: .eh_frame +// CHECK-NEXT: Type: +// CHECK-NEXT: Flags +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 1C000000 00000000 017A5052 00017810 +// CHECK-NEXT: 0010: 061BBEFF FFFF1B0C 07089001 00000000 +// CHECK-NEXT: 0020: 14000000 24000000 A8FFFFFF 00000000 +// CHECK-NEXT: 0030: 00000000 00000000 +// CHECK-NEXT: ) diff --git a/deps/lld/tools/lld/lld.cpp b/deps/lld/tools/lld/lld.cpp index 09f8079010..aa81aa9712 100644 --- a/deps/lld/tools/lld/lld.cpp +++ b/deps/lld/tools/lld/lld.cpp @@ -103,7 +103,7 @@ int main(int Argc, const char **Argv) { case Gnu: return !elf::link(Args, true); case WinLink: - return !coff::link(Args); + return !coff::link(Args, true); case Darwin: return !mach_o::link(Args); default: diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 658de77b31..fa352147cc 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -789,7 +789,7 @@ bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_ zig_unreachable(); case ZigLLVM_COFF: - return lld::coff::link(array_ref_args); + return lld::coff::link(array_ref_args, false, diag); case ZigLLVM_ELF: return lld::elf::link(array_ref_args, false, diag);