diff --git a/deps/lld/CMakeLists.txt b/deps/lld/CMakeLists.txt index e2fbdbfbbb..641f71c114 100644 --- a/deps/lld/CMakeLists.txt +++ b/deps/lld/CMakeLists.txt @@ -56,7 +56,6 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) include(HandleLLVMOptions) if(LLVM_INCLUDE_TESTS) - set(Python_ADDITIONAL_VERSIONS 2.7) include(FindPythonInterp) if(NOT PYTHONINTERP_FOUND) message(FATAL_ERROR diff --git a/deps/lld/COFF/Config.h b/deps/lld/COFF/Config.h index 1b0e240427..4b62cd05f4 100644 --- a/deps/lld/COFF/Config.h +++ b/deps/lld/COFF/Config.h @@ -189,6 +189,7 @@ struct Configuration { // Used for /thinlto-object-suffix-replace: std::pair thinLTOObjectSuffixReplace; + uint64_t align = 4096; uint64_t imageBase = -1; uint64_t fileAlign = 512; uint64_t stackReserve = 1024 * 1024; diff --git a/deps/lld/COFF/Driver.cpp b/deps/lld/COFF/Driver.cpp index 7214d12bde..eb3aff1a8b 100644 --- a/deps/lld/COFF/Driver.cpp +++ b/deps/lld/COFF/Driver.cpp @@ -36,6 +36,7 @@ #include "llvm/Option/Option.h" #include "llvm/Support/Debug.h" #include "llvm/Support/LEB128.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/TarWriter.h" @@ -270,13 +271,12 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName, } void LinkerDriver::enqueueArchiveMember(const Archive::Child &c, - StringRef symName, + const Archive::Symbol &sym, StringRef parentName) { - auto reportBufferError = [=](Error &&e, - StringRef childName) { + auto reportBufferError = [=](Error &&e, StringRef childName) { fatal("could not get the buffer for the member defining symbol " + - symName + ": " + parentName + "(" + childName + "): " + + toCOFFString(sym) + ": " + parentName + "(" + childName + "): " + toString(std::move(e))); }; @@ -287,7 +287,8 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c, reportBufferError(mbOrErr.takeError(), check(c.getFullName())); MemoryBufferRef mb = mbOrErr.get(); enqueueTask([=]() { - driver->addArchiveBuffer(mb, symName, parentName, offsetInArchive); + driver->addArchiveBuffer(mb, toCOFFString(sym), parentName, + offsetInArchive); }); return; } @@ -295,15 +296,16 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c, std::string childName = CHECK( c.getFullName(), "could not get the filename for the member defining symbol " + - symName); + toCOFFString(sym)); auto future = std::make_shared>( createFutureForFile(childName)); enqueueTask([=]() { auto mbOrErr = future->get(); if (mbOrErr.second) reportBufferError(errorCodeToError(mbOrErr.second), childName); - driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), symName, - parentName, /* OffsetInArchive */ 0); + driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), + toCOFFString(sym), parentName, + /*OffsetInArchive=*/0); }); } @@ -1053,6 +1055,12 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) { }); } +static const char *libcallRoutineNames[] = { +#define HANDLE_LIBCALL(code, name) name, +#include "llvm/IR/RuntimeLibcalls.def" +#undef HANDLE_LIBCALL +}; + void LinkerDriver::link(ArrayRef argsArr) { // Needed for LTO. InitializeAllTargetInfos(); @@ -1421,6 +1429,13 @@ void LinkerDriver::link(ArrayRef argsArr) { for (auto *arg : args.filtered(OPT_section)) parseSection(arg->getValue()); + // Handle /align + if (auto *arg = args.getLastArg(OPT_align)) { + parseNumbers(arg->getValue(), &config->align); + if (!isPowerOf2_64(config->align)) + error("/align: not a power of two: " + StringRef(arg->getValue())); + } + // Handle /aligncomm for (auto *arg : args.filtered(OPT_aligncomm)) parseAligncomm(arg->getValue()); @@ -1748,6 +1763,15 @@ void LinkerDriver::link(ArrayRef argsArr) { u->weakAlias = symtab->addUndefined(to); } + // If any inputs are bitcode files, the LTO code generator may create + // references to library functions that are not explicit in the bitcode + // file's symbol table. If any of those library functions are defined in a + // bitcode file in an archive member, we need to arrange to use LTO to + // compile those archive members by adding them to the link beforehand. + if (!BitcodeFile::instances.empty()) + for (const char *s : libcallRoutineNames) + symtab->addLibcall(s); + // Windows specific -- if __load_config_used can be resolved, resolve it. if (symtab->findUnderscore("_load_config_used")) addUndefined(mangle("_load_config_used")); diff --git a/deps/lld/COFF/Driver.h b/deps/lld/COFF/Driver.h index 6100c3ca0c..01bfb02a5c 100644 --- a/deps/lld/COFF/Driver.h +++ b/deps/lld/COFF/Driver.h @@ -72,7 +72,7 @@ public: void parseDirectives(InputFile *file); // Used by ArchiveFile to enqueue members. - void enqueueArchiveMember(const Archive::Child &c, StringRef symName, + void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym, StringRef parentName); MemoryBufferRef takeBuffer(std::unique_ptr mb); diff --git a/deps/lld/COFF/InputFiles.cpp b/deps/lld/COFF/InputFiles.cpp index c00d5c5b49..d02fedfd17 100644 --- a/deps/lld/COFF/InputFiles.cpp +++ b/deps/lld/COFF/InputFiles.cpp @@ -85,16 +85,16 @@ void ArchiveFile::parse() { } // Returns a buffer pointing to a member file containing a given symbol. -void ArchiveFile::addMember(const Archive::Symbol *sym) { +void ArchiveFile::addMember(const Archive::Symbol &sym) { const Archive::Child &c = - CHECK(sym->getMember(), - "could not get the member for symbol " + sym->getName()); + CHECK(sym.getMember(), + "could not get the member for symbol " + toCOFFString(sym)); // Return an empty buffer if we have already returned the same buffer. if (!seen.insert(c.getChildOffset()).second) return; - driver->enqueueArchiveMember(c, sym->getName(), getName()); + driver->enqueueArchiveMember(c, sym, getName()); } std::vector getArchiveMembers(Archive *file) { diff --git a/deps/lld/COFF/InputFiles.h b/deps/lld/COFF/InputFiles.h index dfad9814a3..8d3a021a37 100644 --- a/deps/lld/COFF/InputFiles.h +++ b/deps/lld/COFF/InputFiles.h @@ -96,7 +96,7 @@ public: // Enqueues an archive member load for the given symbol. If we've already // enqueued a load for the same archive member, this function does nothing, // which ensures that we don't load the same member more than once. - void addMember(const Archive::Symbol *sym); + void addMember(const Archive::Symbol &sym); private: std::unique_ptr file; diff --git a/deps/lld/COFF/SymbolTable.cpp b/deps/lld/COFF/SymbolTable.cpp index 0aff164ee5..3f3e660747 100644 --- a/deps/lld/COFF/SymbolTable.cpp +++ b/deps/lld/COFF/SymbolTable.cpp @@ -179,7 +179,7 @@ void SymbolTable::loadMinGWAutomaticImports() { log("Loading lazy " + l->getName() + " from " + l->file->getName() + " for automatic import"); l->pendingArchiveLoad = true; - l->file->addMember(&l->sym); + l->file->addMember(l->sym); } } @@ -363,13 +363,13 @@ Symbol *SymbolTable::addUndefined(StringRef name, InputFile *f, if (auto *l = dyn_cast(s)) { if (!s->pendingArchiveLoad) { s->pendingArchiveLoad = true; - l->file->addMember(&l->sym); + l->file->addMember(l->sym); } } return s; } -void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol sym) { +void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol &sym) { StringRef name = sym.getName(); Symbol *s; bool wasInserted; @@ -382,7 +382,7 @@ void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol sym) { if (!u || u->weakAlias || s->pendingArchiveLoad) return; s->pendingArchiveLoad = true; - f->addMember(&sym); + f->addMember(sym); } void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile) { @@ -505,6 +505,18 @@ Symbol *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id, return nullptr; } +void SymbolTable::addLibcall(StringRef name) { + Symbol *sym = findUnderscore(name); + if (!sym) + return; + + if (Lazy *l = dyn_cast(sym)) { + MemoryBufferRef mb = l->getMemberBuffer(); + if (identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode) + addUndefined(sym->getName()); + } +} + std::vector SymbolTable::getChunks() { std::vector res; for (ObjFile *file : ObjFile::instances) { diff --git a/deps/lld/COFF/SymbolTable.h b/deps/lld/COFF/SymbolTable.h index 88f47cbe9e..f0a7aaf35a 100644 --- a/deps/lld/COFF/SymbolTable.h +++ b/deps/lld/COFF/SymbolTable.h @@ -83,7 +83,7 @@ public: Symbol *addAbsolute(StringRef n, uint64_t va); Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias); - void addLazy(ArchiveFile *f, const Archive::Symbol sym); + void addLazy(ArchiveFile *f, const Archive::Symbol &sym); Symbol *addAbsolute(StringRef n, COFFSymbolRef s); Symbol *addRegular(InputFile *f, StringRef n, const llvm::object::coff_symbol_generic *s = nullptr, @@ -97,6 +97,7 @@ public: Symbol *addImportData(StringRef n, ImportFile *f); Symbol *addImportThunk(StringRef name, DefinedImportData *s, uint16_t machine); + void addLibcall(StringRef name); void reportDuplicate(Symbol *existing, InputFile *newFile); diff --git a/deps/lld/COFF/Symbols.cpp b/deps/lld/COFF/Symbols.cpp index 3583d4cb28..1af11820a7 100644 --- a/deps/lld/COFF/Symbols.cpp +++ b/deps/lld/COFF/Symbols.cpp @@ -20,18 +20,23 @@ using namespace llvm::object; using namespace lld::coff; +namespace lld { + static_assert(sizeof(SymbolUnion) <= 48, "symbols should be optimized for memory usage"); // Returns a symbol name for an error message. -std::string lld::toString(coff::Symbol &b) { +static std::string demangle(StringRef symName) { if (config->demangle) - if (Optional s = lld::demangleMSVC(b.getName())) + if (Optional s = demangleMSVC(symName)) return *s; - return b.getName(); + return symName; +} +std::string toString(coff::Symbol &b) { return demangle(b.getName()); } +std::string toCOFFString(const Archive::Symbol &b) { + return demangle(b.getName()); } -namespace lld { namespace coff { StringRef Symbol::getName() { @@ -113,5 +118,14 @@ Defined *Undefined::getWeakAlias() { return d; return nullptr; } + +MemoryBufferRef Lazy::getMemberBuffer() { + Archive::Child c = + CHECK(sym.getMember(), + "could not get the member for symbol " + toCOFFString(sym)); + return CHECK(c.getMemoryBufferRef(), + "could not get the buffer for the member defining symbol " + + toCOFFString(sym)); +} } // namespace coff } // namespace lld diff --git a/deps/lld/COFF/Symbols.h b/deps/lld/COFF/Symbols.h index 86cd4f585e..78c357aa2a 100644 --- a/deps/lld/COFF/Symbols.h +++ b/deps/lld/COFF/Symbols.h @@ -21,6 +21,14 @@ #include namespace lld { + +std::string toString(coff::Symbol &b); + +// There are two different ways to convert an Archive::Symbol to a string: +// One for Microsoft name mangling and one for Itanium name mangling. +// Call the functions toCOFFString and toELFString, not just toString. +std::string toCOFFString(const coff::Archive::Symbol &b); + namespace coff { using llvm::object::Archive; @@ -257,6 +265,8 @@ public: static bool classof(const Symbol *s) { return s->kind() == LazyKind; } + MemoryBufferRef getMemberBuffer(); + ArchiveFile *file; private: @@ -429,7 +439,6 @@ void replaceSymbol(Symbol *s, ArgT &&... arg) { } } // namespace coff -std::string toString(coff::Symbol &b); } // namespace lld #endif diff --git a/deps/lld/COFF/Writer.cpp b/deps/lld/COFF/Writer.cpp index cc75db0f51..5736281958 100644 --- a/deps/lld/COFF/Writer.cpp +++ b/deps/lld/COFF/Writer.cpp @@ -626,6 +626,9 @@ void Writer::run() { writeMapFile(outputSections); + if (errorCount()) + return; + ScopedTimer t2(diskCommitTimer); if (auto e = buffer->commit()) fatal("failed to write the output file: " + toString(std::move(e))); @@ -1205,9 +1208,11 @@ void Writer::assignAddresses() { sizeOfHeaders += config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); sizeOfHeaders = alignTo(sizeOfHeaders, config->fileAlign); - uint64_t rva = pageSize; // The first page is kept unmapped. fileSize = sizeOfHeaders; + // The first page is kept unmapped. + uint64_t rva = alignTo(sizeOfHeaders, config->align); + for (OutputSection *sec : outputSections) { if (sec == relocSec) addBaserels(); @@ -1237,10 +1242,10 @@ void Writer::assignAddresses() { sec->header.SizeOfRawData = rawSize; if (rawSize != 0) sec->header.PointerToRawData = fileSize; - rva += alignTo(virtualSize, pageSize); + rva += alignTo(virtualSize, config->align); fileSize += alignTo(rawSize, config->fileAlign); } - sizeOfImage = alignTo(rva, pageSize); + sizeOfImage = alignTo(rva, config->align); // Assign addresses to sections in MergeChunks. for (MergeChunk *mc : MergeChunk::instances) @@ -1309,7 +1314,7 @@ template void Writer::writeHeader() { pe->MinorLinkerVersion = 0; pe->ImageBase = config->imageBase; - pe->SectionAlignment = pageSize; + pe->SectionAlignment = config->align; pe->FileAlignment = config->fileAlign; pe->MajorImageVersion = config->majorImageVersion; pe->MinorImageVersion = config->minorImageVersion; diff --git a/deps/lld/ELF/Arch/PPC.cpp b/deps/lld/ELF/Arch/PPC.cpp index 46c5891e4f..cf4ad40499 100644 --- a/deps/lld/ELF/Arch/PPC.cpp +++ b/deps/lld/ELF/Arch/PPC.cpp @@ -190,6 +190,13 @@ bool PPC::inBranchRange(RelType type, uint64_t src, uint64_t dst) const { RelExpr PPC::getRelExpr(RelType type, const Symbol &s, const uint8_t *loc) const { switch (type) { + case R_PPC_NONE: + return R_NONE; + case R_PPC_ADDR16_HA: + case R_PPC_ADDR16_HI: + case R_PPC_ADDR16_LO: + case R_PPC_ADDR32: + return R_ABS; case R_PPC_DTPREL16: case R_PPC_DTPREL16_HA: case R_PPC_DTPREL16_HI: @@ -227,7 +234,9 @@ RelExpr PPC::getRelExpr(RelType type, const Symbol &s, case R_PPC_TPREL16_HI: return R_TLS; default: - return R_ABS; + error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) + + ") against symbol " + toString(s)); + return R_NONE; } } @@ -319,7 +328,7 @@ void PPC::relocateOne(uint8_t *loc, RelType type, uint64_t val) const { break; } default: - error(getErrorLocation(loc) + "unrecognized relocation " + toString(type)); + llvm_unreachable("unknown relocation"); } } diff --git a/deps/lld/ELF/Arch/PPC64.cpp b/deps/lld/ELF/Arch/PPC64.cpp index 70d284cfad..0f382dcd6b 100644 --- a/deps/lld/ELF/Arch/PPC64.cpp +++ b/deps/lld/ELF/Arch/PPC64.cpp @@ -532,6 +532,21 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const { RelExpr PPC64::getRelExpr(RelType type, const Symbol &s, const uint8_t *loc) const { switch (type) { + case R_PPC64_NONE: + return R_NONE; + case R_PPC64_ADDR16: + case R_PPC64_ADDR16_DS: + case R_PPC64_ADDR16_HA: + case R_PPC64_ADDR16_HI: + case R_PPC64_ADDR16_HIGHER: + case R_PPC64_ADDR16_HIGHERA: + case R_PPC64_ADDR16_HIGHEST: + case R_PPC64_ADDR16_HIGHESTA: + case R_PPC64_ADDR16_LO: + case R_PPC64_ADDR16_LO_DS: + case R_PPC64_ADDR32: + case R_PPC64_ADDR64: + return R_ABS; case R_PPC64_GOT16: case R_PPC64_GOT16_DS: case R_PPC64_GOT16_HA: @@ -554,6 +569,7 @@ RelExpr PPC64::getRelExpr(RelType type, const Symbol &s, return R_PPC64_CALL_PLT; case R_PPC64_REL16_LO: case R_PPC64_REL16_HA: + case R_PPC64_REL16_HI: case R_PPC64_REL32: case R_PPC64_REL64: return R_PC; @@ -607,7 +623,9 @@ RelExpr PPC64::getRelExpr(RelType type, const Symbol &s, case R_PPC64_TLS: return R_TLSIE_HINT; default: - return R_ABS; + error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) + + ") against symbol " + toString(s)); + return R_NONE; } } @@ -870,7 +888,7 @@ void PPC64::relocateOne(uint8_t *loc, RelType type, uint64_t val) const { write64(loc, val - dynamicThreadPointerOffset); break; default: - error(getErrorLocation(loc) + "unrecognized relocation " + toString(type)); + llvm_unreachable("unknown relocation"); } } diff --git a/deps/lld/ELF/InputFiles.cpp b/deps/lld/ELF/InputFiles.cpp index 98b88283cf..f9cbf15690 100644 --- a/deps/lld/ELF/InputFiles.cpp +++ b/deps/lld/ELF/InputFiles.cpp @@ -1144,7 +1144,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) { Archive::Child c = CHECK(sym.getMember(), toString(this) + ": could not get the member for symbol " + - sym.getName()); + toELFString(sym)); if (!seen.insert(c.getChildOffset()).second) return; @@ -1153,7 +1153,7 @@ void ArchiveFile::fetch(const Archive::Symbol &sym) { CHECK(c.getMemoryBufferRef(), toString(this) + ": could not get the buffer for the member defining symbol " + - sym.getName()); + toELFString(sym)); if (tar && c.getParent()->isThin()) tar->append(relativeToRoot(CHECK(c.getFullName(), this)), mb.getBuffer()); diff --git a/deps/lld/ELF/Symbols.cpp b/deps/lld/ELF/Symbols.cpp index 62c552e048..22677303c3 100644 --- a/deps/lld/ELF/Symbols.cpp +++ b/deps/lld/ELF/Symbols.cpp @@ -42,6 +42,20 @@ Defined *ElfSym::relaIpltEnd; Defined *ElfSym::riscvGlobalPointer; Defined *ElfSym::tlsModuleBase; +// Returns a symbol for an error message. +static std::string demangle(StringRef symName) { + if (config->demangle) + if (Optional s = demangleItanium(symName)) + return *s; + return symName; +} +namespace lld { +std::string toString(const Symbol &b) { return demangle(b.getName()); } +std::string toELFString(const Archive::Symbol &b) { + return demangle(b.getName()); +} +} // namespace lld + static uint64_t getSymVA(const Symbol &sym, int64_t &addend) { switch (sym.kind()) { case Symbol::DefinedKind: { @@ -250,12 +264,13 @@ void Symbol::fetch() const { } MemoryBufferRef LazyArchive::getMemberBuffer() { - Archive::Child c = CHECK( - sym.getMember(), "could not get the member for symbol " + sym.getName()); + Archive::Child c = + CHECK(sym.getMember(), + "could not get the member for symbol " + toELFString(sym)); return CHECK(c.getMemoryBufferRef(), "could not get the buffer for the member defining symbol " + - sym.getName()); + toELFString(sym)); } uint8_t Symbol::computeBinding() const { @@ -331,14 +346,6 @@ void elf::maybeWarnUnorderableSymbol(const Symbol *sym) { report(": unable to order discarded symbol: "); } -// Returns a symbol for an error message. -std::string lld::toString(const Symbol &b) { - if (config->demangle) - if (Optional s = demangleItanium(b.getName())) - return *s; - return b.getName(); -} - static uint8_t getMinVisibility(uint8_t va, uint8_t vb) { if (va == STV_DEFAULT) return vb; diff --git a/deps/lld/ELF/Symbols.h b/deps/lld/ELF/Symbols.h index d640495b0e..9c1eb387c2 100644 --- a/deps/lld/ELF/Symbols.h +++ b/deps/lld/ELF/Symbols.h @@ -33,7 +33,11 @@ class Undefined; } // namespace elf std::string toString(const elf::Symbol &); -std::string toString(const elf::InputFile *); + +// There are two different ways to convert an Archive::Symbol to a string: +// One for Microsoft name mangling and one for Itanium name mangling. +// Call the functions toCOFFString and toELFString, not just toString. +std::string toELFString(const elf::Archive::Symbol &); namespace elf { diff --git a/deps/lld/ELF/Writer.cpp b/deps/lld/ELF/Writer.cpp index b8c8891648..10b171e8c0 100644 --- a/deps/lld/ELF/Writer.cpp +++ b/deps/lld/ELF/Writer.cpp @@ -2230,25 +2230,27 @@ template void Writer::fixSectionAlignments() { // same with its virtual address modulo the page size, so that the loader can // load executables without any address adjustment. static uint64_t computeFileOffset(OutputSection *os, uint64_t off) { - // File offsets are not significant for .bss sections. By convention, we keep - // section offsets monotonically increasing rather than setting to zero. - if (os->type == SHT_NOBITS) - return off; + // The first section in a PT_LOAD has to have congruent offset and address + // module the page size. + if (os->ptLoad && os->ptLoad->firstSec == os) { + uint64_t alignment = + std::max(os->ptLoad->p_align, config->maxPageSize); + return alignTo(off, alignment, os->addr); + } + + // File offsets are not significant for .bss sections other than the first one + // in a PT_LOAD. By convention, we keep section offsets monotonically + // increasing rather than setting to zero. + if (os->type == SHT_NOBITS) + return off; // If the section is not in a PT_LOAD, we just have to align it. if (!os->ptLoad) return alignTo(off, os->alignment); - // The first section in a PT_LOAD has to have congruent offset and address - // module the page size. - OutputSection *first = os->ptLoad->firstSec; - if (os == first) { - uint64_t alignment = std::max(os->alignment, config->maxPageSize); - return alignTo(off, alignment, os->addr); - } - // If two sections share the same PT_LOAD the file offset is calculated // using this formula: Off2 = Off1 + (VA2 - VA1). + OutputSection *first = os->ptLoad->firstSec; return first->offset + os->addr - first->addr; } diff --git a/deps/lld/docs/ReleaseNotes.rst b/deps/lld/docs/ReleaseNotes.rst index 2d358bf8f2..df00e31bf9 100644 --- a/deps/lld/docs/ReleaseNotes.rst +++ b/deps/lld/docs/ReleaseNotes.rst @@ -5,18 +5,15 @@ lld 9.0.0 Release Notes .. contents:: :local: -.. warning:: - These are in-progress notes for the upcoming LLVM 9.0.0 release. - Release notes for previous releases can be found on - `the Download Page `_. - Introduction ============ -This document contains the release notes for the lld linker, release 9.0.0. -Here we describe the status of lld, including major improvements -from the previous release. All lld releases may be downloaded -from the `LLVM releases web site `_. +lld is a high-performance linker that supports ELF (Unix), COFF +(Windows), Mach-O (macOS), MinGW and WebAssembly. lld is +command-line-compatible with GNU linkers and Microsoft link.exe and is +significantly faster than the system default linkers. + +lld 9 has lots of feature improvements and bug fixes. Non-comprehensive list of changes in this release ================================================= @@ -27,50 +24,187 @@ ELF Improvements * ld.lld now has typo suggestions for flags: ``$ ld.lld --call-shared`` now prints ``unknown argument '--call-shared', did you mean '--call_shared'``. + (`r361518 `_) + +* ``--allow-shlib-undefined`` and ``--no-allow-shlib-undefined`` + options are added. ``--no-allow-shlib-undefined`` is the default for + executables. + (`r352826 `_) + +* ``-nmagic`` and ``-omagic`` options are fully supported. + (`r360593 `_) + +* Segment layout has changed. PT_GNU_RELRO, which was previously + placed in the middle of readable/writable PT_LOAD segments, is now + placed at the beginning of them. This change permits lld-produced + ELF files to be read correctly by GNU strip older than 2.31, which + has a bug to discard a PT_GNU_RELRO in the former layout. + +* ``-z common-page-size`` is supported. + (`r360593 `_) + +* Diagnostics messages have improved. A new flag ``--vs-diagnostics`` + alters the format of diagnostic output to enable source hyperlinks + in Microsoft Visual Studio IDE. + +* Linker script compatibility with GNU BFD linker has generally improved. + +* The clang ``--dependent-library`` form of autolinking is supported. + + This feature is added to implement the Windows-style autolinking for + Unix. On Unix, in order to use a library, you usually have to + include a header file provided by the library and then explicitly + link the library with the linker ``-l`` option. On Windows, header + files usually contain pragmas that list needed libraries. Compilers + copy that information to object files, so that linkers can + automatically link needed libraries. ``--dependent-library`` is + added for implementing that Windows semantics on Unix. + (`r360984 `_) + +* AArch64 BTI and PAC are supported. + (`r362793 `_) * lld now supports replacing ``JAL`` with ``JALX`` instructions in case - of MIPS - microMIPS cross-mode jumps. + of MIPS-microMIPS cross-mode jumps. + (`r354311 `_) * lld now creates LA25 thunks for MIPS R6 code. + (`r354312 `_) * Put MIPS-specific .reginfo, .MIPS.options, and .MIPS.abiflags sections into corresponding PT_MIPS_REGINFO, PT_MIPS_OPTIONS, and PT_MIPS_ABIFLAGS segments. -* ... +* The quality of RISC-V and PowerPC ports have greatly improved. Many + applications can now be linked by lld. PowerPC64 is now almost + production ready. + +* The Linux kernel for arm32_7, arm64, ppc64le and x86_64 can now be + linked by lld. + +* x86-64 TLSDESC is supported. + (`r361911 `_, + `r362078 `_) + +* DF_STATIC_TLS flag is set for i386 and x86-64 when needed. + (`r353293 `_, + `r353378 `_) + +* The experimental partitioning feature is added to allow a program to + be split into multiple pieces. + + The feature allows you to semi-automatically split a single program + into multiple ELF files called "partitions". Since all partitions + share the same memory address space and don't use PLT/GOT, split + programs run as fast as regular programs. + + With the mechanism, you can start a program only with a "main" + partition and load remaining partitions on-demand. For example, you + can split a web browser into a main partition and a PDF reader + sub-partition and load the PDF reader partition only when a user + tries to open a PDF file. + + See `the documentation `_ for more information. + +* If "-" is given as an output filename, lld writes the final result + to the standard output. Previously, it created a file "-" in the + current directory. + (`r351852 `_) + +* ``-z ifunc-noplt`` option is added to reduce IFunc function call + overhead in a freestanding environment such as the OS kernel. + + Functions resolved by the IFunc mechanism are usually dispatched via + PLT and thus slower than regular functions because of the cost of + indirection. With ``-z ifunc-noplt``, you can eliminate it by doing + text relocations at load-time. You need a special loader to utilize + this feature. This feature is added for the FreeBSD kernel but can + be used by any operating systems. + (`r360685 `_) + +* ``--undefined-glob`` option is added. The new option is an extension + to ``--undefined`` to take a glob pattern instead of a single symbol + name. + (`r363396 `_) + COFF Improvements ----------------- * Like the ELF driver, lld-link now has typo suggestions for flags. + (`r361518 `_) -* lld-link now correctly reports duplicate symbol errors for obj files - that were compiled with /Gy. +* lld-link now correctly reports duplicate symbol errors for object + files that were compiled with ``/Gy``. + (`r352590 `_) -* lld-link now correctly reports duplicate symbol errors when several res - input files define resources with the same type, name, and language. - This can be demoted to a warning using ``/force:multipleres``. +* lld-link now correctly reports duplicate symbol errors when several + resource (.res) input files define resources with the same type, + name and language. This can be demoted to a warning using + ``/force:multipleres``. + (`r359829 `_) + +* lld-link now rejects more than one resource object input files, + matching link.exe. Previously, lld-link would silently ignore all + but one. If you hit this: Don't pass resource object files to the + linker, instead pass res files to the linker directly. Don't put + resource files in static libraries, pass them on the command line. + (`r359749 `_) * Having more than two ``/natvis:`` now works correctly; it used to not work for larger binaries before. + (`r327895 `_) * Undefined symbols are now printed only in demangled form. Pass ``/demangle:no`` to see raw symbol names instead. - -* The following flags have been added: ``/functionpadmin``, ``/swaprun:``, - ``/threads:no`` + (`r355878 `_) * Several speed and memory usage improvements. -* Range extension thunks are now created for ARM64, if needed - * lld-link now supports resource object files created by GNU windres and - MS cvtres, not only llvm-cvtres + MS cvtres, not only llvm-cvtres. * The generated thunks for delayimports now share the majority of code - among thunks, significantly reducing the overhead of using delayimport + among thunks, significantly reducing the overhead of using delayimport. + (`r365823 `_) + +* ``IMAGE_REL_ARM{,64}_REL32`` relocations are supported. + (`r352325 `_) + +* Range extension thunks for AArch64 are now supported, so lld can + create large executables for Windows/ARM64. + (`r352929 `_) + +* The following flags have been added: + ``/functionpadmin`` (`r354716 `_), + ``/swaprun:`` (`r359192 `_), + ``/threads:no`` (`r355029 `_), + ``/filealign`` (`r361634 `_) + +WebAssembly Improvements +------------------------ + +* Imports from custom module names are supported. + (`r352828 `_) + +* Symbols that are in llvm.used are now exported by default. + (`r353364 `_) + +* Initial support for PIC and dynamic linking has landed. + (`r357022 `_) + +* wasm-ld now add ``__start_``/``__stop_`` symbols for data sections. + (`r361236 `_) + +* wasm-ld now doesn't report an error on archives without a symbol index. + (`r364338 `_) + +* The following flags have been added: + ``--emit-relocs`` (`r361635 `_), + ``--wrap`` (`r361639 `_), + ``--trace`` and ``--trace-symbol`` + (`r353264 `_). -* ... MinGW Improvements ------------------ @@ -80,22 +214,18 @@ MinGW Improvements DWARF exception handling with libgcc and gcc's crtend.o. * lld now also handles DWARF unwind info generated by GCC, when linking - with libgcc - -* Many more GNU ld options are now supported, which e.g. allows the lld - MinGW frontend to be called by GCC + with libgcc. * PDB output can be requested without manually specifying the PDB file name, with the new option ``-pdb=`` with an empty value to the option. (The old existing syntax ``-pdb `` was more cumbersome to use with an empty parameter value.) -MachO Improvements ------------------- +* ``--no-insert-timestamp`` option is added as an alias to ``/timestamp:0``. + (`r353145 `_) -* Item 1. +* Many more GNU ld options are now supported, which e.g. allows the lld + MinGW frontend to be called by GCC. -WebAssembly Improvements ------------------------- - -* ... +* The following options are added: ``--exclude-all-symbols``, + ``--appcontainer``, ``--undefined`` diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index f42ca3b2f7..316b5bbc6f 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -621,6 +621,7 @@ 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, diff --git a/deps/lld/test/COFF/Inputs/libcall-archive.ll b/deps/lld/test/COFF/Inputs/libcall-archive.ll new file mode 100644 index 0000000000..3f8a24df4c --- /dev/null +++ b/deps/lld/test/COFF/Inputs/libcall-archive.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686-unknown-windows" + +define void @memcpy() { + ret void +} diff --git a/deps/lld/test/COFF/Inputs/libcall-archive.s b/deps/lld/test/COFF/Inputs/libcall-archive.s new file mode 100644 index 0000000000..487cf2009f --- /dev/null +++ b/deps/lld/test/COFF/Inputs/libcall-archive.s @@ -0,0 +1,2 @@ +.globl ___sync_val_compare_and_swap_8 +___sync_val_compare_and_swap_8: diff --git a/deps/lld/test/COFF/align.s b/deps/lld/test/COFF/align.s new file mode 100644 index 0000000000..67ca349e00 --- /dev/null +++ b/deps/lld/test/COFF/align.s @@ -0,0 +1,45 @@ +# RUN: yaml2obj < %s > %t.obj +# RUN: lld-link /out:%t.exe /entry:main /align:32 %t.obj +# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s + +# CHECK: SectionAlignment: 32 + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4096 + SectionData: 0000000000000000 + Relocations: + - VirtualAddress: 0 + SymbolName: __ImageBase + Type: IMAGE_REL_AMD64_ADDR64 +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 8 + NumberOfRelocations: 1 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: main + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: __ImageBase + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/deps/lld/test/COFF/libcall-archive.ll b/deps/lld/test/COFF/libcall-archive.ll new file mode 100644 index 0000000000..631503d0dd --- /dev/null +++ b/deps/lld/test/COFF/libcall-archive.ll @@ -0,0 +1,22 @@ +; REQUIRES: x86 +; RUN: rm -f %t.a +; RUN: llvm-as -o %t.obj %s +; RUN: llvm-as -o %t2.obj %S/Inputs/libcall-archive.ll +; RUN: llvm-mc -filetype=obj -triple=i686-unknown-windows -o %t3.obj %S/Inputs/libcall-archive.s +; RUN: llvm-ar rcs %t.a %t2.obj %t3.obj +; RUN: lld-link -out:%t.exe -subsystem:console -entry:start -safeseh:no -lldmap:- %t.obj %t.a | FileCheck %s + +; CHECK-NOT: ___sync_val_compare_and_swap_8 +; CHECK: _start +; CHECK: _memcpy + +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686-unknown-windows" + +define void @start(i8* %a, i8* %b) { +entry: + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 1024, i1 false) + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) diff --git a/deps/lld/test/COFF/multiple-resource-objs.test b/deps/lld/test/COFF/multiple-resource-objs.test index 4263c64be4..be5f9a2806 100644 --- a/deps/lld/test/COFF/multiple-resource-objs.test +++ b/deps/lld/test/COFF/multiple-resource-objs.test @@ -1,7 +1,9 @@ # RUN: llvm-cvtres /out:%t_resource.obj %S/Inputs/resource.res # RUN: llvm-cvtres /out:%t_id.obj %S/Inputs/id.res +# RUN: rm -f %t.exe # RUN: not lld-link /out:%t.exe /dll /noentry %t_id.obj %t_resource.obj 2>&1 | \ # RUN: FileCheck --check-prefix=TWOOBJ %s +# RUN: not test -f %t.exe TWOOBJ: error: {{.*}}_resource.obj: more than one resource obj file not allowed, already got {{.*}}_id.obj diff --git a/deps/lld/test/COFF/thin-archive.s b/deps/lld/test/COFF/thin-archive.s index f24911de40..6eb896c57d 100644 --- a/deps/lld/test/COFF/thin-archive.s +++ b/deps/lld/test/COFF/thin-archive.s @@ -11,14 +11,18 @@ # RUN: FileCheck --allow-empty %s # RUN: lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe 2>&1 | \ # RUN: FileCheck --allow-empty %s -# RUN: lld-link /entry:main %t.main.obj /wholearchive:%t_thin.lib /out:%t.exe 2>&1 | \ -# RUN: FileCheck --allow-empty %s # RUN: rm %t.lib.obj # RUN: lld-link /entry:main %t.main.obj %t.lib /out:%t.exe 2>&1 | \ # RUN: FileCheck --allow-empty %s +# RUN: not lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe 2>&1 | \ +# RUN: FileCheck --check-prefix=NOOBJ %s +# RUN: not lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe \ +# RUN: /demangle:no 2>&1 | FileCheck --check-prefix=NOOBJNODEMANGLE %s # CHECK-NOT: error: could not get the buffer for the member defining +# NOOBJ: error: could not get the buffer for the member defining symbol int __cdecl f(void): {{.*}}.lib({{.*}}.lib.obj): +# NOOBJNODEMANGLE: error: could not get the buffer for the member defining symbol ?f@@YAHXZ: {{.*}}.lib({{.*}}.lib.obj): .text diff --git a/deps/lld/test/ELF/archive-thin-missing-member.s b/deps/lld/test/ELF/archive-thin-missing-member.s index d96fbc4541..4db1376cfa 100644 --- a/deps/lld/test/ELF/archive-thin-missing-member.s +++ b/deps/lld/test/ELF/archive-thin-missing-member.s @@ -8,17 +8,19 @@ # RUN: rm %t.o # Test error when loading symbols from missing thin archive member. -# RUN: not ld.lld %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1 +# RUN: not ld.lld --entry=_Z1fi %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1 # ERR1: {{.*}}-no-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory # Test error when thin archive has symbol table but member is missing. -# RUN: not ld.lld -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2 -# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol _start: '{{.*}}.o': {{[Nn]}}o such file or directory +# RUN: not ld.lld --entry=_Z1fi -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2 +# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol f(int): '{{.*}}.o': {{[Nn]}}o such file or directory +# RUN: not ld.lld --entry=_Z1fi --no-demangle -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2MANGLE +# ERR2MANGLE: {{.*}}-syms.a: could not get the buffer for the member defining symbol _Z1fi: '{{.*}}.o': {{[Nn]}}o such file or directory # Test error when thin archive is linked using --whole-archive but member is missing. -# RUN: not ld.lld --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3 +# RUN: not ld.lld --entry=_Z1fi --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3 # ERR3: {{.*}}-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory -.global _start -_start: +.global _Z1fi +_Z1fi: nop diff --git a/deps/lld/test/ELF/basic-ppc64.s b/deps/lld/test/ELF/basic-ppc64.s index cab130212b..d1e47464a9 100644 --- a/deps/lld/test/ELF/basic-ppc64.s +++ b/deps/lld/test/ELF/basic-ppc64.s @@ -35,7 +35,7 @@ // CHECK-NEXT: Version: 1 // CHECK-NEXT: Entry: 0x10000 // CHECK-NEXT: ProgramHeaderOffset: 0x40 -// CHECK-NEXT: SectionHeaderOffset: 0x200F8 +// CHECK-NEXT: SectionHeaderOffset: 0x30098 // CHECK-NEXT: Flags [ (0x2) // CHECK-NEXT: 0x2 // CHECK-NEXT: ] @@ -178,7 +178,7 @@ // CHECK-NEXT: SHF_WRITE (0x1) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x30000 -// CHECK-NEXT: Offset: 0x20060 +// CHECK-NEXT: Offset: 0x30000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -194,7 +194,7 @@ // CHECK-NEXT: SHF_STRINGS (0x20) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x20060 +// CHECK-NEXT: Offset: 0x30000 // CHECK-NEXT: Size: 8 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -211,7 +211,7 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x20068 +// CHECK-NEXT: Offset: 0x30008 // CHECK-NEXT: Size: 48 // CHECK-NEXT: Link: 10 // CHECK-NEXT: Info: 2 @@ -233,7 +233,7 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x20098 +// CHECK-NEXT: Offset: 0x30038 // CHECK-NEXT: Size: 84 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -255,7 +255,7 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x200EC +// CHECK-NEXT: Offset: 0x3008C // CHECK-NEXT: Size: 10 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 diff --git a/deps/lld/test/ELF/linkerscript/nobits-offset.s b/deps/lld/test/ELF/linkerscript/nobits-offset.s index c414148763..051f3f99da 100644 --- a/deps/lld/test/ELF/linkerscript/nobits-offset.s +++ b/deps/lld/test/ELF/linkerscript/nobits-offset.s @@ -2,17 +2,24 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo "SECTIONS { \ # RUN: .sec1 (NOLOAD) : { . += 1; } \ -# RUN: .text : { *(.text) } \ +# RUN: .bss : { *(.bss) } \ # RUN: };" > %t.script # RUN: ld.lld %t.o -T %t.script -o %t -# RUN: llvm-readelf --sections %t | FileCheck %s +# RUN: llvm-readelf -S -l %t | FileCheck %s -# We used to misalign section offsets if the first section in a -# PT_LOAD was SHT_NOBITS. +## If a SHT_NOBITS section is the only section of a PT_LOAD segment, +## p_offset will be set to the sh_offset field of the section. Check we align +## sh_offset to sh_addr modulo max-page-size, so that p_vaddr=p_offset (mod +## p_align). -# CHECK: [ 2] .text PROGBITS 0000000000000010 001010 000010 00 AX 0 0 16 +# CHECK: Name Type Address Off Size ES Flg Lk Inf Al +# CHECK: .bss NOBITS 0000000000000400 001400 000001 00 WA 0 0 1024 -.global _start -_start: - nop -.p2align 4 +# CHECK: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# CHECK: LOAD 0x001400 0x0000000000000400 0x0000000000000400 0x000000 0x000001 RW 0x1000 + +# CHECK: 00 .bss + +.bss +.p2align 10 +.byte 0 diff --git a/deps/lld/test/ELF/nmagic.s b/deps/lld/test/ELF/nmagic.s new file mode 100644 index 0000000000..f2feacb1ba --- /dev/null +++ b/deps/lld/test/ELF/nmagic.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# Verify that .rodata is aligned to a 8 byte boundary. + +# RUN: llvm-mc -filetype=obj -triple=i386 %s -o %t.o +# RUN: ld.lld %t.o -o %t.exe -n -Ttext 0 +# RUN: llvm-readelf --section-headers %t.exe | FileCheck %s + +# CHECK: [ 0] NULL 00000000 000000 000000 00 0 0 0 +# CHECK: [ 1] .text PROGBITS 00000000 0000d4 000001 00 AX 0 0 4 +# CHECK: [ 2] .rodata PROGBITS 00000008 0000d8 000008 00 A 0 0 8 +# CHECK: [ 3] .comment PROGBITS 00000000 0000e0 000008 01 MS 0 0 1 +# CHECK: [ 4] .symtab SYMTAB 00000000 0000e8 000020 10 6 1 4 +# CHECK: [ 5] .shstrtab STRTAB 00000000 000108 000032 00 0 0 1 +# CHECK: [ 6] .strtab STRTAB 00000000 00013a 000008 00 0 0 1 + +.globl _start +.text +_start: + ret + +.rodata +.align 8 +.quad 42 diff --git a/deps/lld/test/ELF/nobits-offset.s b/deps/lld/test/ELF/nobits-offset.s new file mode 100644 index 0000000000..c010473290 --- /dev/null +++ b/deps/lld/test/ELF/nobits-offset.s @@ -0,0 +1,21 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-readelf -S -l %t | FileCheck %s + +## If a SHT_NOBITS section is the only section of a PT_LOAD segment, +## p_offset will be set to the sh_offset field of the section. Check we align +## sh_offset to sh_addr modulo max-page-size, so that p_vaddr=p_offset (mod +## p_align). + +# CHECK: Name Type Address Off Size ES Flg Lk Inf Al +# CHECK: .bss NOBITS 0000000000210000 010000 000001 00 WA 0 0 4096 + +# CHECK: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# CHECK: LOAD 0x010000 0x0000000000210000 0x0000000000210000 0x000000 0x000001 RW 0x10000 + +# CHECK: 02 .bss + +.bss +.p2align 12 +.byte 0 diff --git a/deps/lld/test/ELF/ppc64-reloc-rel.s b/deps/lld/test/ELF/ppc64-reloc-rel.s new file mode 100644 index 0000000000..3e3c5c94ef --- /dev/null +++ b/deps/lld/test/ELF/ppc64-reloc-rel.s @@ -0,0 +1,58 @@ +# REQUIRES: ppc + +# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o +# RUN: ld.lld %t.o --defsym=foo=rel16+0x8000 -o %t +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s +# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=REL %s +# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC %s +# RUN: llvm-readelf -x .eh_frame %t | FileCheck --check-prefix=HEX %s + +.section .R_PPC64_REL14,"ax",@progbits +# FIXME This does not produce a relocation + beq 1f +1: +# CHECK-LABEL: Disassembly of section .R_PPC64_REL14: +# CHECK: bt 2, .+4 + +.section .R_PPC64_REL16,"ax",@progbits +.globl rel16 +rel16: + li 3, foo-rel16-1@ha # R_PPC64_REL16_HA + li 3, foo-rel16@ha + li 4, foo-rel16+0x7fff@h # R_PPC64_REL16_HI + li 4, foo-rel16+0x8000@h + li 5, foo-rel16-1@l # R_PPC64_REL16_LO + li 5, foo-rel16@l +# CHECK-LABEL: Disassembly of section .R_PPC64_REL16: +# CHECK: li 3, 0 +# CHECK-NEXT: li 3, 1 +# CHECK-NEXT: li 4, 0 +# CHECK-NEXT: li 4, 1 +# CHECK-NEXT: li 5, 32767 +# CHECK-NEXT: li 5, -32768 + +.section .R_PPC64_REL24,"ax",@progbits + b rel16 +# CHECK-LABEL: Disassembly of section .R_PPC64_REL24: +# CHECK: b .+67108840 + +.section .REL32_AND_REL64,"ax",@progbits + .cfi_startproc + .cfi_personality 148, rel64 + nop + .cfi_endproc +rel64: + li 3, 0 +# REL: .rela.eh_frame { +# REL-NEXT: 0x12 R_PPC64_REL64 .REL32_AND_REL64 0x4 +# REL-NEXT: 0x28 R_PPC64_REL32 .REL32_AND_REL64 0x0 +# REL-NEXT: } + +# SEC: .REL32_AND_REL64 PROGBITS 0000000010010020 + +## CIE Personality Address: 0x10010020-(0x10000168+2)+4 = 0xfeba +## FDE PC Begin: 0x10010020-(0x10000178+8) = 0xfea0 +# HEX: section '.eh_frame': +# HEX-NEXT: 0x10000158 +# HEX-NEXT: 0x10000168 {{....}}bafe 00000000 +# HEX-NEXT: 0x10000178 {{[0-9a-f]+}} {{[0-9a-f]+}} a0fe0000 diff --git a/deps/lld/test/ELF/ppc64-relocs.s b/deps/lld/test/ELF/ppc64-relocs.s index 5e8c529e96..8e69e08df6 100644 --- a/deps/lld/test/ELF/ppc64-relocs.s +++ b/deps/lld/test/ELF/ppc64-relocs.s @@ -18,16 +18,9 @@ _start: li 3,42 sc -.section .rodata,"a",@progbits - .p2align 2 -.LJTI0_0: - .long .LBB0_2-.LJTI0_0 - -.section .toc,"aw",@progbits +.section .toc,"aw",@progbits .L1: -.quad 22, 37, 89, 47 -.LC0: - .tc .LJTI0_0[TC],.LJTI0_0 + .quad 22, 37, 89, 47 .section .R_PPC64_TOC16_LO_DS,"ax",@progbits ld 1, .L1@toc@l(2) @@ -53,91 +46,47 @@ _start: # CHECK-LABEL: Disassembly of section .R_PPC64_TOC16_HA: # CHECK: 10010018: addis 1, 2, 0 -.section .R_PPC64_REL24,"ax",@progbits - b 1f -1: - -# CHECK-LABEL: Disassembly of section .R_PPC64_REL24: -# CHECK: 1001001c: b .+4 - -.section .R_PPC64_REL14,"ax",@progbits - beq 1f -1: - -# CHECK-LABEL: Disassembly of section .R_PPC64_REL14: -# CHECK: 10010020: bt 2, .+4 - .section .R_PPC64_ADDR16_LO,"ax",@progbits li 1, .Lfoo@l # CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_LO: -# CHECK: 10010024: li 1, 0 +# CHECK: li 1, 0 .section .R_PPC64_ADDR16_HI,"ax",@progbits li 1, .Lfoo@h # CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HI: -# CHECK: 10010028: li 1, 4097 +# CHECK: li 1, 4097 .section .R_PPC64_ADDR16_HA,"ax",@progbits li 1, .Lfoo@ha # CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HA: -# CHECK: 1001002c: li 1, 4097 +# CHECK: li 1, 4097 .section .R_PPC64_ADDR16_HIGHER,"ax",@progbits li 1, .Lfoo@higher # CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HIGHER: -# CHECK: 10010030: li 1, 0 +# CHECK: li 1, 0 .section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits li 1, .Lfoo@highera # CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HIGHERA: -# CHECK: 10010034: li 1, 0 +# CHECK: li 1, 0 .section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits li 1, .Lfoo@highest # CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HIGHEST: -# CHECK: 10010038: li 1, 0 +# CHECK: li 1, 0 .section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits li 1, .Lfoo@highesta # CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HIGHESTA: -# CHECK: 1001003c: li 1, 0 - -.section .R_PPC64_REL32, "ax",@progbits - addis 5, 2, .LC0@toc@ha - ld 5, .LC0@toc@l(5) -.LBB0_2: - add 3, 3, 4 - -# DATALE: '.rodata': -# DATALE: 0x100001c8 80fe0000 - -# DATABE: '.rodata': -# DATABE: 0x100001c8 0000fe80 - -# Address of rodata + value stored at rodata entry -# should equal address of LBB0_2. -# 0x10000190 + 0xfeb4 = 0x10010044 -# CHECK-LABEL: Disassembly of section .R_PPC64_REL32: -# CHECK: 10010040: addis 5, 2, 0 -# CHECK: 10010044: ld 5, -32736(5) -# CHECK: 10010048: add 3, 3, 4 - -.section .R_PPC64_REL64, "ax",@progbits - .cfi_startproc - .cfi_personality 148, __foo - li 0, 1 - li 3, 55 - sc - .cfi_endproc -__foo: - li 3,0 +# CHECK: li 1, 0 .section .R_PPC64_TOC,"a",@progbits .quad .TOC.@tocbase @@ -150,15 +99,3 @@ __foo: # DATABE-LABEL: section '.R_PPC64_TOC': # DATABE: 00000000 10028000 - -# Check that the personality (relocated by R_PPC64_REL64) in the .eh_frame -# equals the address of __foo. -# 0x100001ea + 0xfe6e = 0x10010058 -# DATALE: section '.eh_frame': -# DATALE: 0x100001e8 {{....}}6efe - -# DATABE: section '.eh_frame': -# DATABE: 0x100001e8 {{[0-9a-f]+ [0-9a-f]+}} fe6e{{....}} - -# CHECK: __foo -# CHECK-NEXT: 10010058: li 3, 0 diff --git a/deps/lld/test/ELF/relocation-copy-align-common.s b/deps/lld/test/ELF/relocation-copy-align-common.s index 124064c71d..748f84546b 100644 --- a/deps/lld/test/ELF/relocation-copy-align-common.s +++ b/deps/lld/test/ELF/relocation-copy-align-common.s @@ -15,7 +15,7 @@ # CHECK-NEXT: SHF_WRITE # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x203000 -# CHECK-NEXT: Offset: 0x20B0 +# CHECK-NEXT: Offset: 0x3000 # CHECK-NEXT: Size: 16 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0