From 77b530b50aedd1cf9943e1d4fdd97a364fe9a921 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 1 Dec 2017 11:59:14 -0500 Subject: [PATCH 1/7] updated embedded LLD to 5.0.1rc2 --- deps/lld-prebuilt/lld/Config/Version.inc | 4 +- deps/lld/COFF/Driver.cpp | 6 +- deps/lld/ELF/LinkerScript.cpp | 2 +- deps/lld/ELF/SyntheticSections.cpp | 12 +++- deps/lld/ELF/SyntheticSections.h | 3 +- deps/lld/lib/ReaderWriter/MachO/ArchHandler.h | 4 -- .../ReaderWriter/MachO/ArchHandler_arm.cpp | 4 -- .../ReaderWriter/MachO/ArchHandler_arm64.cpp | 4 -- .../ReaderWriter/MachO/ArchHandler_x86.cpp | 4 -- .../ReaderWriter/MachO/ArchHandler_x86_64.cpp | 6 +- .../MachO/MachONormalizedFileFromAtoms.cpp | 57 ----------------- .../test/ELF/eh-frame-padding-no-rosegment.s | 64 +++++++++++++++++++ deps/lld/test/mach-o/lazy-bind-x86_64.yaml | 4 +- 13 files changed, 85 insertions(+), 89 deletions(-) create mode 100644 deps/lld/test/ELF/eh-frame-padding-no-rosegment.s 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/Driver.cpp b/deps/lld/COFF/Driver.cpp index 0dabca6e37..854c3e6909 100644 --- a/deps/lld/COFF/Driver.cpp +++ b/deps/lld/COFF/Driver.cpp @@ -61,7 +61,6 @@ bool link(ArrayRef Args, raw_ostream &Diag) { (ErrorOS == &llvm::errs() && Process::StandardErrHasColors()); Driver = make(); Driver->link(Args); - freeArena(); return !ErrorCount; } @@ -1031,7 +1030,7 @@ void LinkerDriver::link(ArrayRef ArgsArr) { if (!Args.hasArgNoClaim(OPT_INPUT)) { fixupExports(); createImportLibrary(/*AsLib=*/true); - return; + exit(0); } // Handle /delayload @@ -1173,6 +1172,9 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // Write the result. writeResult(&Symtab); + + // Call exit to avoid calling destructors. + exit(0); } } // namespace coff diff --git a/deps/lld/ELF/LinkerScript.cpp b/deps/lld/ELF/LinkerScript.cpp index 614f5e2c8b..8bdbd8db20 100644 --- a/deps/lld/ELF/LinkerScript.cpp +++ b/deps/lld/ELF/LinkerScript.cpp @@ -751,7 +751,7 @@ void LinkerScript::adjustSectionsAfterSorting() { if (auto *Cmd = dyn_cast(Base)) { Cmd->MemRegion = findMemoryRegion(Cmd); // Handle align (e.g. ".foo : ALIGN(16) { ... }"). - if (Cmd->AlignExpr && Cmd->Sec) + if (Cmd->AlignExpr) Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue()); } } 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/lib/ReaderWriter/MachO/ArchHandler.h b/deps/lld/lib/ReaderWriter/MachO/ArchHandler.h index 6028006ca9..70a63bd100 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler.h +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler.h @@ -112,10 +112,6 @@ public: /// info in final executables. virtual bool isLazyPointer(const Reference &); - /// Reference from an __stub_helper entry to the required offset of the - /// lazy bind commands. - virtual Reference::KindValue lazyImmediateLocationKind() = 0; - /// Returns true if the specified relocation is paired to the next relocation. virtual bool isPairedReloc(const normalized::Relocation &) = 0; diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp index 2f663c660f..7d1544854c 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp @@ -67,10 +67,6 @@ public: return invalid; } - Reference::KindValue lazyImmediateLocationKind() override { - return lazyImmediateLocation; - } - Reference::KindValue pointerKind() override { return invalid; } diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp index b9c815c5a3..10360b5c6d 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp @@ -127,10 +127,6 @@ public: return pointer64; } - Reference::KindValue lazyImmediateLocationKind() override { - return lazyImmediateLocation; - } - uint32_t dwarfCompactUnwindType() override { return 0x03000000; } diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp index a2c6809272..2272bff65c 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp @@ -70,10 +70,6 @@ public: return delta32; } - Reference::KindValue lazyImmediateLocationKind() override { - return lazyImmediateLocation; - } - Reference::KindValue unwindRefToEhFrameKind() override { return invalid; } diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index efe23abb91..d687ca5de5 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -116,10 +116,6 @@ public: return unwindFDEToFunction; } - Reference::KindValue lazyImmediateLocationKind() override { - return lazyImmediateLocation; - } - Reference::KindValue unwindRefToEhFrameKind() override { return unwindInfoToEhFrame; } @@ -621,7 +617,7 @@ void ArchHandler_x86_64::applyFixupFinal( // Fall into llvm_unreachable(). break; } - return; + llvm_unreachable("invalid x86_64 Reference Kind"); } void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, diff --git a/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index f2e5ed7816..e58e3d2e7a 100644 --- a/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -172,8 +172,6 @@ private: SymbolScope &symbolScope); void appendSection(SectionInfo *si, NormalizedFile &file); uint32_t sectionIndexForAtom(const Atom *atom); - void fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset, - NormalizedFile &file); typedef llvm::DenseMap AtomToIndex; struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; }; @@ -1425,8 +1423,6 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile, uint8_t segmentIndex; uint64_t segmentStartAddr; - uint32_t offsetInBindInfo = 0; - for (SectionInfo *sect : _sectionInfos) { segIndexForSection(sect, segmentIndex, segmentStartAddr); for (const AtomInfo &info : sect->atomsAndOffsets) { @@ -1471,59 +1467,6 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile, bind.symbolName = targ->name(); bind.addend = ref->addend(); nFile.lazyBindingInfo.push_back(bind); - - // Now that we know the segmentOffset and the ordinal attribute, - // we can fix the helper's code - - fixLazyReferenceImm(atom, offsetInBindInfo, nFile); - - // 5 bytes for opcodes + variable sizes (target name + \0 and offset - // encode's size) - offsetInBindInfo += - 6 + targ->name().size() + llvm::getULEB128Size(bind.segOffset); - if (bind.ordinal > BIND_IMMEDIATE_MASK) - offsetInBindInfo += llvm::getULEB128Size(bind.ordinal); - } - } - } - } -} - -void Util::fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset, - NormalizedFile &file) { - for (const auto &ref : *atom) { - const DefinedAtom *da = dyn_cast(ref->target()); - if (da == nullptr) - return; - - const Reference *helperRef = nullptr; - for (const Reference *hr : *da) { - if (hr->kindValue() == _archHandler.lazyImmediateLocationKind()) { - helperRef = hr; - break; - } - } - if (helperRef == nullptr) - continue; - - // TODO: maybe get the fixed atom content from _archHandler ? - for (SectionInfo *sectInfo : _sectionInfos) { - for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) { - if (atomInfo.atom == helperRef->target()) { - auto sectionContent = - file.sections[sectInfo->normalizedSectionIndex].content; - uint8_t *rawb = - file.ownedAllocations.Allocate(sectionContent.size()); - llvm::MutableArrayRef newContent{rawb, - sectionContent.size()}; - std::copy(sectionContent.begin(), sectionContent.end(), - newContent.begin()); - llvm::support::ulittle32_t *loc = - reinterpret_cast( - &newContent[atomInfo.offsetInSection + - helperRef->offsetInAtom()]); - *loc = offset; - file.sections[sectInfo->normalizedSectionIndex].content = newContent; } } } 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/test/mach-o/lazy-bind-x86_64.yaml b/deps/lld/test/mach-o/lazy-bind-x86_64.yaml index 1322719e5f..5c588c5719 100644 --- a/deps/lld/test/mach-o/lazy-bind-x86_64.yaml +++ b/deps/lld/test/mach-o/lazy-bind-x86_64.yaml @@ -80,8 +80,8 @@ undefined-symbols: # CHECK-HELPERS:Disassembly of section __TEXT,__stub_helper: # CHECK-HELPERS: 68 00 00 00 00 pushq $0 -# CHECK-HELPERS: 68 0b 00 00 00 pushq $11 -# CHECK-HELPERS: 68 16 00 00 00 pushq $22 +# CHECK-HELPERS: 68 10 00 00 00 pushq $16 +# CHECK-HELPERS: 68 20 00 00 00 pushq $32 # Make sure the stub helper is correctly aligned # CHECK-DYLIBS: sectname __stub_helper From 9ea23272fac7f4580d29f7ee557108883f127a5d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 1 Dec 2017 12:06:33 -0500 Subject: [PATCH 2/7] LLD patch: COFF: better behavior when using as a library This applies de776439b61fb71c1256ad86238799c758c66048 from the LLVM git monorepo to the embedded LLD. --- deps/lld/COFF/Config.h | 1 + deps/lld/COFF/Driver.cpp | 16 ++++++++++------ deps/lld/COFF/Error.cpp | 5 +++-- deps/lld/COFF/Error.h | 2 ++ deps/lld/include/lld/Driver/Driver.h | 2 +- deps/lld/tools/lld/lld.cpp | 2 +- 6 files changed, 18 insertions(+), 10 deletions(-) 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 854c3e6909..868ff0aa1e 100644 --- a/deps/lld/COFF/Driver.cpp +++ b/deps/lld/COFF/Driver.cpp @@ -52,15 +52,22 @@ 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; } @@ -1030,7 +1037,7 @@ void LinkerDriver::link(ArrayRef ArgsArr) { if (!Args.hasArgNoClaim(OPT_INPUT)) { fixupExports(); createImportLibrary(/*AsLib=*/true); - exit(0); + return; } // Handle /delayload @@ -1122,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 @@ -1172,9 +1179,6 @@ void LinkerDriver::link(ArrayRef ArgsArr) { // Write the result. writeResult(&Symtab); - - // Call exit to avoid calling destructors. - exit(0); } } // namespace coff 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/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/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: From fa45407e78c7a20281bf063f659d74f86c127ea1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 1 Dec 2017 12:08:16 -0500 Subject: [PATCH 3/7] LLD patch: Fix for LLD on linker scripts with empty sections This reapplies 569cf286ff79a10126b9f20f39fa8c64df9b8b25 to the embedded LLD. --- deps/lld/ELF/LinkerScript.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/lld/ELF/LinkerScript.cpp b/deps/lld/ELF/LinkerScript.cpp index 8bdbd8db20..614f5e2c8b 100644 --- a/deps/lld/ELF/LinkerScript.cpp +++ b/deps/lld/ELF/LinkerScript.cpp @@ -751,7 +751,7 @@ void LinkerScript::adjustSectionsAfterSorting() { if (auto *Cmd = dyn_cast(Base)) { Cmd->MemRegion = findMemoryRegion(Cmd); // Handle align (e.g. ".foo : ALIGN(16) { ... }"). - if (Cmd->AlignExpr) + if (Cmd->AlignExpr && Cmd->Sec) Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue()); } } From ddca67a2b94f68985789fc8254fd1326e26269f6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 1 Dec 2017 12:09:55 -0500 Subject: [PATCH 4/7] LLD patch: workaround for buggy MACH-O code This reapplies 1a1414fc42c7beb25b6de4134d99884ea6544b57 to the embedded LLD. --- deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index d687ca5de5..07958da4b9 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -617,7 +617,6 @@ void ArchHandler_x86_64::applyFixupFinal( // Fall into llvm_unreachable(). break; } - llvm_unreachable("invalid x86_64 Reference Kind"); } void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, From a206ef34bbbc46017e471063a4a1832c1ddafb0a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 1 Dec 2017 12:11:55 -0500 Subject: [PATCH 5/7] LLD patch: Fix the ASM code generated for __stub_helpers section This applies 93ca847862af07632197dcf2d8a68b9b27a26d7a from the llvm-project git monorepo to the embedded LLD. --- deps/lld/lib/ReaderWriter/MachO/ArchHandler.h | 4 ++ .../ReaderWriter/MachO/ArchHandler_arm.cpp | 4 ++ .../ReaderWriter/MachO/ArchHandler_arm64.cpp | 4 ++ .../ReaderWriter/MachO/ArchHandler_x86.cpp | 4 ++ .../ReaderWriter/MachO/ArchHandler_x86_64.cpp | 4 ++ .../MachO/MachONormalizedFileFromAtoms.cpp | 57 +++++++++++++++++++ deps/lld/test/mach-o/lazy-bind-x86_64.yaml | 4 +- 7 files changed, 79 insertions(+), 2 deletions(-) diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler.h b/deps/lld/lib/ReaderWriter/MachO/ArchHandler.h index 70a63bd100..6028006ca9 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler.h +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler.h @@ -112,6 +112,10 @@ public: /// info in final executables. virtual bool isLazyPointer(const Reference &); + /// Reference from an __stub_helper entry to the required offset of the + /// lazy bind commands. + virtual Reference::KindValue lazyImmediateLocationKind() = 0; + /// Returns true if the specified relocation is paired to the next relocation. virtual bool isPairedReloc(const normalized::Relocation &) = 0; diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp index 7d1544854c..2f663c660f 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp @@ -67,6 +67,10 @@ public: return invalid; } + Reference::KindValue lazyImmediateLocationKind() override { + return lazyImmediateLocation; + } + Reference::KindValue pointerKind() override { return invalid; } diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp index 10360b5c6d..b9c815c5a3 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp @@ -127,6 +127,10 @@ public: return pointer64; } + Reference::KindValue lazyImmediateLocationKind() override { + return lazyImmediateLocation; + } + uint32_t dwarfCompactUnwindType() override { return 0x03000000; } diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp index 2272bff65c..a2c6809272 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp @@ -70,6 +70,10 @@ public: return delta32; } + Reference::KindValue lazyImmediateLocationKind() override { + return lazyImmediateLocation; + } + Reference::KindValue unwindRefToEhFrameKind() override { return invalid; } diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index 07958da4b9..b207c85523 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -116,6 +116,10 @@ public: return unwindFDEToFunction; } + Reference::KindValue lazyImmediateLocationKind() override { + return lazyImmediateLocation; + } + Reference::KindValue unwindRefToEhFrameKind() override { return unwindInfoToEhFrame; } diff --git a/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index e58e3d2e7a..f2e5ed7816 100644 --- a/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -172,6 +172,8 @@ private: SymbolScope &symbolScope); void appendSection(SectionInfo *si, NormalizedFile &file); uint32_t sectionIndexForAtom(const Atom *atom); + void fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset, + NormalizedFile &file); typedef llvm::DenseMap AtomToIndex; struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; }; @@ -1423,6 +1425,8 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile, uint8_t segmentIndex; uint64_t segmentStartAddr; + uint32_t offsetInBindInfo = 0; + for (SectionInfo *sect : _sectionInfos) { segIndexForSection(sect, segmentIndex, segmentStartAddr); for (const AtomInfo &info : sect->atomsAndOffsets) { @@ -1467,6 +1471,59 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile, bind.symbolName = targ->name(); bind.addend = ref->addend(); nFile.lazyBindingInfo.push_back(bind); + + // Now that we know the segmentOffset and the ordinal attribute, + // we can fix the helper's code + + fixLazyReferenceImm(atom, offsetInBindInfo, nFile); + + // 5 bytes for opcodes + variable sizes (target name + \0 and offset + // encode's size) + offsetInBindInfo += + 6 + targ->name().size() + llvm::getULEB128Size(bind.segOffset); + if (bind.ordinal > BIND_IMMEDIATE_MASK) + offsetInBindInfo += llvm::getULEB128Size(bind.ordinal); + } + } + } + } +} + +void Util::fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset, + NormalizedFile &file) { + for (const auto &ref : *atom) { + const DefinedAtom *da = dyn_cast(ref->target()); + if (da == nullptr) + return; + + const Reference *helperRef = nullptr; + for (const Reference *hr : *da) { + if (hr->kindValue() == _archHandler.lazyImmediateLocationKind()) { + helperRef = hr; + break; + } + } + if (helperRef == nullptr) + continue; + + // TODO: maybe get the fixed atom content from _archHandler ? + for (SectionInfo *sectInfo : _sectionInfos) { + for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) { + if (atomInfo.atom == helperRef->target()) { + auto sectionContent = + file.sections[sectInfo->normalizedSectionIndex].content; + uint8_t *rawb = + file.ownedAllocations.Allocate(sectionContent.size()); + llvm::MutableArrayRef newContent{rawb, + sectionContent.size()}; + std::copy(sectionContent.begin(), sectionContent.end(), + newContent.begin()); + llvm::support::ulittle32_t *loc = + reinterpret_cast( + &newContent[atomInfo.offsetInSection + + helperRef->offsetInAtom()]); + *loc = offset; + file.sections[sectInfo->normalizedSectionIndex].content = newContent; } } } diff --git a/deps/lld/test/mach-o/lazy-bind-x86_64.yaml b/deps/lld/test/mach-o/lazy-bind-x86_64.yaml index 5c588c5719..1322719e5f 100644 --- a/deps/lld/test/mach-o/lazy-bind-x86_64.yaml +++ b/deps/lld/test/mach-o/lazy-bind-x86_64.yaml @@ -80,8 +80,8 @@ undefined-symbols: # CHECK-HELPERS:Disassembly of section __TEXT,__stub_helper: # CHECK-HELPERS: 68 00 00 00 00 pushq $0 -# CHECK-HELPERS: 68 10 00 00 00 pushq $16 -# CHECK-HELPERS: 68 20 00 00 00 pushq $32 +# CHECK-HELPERS: 68 0b 00 00 00 pushq $11 +# CHECK-HELPERS: 68 16 00 00 00 pushq $22 # Make sure the stub helper is correctly aligned # CHECK-DYLIBS: sectname __stub_helper From bdd5241615bf41b69d3e12f3b6796bd796fb90f2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 1 Dec 2017 12:15:19 -0500 Subject: [PATCH 6/7] update c_headers to llvm 5.0.1rc2 --- c_headers/avx512fintrin.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) 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) From cf96b6f87b5feaa699f0d15b1525d53a374b6227 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 1 Dec 2017 13:44:28 -0500 Subject: [PATCH 7/7] update to LLVM 5.0.1rc2 --- CMakeLists.txt | 11 ++++++++--- src/zig_llvm.cpp | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) 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/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);