Index: vendor/lld/dist/COFF/Chunks.cpp =================================================================== --- vendor/lld/dist/COFF/Chunks.cpp (revision 321191) +++ vendor/lld/dist/COFF/Chunks.cpp (revision 321192) @@ -1,492 +1,500 @@ //===- Chunks.cpp ---------------------------------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "Chunks.h" #include "Error.h" #include "InputFiles.h" #include "Symbols.h" #include "Writer.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/Object/COFF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/raw_ostream.h" #include using namespace llvm; using namespace llvm::object; using namespace llvm::support::endian; using namespace llvm::COFF; using llvm::support::ulittle32_t; namespace lld { namespace coff { SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H) : Chunk(SectionKind), Repl(this), Header(H), File(F), Relocs(File->getCOFFObj()->getRelocations(Header)), NumRelocs(std::distance(Relocs.begin(), Relocs.end())) { // Initialize SectionName. File->getCOFFObj()->getSectionName(Header, SectionName); Align = Header->getAlignment(); // Chunks may be discarded during comdat merging. Discarded = false; // If linker GC is disabled, every chunk starts out alive. If linker GC is // enabled, treat non-comdat sections as roots. Generally optimized object // files will be built with -ffunction-sections or /Gy, so most things worth // stripping will be in a comdat. Live = !Config->DoGC || !isCOMDAT(); } static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); } static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); } static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); } static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); } static void or32(uint8_t *P, uint32_t V) { write32le(P, read32le(P) | V); } static void applySecRel(const SectionChunk *Sec, uint8_t *Off, OutputSection *OS, uint64_t S) { if (!OS) { if (Sec->isCodeView()) return; fatal("SECREL relocation cannot be applied to absolute symbols"); } uint64_t SecRel = S - OS->getRVA(); assert(SecRel < INT32_MAX && "overflow in SECREL relocation"); add32(Off, SecRel); } static void applySecIdx(uint8_t *Off, OutputSection *OS) { // If we have no output section, this must be an absolute symbol. Use the // sentinel absolute symbol section index. uint16_t SecIdx = OS ? OS->SectionIndex : DefinedAbsolute::OutputSectionIndex; add16(Off, SecIdx); } void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, uint64_t P) const { switch (Type) { case IMAGE_REL_AMD64_ADDR32: add32(Off, S + Config->ImageBase); break; case IMAGE_REL_AMD64_ADDR64: add64(Off, S + Config->ImageBase); break; case IMAGE_REL_AMD64_ADDR32NB: add32(Off, S); break; case IMAGE_REL_AMD64_REL32: add32(Off, S - P - 4); break; case IMAGE_REL_AMD64_REL32_1: add32(Off, S - P - 5); break; case IMAGE_REL_AMD64_REL32_2: add32(Off, S - P - 6); break; case IMAGE_REL_AMD64_REL32_3: add32(Off, S - P - 7); break; case IMAGE_REL_AMD64_REL32_4: add32(Off, S - P - 8); break; case IMAGE_REL_AMD64_REL32_5: add32(Off, S - P - 9); break; case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break; case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break; default: fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); } } void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, uint64_t P) const { switch (Type) { case IMAGE_REL_I386_ABSOLUTE: break; case IMAGE_REL_I386_DIR32: add32(Off, S + Config->ImageBase); break; case IMAGE_REL_I386_DIR32NB: add32(Off, S); break; case IMAGE_REL_I386_REL32: add32(Off, S - P - 4); break; case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break; case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break; default: fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); } } static void applyMOV(uint8_t *Off, uint16_t V) { write16le(Off, (read16le(Off) & 0xfbf0) | ((V & 0x800) >> 1) | ((V >> 12) & 0xf)); write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff)); } static uint16_t readMOV(uint8_t *Off) { uint16_t Opcode1 = read16le(Off); uint16_t Opcode2 = read16le(Off + 2); uint16_t Imm = (Opcode2 & 0x00ff) | ((Opcode2 >> 4) & 0x0700); Imm |= ((Opcode1 << 1) & 0x0800) | ((Opcode1 & 0x000f) << 12); return Imm; } static void applyMOV32T(uint8_t *Off, uint32_t V) { uint16_t ImmW = readMOV(Off); // read MOVW operand uint16_t ImmT = readMOV(Off + 4); // read MOVT operand uint32_t Imm = ImmW | (ImmT << 16); V += Imm; // add the immediate offset applyMOV(Off, V); // set MOVW operand applyMOV(Off + 4, V >> 16); // set MOVT operand } static void applyBranch20T(uint8_t *Off, int32_t V) { uint32_t S = V < 0 ? 1 : 0; uint32_t J1 = (V >> 19) & 1; uint32_t J2 = (V >> 18) & 1; or16(Off, (S << 10) | ((V >> 12) & 0x3f)); or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); } static void applyBranch24T(uint8_t *Off, int32_t V) { if (!isInt<25>(V)) fatal("relocation out of range"); uint32_t S = V < 0 ? 1 : 0; uint32_t J1 = ((~V >> 23) & 1) ^ S; uint32_t J2 = ((~V >> 22) & 1) ^ S; or16(Off, (S << 10) | ((V >> 12) & 0x3ff)); // Clear out the J1 and J2 bits which may be set. write16le(Off + 2, (read16le(Off + 2) & 0xd000) | (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); } void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, uint64_t P) const { // Pointer to thumb code must have the LSB set. uint64_t SX = S; if (OS && (OS->getPermissions() & IMAGE_SCN_MEM_EXECUTE)) SX |= 1; switch (Type) { case IMAGE_REL_ARM_ADDR32: add32(Off, SX + Config->ImageBase); break; case IMAGE_REL_ARM_ADDR32NB: add32(Off, SX); break; case IMAGE_REL_ARM_MOV32T: applyMOV32T(Off, SX + Config->ImageBase); break; case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, SX - P - 4); break; case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, SX - P - 4); break; case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, SX - P - 4); break; case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break; case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break; default: fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); } } static void applyArm64Addr(uint8_t *Off, uint64_t Imm) { uint32_t ImmLo = (Imm & 0x3) << 29; uint32_t ImmHi = (Imm & 0x1FFFFC) << 3; uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3); write32le(Off, (read32le(Off) & ~Mask) | ImmLo | ImmHi); } // Update the immediate field in a AARCH64 ldr, str, and add instruction. static void applyArm64Imm(uint8_t *Off, uint64_t Imm) { uint32_t Orig = read32le(Off); Imm += (Orig >> 10) & 0xFFF; Orig &= ~(0xFFF << 10); write32le(Off, Orig | ((Imm & 0xFFF) << 10)); } static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) { int Size = read32le(Off) >> 30; Imm >>= Size; applyArm64Imm(Off, Imm); } void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, uint64_t P) const { switch (Type) { case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, (S >> 12) - (P >> 12)); break; case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff); break; case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break; case IMAGE_REL_ARM64_BRANCH26: or32(Off, ((S - P) & 0x0FFFFFFC) >> 2); break; case IMAGE_REL_ARM64_ADDR32: add32(Off, S + Config->ImageBase); break; case IMAGE_REL_ARM64_ADDR64: add64(Off, S + Config->ImageBase); break; default: fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); } } void SectionChunk::writeTo(uint8_t *Buf) const { if (!hasData()) return; // Copy section contents from source object file to output file. ArrayRef A = getContents(); memcpy(Buf + OutputSectionOff, A.data(), A.size()); // Apply relocations. + size_t InputSize = getSize(); for (const coff_relocation &Rel : Relocs) { + // Check for an invalid relocation offset. This check isn't perfect, because + // we don't have the relocation size, which is only known after checking the + // machine and relocation type. As a result, a relocation may overwrite the + // beginning of the following input section. + if (Rel.VirtualAddress >= InputSize) + fatal("relocation points beyond the end of its parent section"); + uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress; // Get the output section of the symbol for this relocation. The output // section is needed to compute SECREL and SECTION relocations used in debug // info. SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex); Defined *Sym = cast(Body); Chunk *C = Sym->getChunk(); OutputSection *OS = C ? C->getOutputSection() : nullptr; // Only absolute and __ImageBase symbols lack an output section. For any // other symbol, this indicates that the chunk was discarded. Normally // relocations against discarded sections are an error. However, debug info // sections are not GC roots and can end up with these kinds of relocations. // Skip these relocations. if (!OS && !isa(Sym) && !isa(Sym)) { - if (isCodeView()) + if (isCodeView() || isDWARF()) continue; fatal("relocation against symbol in discarded section: " + Sym->getName()); } uint64_t S = Sym->getRVA(); // Compute the RVA of the relocation for relative relocations. uint64_t P = RVA + Rel.VirtualAddress; switch (Config->Machine) { case AMD64: applyRelX64(Off, Rel.Type, OS, S, P); break; case I386: applyRelX86(Off, Rel.Type, OS, S, P); break; case ARMNT: applyRelARM(Off, Rel.Type, OS, S, P); break; case ARM64: applyRelARM64(Off, Rel.Type, OS, S, P); break; default: llvm_unreachable("unknown machine type"); } } } void SectionChunk::addAssociative(SectionChunk *Child) { AssocChildren.push_back(Child); } static uint8_t getBaserelType(const coff_relocation &Rel) { switch (Config->Machine) { case AMD64: if (Rel.Type == IMAGE_REL_AMD64_ADDR64) return IMAGE_REL_BASED_DIR64; return IMAGE_REL_BASED_ABSOLUTE; case I386: if (Rel.Type == IMAGE_REL_I386_DIR32) return IMAGE_REL_BASED_HIGHLOW; return IMAGE_REL_BASED_ABSOLUTE; case ARMNT: if (Rel.Type == IMAGE_REL_ARM_ADDR32) return IMAGE_REL_BASED_HIGHLOW; if (Rel.Type == IMAGE_REL_ARM_MOV32T) return IMAGE_REL_BASED_ARM_MOV32T; return IMAGE_REL_BASED_ABSOLUTE; case ARM64: if (Rel.Type == IMAGE_REL_ARM64_ADDR64) return IMAGE_REL_BASED_DIR64; return IMAGE_REL_BASED_ABSOLUTE; default: llvm_unreachable("unknown machine type"); } } // Windows-specific. // Collect all locations that contain absolute addresses, which need to be // fixed by the loader if load-time relocation is needed. // Only called when base relocation is enabled. void SectionChunk::getBaserels(std::vector *Res) { for (const coff_relocation &Rel : Relocs) { uint8_t Ty = getBaserelType(Rel); if (Ty == IMAGE_REL_BASED_ABSOLUTE) continue; SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex); if (isa(Body)) continue; Res->emplace_back(RVA + Rel.VirtualAddress, Ty); } } bool SectionChunk::hasData() const { return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA); } uint32_t SectionChunk::getPermissions() const { return Header->Characteristics & PermMask; } bool SectionChunk::isCOMDAT() const { return Header->Characteristics & IMAGE_SCN_LNK_COMDAT; } void SectionChunk::printDiscardedMessage() const { // Removed by dead-stripping. If it's removed by ICF, ICF already // printed out the name, so don't repeat that here. if (Sym && this == Repl) { if (Discarded) message("Discarded comdat symbol " + Sym->getName()); else if (!Live) message("Discarded " + Sym->getName()); } } StringRef SectionChunk::getDebugName() { if (Sym) return Sym->getName(); return ""; } ArrayRef SectionChunk::getContents() const { ArrayRef A; File->getCOFFObj()->getSectionContents(Header, A); return A; } void SectionChunk::replace(SectionChunk *Other) { Other->Repl = Repl; Other->Live = false; } CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) { // Common symbols are aligned on natural boundaries up to 32 bytes. // This is what MSVC link.exe does. Align = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue())); } uint32_t CommonChunk::getPermissions() const { return IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; } void StringChunk::writeTo(uint8_t *Buf) const { memcpy(Buf + OutputSectionOff, Str.data(), Str.size()); } ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) { // Intel Optimization Manual says that all branch targets // should be 16-byte aligned. MSVC linker does this too. Align = 16; } void ImportThunkChunkX64::writeTo(uint8_t *Buf) const { memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86)); // The first two bytes is a JMP instruction. Fill its operand. write32le(Buf + OutputSectionOff + 2, ImpSymbol->getRVA() - RVA - getSize()); } void ImportThunkChunkX86::getBaserels(std::vector *Res) { Res->emplace_back(getRVA() + 2); } void ImportThunkChunkX86::writeTo(uint8_t *Buf) const { memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86)); // The first two bytes is a JMP instruction. Fill its operand. write32le(Buf + OutputSectionOff + 2, ImpSymbol->getRVA() + Config->ImageBase); } void ImportThunkChunkARM::getBaserels(std::vector *Res) { Res->emplace_back(getRVA(), IMAGE_REL_BASED_ARM_MOV32T); } void ImportThunkChunkARM::writeTo(uint8_t *Buf) const { memcpy(Buf + OutputSectionOff, ImportThunkARM, sizeof(ImportThunkARM)); // Fix mov.w and mov.t operands. applyMOV32T(Buf + OutputSectionOff, ImpSymbol->getRVA() + Config->ImageBase); } void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const { int64_t PageOff = (ImpSymbol->getRVA() >> 12) - (RVA >> 12); int64_t Off = ImpSymbol->getRVA() & 0xfff; memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64)); applyArm64Addr(Buf + OutputSectionOff, PageOff); applyArm64Ldr(Buf + OutputSectionOff + 4, Off); } void LocalImportChunk::getBaserels(std::vector *Res) { Res->emplace_back(getRVA()); } size_t LocalImportChunk::getSize() const { return Config->is64() ? 8 : 4; } void LocalImportChunk::writeTo(uint8_t *Buf) const { if (Config->is64()) { write64le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase); } else { write32le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase); } } void SEHTableChunk::writeTo(uint8_t *Buf) const { ulittle32_t *Begin = reinterpret_cast(Buf + OutputSectionOff); size_t Cnt = 0; for (Defined *D : Syms) Begin[Cnt++] = D->getRVA(); std::sort(Begin, Begin + Cnt); } // Windows-specific. This class represents a block in .reloc section. // The format is described here. // // On Windows, each DLL is linked against a fixed base address and // usually loaded to that address. However, if there's already another // DLL that overlaps, the loader has to relocate it. To do that, DLLs // contain .reloc sections which contain offsets that need to be fixed // up at runtime. If the loader finds that a DLL cannot be loaded to its // desired base address, it loads it to somewhere else, and add - to each offset that is // specified by the .reloc section. In ELF terms, .reloc sections // contain relative relocations in REL format (as opposed to RELA.) // // This already significantly reduces the size of relocations compared // to ELF .rel.dyn, but Windows does more to reduce it (probably because // it was invented for PCs in the late '80s or early '90s.) Offsets in // .reloc are grouped by page where the page size is 12 bits, and // offsets sharing the same page address are stored consecutively to // represent them with less space. This is very similar to the page // table which is grouped by (multiple stages of) pages. // // For example, let's say we have 0x00030, 0x00500, 0x00700, 0x00A00, // 0x20004, and 0x20008 in a .reloc section for x64. The uppermost 4 // bits have a type IMAGE_REL_BASED_DIR64 or 0xA. In the section, they // are represented like this: // // 0x00000 -- page address (4 bytes) // 16 -- size of this block (4 bytes) // 0xA030 -- entries (2 bytes each) // 0xA500 // 0xA700 // 0xAA00 // 0x20000 -- page address (4 bytes) // 12 -- size of this block (4 bytes) // 0xA004 -- entries (2 bytes each) // 0xA008 // // Usually we have a lot of relocations for each page, so the number of // bytes for one .reloc entry is close to 2 bytes on average. BaserelChunk::BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End) { // Block header consists of 4 byte page RVA and 4 byte block size. // Each entry is 2 byte. Last entry may be padding. Data.resize(alignTo((End - Begin) * 2 + 8, 4)); uint8_t *P = Data.data(); write32le(P, Page); write32le(P + 4, Data.size()); P += 8; for (Baserel *I = Begin; I != End; ++I) { write16le(P, (I->Type << 12) | (I->RVA - Page)); P += 2; } } void BaserelChunk::writeTo(uint8_t *Buf) const { memcpy(Buf + OutputSectionOff, Data.data(), Data.size()); } uint8_t Baserel::getDefaultType() { switch (Config->Machine) { case AMD64: return IMAGE_REL_BASED_DIR64; case I386: return IMAGE_REL_BASED_HIGHLOW; default: llvm_unreachable("unknown machine type"); } } } // namespace coff } // namespace lld Index: vendor/lld/dist/COFF/Chunks.h =================================================================== --- vendor/lld/dist/COFF/Chunks.h (revision 321191) +++ vendor/lld/dist/COFF/Chunks.h (revision 321192) @@ -1,372 +1,375 @@ //===- Chunks.h -------------------------------------------------*- C++ -*-===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLD_COFF_CHUNKS_H #define LLD_COFF_CHUNKS_H #include "Config.h" #include "InputFiles.h" #include "lld/Core/LLVM.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Object/COFF.h" #include #include namespace lld { namespace coff { using llvm::COFF::ImportDirectoryTableEntry; using llvm::object::COFFSymbolRef; using llvm::object::SectionRef; using llvm::object::coff_relocation; using llvm::object::coff_section; class Baserel; class Defined; class DefinedImportData; class DefinedRegular; class ObjectFile; class OutputSection; class SymbolBody; // Mask for section types (code, data, bss, disacardable, etc.) // and permissions (writable, readable or executable). const uint32_t PermMask = 0xFF0000F0; // A Chunk represents a chunk of data that will occupy space in the // output (if the resolver chose that). It may or may not be backed by // a section of an input file. It could be linker-created data, or // doesn't even have actual data (if common or bss). class Chunk { public: enum Kind { SectionKind, OtherKind }; Kind kind() const { return ChunkKind; } virtual ~Chunk() = default; // Returns the size of this chunk (even if this is a common or BSS.) virtual size_t getSize() const = 0; // Write this chunk to a mmap'ed file, assuming Buf is pointing to // beginning of the file. Because this function may use RVA values // of other chunks for relocations, you need to set them properly // before calling this function. virtual void writeTo(uint8_t *Buf) const {} // The writer sets and uses the addresses. uint64_t getRVA() const { return RVA; } uint32_t getAlign() const { return Align; } void setRVA(uint64_t V) { RVA = V; } // Returns true if this has non-zero data. BSS chunks return // false. If false is returned, the space occupied by this chunk // will be filled with zeros. virtual bool hasData() const { return true; } // Returns readable/writable/executable bits. virtual uint32_t getPermissions() const { return 0; } // Returns the section name if this is a section chunk. // It is illegal to call this function on non-section chunks. virtual StringRef getSectionName() const { llvm_unreachable("unimplemented getSectionName"); } // An output section has pointers to chunks in the section, and each // chunk has a back pointer to an output section. void setOutputSection(OutputSection *O) { Out = O; } OutputSection *getOutputSection() { return Out; } // Windows-specific. // Collect all locations that contain absolute addresses for base relocations. virtual void getBaserels(std::vector *Res) {} // Returns a human-readable name of this chunk. Chunks are unnamed chunks of // bytes, so this is used only for logging or debugging. virtual StringRef getDebugName() { return ""; } protected: Chunk(Kind K = OtherKind) : ChunkKind(K) {} const Kind ChunkKind; // The alignment of this chunk. The writer uses the value. uint32_t Align = 1; // The RVA of this chunk in the output. The writer sets a value. uint64_t RVA = 0; public: // The offset from beginning of the output section. The writer sets a value. uint64_t OutputSectionOff = 0; protected: // The output section for this chunk. OutputSection *Out = nullptr; }; // A chunk corresponding a section of an input file. -class SectionChunk : public Chunk { +class SectionChunk final : public Chunk { // Identical COMDAT Folding feature accesses section internal data. friend class ICF; public: class symbol_iterator : public llvm::iterator_adaptor_base< symbol_iterator, const coff_relocation *, std::random_access_iterator_tag, SymbolBody *> { friend SectionChunk; ObjectFile *File; symbol_iterator(ObjectFile *File, const coff_relocation *I) : symbol_iterator::iterator_adaptor_base(I), File(File) {} public: symbol_iterator() = default; SymbolBody *operator*() const { return File->getSymbolBody(I->SymbolTableIndex); } }; SectionChunk(ObjectFile *File, const coff_section *Header); static bool classof(const Chunk *C) { return C->kind() == SectionKind; } size_t getSize() const override { return Header->SizeOfRawData; } ArrayRef getContents() const; void writeTo(uint8_t *Buf) const override; bool hasData() const override; uint32_t getPermissions() const override; StringRef getSectionName() const override { return SectionName; } void getBaserels(std::vector *Res) override; bool isCOMDAT() const; void applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, uint64_t P) const; void applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, uint64_t P) const; void applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, uint64_t P) const; void applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, uint64_t P) const; // Called if the garbage collector decides to not include this chunk // in a final output. It's supposed to print out a log message to stdout. void printDiscardedMessage() const; // Adds COMDAT associative sections to this COMDAT section. A chunk // and its children are treated as a group by the garbage collector. void addAssociative(SectionChunk *Child); StringRef getDebugName() override; void setSymbol(DefinedRegular *S) { if (!Sym) Sym = S; } // Returns true if the chunk was not dropped by GC or COMDAT deduplication. bool isLive() { return Live && !Discarded; } // Used by the garbage collector. void markLive() { assert(Config->DoGC && "should only mark things live from GC"); assert(!isLive() && "Cannot mark an already live section!"); Live = true; } // Returns true if this chunk was dropped by COMDAT deduplication. bool isDiscarded() const { return Discarded; } // Used by the SymbolTable when discarding unused comdat sections. This is // redundant when GC is enabled, as all comdat sections will start out dead. void markDiscarded() { Discarded = true; } // True if this is a codeview debug info chunk. These will not be laid out in // the image. Instead they will end up in the PDB, if one is requested. bool isCodeView() const { return SectionName == ".debug" || SectionName.startswith(".debug$"); } + + // True if this is a DWARF debug info chunk. + bool isDWARF() const { return SectionName.startswith(".debug_"); } // Allow iteration over the bodies of this chunk's relocated symbols. llvm::iterator_range symbols() const { return llvm::make_range(symbol_iterator(File, Relocs.begin()), symbol_iterator(File, Relocs.end())); } // Allow iteration over the associated child chunks for this section. ArrayRef children() const { return AssocChildren; } // A pointer pointing to a replacement for this chunk. // Initially it points to "this" object. If this chunk is merged // with other chunk by ICF, it points to another chunk, // and this chunk is considrered as dead. SectionChunk *Repl; // The CRC of the contents as described in the COFF spec 4.5.5. // Auxiliary Format 5: Section Definitions. Used for ICF. uint32_t Checksum = 0; const coff_section *Header; // The file that this chunk was created from. ObjectFile *File; private: StringRef SectionName; std::vector AssocChildren; llvm::iterator_range Relocs; size_t NumRelocs; // True if this chunk was discarded because it was a duplicate comdat section. bool Discarded; // Used by the garbage collector. bool Live; // Used for ICF (Identical COMDAT Folding) void replace(SectionChunk *Other); uint32_t Class[2] = {0, 0}; // Sym points to a section symbol if this is a COMDAT chunk. DefinedRegular *Sym = nullptr; }; // A chunk for common symbols. Common chunks don't have actual data. class CommonChunk : public Chunk { public: CommonChunk(const COFFSymbolRef Sym); size_t getSize() const override { return Sym.getValue(); } bool hasData() const override { return false; } uint32_t getPermissions() const override; StringRef getSectionName() const override { return ".bss"; } private: const COFFSymbolRef Sym; }; // A chunk for linker-created strings. class StringChunk : public Chunk { public: explicit StringChunk(StringRef S) : Str(S) {} size_t getSize() const override { return Str.size() + 1; } void writeTo(uint8_t *Buf) const override; private: StringRef Str; }; static const uint8_t ImportThunkX86[] = { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // JMP *0x0 }; static const uint8_t ImportThunkARM[] = { 0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0 0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0 0xdc, 0xf8, 0x00, 0xf0, // ldr.w pc, [ip] }; static const uint8_t ImportThunkARM64[] = { 0x10, 0x00, 0x00, 0x90, // adrp x16, #0 0x10, 0x02, 0x40, 0xf9, // ldr x16, [x16] 0x00, 0x02, 0x1f, 0xd6, // br x16 }; // Windows-specific. // A chunk for DLL import jump table entry. In a final output, it's // contents will be a JMP instruction to some __imp_ symbol. class ImportThunkChunkX64 : public Chunk { public: explicit ImportThunkChunkX64(Defined *S); size_t getSize() const override { return sizeof(ImportThunkX86); } void writeTo(uint8_t *Buf) const override; private: Defined *ImpSymbol; }; class ImportThunkChunkX86 : public Chunk { public: explicit ImportThunkChunkX86(Defined *S) : ImpSymbol(S) {} size_t getSize() const override { return sizeof(ImportThunkX86); } void getBaserels(std::vector *Res) override; void writeTo(uint8_t *Buf) const override; private: Defined *ImpSymbol; }; class ImportThunkChunkARM : public Chunk { public: explicit ImportThunkChunkARM(Defined *S) : ImpSymbol(S) {} size_t getSize() const override { return sizeof(ImportThunkARM); } void getBaserels(std::vector *Res) override; void writeTo(uint8_t *Buf) const override; private: Defined *ImpSymbol; }; class ImportThunkChunkARM64 : public Chunk { public: explicit ImportThunkChunkARM64(Defined *S) : ImpSymbol(S) {} size_t getSize() const override { return sizeof(ImportThunkARM64); } void writeTo(uint8_t *Buf) const override; private: Defined *ImpSymbol; }; // Windows-specific. // See comments for DefinedLocalImport class. class LocalImportChunk : public Chunk { public: explicit LocalImportChunk(Defined *S) : Sym(S) {} size_t getSize() const override; void getBaserels(std::vector *Res) override; void writeTo(uint8_t *Buf) const override; private: Defined *Sym; }; // Windows-specific. // A chunk for SEH table which contains RVAs of safe exception handler // functions. x86-only. class SEHTableChunk : public Chunk { public: explicit SEHTableChunk(std::set S) : Syms(std::move(S)) {} size_t getSize() const override { return Syms.size() * 4; } void writeTo(uint8_t *Buf) const override; private: std::set Syms; }; // Windows-specific. // This class represents a block in .reloc section. // See the PE/COFF spec 5.6 for details. class BaserelChunk : public Chunk { public: BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End); size_t getSize() const override { return Data.size(); } void writeTo(uint8_t *Buf) const override; private: std::vector Data; }; class Baserel { public: Baserel(uint32_t V, uint8_t Ty) : RVA(V), Type(Ty) {} explicit Baserel(uint32_t V) : Baserel(V, getDefaultType()) {} uint8_t getDefaultType(); uint32_t RVA; uint8_t Type; }; } // namespace coff } // namespace lld #endif Index: vendor/lld/dist/COFF/Config.h =================================================================== --- vendor/lld/dist/COFF/Config.h (revision 321191) +++ vendor/lld/dist/COFF/Config.h (revision 321192) @@ -1,173 +1,174 @@ //===- Config.h -------------------------------------------------*- C++ -*-===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLD_COFF_CONFIG_H #define LLD_COFF_CONFIG_H #include "llvm/ADT/StringRef.h" #include "llvm/Object/COFF.h" #include #include #include #include namespace lld { namespace coff { using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN; using llvm::COFF::WindowsSubsystem; using llvm::StringRef; class DefinedAbsolute; class DefinedRelative; class StringChunk; struct Symbol; class SymbolBody; // Short aliases. static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64; static const auto ARM64 = llvm::COFF::IMAGE_FILE_MACHINE_ARM64; static const auto ARMNT = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT; static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386; // Represents an /export option. struct Export { StringRef Name; // N in /export:N or /export:E=N StringRef ExtName; // E in /export:E=N SymbolBody *Sym = nullptr; uint16_t Ordinal = 0; bool Noname = false; bool Data = false; bool Private = false; bool Constant = false; // If an export is a form of /export:foo=dllname.bar, that means // that foo should be exported as an alias to bar in the DLL. // ForwardTo is set to "dllname.bar" part. Usually empty. StringRef ForwardTo; StringChunk *ForwardChunk = nullptr; // True if this /export option was in .drectves section. bool Directives = false; StringRef SymbolName; StringRef ExportName; // Name in DLL bool operator==(const Export &E) { return (Name == E.Name && ExtName == E.ExtName && Ordinal == E.Ordinal && Noname == E.Noname && Data == E.Data && Private == E.Private); } }; enum class DebugType { None = 0x0, CV = 0x1, /// CodeView PData = 0x2, /// Procedure Data Fixup = 0x4, /// Relocation Table }; // Global configuration. struct Configuration { enum ManifestKind { SideBySide, Embed, No }; bool is64() { return Machine == AMD64 || Machine == ARM64; } llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN; bool Verbose = false; WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN; SymbolBody *Entry = nullptr; bool NoEntry = false; std::string OutputFile; + std::string ImportName; bool ColorDiagnostics; bool DoGC = true; bool DoICF = true; uint64_t ErrorLimit = 20; bool Relocatable = true; bool Force = false; bool Debug = false; bool WriteSymtab = true; unsigned DebugTypes = static_cast(DebugType::None); llvm::SmallString<128> PDBPath; std::vector Argv; // Symbols in this set are considered as live by the garbage collector. std::set GCRoot; std::set NoDefaultLibs; bool NoDefaultLibAll = false; // True if we are creating a DLL. bool DLL = false; StringRef Implib; std::vector Exports; std::set DelayLoads; std::map DLLOrder; SymbolBody *DelayLoadHelper = nullptr; bool SaveTemps = false; // Used for SafeSEH. Symbol *SEHTable = nullptr; Symbol *SEHCount = nullptr; // Used for /opt:lldlto=N unsigned LTOOptLevel = 2; // Used for /opt:lldltojobs=N unsigned LTOJobs = 0; // Used for /opt:lldltopartitions=N unsigned LTOPartitions = 1; // Used for /merge:from=to (e.g. /merge:.rdata=.text) std::map Merge; // Used for /section=.name,{DEKPRSW} to set section attributes. std::map Section; // Options for manifest files. ManifestKind Manifest = SideBySide; int ManifestID = 1; StringRef ManifestDependency; bool ManifestUAC = true; std::vector ManifestInput; StringRef ManifestLevel = "'asInvoker'"; StringRef ManifestUIAccess = "'false'"; StringRef ManifestFile; // Used for /failifmismatch. std::map MustMatch; // Used for /alternatename. std::map AlternateNames; // Used for /lldmap. std::string MapFile; uint64_t ImageBase = -1; uint64_t StackReserve = 1024 * 1024; uint64_t StackCommit = 4096; uint64_t HeapReserve = 1024 * 1024; uint64_t HeapCommit = 4096; uint32_t MajorImageVersion = 0; uint32_t MinorImageVersion = 0; uint32_t MajorOSVersion = 6; uint32_t MinorOSVersion = 0; bool DynamicBase = true; bool NxCompat = true; bool AllowIsolation = true; bool TerminalServerAware = true; bool LargeAddressAware = false; bool HighEntropyVA = false; bool AppContainer = false; }; extern Configuration *Config; } // namespace coff } // namespace lld #endif Index: vendor/lld/dist/COFF/Driver.cpp =================================================================== --- vendor/lld/dist/COFF/Driver.cpp (revision 321191) +++ vendor/lld/dist/COFF/Driver.cpp (revision 321192) @@ -1,1144 +1,1169 @@ //===- Driver.cpp ---------------------------------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "Driver.h" #include "Config.h" #include "Error.h" #include "InputFiles.h" #include "Memory.h" #include "SymbolTable.h" #include "Symbols.h" #include "Writer.h" #include "lld/Driver/Driver.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/BinaryFormat/Magic.h" #include "llvm/Object/ArchiveWriter.h" #include "llvm/Object/COFFImportFile.h" #include "llvm/Object/COFFModuleDefinition.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/TarWriter.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ToolDrivers/llvm-lib/LibDriver.h" #include #include #include using namespace llvm; using namespace llvm::object; using namespace llvm::COFF; using llvm::sys::Process; namespace lld { namespace coff { Configuration *Config; LinkerDriver *Driver; BumpPtrAllocator BAlloc; StringSaver Saver{BAlloc}; std::vector SpecificAllocBase::Instances; bool link(ArrayRef Args, raw_ostream &Diag) { ErrorCount = 0; ErrorOS = &Diag; Config = make(); Config->Argv = {Args.begin(), Args.end()}; Config->ColorDiagnostics = (ErrorOS == &llvm::errs() && Process::StandardErrHasColors()); Driver = make(); Driver->link(Args); return !ErrorCount; } // Drop directory components and replace extension with ".exe" or ".dll". static std::string getOutputPath(StringRef Path) { auto P = Path.find_last_of("\\/"); StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1); const char* E = Config->DLL ? ".dll" : ".exe"; return (S.substr(0, S.rfind('.')) + E).str(); } // ErrorOr is not default constructible, so it cannot be used as the type // parameter of a future. // FIXME: We could open the file in createFutureForFile and avoid needing to // return an error here, but for the moment that would cost us a file descriptor // (a limited resource on Windows) for the duration that the future is pending. typedef std::pair, std::error_code> MBErrPair; // Create a std::future that opens and maps a file using the best strategy for // the host platform. static std::future createFutureForFile(std::string Path) { #if LLVM_ON_WIN32 // On Windows, file I/O is relatively slow so it is best to do this // asynchronously. auto Strategy = std::launch::async; #else auto Strategy = std::launch::deferred; #endif return std::async(Strategy, [=]() { auto MBOrErr = MemoryBuffer::getFile(Path); if (!MBOrErr) return MBErrPair{nullptr, MBOrErr.getError()}; return MBErrPair{std::move(*MBOrErr), std::error_code()}; }); } MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr MB) { MemoryBufferRef MBRef = *MB; make>(std::move(MB)); // take ownership if (Driver->Tar) Driver->Tar->append(relativeToRoot(MBRef.getBufferIdentifier()), MBRef.getBuffer()); return MBRef; } void LinkerDriver::addBuffer(std::unique_ptr MB) { MemoryBufferRef MBRef = takeBuffer(std::move(MB)); // File type is detected by contents, not by file extension. file_magic Magic = identify_magic(MBRef.getBuffer()); if (Magic == file_magic::windows_resource) { Resources.push_back(MBRef); return; } FilePaths.push_back(MBRef.getBufferIdentifier()); if (Magic == file_magic::archive) return Symtab.addFile(make(MBRef)); if (Magic == file_magic::bitcode) return Symtab.addFile(make(MBRef)); if (Magic == file_magic::coff_cl_gl_object) error(MBRef.getBufferIdentifier() + ": is not a native COFF file. " "Recompile without /GL"); else Symtab.addFile(make(MBRef)); } void LinkerDriver::enqueuePath(StringRef Path) { auto Future = std::make_shared>(createFutureForFile(Path)); std::string PathStr = Path; enqueueTask([=]() { auto MBOrErr = Future->get(); if (MBOrErr.second) error("could not open " + PathStr + ": " + MBOrErr.second.message()); else Driver->addBuffer(std::move(MBOrErr.first)); }); } void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName, StringRef ParentName) { file_magic Magic = identify_magic(MB.getBuffer()); if (Magic == file_magic::coff_import_library) { Symtab.addFile(make(MB)); return; } InputFile *Obj; if (Magic == file_magic::coff_object) { Obj = make(MB); } else if (Magic == file_magic::bitcode) { Obj = make(MB); } else { error("unknown file type: " + MB.getBufferIdentifier()); return; } Obj->ParentName = ParentName; Symtab.addFile(Obj); log("Loaded " + toString(Obj) + " for " + SymName); } void LinkerDriver::enqueueArchiveMember(const Archive::Child &C, StringRef SymName, StringRef ParentName) { if (!C.getParent()->isThin()) { MemoryBufferRef MB = check( C.getMemoryBufferRef(), "could not get the buffer for the member defining symbol " + SymName); enqueueTask([=]() { Driver->addArchiveBuffer(MB, SymName, ParentName); }); return; } auto Future = std::make_shared>(createFutureForFile( check(C.getFullName(), "could not get the filename for the member defining symbol " + SymName))); enqueueTask([=]() { auto MBOrErr = Future->get(); if (MBOrErr.second) fatal(MBOrErr.second, "could not get the buffer for the member defining " + SymName); Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName, ParentName); }); } static bool isDecorated(StringRef Sym) { return Sym.startswith("_") || Sym.startswith("@") || Sym.startswith("?"); } // Parses .drectve section contents and returns a list of files // specified by /defaultlib. void LinkerDriver::parseDirectives(StringRef S) { opt::InputArgList Args = Parser.parse(S); for (auto *Arg : Args) { switch (Arg->getOption().getID()) { case OPT_alternatename: parseAlternateName(Arg->getValue()); break; case OPT_defaultlib: if (Optional Path = findLib(Arg->getValue())) enqueuePath(*Path); break; case OPT_export: { Export E = parseExport(Arg->getValue()); E.Directives = true; Config->Exports.push_back(E); break; } case OPT_failifmismatch: checkFailIfMismatch(Arg->getValue()); break; case OPT_incl: addUndefined(Arg->getValue()); break; case OPT_merge: parseMerge(Arg->getValue()); break; case OPT_nodefaultlib: Config->NoDefaultLibs.insert(doFindLib(Arg->getValue())); break; case OPT_section: parseSection(Arg->getValue()); break; case OPT_editandcontinue: case OPT_fastfail: case OPT_guardsym: case OPT_throwingnew: break; default: error(Arg->getSpelling() + " is not allowed in .drectve"); } } } // Find file from search paths. You can omit ".obj", this function takes // care of that. Note that the returned path is not guaranteed to exist. StringRef LinkerDriver::doFindFile(StringRef Filename) { bool HasPathSep = (Filename.find_first_of("/\\") != StringRef::npos); if (HasPathSep) return Filename; bool HasExt = (Filename.find('.') != StringRef::npos); for (StringRef Dir : SearchPaths) { SmallString<128> Path = Dir; sys::path::append(Path, Filename); if (sys::fs::exists(Path.str())) return Saver.save(Path.str()); if (!HasExt) { Path.append(".obj"); if (sys::fs::exists(Path.str())) return Saver.save(Path.str()); } } return Filename; } // Resolves a file path. This never returns the same path // (in that case, it returns None). Optional LinkerDriver::findFile(StringRef Filename) { StringRef Path = doFindFile(Filename); bool Seen = !VisitedFiles.insert(Path.lower()).second; if (Seen) return None; return Path; } // Find library file from search path. StringRef LinkerDriver::doFindLib(StringRef Filename) { // Add ".lib" to Filename if that has no file extension. bool HasExt = (Filename.find('.') != StringRef::npos); if (!HasExt) Filename = Saver.save(Filename + ".lib"); return doFindFile(Filename); } // Resolves a library path. /nodefaultlib options are taken into // consideration. This never returns the same path (in that case, // it returns None). Optional LinkerDriver::findLib(StringRef Filename) { if (Config->NoDefaultLibAll) return None; if (!VisitedLibs.insert(Filename.lower()).second) return None; StringRef Path = doFindLib(Filename); if (Config->NoDefaultLibs.count(Path)) return None; if (!VisitedFiles.insert(Path.lower()).second) return None; return Path; } // Parses LIB environment which contains a list of search paths. void LinkerDriver::addLibSearchPaths() { Optional EnvOpt = Process::GetEnv("LIB"); if (!EnvOpt.hasValue()) return; StringRef Env = Saver.save(*EnvOpt); while (!Env.empty()) { StringRef Path; std::tie(Path, Env) = Env.split(';'); SearchPaths.push_back(Path); } } SymbolBody *LinkerDriver::addUndefined(StringRef Name) { SymbolBody *B = Symtab.addUndefined(Name); Config->GCRoot.insert(B); return B; } // Symbol names are mangled by appending "_" prefix on x86. StringRef LinkerDriver::mangle(StringRef Sym) { assert(Config->Machine != IMAGE_FILE_MACHINE_UNKNOWN); if (Config->Machine == I386) return Saver.save("_" + Sym); return Sym; } // Windows specific -- find default entry point name. StringRef LinkerDriver::findDefaultEntry() { // User-defined main functions and their corresponding entry points. static const char *Entries[][2] = { {"main", "mainCRTStartup"}, {"wmain", "wmainCRTStartup"}, {"WinMain", "WinMainCRTStartup"}, {"wWinMain", "wWinMainCRTStartup"}, }; for (auto E : Entries) { StringRef Entry = Symtab.findMangle(mangle(E[0])); if (!Entry.empty() && !isa(Symtab.find(Entry)->body())) return mangle(E[1]); } return ""; } WindowsSubsystem LinkerDriver::inferSubsystem() { if (Config->DLL) return IMAGE_SUBSYSTEM_WINDOWS_GUI; if (Symtab.findUnderscore("main") || Symtab.findUnderscore("wmain")) return IMAGE_SUBSYSTEM_WINDOWS_CUI; if (Symtab.findUnderscore("WinMain") || Symtab.findUnderscore("wWinMain")) return IMAGE_SUBSYSTEM_WINDOWS_GUI; return IMAGE_SUBSYSTEM_UNKNOWN; } static uint64_t getDefaultImageBase() { if (Config->is64()) return Config->DLL ? 0x180000000 : 0x140000000; return Config->DLL ? 0x10000000 : 0x400000; } static std::string createResponseFile(const opt::InputArgList &Args, ArrayRef FilePaths, ArrayRef SearchPaths) { SmallString<0> Data; raw_svector_ostream OS(Data); for (auto *Arg : Args) { switch (Arg->getOption().getID()) { case OPT_linkrepro: case OPT_INPUT: case OPT_defaultlib: case OPT_libpath: break; default: OS << toString(Arg) << "\n"; } } for (StringRef Path : SearchPaths) { std::string RelPath = relativeToRoot(Path); OS << "/libpath:" << quote(RelPath) << "\n"; } for (StringRef Path : FilePaths) OS << quote(relativeToRoot(Path)) << "\n"; return Data.str(); } static unsigned getDefaultDebugType(const opt::InputArgList &Args) { unsigned DebugTypes = static_cast(DebugType::CV); if (Args.hasArg(OPT_driver)) DebugTypes |= static_cast(DebugType::PData); if (Args.hasArg(OPT_profile)) DebugTypes |= static_cast(DebugType::Fixup); return DebugTypes; } static unsigned parseDebugType(StringRef Arg) { SmallVector Types; Arg.split(Types, ',', /*KeepEmpty=*/false); unsigned DebugTypes = static_cast(DebugType::None); for (StringRef Type : Types) DebugTypes |= StringSwitch(Type.lower()) .Case("cv", static_cast(DebugType::CV)) .Case("pdata", static_cast(DebugType::PData)) .Case("fixup", static_cast(DebugType::Fixup)) .Default(0); return DebugTypes; } static std::string getMapFile(const opt::InputArgList &Args) { auto *Arg = Args.getLastArg(OPT_lldmap, OPT_lldmap_file); if (!Arg) return ""; if (Arg->getOption().getID() == OPT_lldmap_file) return Arg->getValue(); assert(Arg->getOption().getID() == OPT_lldmap); StringRef OutFile = Config->OutputFile; return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str(); } static std::string getImplibPath() { if (!Config->Implib.empty()) return Config->Implib; SmallString<128> Out = StringRef(Config->OutputFile); sys::path::replace_extension(Out, ".lib"); return Out.str(); } -static void createImportLibrary() { +// +// The import name is caculated as the following: +// +// | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY +// -----+----------------+---------------------+------------------ +// LINK | {value} | {value}.{.dll/.exe} | {output name} +// LIB | {value} | {value}.dll | {output name}.dll +// +static std::string getImportName(bool AsLib) { + SmallString<128> Out; + + if (Config->ImportName.empty()) { + Out.assign(sys::path::filename(Config->OutputFile)); + if (AsLib) + sys::path::replace_extension(Out, ".dll"); + } else { + Out.assign(Config->ImportName); + if (!sys::path::has_extension(Out)) + sys::path::replace_extension(Out, + (Config->DLL || AsLib) ? ".dll" : ".exe"); + } + + return Out.str(); +} + +static void createImportLibrary(bool AsLib) { std::vector Exports; for (Export &E1 : Config->Exports) { COFFShortExport E2; // Use SymbolName, which will have any stdcall or fastcall qualifiers. E2.Name = E1.SymbolName; E2.ExtName = E1.ExtName; E2.Ordinal = E1.Ordinal; E2.Noname = E1.Noname; E2.Data = E1.Data; E2.Private = E1.Private; E2.Constant = E1.Constant; Exports.push_back(E2); } - std::string DLLName = sys::path::filename(Config->OutputFile); - std::string Path = getImplibPath(); - writeImportLibrary(DLLName, Path, Exports, Config->Machine); + writeImportLibrary(getImportName(AsLib), getImplibPath(), Exports, + Config->Machine); } static void parseModuleDefs(StringRef Path) { std::unique_ptr MB = check( MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); COFFModuleDefinition M = check(parseCOFFModuleDefinition(MB->getMemBufferRef(), Config->Machine)); if (Config->OutputFile.empty()) Config->OutputFile = Saver.save(M.OutputFile); + Config->ImportName = Saver.save(M.ImportName); if (M.ImageBase) Config->ImageBase = M.ImageBase; if (M.StackReserve) Config->StackReserve = M.StackReserve; if (M.StackCommit) Config->StackCommit = M.StackCommit; if (M.HeapReserve) Config->HeapReserve = M.HeapReserve; if (M.HeapCommit) Config->HeapCommit = M.HeapCommit; if (M.MajorImageVersion) Config->MajorImageVersion = M.MajorImageVersion; if (M.MinorImageVersion) Config->MinorImageVersion = M.MinorImageVersion; if (M.MajorOSVersion) Config->MajorOSVersion = M.MajorOSVersion; if (M.MinorOSVersion) Config->MinorOSVersion = M.MinorOSVersion; for (COFFShortExport E1 : M.Exports) { Export E2; E2.Name = Saver.save(E1.Name); if (E1.isWeak()) E2.ExtName = Saver.save(E1.ExtName); E2.Ordinal = E1.Ordinal; E2.Noname = E1.Noname; E2.Data = E1.Data; E2.Private = E1.Private; E2.Constant = E1.Constant; Config->Exports.push_back(E2); } } std::vector getArchiveMembers(Archive *File) { std::vector V; Error Err = Error::success(); for (const ErrorOr &COrErr : File->children(Err)) { Archive::Child C = check(COrErr, File->getFileName() + ": could not get the child of the archive"); MemoryBufferRef MBRef = check(C.getMemoryBufferRef(), File->getFileName() + ": could not get the buffer for a child of the archive"); V.push_back(MBRef); } if (Err) fatal(File->getFileName() + ": Archive::children failed: " + toString(std::move(Err))); return V; } // A helper function for filterBitcodeFiles. static bool needsRebuilding(MemoryBufferRef MB) { // The MSVC linker doesn't support thin archives, so if it's a thin // archive, we always need to rebuild it. std::unique_ptr File = check(Archive::create(MB), "Failed to read " + MB.getBufferIdentifier()); if (File->isThin()) return true; // Returns true if the archive contains at least one bitcode file. for (MemoryBufferRef Member : getArchiveMembers(File.get())) if (identify_magic(Member.getBuffer()) == file_magic::bitcode) return true; return false; } // Opens a given path as an archive file and removes bitcode files // from them if exists. This function is to appease the MSVC linker as // their linker doesn't like archive files containing non-native // object files. // // If a given archive doesn't contain bitcode files, the archive path // is returned as-is. Otherwise, a new temporary file is created and // its path is returned. static Optional filterBitcodeFiles(StringRef Path, std::vector &TemporaryFiles) { std::unique_ptr MB = check( MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); MemoryBufferRef MBRef = MB->getMemBufferRef(); file_magic Magic = identify_magic(MBRef.getBuffer()); if (Magic == file_magic::bitcode) return None; if (Magic != file_magic::archive) return Path.str(); if (!needsRebuilding(MBRef)) return Path.str(); std::unique_ptr File = check(Archive::create(MBRef), MBRef.getBufferIdentifier() + ": failed to parse archive"); std::vector New; for (MemoryBufferRef Member : getArchiveMembers(File.get())) if (identify_magic(Member.getBuffer()) != file_magic::bitcode) New.emplace_back(Member); if (New.empty()) return None; log("Creating a temporary archive for " + Path + " to remove bitcode files"); SmallString<128> S; if (auto EC = sys::fs::createTemporaryFile("lld-" + sys::path::stem(Path), ".lib", S)) fatal(EC, "cannot create a temporary file"); std::string Temp = S.str(); TemporaryFiles.push_back(Temp); std::pair Ret = llvm::writeArchive(Temp, New, /*WriteSymtab=*/true, Archive::Kind::K_GNU, /*Deterministics=*/true, /*Thin=*/false); if (Ret.second) error("failed to create a new archive " + S.str() + ": " + Ret.first); return Temp; } // Create response file contents and invoke the MSVC linker. void LinkerDriver::invokeMSVC(opt::InputArgList &Args) { std::string Rsp = "/nologo\n"; std::vector Temps; // Write out archive members that we used in symbol resolution and pass these // to MSVC before any archives, so that MSVC uses the same objects to satisfy // references. for (const auto *O : Symtab.ObjectFiles) { if (O->ParentName.empty()) continue; SmallString<128> S; int Fd; if (auto EC = sys::fs::createTemporaryFile( "lld-" + sys::path::filename(O->ParentName), ".obj", Fd, S)) fatal(EC, "cannot create a temporary file"); raw_fd_ostream OS(Fd, /*shouldClose*/ true); OS << O->MB.getBuffer(); Temps.push_back(S.str()); Rsp += quote(S) + "\n"; } for (auto *Arg : Args) { switch (Arg->getOption().getID()) { case OPT_linkrepro: case OPT_lldmap: case OPT_lldmap_file: case OPT_lldsavetemps: case OPT_msvclto: // LLD-specific options are stripped. break; case OPT_opt: if (!StringRef(Arg->getValue()).startswith("lld")) Rsp += toString(Arg) + " "; break; case OPT_INPUT: { if (Optional Path = doFindFile(Arg->getValue())) { if (Optional S = filterBitcodeFiles(*Path, Temps)) Rsp += quote(*S) + "\n"; continue; } Rsp += quote(Arg->getValue()) + "\n"; break; } default: Rsp += toString(Arg) + "\n"; } } std::vector ObjectFiles = Symtab.compileBitcodeFiles(); runMSVCLinker(Rsp, ObjectFiles); for (StringRef Path : Temps) sys::fs::remove(Path); } void LinkerDriver::enqueueTask(std::function Task) { TaskQueue.push_back(std::move(Task)); } bool LinkerDriver::run() { bool DidWork = !TaskQueue.empty(); while (!TaskQueue.empty()) { TaskQueue.front()(); TaskQueue.pop_front(); } return DidWork; } void LinkerDriver::link(ArrayRef ArgsArr) { // If the first command line argument is "/lib", link.exe acts like lib.exe. // We call our own implementation of lib.exe that understands bitcode files. if (ArgsArr.size() > 1 && StringRef(ArgsArr[1]).equals_lower("/lib")) { if (llvm::libDriverMain(ArgsArr.slice(1)) != 0) fatal("lib failed"); return; } // Needed for LTO. InitializeAllTargetInfos(); InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmParsers(); InitializeAllAsmPrinters(); InitializeAllDisassemblers(); // Parse command line options. opt::InputArgList Args = Parser.parseLINK(ArgsArr.slice(1)); // Parse and evaluate -mllvm options. std::vector V; V.push_back("lld-link (LLVM option parsing)"); for (auto *Arg : Args.filtered(OPT_mllvm)) V.push_back(Arg->getValue()); cl::ParseCommandLineOptions(V.size(), V.data()); // Handle /errorlimit early, because error() depends on it. if (auto *Arg = Args.getLastArg(OPT_errorlimit)) { int N = 20; StringRef S = Arg->getValue(); if (S.getAsInteger(10, N)) error(Arg->getSpelling() + " number expected, but got " + S); Config->ErrorLimit = N; } // Handle /help if (Args.hasArg(OPT_help)) { printHelp(ArgsArr[0]); return; } if (auto *Arg = Args.getLastArg(OPT_linkrepro)) { SmallString<64> Path = StringRef(Arg->getValue()); sys::path::append(Path, "repro.tar"); Expected> ErrOrWriter = TarWriter::create(Path, "repro"); if (ErrOrWriter) { Tar = std::move(*ErrOrWriter); } else { error("/linkrepro: failed to open " + Path + ": " + toString(ErrOrWriter.takeError())); } } if (!Args.hasArgNoClaim(OPT_INPUT)) { if (Args.hasArgNoClaim(OPT_deffile)) Config->NoEntry = true; else fatal("no input files"); } // Construct search path list. SearchPaths.push_back(""); for (auto *Arg : Args.filtered(OPT_libpath)) SearchPaths.push_back(Arg->getValue()); addLibSearchPaths(); // Handle /out if (auto *Arg = Args.getLastArg(OPT_out)) Config->OutputFile = Arg->getValue(); // Handle /verbose if (Args.hasArg(OPT_verbose)) Config->Verbose = true; // Handle /force or /force:unresolved if (Args.hasArg(OPT_force) || Args.hasArg(OPT_force_unresolved)) Config->Force = true; // Handle /debug if (Args.hasArg(OPT_debug)) { Config->Debug = true; Config->DebugTypes = Args.hasArg(OPT_debugtype) ? parseDebugType(Args.getLastArg(OPT_debugtype)->getValue()) : getDefaultDebugType(Args); } // Create a dummy PDB file to satisfy build sytem rules. if (auto *Arg = Args.getLastArg(OPT_pdb)) Config->PDBPath = Arg->getValue(); // Handle /noentry if (Args.hasArg(OPT_noentry)) { if (Args.hasArg(OPT_dll)) Config->NoEntry = true; else error("/noentry must be specified with /dll"); } // Handle /dll if (Args.hasArg(OPT_dll)) { Config->DLL = true; Config->ManifestID = 2; } // Handle /fixed if (Args.hasArg(OPT_fixed)) { if (Args.hasArg(OPT_dynamicbase)) { error("/fixed must not be specified with /dynamicbase"); } else { Config->Relocatable = false; Config->DynamicBase = false; } } if (Args.hasArg(OPT_appcontainer)) Config->AppContainer = true; // Handle /machine if (auto *Arg = Args.getLastArg(OPT_machine)) Config->Machine = getMachineType(Arg->getValue()); // Handle /nodefaultlib: for (auto *Arg : Args.filtered(OPT_nodefaultlib)) Config->NoDefaultLibs.insert(doFindLib(Arg->getValue())); // Handle /nodefaultlib if (Args.hasArg(OPT_nodefaultlib_all)) Config->NoDefaultLibAll = true; // Handle /base if (auto *Arg = Args.getLastArg(OPT_base)) parseNumbers(Arg->getValue(), &Config->ImageBase); // Handle /stack if (auto *Arg = Args.getLastArg(OPT_stack)) parseNumbers(Arg->getValue(), &Config->StackReserve, &Config->StackCommit); // Handle /heap if (auto *Arg = Args.getLastArg(OPT_heap)) parseNumbers(Arg->getValue(), &Config->HeapReserve, &Config->HeapCommit); // Handle /version if (auto *Arg = Args.getLastArg(OPT_version)) parseVersion(Arg->getValue(), &Config->MajorImageVersion, &Config->MinorImageVersion); // Handle /subsystem if (auto *Arg = Args.getLastArg(OPT_subsystem)) parseSubsystem(Arg->getValue(), &Config->Subsystem, &Config->MajorOSVersion, &Config->MinorOSVersion); // Handle /alternatename for (auto *Arg : Args.filtered(OPT_alternatename)) parseAlternateName(Arg->getValue()); // Handle /include for (auto *Arg : Args.filtered(OPT_incl)) addUndefined(Arg->getValue()); // Handle /implib if (auto *Arg = Args.getLastArg(OPT_implib)) Config->Implib = Arg->getValue(); // Handle /opt for (auto *Arg : Args.filtered(OPT_opt)) { std::string Str = StringRef(Arg->getValue()).lower(); SmallVector Vec; StringRef(Str).split(Vec, ','); for (StringRef S : Vec) { if (S == "noref") { Config->DoGC = false; Config->DoICF = false; continue; } if (S == "icf" || StringRef(S).startswith("icf=")) { Config->DoICF = true; continue; } if (S == "noicf") { Config->DoICF = false; continue; } if (StringRef(S).startswith("lldlto=")) { StringRef OptLevel = StringRef(S).substr(7); if (OptLevel.getAsInteger(10, Config->LTOOptLevel) || Config->LTOOptLevel > 3) error("/opt:lldlto: invalid optimization level: " + OptLevel); continue; } if (StringRef(S).startswith("lldltojobs=")) { StringRef Jobs = StringRef(S).substr(11); if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0) error("/opt:lldltojobs: invalid job count: " + Jobs); continue; } if (StringRef(S).startswith("lldltopartitions=")) { StringRef N = StringRef(S).substr(17); if (N.getAsInteger(10, Config->LTOPartitions) || Config->LTOPartitions == 0) error("/opt:lldltopartitions: invalid partition count: " + N); continue; } if (S != "ref" && S != "lbr" && S != "nolbr") error("/opt: unknown option: " + S); } } // Handle /lldsavetemps if (Args.hasArg(OPT_lldsavetemps)) Config->SaveTemps = true; // Handle /failifmismatch for (auto *Arg : Args.filtered(OPT_failifmismatch)) checkFailIfMismatch(Arg->getValue()); // Handle /merge for (auto *Arg : Args.filtered(OPT_merge)) parseMerge(Arg->getValue()); // Handle /section for (auto *Arg : Args.filtered(OPT_section)) parseSection(Arg->getValue()); // Handle /manifest if (auto *Arg = Args.getLastArg(OPT_manifest_colon)) parseManifest(Arg->getValue()); // Handle /manifestuac if (auto *Arg = Args.getLastArg(OPT_manifestuac)) parseManifestUAC(Arg->getValue()); // Handle /manifestdependency if (auto *Arg = Args.getLastArg(OPT_manifestdependency)) Config->ManifestDependency = Arg->getValue(); // Handle /manifestfile if (auto *Arg = Args.getLastArg(OPT_manifestfile)) Config->ManifestFile = Arg->getValue(); // Handle /manifestinput for (auto *Arg : Args.filtered(OPT_manifestinput)) Config->ManifestInput.push_back(Arg->getValue()); // Handle miscellaneous boolean flags. if (Args.hasArg(OPT_allowisolation_no)) Config->AllowIsolation = false; if (Args.hasArg(OPT_dynamicbase_no)) Config->DynamicBase = false; if (Args.hasArg(OPT_nxcompat_no)) Config->NxCompat = false; if (Args.hasArg(OPT_tsaware_no)) Config->TerminalServerAware = false; if (Args.hasArg(OPT_nosymtab)) Config->WriteSymtab = false; Config->MapFile = getMapFile(Args); if (ErrorCount) return; // Create a list of input files. Files can be given as arguments // for /defaultlib option. std::vector MBs; for (auto *Arg : Args.filtered(OPT_INPUT)) if (Optional Path = findFile(Arg->getValue())) enqueuePath(*Path); for (auto *Arg : Args.filtered(OPT_defaultlib)) if (Optional Path = findLib(Arg->getValue())) enqueuePath(*Path); // Windows specific -- Create a resource file containing a manifest file. if (Config->Manifest == Configuration::Embed) addBuffer(createManifestRes()); // Read all input files given via the command line. run(); // We should have inferred a machine type by now from the input files, but if // not we assume x64. if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { warn("/machine is not specified. x64 is assumed"); Config->Machine = AMD64; } // Input files can be Windows resource files (.res files). We use // WindowsResource to convert resource files to a regular COFF file, // then link the resulting file normally. if (!Resources.empty()) addBuffer(convertResToCOFF(Resources)); if (Tar) Tar->append("response.txt", createResponseFile(Args, FilePaths, ArrayRef(SearchPaths).slice(1))); // Handle /largeaddressaware if (Config->is64() || Args.hasArg(OPT_largeaddressaware)) Config->LargeAddressAware = true; // Handle /highentropyva if (Config->is64() && !Args.hasArg(OPT_highentropyva_no)) Config->HighEntropyVA = true; // Handle /entry and /dll if (auto *Arg = Args.getLastArg(OPT_entry)) { Config->Entry = addUndefined(mangle(Arg->getValue())); } else if (Args.hasArg(OPT_dll) && !Config->NoEntry) { StringRef S = (Config->Machine == I386) ? "__DllMainCRTStartup@12" : "_DllMainCRTStartup"; Config->Entry = addUndefined(S); } else if (!Config->NoEntry) { // Windows specific -- If entry point name is not given, we need to // infer that from user-defined entry name. StringRef S = findDefaultEntry(); if (S.empty()) fatal("entry point must be defined"); Config->Entry = addUndefined(S); log("Entry name inferred: " + S); } // Handle /export for (auto *Arg : Args.filtered(OPT_export)) { Export E = parseExport(Arg->getValue()); if (Config->Machine == I386) { if (!isDecorated(E.Name)) E.Name = Saver.save("_" + E.Name); if (!E.ExtName.empty() && !isDecorated(E.ExtName)) E.ExtName = Saver.save("_" + E.ExtName); } Config->Exports.push_back(E); } // Handle /def if (auto *Arg = Args.getLastArg(OPT_deffile)) { // parseModuleDefs mutates Config object. parseModuleDefs(Arg->getValue()); } // Handle generation of import library from a def file. if (!Args.hasArgNoClaim(OPT_INPUT)) { fixupExports(); - createImportLibrary(); + createImportLibrary(/*AsLib=*/true); exit(0); } // Handle /delayload for (auto *Arg : Args.filtered(OPT_delayload)) { Config->DelayLoads.insert(StringRef(Arg->getValue()).lower()); if (Config->Machine == I386) { Config->DelayLoadHelper = addUndefined("___delayLoadHelper2@8"); } else { Config->DelayLoadHelper = addUndefined("__delayLoadHelper2"); } } // Set default image name if neither /out or /def set it. if (Config->OutputFile.empty()) { Config->OutputFile = getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue()); } // Put the PDB next to the image if no /pdb flag was passed. if (Config->Debug && Config->PDBPath.empty()) { Config->PDBPath = Config->OutputFile; sys::path::replace_extension(Config->PDBPath, ".pdb"); } // Disable PDB generation if the user requested it. if (Args.hasArg(OPT_nopdb)) Config->PDBPath = ""; // Set default image base if /base is not given. if (Config->ImageBase == uint64_t(-1)) Config->ImageBase = getDefaultImageBase(); Symtab.addSynthetic(mangle("__ImageBase"), nullptr); if (Config->Machine == I386) { Symtab.addAbsolute("___safe_se_handler_table", 0); Symtab.addAbsolute("___safe_se_handler_count", 0); } // We do not support /guard:cf (control flow protection) yet. // Define CFG symbols anyway so that we can link MSVC 2015 CRT. Symtab.addAbsolute(mangle("__guard_fids_count"), 0); Symtab.addAbsolute(mangle("__guard_fids_table"), 0); Symtab.addAbsolute(mangle("__guard_flags"), 0x100); Symtab.addAbsolute(mangle("__guard_iat_count"), 0); Symtab.addAbsolute(mangle("__guard_iat_table"), 0); Symtab.addAbsolute(mangle("__guard_longjmp_count"), 0); Symtab.addAbsolute(mangle("__guard_longjmp_table"), 0); // This code may add new undefined symbols to the link, which may enqueue more // symbol resolution tasks, so we need to continue executing tasks until we // converge. do { // Windows specific -- if entry point is not found, // search for its mangled names. if (Config->Entry) Symtab.mangleMaybe(Config->Entry); // Windows specific -- Make sure we resolve all dllexported symbols. for (Export &E : Config->Exports) { if (!E.ForwardTo.empty()) continue; E.Sym = addUndefined(E.Name); if (!E.Directives) Symtab.mangleMaybe(E.Sym); } // Add weak aliases. Weak aliases is a mechanism to give remaining // undefined symbols final chance to be resolved successfully. for (auto Pair : Config->AlternateNames) { StringRef From = Pair.first; StringRef To = Pair.second; Symbol *Sym = Symtab.find(From); if (!Sym) continue; if (auto *U = dyn_cast(Sym->body())) if (!U->WeakAlias) U->WeakAlias = Symtab.addUndefined(To); } // Windows specific -- if __load_config_used can be resolved, resolve it. if (Symtab.findUnderscore("_load_config_used")) addUndefined(mangle("_load_config_used")); } while (run()); if (ErrorCount) return; // If /msvclto is given, we use the MSVC linker to link LTO output files. // This is useful because MSVC link.exe can generate complete PDBs. if (Args.hasArg(OPT_msvclto)) { invokeMSVC(Args); exit(0); } // Do LTO by compiling bitcode input files to a set of native COFF files then // link those files. Symtab.addCombinedLTOObjects(); run(); // Make sure we have resolved all symbols. Symtab.reportRemainingUndefines(); // Windows specific -- if no /subsystem is given, we need to infer // that from entry point name. if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) { Config->Subsystem = inferSubsystem(); if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) fatal("subsystem must be defined"); } // Handle /safeseh. if (Args.hasArg(OPT_safeseh)) { for (ObjectFile *File : Symtab.ObjectFiles) if (!File->SEHCompat) error("/safeseh: " + File->getName() + " is not compatible with SEH"); if (ErrorCount) return; } // Windows specific -- when we are creating a .dll file, we also // need to create a .lib file. if (!Config->Exports.empty() || Config->DLL) { fixupExports(); - createImportLibrary(); + createImportLibrary(/*AsLib=*/false); assignExportOrdinals(); } // Windows specific -- Create a side-by-side manifest file. if (Config->Manifest == Configuration::SideBySide) createSideBySideManifest(); // Identify unreferenced COMDAT sections. if (Config->DoGC) markLive(Symtab.getChunks()); // Identify identical COMDAT sections to merge them. if (Config->DoICF) doICF(Symtab.getChunks()); // Write the result. writeResult(&Symtab); // Call exit to avoid calling destructors. exit(0); } } // namespace coff } // namespace lld Index: vendor/lld/dist/COFF/PDB.cpp =================================================================== --- vendor/lld/dist/COFF/PDB.cpp (revision 321191) +++ vendor/lld/dist/COFF/PDB.cpp (revision 321192) @@ -1,510 +1,672 @@ //===- PDB.cpp ------------------------------------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "PDB.h" #include "Chunks.h" #include "Config.h" #include "Error.h" #include "SymbolTable.h" #include "Symbols.h" #include "llvm/DebugInfo/CodeView/CVDebugRecord.h" -#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" -#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h" #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" #include "llvm/DebugInfo/MSF/MSFBuilder.h" #include "llvm/DebugInfo/MSF/MSFCommon.h" +#include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" #include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h" #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h" -#include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h" +#include "llvm/DebugInfo/PDB/PDB.h" #include "llvm/Object/COFF.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/Endian.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/ScopedPrinter.h" #include using namespace lld; using namespace lld::coff; using namespace llvm; using namespace llvm::codeview; using llvm::object::coff_section; static ExitOnError ExitOnErr; +namespace { +/// Map from type index and item index in a type server PDB to the +/// corresponding index in the destination PDB. +struct CVIndexMap { + SmallVector TPIMap; + SmallVector IPIMap; + bool IsTypeServerMap = false; +}; + +class PDBLinker { +public: + PDBLinker(SymbolTable *Symtab) + : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc), + IDTable(Alloc) {} + + /// Emit the basic PDB structure: initial streams, headers, etc. + void initialize(const llvm::codeview::DebugInfo *DI); + + /// Link CodeView from each object file in the symbol table into the PDB. + void addObjectsToPDB(); + + /// Link CodeView from a single object file into the PDB. + void addObjectFile(ObjectFile *File); + + /// Produce a mapping from the type and item indices used in the object + /// file to those in the destination PDB. + /// + /// If the object file uses a type server PDB (compiled with /Zi), merge TPI + /// and IPI from the type server PDB and return a map for it. Each unique type + /// server PDB is merged at most once, so this may return an existing index + /// mapping. + /// + /// If the object does not use a type server PDB (compiled with /Z7), we merge + /// all the type and item records from the .debug$S stream and fill in the + /// caller-provided ObjectIndexMap. + const CVIndexMap &mergeDebugT(ObjectFile *File, CVIndexMap &ObjectIndexMap); + + const CVIndexMap &maybeMergeTypeServerPDB(ObjectFile *File, + TypeServer2Record &TS); + + /// Add the section map and section contributions to the PDB. + void addSections(ArrayRef SectionTable); + + /// Write the PDB to disk. + void commit(); + +private: + BumpPtrAllocator Alloc; + + SymbolTable *Symtab; + + pdb::PDBFileBuilder Builder; + + /// Type records that will go into the PDB TPI stream. + TypeTableBuilder TypeTable; + + /// Item records that will go into the PDB IPI stream. + TypeTableBuilder IDTable; + + /// PDBs use a single global string table for filenames in the file checksum + /// table. + DebugStringTableSubsection PDBStrTab; + + llvm::SmallString<128> NativePath; + + std::vector SectionMap; + + /// Type index mappings of type server PDBs that we've loaded so far. + std::map TypeServerIndexMappings; +}; +} + // Returns a list of all SectionChunks. -static void addSectionContribs(SymbolTable *Symtab, pdb::DbiStreamBuilder &DbiBuilder) { +static void addSectionContribs(SymbolTable *Symtab, + pdb::DbiStreamBuilder &DbiBuilder) { for (Chunk *C : Symtab->getChunks()) if (auto *SC = dyn_cast(C)) DbiBuilder.addSectionContrib(SC->File->ModuleDBI, SC->Header); } static SectionChunk *findByName(std::vector &Sections, StringRef Name) { for (SectionChunk *C : Sections) if (C->getSectionName() == Name) return C; return nullptr; } static ArrayRef consumeDebugMagic(ArrayRef Data, StringRef SecName) { // First 4 bytes are section magic. if (Data.size() < 4) fatal(SecName + " too short"); if (support::endian::read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC) fatal(SecName + " has an invalid magic"); return Data.slice(4); } static ArrayRef getDebugSection(ObjectFile *File, StringRef SecName) { if (SectionChunk *Sec = findByName(File->getDebugChunks(), SecName)) return consumeDebugMagic(Sec->getContents(), SecName); return {}; } static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder, TypeTableBuilder &TypeTable) { // Start the TPI or IPI stream header. TpiBuilder.setVersionHeader(pdb::PdbTpiV80); // Flatten the in memory type table. TypeTable.ForEachRecord([&](TypeIndex TI, ArrayRef Rec) { // FIXME: Hash types. TpiBuilder.addTypeRecord(Rec, None); }); } -static void mergeDebugT(ObjectFile *File, - TypeTableBuilder &IDTable, - TypeTableBuilder &TypeTable, - SmallVectorImpl &TypeIndexMap, - pdb::PDBTypeServerHandler &Handler) { +static Optional +maybeReadTypeServerRecord(CVTypeArray &Types) { + auto I = Types.begin(); + if (I == Types.end()) + return None; + const CVType &Type = *I; + if (Type.kind() != LF_TYPESERVER2) + return None; + TypeServer2Record TS; + if (auto EC = TypeDeserializer::deserializeAs(const_cast(Type), TS)) + fatal(EC, "error reading type server record"); + return std::move(TS); +} + +const CVIndexMap &PDBLinker::mergeDebugT(ObjectFile *File, + CVIndexMap &ObjectIndexMap) { ArrayRef Data = getDebugSection(File, ".debug$T"); if (Data.empty()) - return; + return ObjectIndexMap; BinaryByteStream Stream(Data, support::little); CVTypeArray Types; BinaryStreamReader Reader(Stream); - Handler.addSearchPath(sys::path::parent_path(File->getName())); if (auto EC = Reader.readArray(Types, Reader.getLength())) fatal(EC, "Reader::readArray failed"); + + // Look through type servers. If we've already seen this type server, don't + // merge any type information. + if (Optional TS = maybeReadTypeServerRecord(Types)) + return maybeMergeTypeServerPDB(File, *TS); + + // This is a /Z7 object. Fill in the temporary, caller-provided + // ObjectIndexMap. if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable, - TypeIndexMap, &Handler, Types)) - fatal(Err, "codeview::mergeTypeStreams failed"); + ObjectIndexMap.TPIMap, Types)) + fatal(Err, "codeview::mergeTypeAndIdRecords failed"); + return ObjectIndexMap; } +static Expected> +tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) { + std::unique_ptr ThisSession; + if (auto EC = + pdb::loadDataForPDB(pdb::PDB_ReaderType::Native, TSPath, ThisSession)) + return std::move(EC); + + std::unique_ptr NS( + static_cast(ThisSession.release())); + pdb::PDBFile &File = NS->getPDBFile(); + auto ExpectedInfo = File.getPDBInfoStream(); + // All PDB Files should have an Info stream. + if (!ExpectedInfo) + return ExpectedInfo.takeError(); + + // Just because a file with a matching name was found and it was an actual + // PDB file doesn't mean it matches. For it to match the InfoStream's GUID + // must match the GUID specified in the TypeServer2 record. + if (ExpectedInfo->getGuid() != GuidFromObj) + return make_error( + pdb::generic_error_code::type_server_not_found, TSPath); + + return std::move(NS); +} + +const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjectFile *File, + TypeServer2Record &TS) { + // First, check if we already loaded a PDB with this GUID. Return the type + // index mapping if we have it. + auto Insertion = TypeServerIndexMappings.insert({TS.getGuid(), CVIndexMap()}); + CVIndexMap &IndexMap = Insertion.first->second; + if (!Insertion.second) + return IndexMap; + + // Mark this map as a type server map. + IndexMap.IsTypeServerMap = true; + + // Check for a PDB at: + // 1. The given file path + // 2. Next to the object file or archive file + auto ExpectedSession = tryToLoadPDB(TS.getGuid(), TS.getName()); + if (!ExpectedSession) { + consumeError(ExpectedSession.takeError()); + StringRef LocalPath = + !File->ParentName.empty() ? File->ParentName : File->getName(); + SmallString<128> Path = sys::path::parent_path(LocalPath); + sys::path::append( + Path, sys::path::filename(TS.getName(), sys::path::Style::windows)); + ExpectedSession = tryToLoadPDB(TS.getGuid(), Path); + } + if (auto E = ExpectedSession.takeError()) + fatal(E, "Type server PDB was not found"); + + // Merge TPI first, because the IPI stream will reference type indices. + auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream(); + if (auto E = ExpectedTpi.takeError()) + fatal(E, "Type server does not have TPI stream"); + if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap, + ExpectedTpi->typeArray())) + fatal(Err, "codeview::mergeTypeRecords failed"); + + // Merge IPI. + auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream(); + if (auto E = ExpectedIpi.takeError()) + fatal(E, "Type server does not have TPI stream"); + if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap, + ExpectedIpi->typeArray())) + fatal(Err, "codeview::mergeIdRecords failed"); + + return IndexMap; +} + static bool remapTypeIndex(TypeIndex &TI, ArrayRef TypeIndexMap) { if (TI.isSimple()) return true; if (TI.toArrayIndex() >= TypeIndexMap.size()) return false; TI = TypeIndexMap[TI.toArrayIndex()]; return true; } static void remapTypesInSymbolRecord(ObjectFile *File, MutableArrayRef Contents, - ArrayRef TypeIndexMap, + const CVIndexMap &IndexMap, ArrayRef TypeRefs) { for (const TiReference &Ref : TypeRefs) { unsigned ByteSize = Ref.Count * sizeof(TypeIndex); if (Contents.size() < Ref.Offset + ByteSize) fatal("symbol record too short"); + + // This can be an item index or a type index. Choose the appropriate map. + ArrayRef TypeOrItemMap = IndexMap.TPIMap; + if (Ref.Kind == TiRefKind::IndexRef && IndexMap.IsTypeServerMap) + TypeOrItemMap = IndexMap.IPIMap; + MutableArrayRef TIs( reinterpret_cast(Contents.data() + Ref.Offset), Ref.Count); for (TypeIndex &TI : TIs) { - if (!remapTypeIndex(TI, TypeIndexMap)) { + if (!remapTypeIndex(TI, TypeOrItemMap)) { TI = TypeIndex(SimpleTypeKind::NotTranslated); log("ignoring symbol record in " + File->getName() + " with bad type index 0x" + utohexstr(TI.getIndex())); continue; } } } } /// MSVC translates S_PROC_ID_END to S_END. uint16_t canonicalizeSymbolKind(SymbolKind Kind) { if (Kind == SymbolKind::S_PROC_ID_END) return SymbolKind::S_END; return Kind; } /// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned. /// The object file may not be aligned. static MutableArrayRef copySymbolForPdb(const CVSymbol &Sym, BumpPtrAllocator &Alloc) { size_t Size = alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb)); assert(Size >= 4 && "record too short"); assert(Size <= MaxRecordLength && "record too long"); void *Mem = Alloc.Allocate(Size, 4); // Copy the symbol record and zero out any padding bytes. MutableArrayRef NewData(reinterpret_cast(Mem), Size); memcpy(NewData.data(), Sym.data().data(), Sym.length()); memset(NewData.data() + Sym.length(), 0, Size - Sym.length()); // Update the record prefix length. It should point to the beginning of the // next record. MSVC does some canonicalization of the record kind, so we do // that as well. auto *Prefix = reinterpret_cast(Mem); Prefix->RecordKind = canonicalizeSymbolKind(Sym.kind()); Prefix->RecordLen = Size - 2; return NewData; } /// Return true if this symbol opens a scope. This implies that the symbol has /// "parent" and "end" fields, which contain the offset of the S_END or /// S_INLINESITE_END record. static bool symbolOpensScope(SymbolKind Kind) { switch (Kind) { case SymbolKind::S_GPROC32: case SymbolKind::S_LPROC32: case SymbolKind::S_LPROC32_ID: case SymbolKind::S_GPROC32_ID: case SymbolKind::S_BLOCK32: case SymbolKind::S_SEPCODE: case SymbolKind::S_THUNK32: case SymbolKind::S_INLINESITE: case SymbolKind::S_INLINESITE2: return true; default: break; } return false; } static bool symbolEndsScope(SymbolKind Kind) { switch (Kind) { case SymbolKind::S_END: case SymbolKind::S_PROC_ID_END: case SymbolKind::S_INLINESITE_END: return true; default: break; } return false; } struct ScopeRecord { ulittle32_t PtrParent; ulittle32_t PtrEnd; }; struct SymbolScope { ScopeRecord *OpeningRecord; uint32_t ScopeOffset; }; static void scopeStackOpen(SmallVectorImpl &Stack, uint32_t CurOffset, CVSymbol &Sym) { assert(symbolOpensScope(Sym.kind())); SymbolScope S; S.ScopeOffset = CurOffset; S.OpeningRecord = const_cast( reinterpret_cast(Sym.content().data())); S.OpeningRecord->PtrParent = Stack.empty() ? 0 : Stack.back().ScopeOffset; Stack.push_back(S); } static void scopeStackClose(SmallVectorImpl &Stack, uint32_t CurOffset, ObjectFile *File) { if (Stack.empty()) { warn("symbol scopes are not balanced in " + File->getName()); return; } SymbolScope S = Stack.pop_back_val(); S.OpeningRecord->PtrEnd = CurOffset; } static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File, - ArrayRef TypeIndexMap, + const CVIndexMap &IndexMap, BinaryStreamRef SymData) { // FIXME: Improve error recovery by warning and skipping records when // possible. CVSymbolArray Syms; BinaryStreamReader Reader(SymData); ExitOnErr(Reader.readArray(Syms, Reader.getLength())); SmallVector Scopes; for (const CVSymbol &Sym : Syms) { // Discover type index references in the record. Skip it if we don't know // where they are. SmallVector TypeRefs; if (!discoverTypeIndices(Sym, TypeRefs)) { log("ignoring unknown symbol record with kind 0x" + utohexstr(Sym.kind())); continue; } // Copy the symbol record so we can mutate it. MutableArrayRef NewData = copySymbolForPdb(Sym, Alloc); // Re-map all the type index references. MutableArrayRef Contents = NewData.drop_front(sizeof(RecordPrefix)); - remapTypesInSymbolRecord(File, Contents, TypeIndexMap, TypeRefs); + remapTypesInSymbolRecord(File, Contents, IndexMap, TypeRefs); // Fill in "Parent" and "End" fields by maintaining a stack of scopes. CVSymbol NewSym(Sym.kind(), NewData); if (symbolOpensScope(Sym.kind())) scopeStackOpen(Scopes, File->ModuleDBI->getNextSymbolOffset(), NewSym); else if (symbolEndsScope(Sym.kind())) scopeStackClose(Scopes, File->ModuleDBI->getNextSymbolOffset(), File); // Add the symbol to the module. File->ModuleDBI->addSymbol(NewSym); } } // Allocate memory for a .debug$S section and relocate it. static ArrayRef relocateDebugChunk(BumpPtrAllocator &Alloc, SectionChunk *DebugChunk) { uint8_t *Buffer = Alloc.Allocate(DebugChunk->getSize()); assert(DebugChunk->OutputSectionOff == 0 && "debug sections should not be in output sections"); DebugChunk->writeTo(Buffer); return consumeDebugMagic(makeArrayRef(Buffer, DebugChunk->getSize()), ".debug$S"); } -// Add all object files to the PDB. Merge .debug$T sections into IpiData and -// TpiData. -static void addObjectsToPDB(BumpPtrAllocator &Alloc, SymbolTable *Symtab, - pdb::PDBFileBuilder &Builder, - TypeTableBuilder &TypeTable, - TypeTableBuilder &IDTable) { - // Follow type servers. If the same type server is encountered more than - // once for this instance of `PDBTypeServerHandler` (for example if many - // object files reference the same TypeServer), the types from the - // TypeServer will only be visited once. - pdb::PDBTypeServerHandler Handler; +void PDBLinker::addObjectFile(ObjectFile *File) { + // Add a module descriptor for every object file. We need to put an absolute + // path to the object into the PDB. If this is a plain object, we make its + // path absolute. If it's an object in an archive, we make the archive path + // absolute. + bool InArchive = !File->ParentName.empty(); + SmallString<128> Path = InArchive ? File->ParentName : File->getName(); + sys::fs::make_absolute(Path); + sys::path::native(Path, sys::path::Style::windows); + StringRef Name = InArchive ? File->getName() : StringRef(Path); - // PDBs use a single global string table for filenames in the file checksum - // table. - auto PDBStrTab = std::make_shared(); + File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name)); + File->ModuleDBI->setObjFileName(Path); - // Visit all .debug$T sections to add them to Builder. - for (ObjectFile *File : Symtab->ObjectFiles) { - // Add a module descriptor for every object file. We need to put an absolute - // path to the object into the PDB. If this is a plain object, we make its - // path absolute. If it's an object in an archive, we make the archive path - // absolute. - bool InArchive = !File->ParentName.empty(); - SmallString<128> Path = InArchive ? File->ParentName : File->getName(); - sys::fs::make_absolute(Path); - sys::path::native(Path, llvm::sys::path::Style::windows); - StringRef Name = InArchive ? File->getName() : StringRef(Path); + // Before we can process symbol substreams from .debug$S, we need to process + // type information, file checksums, and the string table. Add type info to + // the PDB first, so that we can get the map from object file type and item + // indices to PDB type and item indices. + CVIndexMap ObjectIndexMap; + const CVIndexMap &IndexMap = mergeDebugT(File, ObjectIndexMap); - File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name)); - File->ModuleDBI->setObjFileName(Path); + // Now do all live .debug$S sections. + for (SectionChunk *DebugChunk : File->getDebugChunks()) { + if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S") + continue; - // Before we can process symbol substreams from .debug$S, we need to process - // type information, file checksums, and the string table. Add type info to - // the PDB first, so that we can get the map from object file type and item - // indices to PDB type and item indices. - SmallVector TypeIndexMap; - mergeDebugT(File, IDTable, TypeTable, TypeIndexMap, Handler); + ArrayRef RelocatedDebugContents = + relocateDebugChunk(Alloc, DebugChunk); + if (RelocatedDebugContents.empty()) + continue; - // Now do all line info. - for (SectionChunk *DebugChunk : File->getDebugChunks()) { - if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S") - continue; + DebugSubsectionArray Subsections; + BinaryStreamReader Reader(RelocatedDebugContents, support::little); + ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size())); - ArrayRef RelocatedDebugContents = - relocateDebugChunk(Alloc, DebugChunk); - if (RelocatedDebugContents.empty()) - continue; - - DebugSubsectionArray Subsections; - BinaryStreamReader Reader(RelocatedDebugContents, support::little); - ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size())); - - DebugStringTableSubsectionRef CVStrTab; - DebugChecksumsSubsectionRef Checksums; - for (const DebugSubsectionRecord &SS : Subsections) { - switch (SS.kind()) { - case DebugSubsectionKind::StringTable: - ExitOnErr(CVStrTab.initialize(SS.getRecordData())); - break; - case DebugSubsectionKind::FileChecksums: - ExitOnErr(Checksums.initialize(SS.getRecordData())); - break; - case DebugSubsectionKind::Lines: - // We can add the relocated line table directly to the PDB without - // modification because the file checksum offsets will stay the same. - File->ModuleDBI->addDebugSubsection(SS); - break; - case DebugSubsectionKind::Symbols: - mergeSymbolRecords(Alloc, File, TypeIndexMap, SS.getRecordData()); - break; - default: - // FIXME: Process the rest of the subsections. - break; - } + DebugStringTableSubsectionRef CVStrTab; + DebugChecksumsSubsectionRef Checksums; + for (const DebugSubsectionRecord &SS : Subsections) { + switch (SS.kind()) { + case DebugSubsectionKind::StringTable: + ExitOnErr(CVStrTab.initialize(SS.getRecordData())); + break; + case DebugSubsectionKind::FileChecksums: + ExitOnErr(Checksums.initialize(SS.getRecordData())); + break; + case DebugSubsectionKind::Lines: + // We can add the relocated line table directly to the PDB without + // modification because the file checksum offsets will stay the same. + File->ModuleDBI->addDebugSubsection(SS); + break; + case DebugSubsectionKind::Symbols: + mergeSymbolRecords(Alloc, File, IndexMap, SS.getRecordData()); + break; + default: + // FIXME: Process the rest of the subsections. + break; } + } - if (Checksums.valid()) { - // Make a new file checksum table that refers to offsets in the PDB-wide - // string table. Generally the string table subsection appears after the - // checksum table, so we have to do this after looping over all the - // subsections. - if (!CVStrTab.valid()) - fatal(".debug$S sections must have both a string table subsection " - "and a checksum subsection table or neither"); - auto NewChecksums = - make_unique(*PDBStrTab); - for (FileChecksumEntry &FC : Checksums) { - StringRef FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset)); - ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile( - *File->ModuleDBI, FileName)); - NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum); - } - File->ModuleDBI->addDebugSubsection(std::move(NewChecksums)); + if (Checksums.valid()) { + // Make a new file checksum table that refers to offsets in the PDB-wide + // string table. Generally the string table subsection appears after the + // checksum table, so we have to do this after looping over all the + // subsections. + if (!CVStrTab.valid()) + fatal(".debug$S sections must have both a string table subsection " + "and a checksum subsection table or neither"); + auto NewChecksums = make_unique(PDBStrTab); + for (FileChecksumEntry &FC : Checksums) { + StringRef FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset)); + ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(*File->ModuleDBI, + FileName)); + NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum); } + File->ModuleDBI->addDebugSubsection(std::move(NewChecksums)); } } +} - Builder.getStringTableBuilder().setStrings(*PDBStrTab); +// Add all object files to the PDB. Merge .debug$T sections into IpiData and +// TpiData. +void PDBLinker::addObjectsToPDB() { + for (ObjectFile *File : Symtab->ObjectFiles) + addObjectFile(File); + Builder.getStringTableBuilder().setStrings(PDBStrTab); + // Construct TPI stream contents. addTypeInfo(Builder.getTpiBuilder(), TypeTable); // Construct IPI stream contents. addTypeInfo(Builder.getIpiBuilder(), IDTable); + + // Add public and symbol records stream. + + // For now we don't actually write any thing useful to the publics stream, but + // the act of "getting" it also creates it lazily so that we write an empty + // stream. + (void)Builder.getPublicsBuilder(); } static void addLinkerModuleSymbols(StringRef Path, pdb::DbiModuleDescriptorBuilder &Mod, BumpPtrAllocator &Allocator) { codeview::SymbolSerializer Serializer(Allocator, CodeViewContainer::Pdb); codeview::ObjNameSym ONS(SymbolRecordKind::ObjNameSym); codeview::Compile3Sym CS(SymbolRecordKind::Compile3Sym); codeview::EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym); ONS.Name = "* Linker *"; ONS.Signature = 0; CS.Machine = Config->is64() ? CPUType::X64 : CPUType::Intel80386; CS.Flags = CompileSym3Flags::None; CS.VersionBackendBuild = 0; CS.VersionBackendMajor = 0; CS.VersionBackendMinor = 0; CS.VersionBackendQFE = 0; CS.VersionFrontendBuild = 0; CS.VersionFrontendMajor = 0; CS.VersionFrontendMinor = 0; CS.VersionFrontendQFE = 0; CS.Version = "LLVM Linker"; CS.setLanguage(SourceLanguage::Link); ArrayRef Args = makeArrayRef(Config->Argv).drop_front(); std::string ArgStr = llvm::join(Args, " "); EBS.Fields.push_back("cwd"); SmallString<64> cwd; - llvm::sys::fs::current_path(cwd); + sys::fs::current_path(cwd); EBS.Fields.push_back(cwd); EBS.Fields.push_back("exe"); EBS.Fields.push_back(Config->Argv[0]); EBS.Fields.push_back("pdb"); EBS.Fields.push_back(Path); EBS.Fields.push_back("cmd"); EBS.Fields.push_back(ArgStr); Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( ONS, Allocator, CodeViewContainer::Pdb)); Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( CS, Allocator, CodeViewContainer::Pdb)); Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( EBS, Allocator, CodeViewContainer::Pdb)); } // Creates a PDB file. void coff::createPDB(SymbolTable *Symtab, ArrayRef SectionTable, const llvm::codeview::DebugInfo *DI) { - BumpPtrAllocator Alloc; - pdb::PDBFileBuilder Builder(Alloc); + PDBLinker PDB(Symtab); + PDB.initialize(DI); + PDB.addObjectsToPDB(); + PDB.addSections(SectionTable); + PDB.commit(); +} + +void PDBLinker::initialize(const llvm::codeview::DebugInfo *DI) { ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize // Create streams in MSF for predefined streams, namely // PDB, TPI, DBI and IPI. for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I) ExitOnErr(Builder.getMsfBuilder().addStream(0)); // Add an Info stream. auto &InfoBuilder = Builder.getInfoBuilder(); InfoBuilder.setAge(DI ? DI->PDB70.Age : 0); - llvm::SmallString<128> NativePath(Config->PDBPath.begin(), - Config->PDBPath.end()); - llvm::sys::fs::make_absolute(NativePath); - llvm::sys::path::native(NativePath, llvm::sys::path::Style::windows); - - pdb::PDB_UniqueId uuid{}; + GUID uuid{}; if (DI) memcpy(&uuid, &DI->PDB70.Signature, sizeof(uuid)); InfoBuilder.setGuid(uuid); InfoBuilder.setSignature(time(nullptr)); InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70); // Add an empty DBI stream. pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); DbiBuilder.setVersionHeader(pdb::PdbDbiV70); ExitOnErr(DbiBuilder.addDbgStream(pdb::DbgHeaderType::NewFPO, {})); +} - // It's not entirely clear what this is, but the * Linker * module uses it. - uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath); - - TypeTableBuilder TypeTable(BAlloc); - TypeTableBuilder IDTable(BAlloc); - addObjectsToPDB(Alloc, Symtab, Builder, TypeTable, IDTable); - - // Add public and symbol records stream. - - // For now we don't actually write any thing useful to the publics stream, but - // the act of "getting" it also creates it lazily so that we write an empty - // stream. - (void)Builder.getPublicsBuilder(); - +void PDBLinker::addSections(ArrayRef SectionTable) { // Add Section Contributions. + pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); addSectionContribs(Symtab, DbiBuilder); // Add Section Map stream. ArrayRef Sections = { (const object::coff_section *)SectionTable.data(), SectionTable.size() / sizeof(object::coff_section)}; - std::vector SectionMap = - pdb::DbiStreamBuilder::createSectionMap(Sections); + SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections); DbiBuilder.setSectionMap(SectionMap); + // It's not entirely clear what this is, but the * Linker * module uses it. + NativePath = Config->PDBPath; + sys::fs::make_absolute(NativePath); + sys::path::native(NativePath, sys::path::Style::windows); + uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath); auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *")); LinkerModule.setPdbFilePathNI(PdbFilePathNI); addLinkerModuleSymbols(NativePath, LinkerModule, Alloc); // Add COFF section header stream. ExitOnErr( DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable)); +} +void PDBLinker::commit() { // Write to a file. ExitOnErr(Builder.commit(Config->PDBPath)); } Index: vendor/lld/dist/ELF/Arch/ARM.cpp =================================================================== --- vendor/lld/dist/ELF/Arch/ARM.cpp (revision 321191) +++ vendor/lld/dist/ELF/Arch/ARM.cpp (revision 321192) @@ -1,435 +1,480 @@ //===- ARM.cpp ------------------------------------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "Error.h" #include "InputFiles.h" #include "Symbols.h" #include "SyntheticSections.h" #include "Target.h" #include "Thunks.h" #include "llvm/Object/ELF.h" #include "llvm/Support/Endian.h" using namespace llvm; using namespace llvm::support::endian; using namespace llvm::ELF; using namespace lld; using namespace lld::elf; namespace { class ARM final : public TargetInfo { public: ARM(); RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, const uint8_t *Loc) const override; bool isPicRel(uint32_t Type) const override; uint32_t getDynRel(uint32_t Type) const override; int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override; void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override; void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const override; void writePltHeader(uint8_t *Buf) const override; void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, int32_t Index, unsigned RelOff) const override; void addPltSymbols(InputSectionBase *IS, uint64_t Off) const override; void addPltHeaderSymbols(InputSectionBase *ISD) const override; bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File, const SymbolBody &S) const override; + bool inBranchRange(uint32_t RelocType, uint64_t Src, + uint64_t Dst) const override; void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; }; } // namespace ARM::ARM() { CopyRel = R_ARM_COPY; RelativeRel = R_ARM_RELATIVE; IRelativeRel = R_ARM_IRELATIVE; GotRel = R_ARM_GLOB_DAT; PltRel = R_ARM_JUMP_SLOT; TlsGotRel = R_ARM_TLS_TPOFF32; TlsModuleIndexRel = R_ARM_TLS_DTPMOD32; TlsOffsetRel = R_ARM_TLS_DTPOFF32; GotEntrySize = 4; GotPltEntrySize = 4; PltEntrySize = 16; PltHeaderSize = 20; TrapInstr = 0xd4d4d4d4; // ARM uses Variant 1 TLS TcbSize = 8; NeedsThunks = true; } RelExpr ARM::getRelExpr(uint32_t Type, const SymbolBody &S, const uint8_t *Loc) const { switch (Type) { default: return R_ABS; case R_ARM_THM_JUMP11: return R_PC; case R_ARM_CALL: case R_ARM_JUMP24: case R_ARM_PC24: case R_ARM_PLT32: case R_ARM_PREL31: case R_ARM_THM_JUMP19: case R_ARM_THM_JUMP24: case R_ARM_THM_CALL: return R_PLT_PC; case R_ARM_GOTOFF32: // (S + A) - GOT_ORG return R_GOTREL; case R_ARM_GOT_BREL: // GOT(S) + A - GOT_ORG return R_GOT_OFF; case R_ARM_GOT_PREL: case R_ARM_TLS_IE32: // GOT(S) + A - P return R_GOT_PC; case R_ARM_SBREL32: return R_ARM_SBREL; case R_ARM_TARGET1: return Config->Target1Rel ? R_PC : R_ABS; case R_ARM_TARGET2: if (Config->Target2 == Target2Policy::Rel) return R_PC; if (Config->Target2 == Target2Policy::Abs) return R_ABS; return R_GOT_PC; case R_ARM_TLS_GD32: return R_TLSGD_PC; case R_ARM_TLS_LDM32: return R_TLSLD_PC; case R_ARM_BASE_PREL: // B(S) + A - P // FIXME: currently B(S) assumed to be .got, this may not hold for all // platforms. return R_GOTONLY_PC; case R_ARM_MOVW_PREL_NC: case R_ARM_MOVT_PREL: case R_ARM_REL32: case R_ARM_THM_MOVW_PREL_NC: case R_ARM_THM_MOVT_PREL: return R_PC; case R_ARM_NONE: return R_NONE; case R_ARM_TLS_LE32: return R_TLS; } } bool ARM::isPicRel(uint32_t Type) const { return (Type == R_ARM_TARGET1 && !Config->Target1Rel) || (Type == R_ARM_ABS32); } uint32_t ARM::getDynRel(uint32_t Type) const { if (Type == R_ARM_TARGET1 && !Config->Target1Rel) return R_ARM_ABS32; if (Type == R_ARM_ABS32) return Type; // Keep it going with a dummy value so that we can find more reloc errors. return R_ARM_ABS32; } void ARM::writeGotPlt(uint8_t *Buf, const SymbolBody &) const { write32le(Buf, InX::Plt->getVA()); } void ARM::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const { // An ARM entry is the address of the ifunc resolver function. write32le(Buf, S.getVA()); } void ARM::writePltHeader(uint8_t *Buf) const { const uint8_t PltData[] = { 0x04, 0xe0, 0x2d, 0xe5, // str lr, [sp,#-4]! 0x04, 0xe0, 0x9f, 0xe5, // ldr lr, L2 0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr 0x08, 0xf0, 0xbe, 0xe5, // ldr pc, [lr, #8] 0x00, 0x00, 0x00, 0x00, // L2: .word &(.got.plt) - L1 - 8 }; memcpy(Buf, PltData, sizeof(PltData)); uint64_t GotPlt = InX::GotPlt->getVA(); uint64_t L1 = InX::Plt->getVA() + 8; write32le(Buf + 16, GotPlt - L1 - 8); } void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const { auto *IS = cast(ISD); addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS); addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS); } void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, int32_t Index, unsigned RelOff) const { // FIXME: Using simple code sequence with simple relocations. // There is a more optimal sequence but it requires support for the group // relocations. See ELF for the ARM Architecture Appendix A.3 const uint8_t PltData[] = { 0x04, 0xc0, 0x9f, 0xe5, // ldr ip, L2 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc 0x00, 0xf0, 0x9c, 0xe5, // ldr pc, [ip] 0x00, 0x00, 0x00, 0x00, // L2: .word Offset(&(.plt.got) - L1 - 8 }; memcpy(Buf, PltData, sizeof(PltData)); uint64_t L1 = PltEntryAddr + 4; write32le(Buf + 12, GotPltEntryAddr - L1 - 8); } void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const { auto *IS = cast(ISD); addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS); addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS); } bool ARM::needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File, const SymbolBody &S) const { // If S is an undefined weak symbol in an executable we don't need a Thunk. // In a DSO calls to undefined symbols, including weak ones get PLT entries // which may need a thunk. if (S.isUndefined() && !S.isLocal() && S.symbol()->isWeak() && !Config->Shared) return false; // A state change from ARM to Thumb and vice versa must go through an // interworking thunk if the relocation type is not R_ARM_CALL or // R_ARM_THM_CALL. switch (RelocType) { case R_ARM_PC24: case R_ARM_PLT32: case R_ARM_JUMP24: // Source is ARM, all PLT entries are ARM so no interworking required. // Otherwise we need to interwork if Symbol has bit 0 set (Thumb). if (Expr == R_PC && ((S.getVA() & 1) == 1)) return true; break; case R_ARM_THM_JUMP19: case R_ARM_THM_JUMP24: // Source is Thumb, all PLT entries are ARM so interworking is required. // Otherwise we need to interwork if Symbol has bit 0 clear (ARM). if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0)) return true; break; } return false; +} + +bool ARM::inBranchRange(uint32_t RelocType, uint64_t Src, uint64_t Dst) const { + uint64_t Range; + uint64_t InstrSize; + + switch (RelocType) { + case R_ARM_PC24: + case R_ARM_PLT32: + case R_ARM_JUMP24: + case R_ARM_CALL: + Range = 0x2000000; + InstrSize = 4; + break; + case R_ARM_THM_JUMP19: + Range = 0x100000; + InstrSize = 2; + break; + case R_ARM_THM_JUMP24: + case R_ARM_THM_CALL: + Range = 0x1000000; + InstrSize = 2; + break; + default: + return true; + } + // PC at Src is 2 instructions ahead, immediate of branch is signed + if (Src > Dst) + Range -= 2 * InstrSize; + else + Range += InstrSize; + + if ((Dst & 0x1) == 0) + // Destination is ARM, if ARM caller then Src is already 4-byte aligned. + // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure + // destination will be 4 byte aligned. + Src &= ~0x3; + else + // Bit 0 == 1 denotes Thumb state, it is not part of the range + Dst &= ~0x1; + + uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src; + return Distance <= Range; } void ARM::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { switch (Type) { case R_ARM_ABS32: case R_ARM_BASE_PREL: case R_ARM_GLOB_DAT: case R_ARM_GOTOFF32: case R_ARM_GOT_BREL: case R_ARM_GOT_PREL: case R_ARM_REL32: case R_ARM_RELATIVE: case R_ARM_SBREL32: case R_ARM_TARGET1: case R_ARM_TARGET2: case R_ARM_TLS_GD32: case R_ARM_TLS_IE32: case R_ARM_TLS_LDM32: case R_ARM_TLS_LDO32: case R_ARM_TLS_LE32: case R_ARM_TLS_TPOFF32: case R_ARM_TLS_DTPOFF32: write32le(Loc, Val); break; case R_ARM_TLS_DTPMOD32: write32le(Loc, 1); break; case R_ARM_PREL31: checkInt<31>(Loc, Val, Type); write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000)); break; case R_ARM_CALL: // R_ARM_CALL is used for BL and BLX instructions, depending on the // value of bit 0 of Val, we must select a BL or BLX instruction if (Val & 1) { // If bit 0 of Val is 1 the target is Thumb, we must select a BLX. // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1' checkInt<26>(Loc, Val, Type); write32le(Loc, 0xfa000000 | // opcode ((Val & 2) << 23) | // H ((Val >> 2) & 0x00ffffff)); // imm24 break; } if ((read32le(Loc) & 0xfe000000) == 0xfa000000) // BLX (always unconditional) instruction to an ARM Target, select an // unconditional BL. write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff)); // fall through as BL encoding is shared with B LLVM_FALLTHROUGH; case R_ARM_JUMP24: case R_ARM_PC24: case R_ARM_PLT32: checkInt<26>(Loc, Val, Type); write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff)); break; case R_ARM_THM_JUMP11: checkInt<12>(Loc, Val, Type); write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff)); break; case R_ARM_THM_JUMP19: // Encoding T3: Val = S:J2:J1:imm6:imm11:0 checkInt<21>(Loc, Val, Type); write16le(Loc, (read16le(Loc) & 0xfbc0) | // opcode cond ((Val >> 10) & 0x0400) | // S ((Val >> 12) & 0x003f)); // imm6 write16le(Loc + 2, 0x8000 | // opcode ((Val >> 8) & 0x0800) | // J2 ((Val >> 5) & 0x2000) | // J1 ((Val >> 1) & 0x07ff)); // imm11 break; case R_ARM_THM_CALL: // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the // value of bit 0 of Val, we must select a BL or BLX instruction if ((Val & 1) == 0) { // Ensure BLX destination is 4-byte aligned. As BLX instruction may // only be two byte aligned. This must be done before overflow check Val = alignTo(Val, 4); } // Bit 12 is 0 for BLX, 1 for BL write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12); // Fall through as rest of encoding is the same as B.W LLVM_FALLTHROUGH; case R_ARM_THM_JUMP24: // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0 // FIXME: Use of I1 and I2 require v6T2ops checkInt<25>(Loc, Val, Type); write16le(Loc, 0xf000 | // opcode ((Val >> 14) & 0x0400) | // S ((Val >> 12) & 0x03ff)); // imm10 write16le(Loc + 2, (read16le(Loc + 2) & 0xd000) | // opcode (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1 (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2 ((Val >> 1) & 0x07ff)); // imm11 break; case R_ARM_MOVW_ABS_NC: case R_ARM_MOVW_PREL_NC: write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) | (Val & 0x0fff)); break; case R_ARM_MOVT_ABS: case R_ARM_MOVT_PREL: checkInt<32>(Loc, Val, Type); write32le(Loc, (read32le(Loc) & ~0x000f0fff) | (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff)); break; case R_ARM_THM_MOVT_ABS: case R_ARM_THM_MOVT_PREL: // Encoding T1: A = imm4:i:imm3:imm8 checkInt<32>(Loc, Val, Type); write16le(Loc, 0xf2c0 | // opcode ((Val >> 17) & 0x0400) | // i ((Val >> 28) & 0x000f)); // imm4 write16le(Loc + 2, (read16le(Loc + 2) & 0x8f00) | // opcode ((Val >> 12) & 0x7000) | // imm3 ((Val >> 16) & 0x00ff)); // imm8 break; case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVW_PREL_NC: // Encoding T3: A = imm4:i:imm3:imm8 write16le(Loc, 0xf240 | // opcode ((Val >> 1) & 0x0400) | // i ((Val >> 12) & 0x000f)); // imm4 write16le(Loc + 2, (read16le(Loc + 2) & 0x8f00) | // opcode ((Val << 4) & 0x7000) | // imm3 (Val & 0x00ff)); // imm8 break; default: error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); } } int64_t ARM::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { switch (Type) { default: return 0; case R_ARM_ABS32: case R_ARM_BASE_PREL: case R_ARM_GOTOFF32: case R_ARM_GOT_BREL: case R_ARM_GOT_PREL: case R_ARM_REL32: case R_ARM_TARGET1: case R_ARM_TARGET2: case R_ARM_TLS_GD32: case R_ARM_TLS_LDM32: case R_ARM_TLS_LDO32: case R_ARM_TLS_IE32: case R_ARM_TLS_LE32: return SignExtend64<32>(read32le(Buf)); case R_ARM_PREL31: return SignExtend64<31>(read32le(Buf)); case R_ARM_CALL: case R_ARM_JUMP24: case R_ARM_PC24: case R_ARM_PLT32: return SignExtend64<26>(read32le(Buf) << 2); case R_ARM_THM_JUMP11: return SignExtend64<12>(read16le(Buf) << 1); case R_ARM_THM_JUMP19: { // Encoding T3: A = S:J2:J1:imm10:imm6:0 uint16_t Hi = read16le(Buf); uint16_t Lo = read16le(Buf + 2); return SignExtend64<20>(((Hi & 0x0400) << 10) | // S ((Lo & 0x0800) << 8) | // J2 ((Lo & 0x2000) << 5) | // J1 ((Hi & 0x003f) << 12) | // imm6 ((Lo & 0x07ff) << 1)); // imm11:0 } case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: { // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0 // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S) // FIXME: I1 and I2 require v6T2ops uint16_t Hi = read16le(Buf); uint16_t Lo = read16le(Buf + 2); return SignExtend64<24>(((Hi & 0x0400) << 14) | // S (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1 (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2 ((Hi & 0x003ff) << 12) | // imm0 ((Lo & 0x007ff) << 1)); // imm11:0 } // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and // MOVT is in the range -32768 <= A < 32768 case R_ARM_MOVW_ABS_NC: case R_ARM_MOVT_ABS: case R_ARM_MOVW_PREL_NC: case R_ARM_MOVT_PREL: { uint64_t Val = read32le(Buf) & 0x000f0fff; return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff)); } case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVT_ABS: case R_ARM_THM_MOVW_PREL_NC: case R_ARM_THM_MOVT_PREL: { // Encoding T3: A = imm4:i:imm3:imm8 uint16_t Hi = read16le(Buf); uint16_t Lo = read16le(Buf + 2); return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4 ((Hi & 0x0400) << 1) | // i ((Lo & 0x7000) >> 4) | // imm3 (Lo & 0x00ff)); // imm8 } } } TargetInfo *elf::getARMTargetInfo() { static ARM Target; return &Target; } Index: vendor/lld/dist/ELF/Arch/MipsArchTree.cpp =================================================================== --- vendor/lld/dist/ELF/Arch/MipsArchTree.cpp (revision 321191) +++ vendor/lld/dist/ELF/Arch/MipsArchTree.cpp (revision 321192) @@ -1,369 +1,369 @@ //===- MipsArchTree.cpp --------------------------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===---------------------------------------------------------------------===// // // This file contains a helper function for the Writer. // //===---------------------------------------------------------------------===// #include "Error.h" #include "InputFiles.h" #include "SymbolTable.h" #include "Writer.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Object/ELF.h" #include "llvm/Support/MipsABIFlags.h" using namespace llvm; using namespace llvm::object; using namespace llvm::ELF; using namespace lld; using namespace lld::elf; namespace { struct ArchTreeEdge { uint32_t Child; uint32_t Parent; }; struct FileFlags { StringRef Filename; uint32_t Flags; }; -} +} // namespace static StringRef getAbiName(uint32_t Flags) { switch (Flags) { case 0: return "n64"; case EF_MIPS_ABI2: return "n32"; case EF_MIPS_ABI_O32: return "o32"; case EF_MIPS_ABI_O64: return "o64"; case EF_MIPS_ABI_EABI32: return "eabi32"; case EF_MIPS_ABI_EABI64: return "eabi64"; default: return "unknown"; } } static StringRef getNanName(bool IsNan2008) { return IsNan2008 ? "2008" : "legacy"; } static StringRef getFpName(bool IsFp64) { return IsFp64 ? "64" : "32"; } static void checkFlags(ArrayRef Files) { uint32_t ABI = Files[0].Flags & (EF_MIPS_ABI | EF_MIPS_ABI2); bool Nan = Files[0].Flags & EF_MIPS_NAN2008; bool Fp = Files[0].Flags & EF_MIPS_FP64; for (const FileFlags &F : Files.slice(1)) { uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2); if (ABI != ABI2) error("target ABI '" + getAbiName(ABI) + "' is incompatible with '" + getAbiName(ABI2) + "': " + F.Filename); bool Nan2 = F.Flags & EF_MIPS_NAN2008; if (Nan != Nan2) error("target -mnan=" + getNanName(Nan) + " is incompatible with -mnan=" + getNanName(Nan2) + ": " + F.Filename); bool Fp2 = F.Flags & EF_MIPS_FP64; if (Fp != Fp2) error("target -mfp" + getFpName(Fp) + " is incompatible with -mfp" + getFpName(Fp2) + ": " + F.Filename); } } static uint32_t getMiscFlags(ArrayRef Files) { uint32_t Ret = 0; for (const FileFlags &F : Files) Ret |= F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER | EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE); return Ret; } static uint32_t getPicFlags(ArrayRef Files) { // Check PIC/non-PIC compatibility. bool IsPic = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC); for (const FileFlags &F : Files.slice(1)) { bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC); if (IsPic && !IsPic2) warn("linking abicalls code with non-abicalls file: " + F.Filename); if (!IsPic && IsPic2) warn("linking non-abicalls code with abicalls file: " + F.Filename); } // Compute the result PIC/non-PIC flag. uint32_t Ret = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC); for (const FileFlags &F : Files.slice(1)) Ret &= F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC); // PIC code is inherently CPIC and may not set CPIC flag explicitly. if (Ret & EF_MIPS_PIC) Ret |= EF_MIPS_CPIC; return Ret; } static ArchTreeEdge ArchTree[] = { // MIPS32R6 and MIPS64R6 are not compatible with other extensions // MIPS64R2 extensions. {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, EF_MIPS_ARCH_64R2}, {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, EF_MIPS_ARCH_64R2}, {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, EF_MIPS_ARCH_64R2}, {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, EF_MIPS_ARCH_64R2}, // MIPS64 extensions. {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, EF_MIPS_ARCH_64}, {EF_MIPS_ARCH_64 | EF_MIPS_MACH_XLR, EF_MIPS_ARCH_64}, {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64}, // MIPS V extensions. {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5}, // R5000 extensions. {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400}, // MIPS IV extensions. {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, EF_MIPS_ARCH_4}, {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, EF_MIPS_ARCH_4}, {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4}, // VR4100 extensions. {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100}, {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100}, // MIPS III extensions. {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, EF_MIPS_ARCH_3}, {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, EF_MIPS_ARCH_3}, {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, EF_MIPS_ARCH_3}, {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, EF_MIPS_ARCH_3}, {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, EF_MIPS_ARCH_3}, {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, EF_MIPS_ARCH_3}, {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3}, // MIPS32 extensions. {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32}, // MIPS II extensions. {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2}, {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2}, // MIPS I extensions. {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, EF_MIPS_ARCH_1}, {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1}, }; static bool isArchMatched(uint32_t New, uint32_t Res) { if (New == Res) return true; if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, Res)) return true; if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, Res)) return true; for (const auto &Edge : ArchTree) { if (Res == Edge.Child) { Res = Edge.Parent; if (Res == New) return true; } } return false; } static StringRef getMachName(uint32_t Flags) { switch (Flags & EF_MIPS_MACH) { case EF_MIPS_MACH_NONE: return ""; case EF_MIPS_MACH_3900: return "r3900"; case EF_MIPS_MACH_4010: return "r4010"; case EF_MIPS_MACH_4100: return "r4100"; case EF_MIPS_MACH_4650: return "r4650"; case EF_MIPS_MACH_4120: return "r4120"; case EF_MIPS_MACH_4111: return "r4111"; case EF_MIPS_MACH_5400: return "vr5400"; case EF_MIPS_MACH_5900: return "vr5900"; case EF_MIPS_MACH_5500: return "vr5500"; case EF_MIPS_MACH_9000: return "rm9000"; case EF_MIPS_MACH_LS2E: return "loongson2e"; case EF_MIPS_MACH_LS2F: return "loongson2f"; case EF_MIPS_MACH_LS3A: return "loongson3a"; case EF_MIPS_MACH_OCTEON: return "octeon"; case EF_MIPS_MACH_OCTEON2: return "octeon2"; case EF_MIPS_MACH_OCTEON3: return "octeon3"; case EF_MIPS_MACH_SB1: return "sb1"; case EF_MIPS_MACH_XLR: return "xlr"; default: return "unknown machine"; } } static StringRef getArchName(uint32_t Flags) { StringRef S = getMachName(Flags); if (!S.empty()) return S; switch (Flags & EF_MIPS_ARCH) { case EF_MIPS_ARCH_1: return "mips1"; case EF_MIPS_ARCH_2: return "mips2"; case EF_MIPS_ARCH_3: return "mips3"; case EF_MIPS_ARCH_4: return "mips4"; case EF_MIPS_ARCH_5: return "mips5"; case EF_MIPS_ARCH_32: return "mips32"; case EF_MIPS_ARCH_64: return "mips64"; case EF_MIPS_ARCH_32R2: return "mips32r2"; case EF_MIPS_ARCH_64R2: return "mips64r2"; case EF_MIPS_ARCH_32R6: return "mips32r6"; case EF_MIPS_ARCH_64R6: return "mips64r6"; default: return "unknown arch"; } } // There are (arguably too) many MIPS ISAs out there. Their relationships // can be represented as a forest. If all input files have ISAs which // reachable by repeated proceeding from the single child to the parent, // these input files are compatible. In that case we need to return "highest" // ISA. If there are incompatible input files, we show an error. // For example, mips1 is a "parent" of mips2 and such files are compatible. // Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32 // are incompatible because nor mips3 is a parent for misp32, nor mips32 // is a parent for mips3. static uint32_t getArchFlags(ArrayRef Files) { uint32_t Ret = Files[0].Flags & (EF_MIPS_ARCH | EF_MIPS_MACH); for (const FileFlags &F : Files.slice(1)) { uint32_t New = F.Flags & (EF_MIPS_ARCH | EF_MIPS_MACH); // Check ISA compatibility. if (isArchMatched(New, Ret)) continue; if (!isArchMatched(Ret, New)) { error("target ISA '" + getArchName(Ret) + "' is incompatible with '" + getArchName(New) + "': " + F.Filename); return 0; } Ret = New; } return Ret; } template uint32_t elf::getMipsEFlags() { std::vector V; for (elf::ObjectFile *F : Symtab::X->getObjectFiles()) V.push_back({F->getName(), F->getObj().getHeader()->e_flags}); if (V.empty()) return 0; checkFlags(V); return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V); } static int compareMipsFpAbi(uint8_t FpA, uint8_t FpB) { if (FpA == FpB) return 0; if (FpB == Mips::Val_GNU_MIPS_ABI_FP_ANY) return 1; if (FpB == Mips::Val_GNU_MIPS_ABI_FP_64A && FpA == Mips::Val_GNU_MIPS_ABI_FP_64) return 1; if (FpB != Mips::Val_GNU_MIPS_ABI_FP_XX) return -1; if (FpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE || FpA == Mips::Val_GNU_MIPS_ABI_FP_64 || FpA == Mips::Val_GNU_MIPS_ABI_FP_64A) return 1; return -1; } static StringRef getMipsFpAbiName(uint8_t FpAbi) { switch (FpAbi) { case Mips::Val_GNU_MIPS_ABI_FP_ANY: return "any"; case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE: return "-mdouble-float"; case Mips::Val_GNU_MIPS_ABI_FP_SINGLE: return "-msingle-float"; case Mips::Val_GNU_MIPS_ABI_FP_SOFT: return "-msoft-float"; case Mips::Val_GNU_MIPS_ABI_FP_OLD_64: return "-mips32r2 -mfp64 (old)"; case Mips::Val_GNU_MIPS_ABI_FP_XX: return "-mfpxx"; case Mips::Val_GNU_MIPS_ABI_FP_64: return "-mgp32 -mfp64"; case Mips::Val_GNU_MIPS_ABI_FP_64A: return "-mgp32 -mfp64 -mno-odd-spreg"; default: return "unknown"; } } uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag, StringRef FileName) { if (compareMipsFpAbi(NewFlag, OldFlag) >= 0) return NewFlag; if (compareMipsFpAbi(OldFlag, NewFlag) < 0) error("target floating point ABI '" + getMipsFpAbiName(OldFlag) + - "' is incompatible with '" + getMipsFpAbiName(NewFlag) + "': " + - FileName); + "' is incompatible with '" + getMipsFpAbiName(NewFlag) + + "': " + FileName); return OldFlag; } template static bool isN32Abi(const InputFile *F) { if (auto *EF = dyn_cast>(F)) return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2; return false; } bool elf::isMipsN32Abi(const InputFile *F) { switch (Config->EKind) { case ELF32LEKind: return isN32Abi(F); case ELF32BEKind: return isN32Abi(F); case ELF64LEKind: return isN32Abi(F); case ELF64BEKind: return isN32Abi(F); default: llvm_unreachable("unknown Config->EKind"); } } template uint32_t elf::getMipsEFlags(); template uint32_t elf::getMipsEFlags(); template uint32_t elf::getMipsEFlags(); template uint32_t elf::getMipsEFlags(); Index: vendor/lld/dist/ELF/Config.h =================================================================== --- vendor/lld/dist/ELF/Config.h (revision 321191) +++ vendor/lld/dist/ELF/Config.h (revision 321192) @@ -1,237 +1,238 @@ //===- Config.h -------------------------------------------------*- C++ -*-===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLD_ELF_CONFIG_H #define LLD_ELF_CONFIG_H #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/CachePruning.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Endian.h" #include namespace lld { namespace elf { class InputFile; struct Symbol; enum ELFKind { ELFNoneKind, ELF32LEKind, ELF32BEKind, ELF64LEKind, ELF64BEKind }; // For --build-id. enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid }; // For --discard-{all,locals,none}. enum class DiscardPolicy { Default, All, Locals, None }; // For --strip-{all,debug}. enum class StripPolicy { None, All, Debug }; // For --unresolved-symbols. enum class UnresolvedPolicy { ReportError, Warn, WarnAll, Ignore, IgnoreAll }; // For --sort-section and linkerscript sorting rules. enum class SortSectionPolicy { Default, None, Alignment, Name, Priority }; // For --target2 enum class Target2Policy { Abs, Rel, GotRel }; struct SymbolVersion { llvm::StringRef Name; bool IsExternCpp; bool HasWildcard; }; // This struct contains symbols version definition that // can be found in version script if it is used for link. struct VersionDefinition { llvm::StringRef Name; uint16_t Id = 0; std::vector Globals; size_t NameOff = 0; // Offset in the string table }; // Structure for mapping renamed symbols struct RenamedSymbol { Symbol *Target; uint8_t OriginalBinding; }; // This struct contains the global configuration for the linker. // Most fields are direct mapping from the command line options // and such fields have the same name as the corresponding options. // Most fields are initialized by the driver. struct Configuration { InputFile *FirstElf = nullptr; uint8_t OSABI = 0; llvm::CachePruningPolicy ThinLTOCachePolicy; llvm::StringMap SectionStartMap; llvm::StringRef DynamicLinker; llvm::StringRef Entry; llvm::StringRef Emulation; llvm::StringRef Fini; llvm::StringRef Init; llvm::StringRef LTOAAPipeline; llvm::StringRef LTONewPmPasses; llvm::StringRef MapFile; llvm::StringRef OutputFile; llvm::StringRef OptRemarksFilename; llvm::StringRef SoName; llvm::StringRef Sysroot; llvm::StringRef ThinLTOCacheDir; std::string Rpath; std::vector VersionDefinitions; std::vector Argv; std::vector AuxiliaryList; + std::vector FilterList; std::vector SearchPaths; std::vector SymbolOrderingFile; std::vector Undefined; std::vector VersionScriptGlobals; std::vector VersionScriptLocals; std::vector BuildIdVector; llvm::MapVector RenamedSymbols; bool AllowMultipleDefinition; bool AsNeeded = false; bool Bsymbolic; bool BsymbolicFunctions; bool ColorDiagnostics = false; bool CompressDebugSections; bool DefineCommon; bool Demangle = true; bool DisableVerify; bool EhFrameHdr; bool EmitRelocs; bool EnableNewDtags; bool ExportDynamic; bool FatalWarnings; bool GcSections; bool GdbIndex; bool GnuHash; bool ICF; bool MipsN32Abi = false; bool NoGnuUnique; bool NoUndefinedVersion; bool Nostdlib; bool OFormatBinary; bool Omagic; bool OptRemarksWithHotness; bool Pie; bool PrintGcSections; bool Relocatable; bool SaveTemps; bool SingleRoRx; bool Shared; bool Static = false; bool SysvHash; bool Target1Rel; bool Threads; bool Trace; bool Verbose; bool WarnCommon; bool WarnMissingEntry; bool ZCombreloc; bool ZExecstack; bool ZNocopyreloc; bool ZNodelete; bool ZNodlopen; bool ZNow; bool ZOrigin; bool ZRelro; bool ZRodynamic; bool ZText; bool ExitEarly; bool ZWxneeded; DiscardPolicy Discard; SortSectionPolicy SortSection; StripPolicy Strip; UnresolvedPolicy UnresolvedSymbols; Target2Policy Target2; BuildIdKind BuildId = BuildIdKind::None; ELFKind EKind = ELFNoneKind; uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL; uint16_t EMachine = llvm::ELF::EM_NONE; uint64_t ErrorLimit = 20; uint64_t ImageBase; uint64_t MaxPageSize; uint64_t ZStackSize; unsigned LTOPartitions; unsigned LTOO; unsigned Optimize; unsigned ThinLTOJobs; // The following config options do not directly correspond to any // particualr command line options. // True if we need to pass through relocations in input files to the // output file. Usually false because we consume relocations. bool CopyRelocs; // True if the target is ELF64. False if ELF32. bool Is64; // True if the target is little-endian. False if big-endian. bool IsLE; // endianness::little if IsLE is true. endianness::big otherwise. llvm::support::endianness Endianness; // True if the target is the little-endian MIPS64. // // The reason why we have this variable only for the MIPS is because // we use this often. Some ELF headers for MIPS64EL are in a // mixed-endian (which is horrible and I'd say that's a serious spec // bug), and we need to know whether we are reading MIPS ELF files or // not in various places. // // (Note that MIPS64EL is not a typo for MIPS64LE. This is the official // name whatever that means. A fun hypothesis is that "EL" is short for // little-endian written in the little-endian order, but I don't know // if that's true.) bool IsMips64EL; // The ELF spec defines two types of relocation table entries, RELA and // REL. RELA is a triplet of (offset, info, addend) while REL is a // tuple of (offset, info). Addends for REL are implicit and read from // the location where the relocations are applied. So, REL is more // compact than RELA but requires a bit of more work to process. // // (From the linker writer's view, this distinction is not necessary. // If the ELF had chosen whichever and sticked with it, it would have // been easier to write code to process relocations, but it's too late // to change the spec.) // // Each ABI defines its relocation type. IsRela is true if target // uses RELA. As far as we know, all 64-bit ABIs are using RELA. A // few 32-bit ABIs are using RELA too. bool IsRela; // True if we are creating position-independent code. bool Pic; // 4 for ELF32, 8 for ELF64. int Wordsize; }; // The only instance of Configuration struct. extern Configuration *Config; } // namespace elf } // namespace lld #endif Index: vendor/lld/dist/ELF/Driver.cpp =================================================================== --- vendor/lld/dist/ELF/Driver.cpp (revision 321191) +++ vendor/lld/dist/ELF/Driver.cpp (revision 321192) @@ -1,1057 +1,1061 @@ //===- Driver.cpp ---------------------------------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // The driver drives the entire linking process. It is responsible for // parsing command line options and doing whatever it is instructed to do. // // One notable thing in the LLD's driver when compared to other linkers is // that the LLD's driver is agnostic on the host operating system. // Other linkers usually have implicit default values (such as a dynamic // linker path or library paths) for each host OS. // // I don't think implicit default values are useful because they are // usually explicitly specified by the compiler driver. They can even // be harmful when you are doing cross-linking. Therefore, in LLD, we // simply trust the compiler driver to pass all required options and // don't try to make effort on our side. // //===----------------------------------------------------------------------===// #include "Driver.h" #include "Config.h" #include "Error.h" #include "Filesystem.h" #include "ICF.h" #include "InputFiles.h" #include "InputSection.h" #include "LinkerScript.h" #include "Memory.h" #include "OutputSections.h" #include "ScriptParser.h" #include "Strings.h" #include "SymbolTable.h" #include "SyntheticSections.h" #include "Target.h" #include "Threads.h" #include "Writer.h" #include "lld/Config/Version.h" #include "lld/Driver/Driver.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Path.h" #include "llvm/Support/TarWriter.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include #include using namespace llvm; using namespace llvm::ELF; using namespace llvm::object; using namespace llvm::sys; using namespace lld; using namespace lld::elf; Configuration *elf::Config; LinkerDriver *elf::Driver; BumpPtrAllocator elf::BAlloc; StringSaver elf::Saver{BAlloc}; std::vector elf::SpecificAllocBase::Instances; static void setConfigs(); bool elf::link(ArrayRef Args, bool CanExitEarly, raw_ostream &Error) { ErrorCount = 0; ErrorOS = &Error; InputSections.clear(); Tar = nullptr; Config = make(); Driver = make(); Script = make(); Config->Argv = {Args.begin(), Args.end()}; Driver->main(Args, CanExitEarly); freeArena(); return !ErrorCount; } // Parses a linker -m option. static std::tuple parseEmulation(StringRef Emul) { uint8_t OSABI = 0; StringRef S = Emul; if (S.endswith("_fbsd")) { S = S.drop_back(5); OSABI = ELFOSABI_FREEBSD; } std::pair Ret = StringSwitch>(S) .Cases("aarch64elf", "aarch64linux", {ELF64LEKind, EM_AARCH64}) .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM}) .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64}) .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS}) .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS}) .Case("elf32ppc", {ELF32BEKind, EM_PPC}) .Case("elf64btsmip", {ELF64BEKind, EM_MIPS}) .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS}) .Case("elf64ppc", {ELF64BEKind, EM_PPC64}) .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64}) .Case("elf_i386", {ELF32LEKind, EM_386}) .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU}) .Default({ELFNoneKind, EM_NONE}); if (Ret.first == ELFNoneKind) { if (S == "i386pe" || S == "i386pep" || S == "thumb2pe") error("Windows targets are not supported on the ELF frontend: " + Emul); else error("unknown emulation: " + Emul); } return std::make_tuple(Ret.first, Ret.second, OSABI); } // Returns slices of MB by parsing MB as an archive file. // Each slice consists of a member file in the archive. std::vector> static getArchiveMembers( MemoryBufferRef MB) { std::unique_ptr File = check(Archive::create(MB), MB.getBufferIdentifier() + ": failed to parse archive"); std::vector> V; Error Err = Error::success(); for (const ErrorOr &COrErr : File->children(Err)) { Archive::Child C = check(COrErr, MB.getBufferIdentifier() + ": could not get the child of the archive"); MemoryBufferRef MBRef = check(C.getMemoryBufferRef(), MB.getBufferIdentifier() + ": could not get the buffer for a child of the archive"); V.push_back(std::make_pair(MBRef, C.getChildOffset())); } if (Err) fatal(MB.getBufferIdentifier() + ": Archive::children failed: " + toString(std::move(Err))); // Take ownership of memory buffers created for members of thin archives. for (std::unique_ptr &MB : File->takeThinBuffers()) make>(std::move(MB)); return V; } // Opens a file and create a file object. Path has to be resolved already. void LinkerDriver::addFile(StringRef Path, bool WithLOption) { using namespace sys::fs; Optional Buffer = readFile(Path); if (!Buffer.hasValue()) return; MemoryBufferRef MBRef = *Buffer; if (InBinary) { Files.push_back(make(MBRef)); return; } switch (identify_magic(MBRef.getBuffer())) { case file_magic::unknown: readLinkerScript(MBRef); return; case file_magic::archive: { // Handle -whole-archive. if (InWholeArchive) { for (const auto &P : getArchiveMembers(MBRef)) Files.push_back(createObjectFile(P.first, Path, P.second)); return; } std::unique_ptr File = check(Archive::create(MBRef), Path + ": failed to parse archive"); // If an archive file has no symbol table, it is likely that a user // is attempting LTO and using a default ar command that doesn't // understand the LLVM bitcode file. It is a pretty common error, so // we'll handle it as if it had a symbol table. if (!File->isEmpty() && !File->hasSymbolTable()) { for (const auto &P : getArchiveMembers(MBRef)) Files.push_back(make(P.first, Path, P.second)); return; } // Handle the regular case. Files.push_back(make(std::move(File))); return; } case file_magic::elf_shared_object: if (Config->Relocatable) { error("attempted static link of dynamic object " + Path); return; } // DSOs usually have DT_SONAME tags in their ELF headers, and the // sonames are used to identify DSOs. But if they are missing, // they are identified by filenames. We don't know whether the new // file has a DT_SONAME or not because we haven't parsed it yet. // Here, we set the default soname for the file because we might // need it later. // // If a file was specified by -lfoo, the directory part is not // significant, as a user did not specify it. This behavior is // compatible with GNU. Files.push_back( createSharedFile(MBRef, WithLOption ? path::filename(Path) : Path)); return; default: if (InLib) Files.push_back(make(MBRef, "", 0)); else Files.push_back(createObjectFile(MBRef)); } } // Add a given library by searching it from input search paths. void LinkerDriver::addLibrary(StringRef Name) { if (Optional Path = searchLibrary(Name)) addFile(*Path, /*WithLOption=*/true); else error("unable to find library -l" + Name); } // This function is called on startup. We need this for LTO since // LTO calls LLVM functions to compile bitcode files to native code. // Technically this can be delayed until we read bitcode files, but // we don't bother to do lazily because the initialization is fast. static void initLLVM(opt::InputArgList &Args) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); // Parse and evaluate -mllvm options. std::vector V; V.push_back("lld (LLVM option parsing)"); for (auto *Arg : Args.filtered(OPT_mllvm)) V.push_back(Arg->getValue()); cl::ParseCommandLineOptions(V.size(), V.data()); } // Some command line options or some combinations of them are not allowed. // This function checks for such errors. static void checkOptions(opt::InputArgList &Args) { // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup // table which is a relatively new feature. if (Config->EMachine == EM_MIPS && Config->GnuHash) error("the .gnu.hash section is not compatible with the MIPS target."); if (Config->Pie && Config->Shared) error("-shared and -pie may not be used together"); + if (!Config->Shared && !Config->FilterList.empty()) + error("-F may not be used without -shared"); + if (!Config->Shared && !Config->AuxiliaryList.empty()) error("-f may not be used without -shared"); if (Config->Relocatable) { if (Config->Shared) error("-r and -shared may not be used together"); if (Config->GcSections) error("-r and --gc-sections may not be used together"); if (Config->ICF) error("-r and --icf may not be used together"); if (Config->Pie) error("-r and -pie may not be used together"); } } static int getInteger(opt::InputArgList &Args, unsigned Key, int Default) { int V = Default; if (auto *Arg = Args.getLastArg(Key)) { StringRef S = Arg->getValue(); if (!to_integer(S, V, 10)) error(Arg->getSpelling() + ": number expected, but got " + S); } return V; } static const char *getReproduceOption(opt::InputArgList &Args) { if (auto *Arg = Args.getLastArg(OPT_reproduce)) return Arg->getValue(); return getenv("LLD_REPRODUCE"); } static bool hasZOption(opt::InputArgList &Args, StringRef Key) { for (auto *Arg : Args.filtered(OPT_z)) if (Key == Arg->getValue()) return true; return false; } static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key, uint64_t Default) { for (auto *Arg : Args.filtered(OPT_z)) { std::pair KV = StringRef(Arg->getValue()).split('='); if (KV.first == Key) { uint64_t Result = Default; if (!to_integer(KV.second, Result)) error("invalid " + Key + ": " + KV.second); return Result; } } return Default; } void LinkerDriver::main(ArrayRef ArgsArr, bool CanExitEarly) { ELFOptTable Parser; opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); // Interpret this flag early because error() depends on them. Config->ErrorLimit = getInteger(Args, OPT_error_limit, 20); // Handle -help if (Args.hasArg(OPT_help)) { printHelp(ArgsArr[0]); return; } // Handle -v or -version. // // A note about "compatible with GNU linkers" message: this is a hack for // scripts generated by GNU Libtool 2.4.6 (released in February 2014 and // still the newest version in March 2017) or earlier to recognize LLD as // a GNU compatible linker. As long as an output for the -v option // contains "GNU" or "with BFD", they recognize us as GNU-compatible. // // This is somewhat ugly hack, but in reality, we had no choice other // than doing this. Considering the very long release cycle of Libtool, // it is not easy to improve it to recognize LLD as a GNU compatible // linker in a timely manner. Even if we can make it, there are still a // lot of "configure" scripts out there that are generated by old version // of Libtool. We cannot convince every software developer to migrate to // the latest version and re-generate scripts. So we have this hack. if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version)) message(getLLDVersion() + " (compatible with GNU linkers)"); // ld.bfd always exits after printing out the version string. // ld.gold proceeds if a given option is -v. Because gold's behavior // is more permissive than ld.bfd, we chose what gold does here. if (Args.hasArg(OPT_version)) return; Config->ExitEarly = CanExitEarly && !Args.hasArg(OPT_full_shutdown); if (const char *Path = getReproduceOption(Args)) { // Note that --reproduce is a debug option so you can ignore it // if you are trying to understand the whole picture of the code. Expected> ErrOrWriter = TarWriter::create(Path, path::stem(Path)); if (ErrOrWriter) { Tar = ErrOrWriter->get(); Tar->append("response.txt", createResponseFile(Args)); Tar->append("version.txt", getLLDVersion() + "\n"); make>(std::move(*ErrOrWriter)); } else { error(Twine("--reproduce: failed to open ") + Path + ": " + toString(ErrOrWriter.takeError())); } } readConfigs(Args); initLLVM(Args); createFiles(Args); inferMachineType(); setConfigs(); checkOptions(Args); if (ErrorCount) return; switch (Config->EKind) { case ELF32LEKind: link(Args); return; case ELF32BEKind: link(Args); return; case ELF64LEKind: link(Args); return; case ELF64BEKind: link(Args); return; default: llvm_unreachable("unknown Config->EKind"); } } static bool getArg(opt::InputArgList &Args, unsigned K1, unsigned K2, bool Default) { if (auto *Arg = Args.getLastArg(K1, K2)) return Arg->getOption().getID() == K1; return Default; } static std::vector getArgs(opt::InputArgList &Args, int Id) { std::vector V; for (auto *Arg : Args.filtered(Id)) V.push_back(Arg->getValue()); return V; } static std::string getRpath(opt::InputArgList &Args) { std::vector V = getArgs(Args, OPT_rpath); return llvm::join(V.begin(), V.end(), ":"); } // Determines what we should do if there are remaining unresolved // symbols after the name resolution. static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) { // -noinhibit-exec or -r imply some default values. if (Args.hasArg(OPT_noinhibit_exec)) return UnresolvedPolicy::WarnAll; if (Args.hasArg(OPT_relocatable)) return UnresolvedPolicy::IgnoreAll; UnresolvedPolicy ErrorOrWarn = getArg(Args, OPT_error_unresolved_symbols, OPT_warn_unresolved_symbols, true) ? UnresolvedPolicy::ReportError : UnresolvedPolicy::Warn; // Process the last of -unresolved-symbols, -no-undefined or -z defs. for (auto *Arg : llvm::reverse(Args)) { switch (Arg->getOption().getID()) { case OPT_unresolved_symbols: { StringRef S = Arg->getValue(); if (S == "ignore-all" || S == "ignore-in-object-files") return UnresolvedPolicy::Ignore; if (S == "ignore-in-shared-libs" || S == "report-all") return ErrorOrWarn; error("unknown --unresolved-symbols value: " + S); continue; } case OPT_no_undefined: return ErrorOrWarn; case OPT_z: if (StringRef(Arg->getValue()) == "defs") return ErrorOrWarn; continue; } } // -shared implies -unresolved-symbols=ignore-all because missing // symbols are likely to be resolved at runtime using other DSOs. if (Config->Shared) return UnresolvedPolicy::Ignore; return ErrorOrWarn; } static Target2Policy getTarget2(opt::InputArgList &Args) { StringRef S = Args.getLastArgValue(OPT_target2, "got-rel"); if (S == "rel") return Target2Policy::Rel; if (S == "abs") return Target2Policy::Abs; if (S == "got-rel") return Target2Policy::GotRel; error("unknown --target2 option: " + S); return Target2Policy::GotRel; } static bool isOutputFormatBinary(opt::InputArgList &Args) { if (auto *Arg = Args.getLastArg(OPT_oformat)) { StringRef S = Arg->getValue(); if (S == "binary") return true; error("unknown --oformat value: " + S); } return false; } static DiscardPolicy getDiscard(opt::InputArgList &Args) { if (Args.hasArg(OPT_relocatable)) return DiscardPolicy::None; auto *Arg = Args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none); if (!Arg) return DiscardPolicy::Default; if (Arg->getOption().getID() == OPT_discard_all) return DiscardPolicy::All; if (Arg->getOption().getID() == OPT_discard_locals) return DiscardPolicy::Locals; return DiscardPolicy::None; } static StringRef getDynamicLinker(opt::InputArgList &Args) { auto *Arg = Args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker); if (!Arg || Arg->getOption().getID() == OPT_no_dynamic_linker) return ""; return Arg->getValue(); } static StripPolicy getStrip(opt::InputArgList &Args) { if (Args.hasArg(OPT_relocatable)) return StripPolicy::None; auto *Arg = Args.getLastArg(OPT_strip_all, OPT_strip_debug); if (!Arg) return StripPolicy::None; if (Arg->getOption().getID() == OPT_strip_all) return StripPolicy::All; return StripPolicy::Debug; } static uint64_t parseSectionAddress(StringRef S, opt::Arg *Arg) { uint64_t VA = 0; if (S.startswith("0x")) S = S.drop_front(2); if (!to_integer(S, VA, 16)) error("invalid argument: " + toString(Arg)); return VA; } static StringMap getSectionStartMap(opt::InputArgList &Args) { StringMap Ret; for (auto *Arg : Args.filtered(OPT_section_start)) { StringRef Name; StringRef Addr; std::tie(Name, Addr) = StringRef(Arg->getValue()).split('='); Ret[Name] = parseSectionAddress(Addr, Arg); } if (auto *Arg = Args.getLastArg(OPT_Ttext)) Ret[".text"] = parseSectionAddress(Arg->getValue(), Arg); if (auto *Arg = Args.getLastArg(OPT_Tdata)) Ret[".data"] = parseSectionAddress(Arg->getValue(), Arg); if (auto *Arg = Args.getLastArg(OPT_Tbss)) Ret[".bss"] = parseSectionAddress(Arg->getValue(), Arg); return Ret; } static SortSectionPolicy getSortSection(opt::InputArgList &Args) { StringRef S = Args.getLastArgValue(OPT_sort_section); if (S == "alignment") return SortSectionPolicy::Alignment; if (S == "name") return SortSectionPolicy::Name; if (!S.empty()) error("unknown --sort-section rule: " + S); return SortSectionPolicy::Default; } static std::pair getHashStyle(opt::InputArgList &Args) { StringRef S = Args.getLastArgValue(OPT_hash_style, "sysv"); if (S == "sysv") return {true, false}; if (S == "gnu") return {false, true}; if (S != "both") error("unknown -hash-style: " + S); return {true, true}; } // Parse --build-id or --build-id= .. role:: none .. role:: partial .. role:: good =============== Windows support =============== LLD supports Windows operating system. When invoked as ``lld-link.exe`` or with ``-flavor link``, the driver for Windows operating system is used to parse command line options, and it drives further linking processes. LLD accepts almost all command line options that the linker shipped with Microsoft Visual C++ (link.exe) supports. The current status is that LLD can link itself on Windows x86/x64 using Visual C++ 2013 as the compiler. Development status ================== Driver :good:`Mostly done`. Some exotic command line options that are not usually used for application develompent, such as ``/DRIVER``, are not supported. - Options for Windows 8 app store are not recognized too - (e.g. ``/APPCONTAINER``). Linking against DLL :good:`Done`. LLD can read import libraries needed to link against DLL. Both export-by-name and export-by-ordinal are supported. Linking against static library :good:`Done`. The format of static library (.lib) on Windows is actually the same as on Unix (.a). LLD can read it. Creating DLL :good:`Done`. LLD creates a DLL if ``/DLL`` option is given. Exported functions can be specified either via command line (``/EXPORT``) or via module-definition file (.def). Both export-by-name and export-by-ordinal are - supported. LLD uses Microsoft ``lib.exe`` tool to create an import library - file. + supported. Windows resource files support :good:`Done`. If an ``.res`` file is given, LLD converts the file to a COFF file using LLVM's Object library. Safe Structured Exception Handler (SEH) :good:`Done` for both x86 and x64. Module-definition file :partial:`Partially done`. LLD currently recognizes these directives: ``EXPORTS``, ``HEAPSIZE``, ``STACKSIZE``, ``NAME``, and ``VERSION``. Debug info :none:`No progress has been made`. Microsoft linker can interpret the CodeGen debug info (old-style debug info) and PDB to emit an .pdb file. LLD doesn't support neither. Building LLD ============ Using Visual Studio IDE/MSBuild ------------------------------- 1. Check out LLVM and LLD from the LLVM SVN repository (or Git mirror), #. run ``cmake -G "Visual Studio 12" `` from VS command prompt, #. open LLVM.sln with Visual Studio, and #. build ``lld`` target in ``lld executables`` folder Alternatively, you can use msbuild if you don't like to work in an IDE:: msbuild LLVM.sln /m /target:"lld executables\lld" MSBuild.exe had been shipped as a component of the .NET framework, but since 2013 it's part of Visual Studio. You can find it at "C:\\Program Files (x86)\\msbuild". You can build LLD as a 64 bit application. To do that, open VS2013 x64 command prompt and run cmake for "Visual Studio 12 Win64" target. Using Ninja ----------- 1. Check out LLVM and LLD from the LLVM SVN repository (or Git mirror), #. run ``cmake -G ninja `` from VS command prompt, #. run ``ninja lld`` Index: vendor/lld/dist/test/COFF/Inputs/default.def =================================================================== --- vendor/lld/dist/test/COFF/Inputs/default.def (nonexistent) +++ vendor/lld/dist/test/COFF/Inputs/default.def (revision 321192) @@ -0,0 +1,2 @@ +EXPORTS + f Index: vendor/lld/dist/test/COFF/Inputs/extension.def =================================================================== --- vendor/lld/dist/test/COFF/Inputs/extension.def (nonexistent) +++ vendor/lld/dist/test/COFF/Inputs/extension.def (revision 321192) @@ -0,0 +1,3 @@ +LIBRARY library.ext +EXPORTS + f Index: vendor/lld/dist/test/COFF/Inputs/named.def =================================================================== --- vendor/lld/dist/test/COFF/Inputs/named.def (nonexistent) +++ vendor/lld/dist/test/COFF/Inputs/named.def (revision 321192) @@ -0,0 +1,3 @@ +LIBRARY library +EXPORTS + f Index: vendor/lld/dist/test/COFF/Inputs/object.s =================================================================== --- vendor/lld/dist/test/COFF/Inputs/object.s (nonexistent) +++ vendor/lld/dist/test/COFF/Inputs/object.s (revision 321192) @@ -0,0 +1,13 @@ + + .text + + .def f + .scl 2 + .type 32 + .endef + .global f +f: + retq $0 + + .section .drectve,"rd" + .ascii " /EXPORT:f" Property changes on: vendor/lld/dist/test/COFF/Inputs/object.s ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: vendor/lld/dist/test/COFF/Inputs/pdb-type-server-simple-a.yaml =================================================================== --- vendor/lld/dist/test/COFF/Inputs/pdb-type-server-simple-a.yaml (nonexistent) +++ vendor/lld/dist/test/COFF/Inputs/pdb-type-server-simple-a.yaml (revision 321192) @@ -0,0 +1,255 @@ +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Subsections: + - !Symbols + Records: + - Kind: S_OBJNAME + ObjNameSym: + Signature: 0 + ObjectName: 'C:\src\llvm-project\build\a.obj' + - Kind: S_COMPILE3 + Compile3Sym: + Flags: [ SecurityChecks, HotPatch ] + Machine: X64 + FrontendMajor: 19 + FrontendMinor: 0 + FrontendBuild: 24215 + FrontendQFE: 1 + BackendMajor: 19 + BackendMinor: 0 + BackendBuild: 24215 + BackendQFE: 1 + Version: 'Microsoft (R) Optimizing Compiler' + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 27 + DbgStart: 4 + DbgEnd: 22 + FunctionType: 4098 + Flags: [ ] + DisplayName: main + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 56 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] + - Kind: S_REGREL32 + RegRelativeSym: + Offset: 32 + Type: 4102 + Register: RSP + VarName: f + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 27 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'c:\src\llvm-project\build\a.c' + Lines: + - Offset: 0 + LineStart: 3 + IsStatement: true + EndDelta: 0 + - Offset: 4 + LineStart: 4 + IsStatement: true + EndDelta: 0 + - Offset: 12 + LineStart: 5 + IsStatement: true + EndDelta: 0 + - Offset: 22 + LineStart: 6 + IsStatement: true + EndDelta: 0 + Columns: + - !Symbols + Records: + - Kind: S_UDT + UDTSym: + Type: 4102 + UDTName: Foo + - !FileChecksums + Checksums: + - FileName: 'c:\src\llvm-project\build\a.c' + Kind: MD5 + Checksum: BF69E7E933074E1B7ED1FE8FB395965B + - !StringTable + Strings: + - 'c:\src\llvm-project\build\a.c' + - !Symbols + Records: + - Kind: S_BUILDINFO + BuildInfoSym: + BuildId: 4107 + Relocations: + - VirtualAddress: 152 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 156 + SymbolName: main + Type: IMAGE_REL_AMD64_SECTION + - VirtualAddress: 224 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 228 + SymbolName: main + Type: IMAGE_REL_AMD64_SECTION + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Types: + - Kind: LF_TYPESERVER2 + TypeServer2: + Guid: '{41414141-4141-4141-4141-414141414141}' + Age: 1 + Name: 'C:\src\llvm-project\build\ts.pdb' + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 4883EC38C74424202A000000488D4C2420E8000000004883C438C3 + Relocations: + - VirtualAddress: 18 + SymbolName: g + Type: IMAGE_REL_AMD64_REL32 + - Name: .xdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '0104010004620000' + - Name: .pdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 000000001B00000000000000 + Relocations: + - VirtualAddress: 0 + SymbolName: '$LN3' + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 4 + SymbolName: '$LN3' + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 8 + SymbolName: '$unwind$main' + Type: IMAGE_REL_AMD64_ADDR32NB +symbols: + - Name: .drectve + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 47 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.debug$S' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 388 + NumberOfRelocations: 4 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.debug$T' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 64 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.text$mn' + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 27 + NumberOfRelocations: 1 + NumberOfLinenumbers: 0 + CheckSum: 1939996292 + Number: 0 + - Name: g + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: main + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: '$LN3' + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_LABEL + - Name: .xdata + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 8 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 931692337 + Number: 0 + - Name: '$unwind$main' + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: .pdata + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 12 + NumberOfRelocations: 3 + NumberOfLinenumbers: 0 + CheckSum: 567356797 + Number: 0 + - Name: '$pdata$main' + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... Index: vendor/lld/dist/test/COFF/Inputs/pdb-type-server-simple-b.yaml =================================================================== --- vendor/lld/dist/test/COFF/Inputs/pdb-type-server-simple-b.yaml (nonexistent) +++ vendor/lld/dist/test/COFF/Inputs/pdb-type-server-simple-b.yaml (revision 321192) @@ -0,0 +1,173 @@ +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Subsections: + - !Symbols + Records: + - Kind: S_OBJNAME + ObjNameSym: + Signature: 0 + ObjectName: 'C:\src\llvm-project\build\b.obj' + - Kind: S_COMPILE3 + Compile3Sym: + Flags: [ SecurityChecks, HotPatch ] + Machine: X64 + FrontendMajor: 19 + FrontendMinor: 0 + FrontendBuild: 24215 + FrontendQFE: 1 + BackendMajor: 19 + BackendMinor: 0 + BackendBuild: 24215 + BackendQFE: 1 + Version: 'Microsoft (R) Optimizing Compiler' + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 13 + DbgStart: 5 + DbgEnd: 12 + FunctionType: 4099 + Flags: [ ] + DisplayName: g + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 0 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] + - Kind: S_REGREL32 + RegRelativeSym: + Offset: 8 + Type: 4097 + Register: RSP + VarName: p + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 13 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'c:\src\llvm-project\build\b.c' + Lines: + - Offset: 0 + LineStart: 2 + IsStatement: true + EndDelta: 0 + Columns: + - !Symbols + Records: + - Kind: S_UDT + UDTSym: + Type: 4102 + UDTName: Foo + - !FileChecksums + Checksums: + - FileName: 'c:\src\llvm-project\build\b.c' + Kind: MD5 + Checksum: DDF8FD35CD67990C5D4147516BE10D0C + - !StringTable + Strings: + - 'c:\src\llvm-project\build\b.c' + - !Symbols + Records: + - Kind: S_BUILDINFO + BuildInfoSym: + BuildId: 4111 + Relocations: + - VirtualAddress: 152 + SymbolName: g + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 156 + SymbolName: g + Type: IMAGE_REL_AMD64_SECTION + - VirtualAddress: 220 + SymbolName: g + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 224 + SymbolName: g + Type: IMAGE_REL_AMD64_SECTION + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Types: + - Kind: LF_TYPESERVER2 + TypeServer2: + Guid: '{41414141-4141-4141-4141-414141414141}' + Age: 1 + Name: 'C:\src\llvm-project\build\ts.pdb' + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 48894C2408488B4424088B00C3 +symbols: + - Name: .drectve + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 47 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.debug$S' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 360 + NumberOfRelocations: 4 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.debug$T' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 64 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.text$mn' + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 13 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 3246683207 + Number: 0 + - Name: g + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: vendor/lld/dist/test/COFF/Inputs/pdb-type-server-simple-ts.yaml =================================================================== --- vendor/lld/dist/test/COFF/Inputs/pdb-type-server-simple-ts.yaml (nonexistent) +++ vendor/lld/dist/test/COFF/Inputs/pdb-type-server-simple-ts.yaml (revision 321192) @@ -0,0 +1,147 @@ +--- +MSF: + SuperBlock: + BlockSize: 4096 + FreeBlockMap: 1 + NumBlocks: 19 + NumDirectoryBytes: 64 + Unknown1: 0 + BlockMapAddr: 17 + NumDirectoryBlocks: 1 + DirectoryBlocks: [ 16 ] + NumStreams: 0 + FileSize: 77824 +PdbStream: + Age: 1 + Guid: '{41414141-4141-4141-4141-414141414141}' + Signature: 1500053944 + Features: [ VC140 ] + Version: VC70 +TpiStream: + Version: VC80 + Records: + - Kind: LF_STRUCTURE + Class: + MemberCount: 0 + Options: [ None, ForwardReference, HasUniqueName ] + FieldList: 0 + Name: Foo + UniqueName: '.?AUFoo@@' + DerivationList: 0 + VTableShape: 0 + Size: 0 + - Kind: LF_POINTER + Pointer: + ReferentType: 4096 + Attrs: 65548 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 4097 ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 1 + ArgumentList: 4098 + - Kind: LF_POINTER + Pointer: + ReferentType: 4099 + Attrs: 65548 + - Kind: LF_FIELDLIST + FieldList: + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 0 + Name: x + - Kind: LF_STRUCTURE + Class: + MemberCount: 1 + Options: [ None, HasUniqueName ] + FieldList: 4101 + Name: Foo + UniqueName: '.?AUFoo@@' + DerivationList: 0 + VTableShape: 0 + Size: 4 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 0 ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 0 + ArgumentList: 4103 +IpiStream: + Version: VC80 + Records: + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'c:\src\llvm-project\build\a.c' + - Kind: LF_UDT_SRC_LINE + UdtSourceLine: + UDT: 4102 + SourceFile: 4096 + LineNumber: 1 + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 0 + FunctionType: 4104 + Name: main + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 0 + FunctionType: 4099 + Name: g + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'C:\src\llvm-project\build' + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe' + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: '-c -Zi -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um' + - Kind: LF_SUBSTR_LIST + StringList: + StringIndices: [ 4102 ] + - Kind: LF_STRING_ID + StringId: + Id: 4103 + String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X' + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: a.c + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'C:\src\llvm-project\build\ts.pdb' + - Kind: LF_BUILDINFO + BuildInfo: + ArgIndices: [ 4100, 4101, 4105, 4106, 4104 ] + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'c:\src\llvm-project\build\b.c' + - Kind: LF_UDT_SRC_LINE + UdtSourceLine: + UDT: 4102 + SourceFile: 4108 + LineNumber: 1 + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: b.c + - Kind: LF_BUILDINFO + BuildInfo: + ArgIndices: [ 4100, 4101, 4110, 4106, 4104 ] +... Index: vendor/lld/dist/test/COFF/common.test =================================================================== --- vendor/lld/dist/test/COFF/common.test (revision 321191) +++ vendor/lld/dist/test/COFF/common.test (revision 321192) @@ -1,102 +1,103 @@ +# REQUIRES: x86 # RUN: yaml2obj %s > %t.obj # RUN: lld-link /out:%t.exe /entry:main %t.obj %t.obj # RUN: llvm-objdump -d %t.exe | FileCheck %s # Operands of B8 (MOV EAX) are common symbols # CHECK: 3000: b8 00 10 00 40 # CHECK: 3005: b8 04 10 00 40 # CHECK: 300a: b8 20 10 00 40 # CHECK: 300f: b8 60 10 00 40 # CHECK: 3014: b8 70 10 00 40 --- !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: 4 SectionData: b800000000b800000000b800000000b800000000b800000000 Relocations: - VirtualAddress: 1 SymbolName: bssdata4 Type: IMAGE_REL_AMD64_ADDR32 - VirtualAddress: 6 SymbolName: bsspad1 Type: IMAGE_REL_AMD64_ADDR32 - VirtualAddress: 11 SymbolName: bssdata64 Type: IMAGE_REL_AMD64_ADDR32 - VirtualAddress: 16 SymbolName: bsspad2 Type: IMAGE_REL_AMD64_ADDR32 - VirtualAddress: 21 SymbolName: bssdata16 Type: IMAGE_REL_AMD64_ADDR32 - Name: .data Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] Alignment: 4 SectionData: 03000000 symbols: - Name: .text Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: Length: 0 NumberOfRelocations: 5 NumberOfLinenumbers: 0 CheckSum: 0 Number: 0 - Name: .data Value: 0 SectionNumber: 2 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: Length: 4 NumberOfRelocations: 0 NumberOfLinenumbers: 0 CheckSum: 0 Number: 0 - Name: main Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_FUNCTION StorageClass: IMAGE_SYM_CLASS_EXTERNAL - Name: bssdata4 Value: 4 SectionNumber: 0 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL - Name: bsspad1 Value: 1 SectionNumber: 0 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL - Name: bssdata64 Value: 64 SectionNumber: 0 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL - Name: bsspad2 Value: 1 SectionNumber: 0 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL - Name: bssdata16 Value: 16 SectionNumber: 0 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL ... Index: vendor/lld/dist/test/COFF/conflict.test =================================================================== --- vendor/lld/dist/test/COFF/conflict.test (revision 321191) +++ vendor/lld/dist/test/COFF/conflict.test (revision 321192) @@ -1,41 +1,42 @@ +# REQUIRES: x86 # RUN: yaml2obj < %s > %t1.obj # RUN: yaml2obj < %s > %t2.obj # RUN: not lld-link /out:%t.exe %t1.obj %t2.obj >& %t.log # RUN: FileCheck %s < %t.log # RUN: llvm-as -o %t.lto1.obj %S/Inputs/conflict.ll # RUN: llvm-as -o %t.lto2.obj %S/Inputs/conflict.ll # RUN: not lld-link /out:%t.exe %t.lto1.obj %t.lto2.obj >& %t.log # RUN: FileCheck %s < %t.log # CHECK: duplicate symbol: foo in {{.+}}1.obj and in {{.+}}2.obj --- !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: 16 SectionData: 000000000000 symbols: - Name: .text Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: Length: 6 NumberOfRelocations: 0 NumberOfLinenumbers: 0 CheckSum: 0 Number: 0 - Name: foo Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_FUNCTION StorageClass: IMAGE_SYM_CLASS_EXTERNAL ... Index: vendor/lld/dist/test/COFF/constant.test =================================================================== --- vendor/lld/dist/test/COFF/constant.test (revision 321191) +++ vendor/lld/dist/test/COFF/constant.test (revision 321192) @@ -1,5 +1,6 @@ +REQUIRES: x86 RUN: mkdir -p %t RUN: llvm-mc -triple i686-unknown-windows-msvc -filetype obj -o %t/import.o %S/Inputs/constant-import.s RUN: llc -mtriple i686-unknown-windows-msvc -filetype obj -o %t/export.o %S/Inputs/constant-export.ll RUN: lld-link -machine:x86 -dll -out:%t/export.dll %t/export.o -entry:__CFConstantStringClassReference RUN: lld-link -machine:x86 -dll -out:%t/import.dll %t/import.o %t/export.lib Index: vendor/lld/dist/test/COFF/def-export-stdcall.s =================================================================== --- vendor/lld/dist/test/COFF/def-export-stdcall.s (revision 321191) +++ vendor/lld/dist/test/COFF/def-export-stdcall.s (revision 321192) @@ -1,25 +1,26 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o %t.obj # RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall" > %t.def # RUN: lld-link -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib # RUN: llvm-nm %t.lib | FileCheck %s # CHECK: __imp__stdcall@8 # CHECK: _stdcall@8 .def _stdcall@8; .scl 2; .type 32; .endef .globl _stdcall@8 _stdcall@8: movl 8(%esp), %eax addl 4(%esp), %eax retl $8 .def _dllmain; .scl 2; .type 32; .endef .globl _dllmain _dllmain: retl Index: vendor/lld/dist/test/COFF/delayimports32.test =================================================================== --- vendor/lld/dist/test/COFF/delayimports32.test (revision 321191) +++ vendor/lld/dist/test/COFF/delayimports32.test (revision 321192) @@ -1,86 +1,87 @@ +# REQUIRES: x86 # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj # RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \ # RUN: /entry:main@0 /alternatename:___delayLoadHelper2@8=_main@0 \ # RUN: /debug /delayload:std32.dll /out:%t.exe # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s IMPORT: Format: COFF-i386 IMPORT-NEXT: Arch: i386 IMPORT-NEXT: AddressSize: 32bit IMPORT-NEXT: DelayImport { IMPORT-NEXT: Name: std32.dll IMPORT-NEXT: Attributes: 0x1 IMPORT-NEXT: ModuleHandle: 0x1018 IMPORT-NEXT: ImportAddressTable: 0x1020 IMPORT-NEXT: ImportNameTable: 0x4040 IMPORT-NEXT: BoundDelayImportTable: 0x0 IMPORT-NEXT: UnloadDelayImportTable: 0x0 IMPORT-NEXT: Import { IMPORT-NEXT: Symbol: ExitProcess (0) IMPORT-NEXT: Address: 0x402029 IMPORT-NEXT: } IMPORT-NEXT: Import { IMPORT-NEXT: Symbol: MessageBoxA (0) IMPORT-NEXT: Address: 0x40203E IMPORT-NEXT: } IMPORT-NEXT: } BASEREL: BaseReloc [ BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x1020 BASEREL-NEXT: } BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x1024 BASEREL-NEXT: } BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x2005 BASEREL-NEXT: } BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x200C BASEREL-NEXT: } BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x201F BASEREL-NEXT: } BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x2025 BASEREL-NEXT: } BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x202C BASEREL-NEXT: } BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x2031 BASEREL-NEXT: } BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x2041 BASEREL-NEXT: } BASEREL-NEXT: Entry { BASEREL-NEXT: Type: HIGHLOW BASEREL-NEXT: Address: 0x2046 BASEREL-NEXT: } BASEREL-NEXT: ] DISASM: 202b: 68 20 10 40 00 pushl $4198432 DISASM-NEXT: 2030: 68 00 40 40 00 pushl $4210688 DISASM-NEXT: 2035: e8 c6 ff ff ff calll -58 <_main@0> DISASM-NEXT: 203a: 5a popl %edx DISASM-NEXT: 203b: 59 popl %ecx DISASM-NEXT: 203c: ff e0 jmpl *%eax DISASM-NEXT: 203e: 51 pushl %ecx DISASM-NEXT: 203f: 52 pushl %edx DISASM-NEXT: 2040: 68 24 10 40 00 pushl $4198436 DISASM-NEXT: 2045: 68 00 40 40 00 pushl $4210688 DISASM-NEXT: 204a: e8 b1 ff ff ff calll -79 <_main@0> DISASM-NEXT: 204f: 5a popl %edx DISASM-NEXT: 2050: 59 popl %ecx DISASM-NEXT: 2051: ff e0 jmpl *%eax Index: vendor/lld/dist/test/COFF/entry-mangled.test =================================================================== --- vendor/lld/dist/test/COFF/entry-mangled.test (revision 321191) +++ vendor/lld/dist/test/COFF/entry-mangled.test (revision 321192) @@ -1,35 +1,36 @@ +# REQUIRES: x86 # RUN: yaml2obj < %s > %t.obj # RUN: lld-link /out:%t.exe /entry:main %t.obj # RUN: llvm-as -o %t.lto.obj %S/Inputs/entry-mangled.ll # RUN: lld-link /out:%t.exe /entry:main %t.lto.obj --- !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: 4 SectionData: 000000000000 symbols: - Name: .text Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: Length: 6 NumberOfRelocations: 0 NumberOfLinenumbers: 0 CheckSum: 0 Number: 0 Selection: IMAGE_COMDAT_SELECT_ANY - Name: '?main@@YAHXZ' Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_FUNCTION StorageClass: IMAGE_SYM_CLASS_EXTERNAL ... Index: vendor/lld/dist/test/COFF/entrylib.ll =================================================================== --- vendor/lld/dist/test/COFF/entrylib.ll (revision 321191) +++ vendor/lld/dist/test/COFF/entrylib.ll (revision 321192) @@ -1,11 +1,12 @@ +; REQUIRES: x86 ; RUN: llvm-as -o %t.obj %s ; RUN: rm -f %t.lib ; RUN: llvm-ar cru %t.lib %t.obj ; RUN: lld-link /out:%t.exe /entry:main %t.lib target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" define i32 @main() { ret i32 0 } Index: vendor/lld/dist/test/COFF/implib-name.test =================================================================== --- vendor/lld/dist/test/COFF/implib-name.test (nonexistent) +++ vendor/lld/dist/test/COFF/implib-name.test (revision 321192) @@ -0,0 +1,71 @@ +# RUN: mkdir -p %T +# RUN: llvm-mc -triple x86_64-unknown-windows-msvc -filetype obj -o %T/object.obj %S/Inputs/object.s + +# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/named.def /out:%T/library.dll %T/object.obj /entry:f /subsystem:CONSOLE +# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-DLL-EXT + +# RUN: lld-link /machine:x64 /def:%S/Inputs/named.def /out:%T/library.lib +# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-DLL-EXT + +CHECK-DEFAULT-DLL-EXT: library.dll +CHECK-DEFAULT-DLL-EXT: library.dll +CHECK-DEFAULT-DLL-EXT: library.dll +CHECK-DEFAULT-DLL-EXT: library.dll + +# RUN: lld-link /machine:x64 /def:%S/Inputs/named.def /out:%T/library.exe %T/object.obj /entry:f /subsystem:CONSOLE +# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-EXE-EXT + +CHECK-DEFAULT-EXE-EXT: library.exe +CHECK-DEFAULT-EXE-EXT: library.exe +CHECK-DEFAULT-EXE-EXT: library.exe +CHECK-DEFAULT-EXE-EXT: library.exe + +# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.dll /entry:f /subsystem:CONSOLE +# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION + +# RUN: lld-link /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.exe /entry:f /subsystem:CONSOLE +# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION + +# RUN: lld-link /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.lib +# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION + +CHECK-EXTENSION: library.ext +CHECK-EXTENSION: library.ext +CHECK-EXTENSION: library.ext +CHECK-EXTENSION: library.ext + +# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/default.def /out:%T/default.dll /entry:f /subsystem:CONSOLE +# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-DLL + +# RUN: lld-link /machine:x64 /def:%S/Inputs/default.def /out:%T/default.lib +# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-DLL + +CHECK-OUTPUT-NAME-DLL: default.dll +CHECK-OUTPUT-NAME-DLL: default.dll +CHECK-OUTPUT-NAME-DLL: default.dll +CHECK-OUTPUT-NAME-DLL: default.dll + +# RUN: lld-link /machine:x64 /def:%S/Inputs/default.def /out:%T/default.exe %T/object.obj /entry:f /subsystem:CONSOLE +# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-EXE + +CHECK-OUTPUT-NAME-EXE: default.exe +CHECK-OUTPUT-NAME-EXE: default.exe +CHECK-OUTPUT-NAME-EXE: default.exe +CHECK-OUTPUT-NAME-EXE: default.exe + +# RUN: lld-link /machine:x64 /out:%T/default.exe %T/object.obj /entry:f /subsystem:CONSOLE +# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-NODEF-EXE + +CHECK-NODEF-EXE: default.exe +CHECK-NODEF-EXE: default.exe +CHECK-NODEF-EXE: default.exe +CHECK-NODEF-EXE: default.exe + +# RUN: lld-link /machine:x64 /dll /out:%T/default.dll %T/object.obj /entry:f /subsystem:CONSOLE +# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-NODEF-DLL + +CHECK-NODEF-DLL: default.dll +CHECK-NODEF-DLL: default.dll +CHECK-NODEF-DLL: default.dll +CHECK-NODEF-DLL: default.dll + Index: vendor/lld/dist/test/COFF/imports.test =================================================================== --- vendor/lld/dist/test/COFF/imports.test (revision 321191) +++ vendor/lld/dist/test/COFF/imports.test (revision 321192) @@ -1,35 +1,36 @@ +# REQUIRES: x86 # Verify that the lld can handle .lib files and emit .idata sections. # # RUN: lld-link /out:%t.exe /entry:main /subsystem:console \ # RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=TEXT %s # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s # RUN: lld-link /out:%t.exe /entry:main /subsystem:console \ # RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=TEXT %s # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s TEXT: Disassembly of section .text: TEXT-NEXT: .text: TEXT-NEXT: subq $40, %rsp TEXT-NEXT: movq $0, %rcx TEXT-NEXT: leaq -4108(%rip), %rdx TEXT-NEXT: leaq -4121(%rip), %r8 TEXT-NEXT: movl $0, %r9d TEXT-NEXT: callq 60 TEXT-NEXT: movl $0, %ecx TEXT-NEXT: callq 18 TEXT-NEXT: callq 29 TEXT: jmpq *4098(%rip) TEXT: jmpq *4090(%rip) TEXT: jmpq *4082(%rip) IMPORT: Import { IMPORT-NEXT: Name: std64.dll IMPORT-NEXT: ImportLookupTableRVA: 0x3028 IMPORT-NEXT: ImportAddressTableRVA: 0x3048 IMPORT-NEXT: Symbol: ExitProcess (0) IMPORT-NEXT: Symbol: (50) IMPORT-NEXT: Symbol: MessageBoxA (1) IMPORT-NEXT: } Index: vendor/lld/dist/test/COFF/include-lto.ll =================================================================== --- vendor/lld/dist/test/COFF/include-lto.ll (revision 321191) +++ vendor/lld/dist/test/COFF/include-lto.ll (revision 321192) @@ -1,21 +1,22 @@ +; REQUIRES: x86 ; RUN: llvm-as -o %t.obj %s ; RUN: lld-link /dll /out:%t.dll %t.obj ; RUN: llvm-objdump -d %t.dll | FileCheck %s ; Checks that code for foo is emitted, as required by the /INCLUDE directive. ; CHECK: xorl %eax, %eax ; CHECK-NEXT: retq target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" define void @_DllMainCRTStartup() { ret void } define i32 @foo() { ret i32 0 } !llvm.linker.options = !{!0} !0 = !{!"/INCLUDE:foo"} Index: vendor/lld/dist/test/COFF/msvclto-archive.ll =================================================================== --- vendor/lld/dist/test/COFF/msvclto-archive.ll (revision 321191) +++ vendor/lld/dist/test/COFF/msvclto-archive.ll (revision 321192) @@ -1,39 +1,40 @@ +; REQUIRES: x86 ;; Make sure we re-create archive files to strip bitcode files. ;; Do not create empty archives because the MSVC linker ;; doesn't support them. ; RUN: llvm-as -o %t.obj %s ; RUN: rm -f %t-main1.a ; RUN: llvm-ar cru %t-main1.a %t.obj ; RUN: mkdir -p %t.dir ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s ; RUN: lld-link %t-main1.a %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ ; RUN: /entry:main /verbose > %t.log || true ; RUN: FileCheck -check-prefix=BC %s < %t.log ; BC-NOT: Creating a temporary archive for ; RUN: rm -f %t-main2.a ; RUN: llvm-ar cru %t-main2.a %t.dir/bitcode.obj ; RUN: lld-link %t.obj %t-main2.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ ; RUN: /entry:main /verbose > %t.log || true ; RUN: FileCheck -check-prefix=OBJ %s < %t.log ; OBJ-NOT: Creating a temporary archive ;; Make sure that we always rebuild thin archives because ;; the MSVC linker doesn't support thin archives. ; RUN: rm -f %t-main3.a ; RUN: llvm-ar cruT %t-main3.a %t.dir/bitcode.obj ; RUN: lld-link %t.obj %t-main3.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ ; RUN: /entry:main /verbose > %t.log || true ; RUN: FileCheck -check-prefix=THIN %s < %t.log ; THIN: Creating a temporary archive target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" declare void @foo() define i32 @main() { call void @foo() ret i32 0 } Index: vendor/lld/dist/test/COFF/msvclto-order.ll =================================================================== --- vendor/lld/dist/test/COFF/msvclto-order.ll (revision 321191) +++ vendor/lld/dist/test/COFF/msvclto-order.ll (revision 321192) @@ -1,24 +1,25 @@ +; REQUIRES: x86 ; RUN: opt -thinlto-bc %s -o %t.obj ; RUN: llc -filetype=obj %S/Inputs/msvclto-order-a.ll -o %T/msvclto-order-a.obj ; RUN: llvm-ar crs %T/msvclto-order-a.lib %T/msvclto-order-a.obj ; RUN: llc -filetype=obj %S/Inputs/msvclto-order-b.ll -o %T/msvclto-order-b.obj ; RUN: llvm-ar crs %T/msvclto-order-b.lib %T/msvclto-order-b.obj ; RUN: lld-link /verbose /msvclto /out:%t.exe /entry:main %t.obj \ ; RUN: %T/msvclto-order-a.lib %T/msvclto-order-b.lib > %t.log || true ; RUN: FileCheck %s < %t.log ; CHECK: : link.exe ; CHECK-NOT: .lib{{$}} ; CHECK: lld-msvclto-order-a{{.*}}.obj ; CHECK-NOT: lld-msvclto-order-b{{.*}}.obj ; CHECK: .lib{{$}} target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" declare void @foo() define i32 @main() { call void @foo() ret i32 0 } Index: vendor/lld/dist/test/COFF/msvclto.ll =================================================================== --- vendor/lld/dist/test/COFF/msvclto.ll (revision 321191) +++ vendor/lld/dist/test/COFF/msvclto.ll (revision 321192) @@ -1,19 +1,20 @@ +; REQUIRES: x86 ; RUN: llvm-as -o %t.obj %s ; RUN: mkdir -p %t.dir ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s ; RUN: lld-link %t.obj %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ ; RUN: /entry:main /verbose > %t.log || true ; RUN: FileCheck %s < %t.log ; CHECK: /opt:icf /entry:main ; CHECK: /verbose target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" declare void @foo() define i32 @main() { call void @foo() ret i32 0 } Index: vendor/lld/dist/test/COFF/pdb-comdat.test =================================================================== --- vendor/lld/dist/test/COFF/pdb-comdat.test (revision 321191) +++ vendor/lld/dist/test/COFF/pdb-comdat.test (revision 321192) @@ -1,99 +1,99 @@ Consider this example program with an inline function "foo": ==> foo.h <== extern int global; __inline void foo() { ++global; } void bar(); ==> pdb_comdat_main.c <== #include "foo.h" int main(void) { foo(); bar(); return 42; } ==> pdb_comdat_bar.c <== #include "foo.h" void bar(void) { foo(); } Both object files will contain debug info for foo, but only the debug info from pdb_comdat_main.obj should be included in the PDB. RUN: rm -rf %t && mkdir -p %t && cd %t RUN: yaml2obj %S/Inputs/pdb_comdat_main.yaml -o pdb_comdat_main.obj RUN: yaml2obj %S/Inputs/pdb_comdat_bar.yaml -o pdb_comdat_bar.obj RUN: lld-link pdb_comdat_main.obj pdb_comdat_bar.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main RUN: llvm-pdbutil dump -l -symbols t.pdb | FileCheck %s CHECK: Lines CHECK: ============================================================ CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`: CHECK: c:\src\llvm-project\build\pdb_comdat_main.c (MD5: F969E51BBE373436D81492EB61387F36) CHECK: c:\src\llvm-project\build\foo.h (MD5: D74D834EFAC3AE2B45E606A8320B1D5C) CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`: CHECK: c:\src\llvm-project\build\pdb_comdat_bar.c (MD5: 365279DB4FCBEDD721BBFC3B14A953C2) CHECK-NOT: c:\src\llvm-project\build\foo.h CHECK-LABEL: Mod 0002 | `* Linker *`: CHECK: Symbols CHECK: ============================================================ CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`: CHECK: 4 | S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_main.obj` CHECK: 60 | S_COMPILE3 [size = 60] CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 CHECK: flags = security checks | hot patchable CHECK: 120 | S_GPROC32_ID [size = 44] `main` CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 24 CHECK: debug start = 4, debug end = 19, flags = none CHECK: 164 | S_FRAMEPROC [size = 32] CHECK: size = 40, padding size = 0, offset to padding = 0 CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 CHECK: flags = has async eh | opt speed CHECK: 196 | S_END [size = 4] CHECK: 200 | S_GDATA32 [size = 24] `global` CHECK: type = 0x0074 (int), addr = 0000:0000 -CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `4106` +CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100A` CHECK: 232 | S_GPROC32_ID [size = 44] `foo` CHECK: parent = 0, end = 308, addr = 0002:0032, code size = 15 CHECK: debug start = 0, debug end = 14, flags = none CHECK: 276 | S_FRAMEPROC [size = 32] CHECK: size = 0, padding size = 0, offset to padding = 0 CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 CHECK: flags = marked inline | has async eh | opt speed CHECK: 308 | S_END [size = 4] CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`: CHECK: 4 | S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_bar.obj` CHECK: 60 | S_COMPILE3 [size = 60] CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 CHECK: flags = security checks | hot patchable CHECK: 120 | S_GPROC32_ID [size = 44] `bar` CHECK: parent = 0, end = 196, addr = 0002:0048, code size = 14 CHECK: debug start = 4, debug end = 9, flags = none CHECK: 164 | S_FRAMEPROC [size = 32] CHECK: size = 40, padding size = 0, offset to padding = 0 CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 CHECK: flags = has async eh | opt speed CHECK: 196 | S_END [size = 4] CHECK: 200 | S_GDATA32 [size = 24] `global` CHECK: type = 0x0074 (int), addr = 0000:0000 -CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `4109` +CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100D` CHECK-NOT: S_GPROC32_ID {{.*}} `foo` CHECK-LABEL: Mod 0002 | `* Linker *`: Reorder the object files and verify that the other table is selected. RUN: lld-link pdb_comdat_bar.obj pdb_comdat_main.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main RUN: llvm-pdbutil dump -l t.pdb | FileCheck %s --check-prefix=REORDER REORDER-LABEL: Mod 0000 | `{{.*}}pdb_comdat_bar.obj`: REORDER: c:\src\llvm-project\build\pdb_comdat_bar.c (MD5: 365279DB4FCBEDD721BBFC3B14A953C2) REORDER: c:\src\llvm-project\build\foo.h (MD5: D74D834EFAC3AE2B45E606A8320B1D5C) REORDER-LABEL: Mod 0001 | `{{.*}}pdb_comdat_main.obj`: REORDER: c:\src\llvm-project\build\pdb_comdat_main.c REORDER-NOT: c:\src\llvm-project\build\foo.h REORDER-LABEL: Mod 0002 | `* Linker *`: Index: vendor/lld/dist/test/COFF/pdb-lib.s =================================================================== --- vendor/lld/dist/test/COFF/pdb-lib.s (revision 321191) +++ vendor/lld/dist/test/COFF/pdb-lib.s (revision 321192) @@ -1,35 +1,36 @@ +# REQUIRES: x86 # RUN: rm -rf %t && mkdir -p %t && cd %t # RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o foo.obj # RUN: llc %S/Inputs/bar.ll -filetype=obj -mtriple=i686-windows-msvc -o bar.obj # RUN: llvm-lib bar.obj -out:bar.lib # RUN: lld-link -debug -pdb:foo.pdb foo.obj bar.lib -out:foo.exe -entry:main # RUN: llvm-pdbutil dump -modules %t/foo.pdb | FileCheck %s # Make sure that the PDB has module descriptors. foo.obj and bar.lib should be # absolute paths, and bar.obj should be the relative path passed to llvm-lib. # CHECK: Modules # CHECK-NEXT: ============================================================ # CHECK-NEXT: Mod 0000 | Name: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: # CHECK-NEXT: debug stream: 9, # files: 0, has ec info: false # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` # CHECK-NEXT: Mod 0001 | Name: `bar.obj`: # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]bar.lib}}`: # CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` # CHECK-NEXT: Mod 0002 | Name: `* Linker *`: # CHECK-NEXT: Obj: ``: # CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false # CHECK-NEXT: pdb file ni: 1 `{{.*foo.pdb}}`, src file ni: 0 `` .def _main; .scl 2; .type 32; .endef .globl _main _main: calll _bar xor %eax, %eax retl Index: vendor/lld/dist/test/COFF/pdb-symbol-types.yaml =================================================================== --- vendor/lld/dist/test/COFF/pdb-symbol-types.yaml (revision 321191) +++ vendor/lld/dist/test/COFF/pdb-symbol-types.yaml (revision 321192) @@ -1,344 +1,344 @@ # RUN: yaml2obj %s -o %t.obj # RUN: lld-link %t.obj -nodefaultlib -entry:main -debug -out:%t.exe -pdb:%t.pdb # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s # To regenerate the object file: # $ cat symbol-types.c # struct Foo { int x; }; # typedef struct Foo UDT_Foo; # UDT_Foo global_foo = {42}; # int main() { return global_foo.x; } # $ cl -c -Z7 symbol-types.c # Note that the type of 'global' goes from 0x1005 in the object file to 0x1004 # in the PDB because the LF_FUNC_ID is moved to the id stream. # CHECK: Symbols # CHECK: ============================================================ # CHECK-LABEL: Mod 0000 | `{{.*}}pdb-symbol-types.yaml.tmp.obj`: # CHECK: 4 | S_OBJNAME [size = 52] sig=0, `C:\src\llvm-project\build\symbol-types.obj` # CHECK: 56 | S_COMPILE3 [size = 60] # CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c # CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 # CHECK: flags = security checks | hot patchable # CHECK: 116 | S_GPROC32_ID [size = 44] `main` # CHECK: parent = 0, end = 192, addr = 0002:0000, code size = 7 # CHECK: debug start = 0, debug end = 6, flags = none # CHECK: 160 | S_FRAMEPROC [size = 32] # CHECK: size = 0, padding size = 0, offset to padding = 0 # CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 # CHECK: flags = has async eh | opt speed # CHECK: 192 | S_END [size = 4] # CHECK: 196 | S_GDATA32 [size = 28] `global_foo` # CHECK: type = 0x1004 (Foo), addr = 0001:0000 # CHECK: 224 | S_UDT [size = 16] `UDT_Foo` # CHECK: original type = 0x1004 # CHECK: 240 | S_UDT [size = 12] `Foo` # CHECK: original type = 0x1004 -# CHECK: 252 | S_BUILDINFO [size = 8] BuildId = `4106` +# CHECK: 252 | S_BUILDINFO [size = 8] BuildId = `0x100A` # CHECK-LABEL: Mod 0001 | `* Linker *`: --- !COFF header: Machine: IMAGE_FILE_MACHINE_AMD64 Characteristics: [ ] sections: - Name: .drectve Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] Alignment: 1 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220 - Name: '.debug$S' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 1 Subsections: - !Symbols Records: - Kind: S_OBJNAME ObjNameSym: Signature: 0 ObjectName: 'C:\src\llvm-project\build\symbol-types.obj' - Kind: S_COMPILE3 Compile3Sym: Flags: [ SecurityChecks, HotPatch ] Machine: X64 FrontendMajor: 19 FrontendMinor: 0 FrontendBuild: 24215 FrontendQFE: 1 BackendMajor: 19 BackendMinor: 0 BackendBuild: 24215 BackendQFE: 1 Version: 'Microsoft (R) Optimizing Compiler' - !Symbols Records: - Kind: S_GPROC32_ID ProcSym: CodeSize: 7 DbgStart: 0 DbgEnd: 6 FunctionType: 4098 Flags: [ ] DisplayName: main - Kind: S_FRAMEPROC FrameProcSym: TotalFrameBytes: 0 PaddingFrameBytes: 0 OffsetToPadding: 0 BytesOfCalleeSavedRegisters: 0 OffsetOfExceptionHandler: 0 SectionIdOfExceptionHandler: 0 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] - Kind: S_PROC_ID_END ScopeEndSym: - !Lines CodeSize: 7 Flags: [ ] RelocOffset: 0 RelocSegment: 0 Blocks: - FileName: 'c:\src\llvm-project\build\symbol-types.c' Lines: - Offset: 0 LineStart: 4 IsStatement: true EndDelta: 0 - Offset: 0 LineStart: 5 IsStatement: true EndDelta: 0 - Offset: 6 LineStart: 6 IsStatement: true EndDelta: 0 Columns: - !Symbols Records: - Kind: S_GDATA32 DataSym: Type: 4101 DisplayName: global_foo - Kind: S_UDT UDTSym: Type: 4101 UDTName: UDT_Foo - Kind: S_UDT UDTSym: Type: 4101 UDTName: Foo - !FileChecksums Checksums: - FileName: 'c:\src\llvm-project\build\symbol-types.c' Kind: MD5 Checksum: F833E1A4909FF6FEC5689A664F3BE725 - !StringTable Strings: - 'c:\src\llvm-project\build\symbol-types.c' - !Symbols Records: - Kind: S_BUILDINFO BuildInfoSym: BuildId: 4111 Relocations: - VirtualAddress: 164 SymbolName: main Type: IMAGE_REL_AMD64_SECREL - VirtualAddress: 168 SymbolName: main Type: IMAGE_REL_AMD64_SECTION - VirtualAddress: 220 SymbolName: main Type: IMAGE_REL_AMD64_SECREL - VirtualAddress: 224 SymbolName: main Type: IMAGE_REL_AMD64_SECTION - VirtualAddress: 284 SymbolName: global_foo Type: IMAGE_REL_AMD64_SECREL - VirtualAddress: 288 SymbolName: global_foo Type: IMAGE_REL_AMD64_SECTION - Name: '.debug$T' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 1 Types: - Kind: LF_ARGLIST ArgList: ArgIndices: [ 0 ] - Kind: LF_PROCEDURE Procedure: ReturnType: 116 CallConv: NearC Options: [ None ] ParameterCount: 0 ArgumentList: 4096 - Kind: LF_FUNC_ID FuncId: ParentScope: 0 FunctionType: 4097 Name: main - Kind: LF_STRUCTURE Class: MemberCount: 0 Options: [ None, ForwardReference, HasUniqueName ] FieldList: 0 Name: Foo UniqueName: '.?AUFoo@@' DerivationList: 0 VTableShape: 0 Size: 0 - Kind: LF_FIELDLIST FieldList: - Kind: LF_MEMBER DataMember: Attrs: 3 Type: 116 FieldOffset: 0 Name: x - Kind: LF_STRUCTURE Class: MemberCount: 1 Options: [ None, HasUniqueName ] FieldList: 4100 Name: Foo UniqueName: '.?AUFoo@@' DerivationList: 0 VTableShape: 0 Size: 4 - Kind: LF_STRING_ID StringId: Id: 0 String: 'c:\src\llvm-project\build\symbol-types.c' - Kind: LF_UDT_SRC_LINE UdtSourceLine: UDT: 4101 SourceFile: 4102 LineNumber: 1 - Kind: LF_STRING_ID StringId: Id: 0 String: 'C:\src\llvm-project\build' - Kind: LF_STRING_ID StringId: Id: 0 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe' - Kind: LF_STRING_ID StringId: Id: 0 String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um' - Kind: LF_SUBSTR_LIST StringList: StringIndices: [ 4106 ] - Kind: LF_STRING_ID StringId: Id: 4107 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X' - Kind: LF_STRING_ID StringId: Id: 0 String: symbol-types.c - Kind: LF_STRING_ID StringId: Id: 0 String: 'C:\src\llvm-project\build\vc140.pdb' - Kind: LF_BUILDINFO BuildInfo: ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ] - Name: .data Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] Alignment: 4 SectionData: 2A000000 - Name: '.text$mn' Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] Alignment: 16 SectionData: 8B0500000000C3 Relocations: - VirtualAddress: 2 SymbolName: global_foo Type: IMAGE_REL_AMD64_REL32 symbols: - Name: '@comp.id' Value: 17063575 SectionNumber: -1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - Name: '@feat.00' Value: 2147484048 SectionNumber: -1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - Name: .drectve Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: Length: 47 NumberOfRelocations: 0 NumberOfLinenumbers: 0 CheckSum: 0 Number: 0 - Name: '.debug$S' Value: 0 SectionNumber: 2 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: Length: 432 NumberOfRelocations: 6 NumberOfLinenumbers: 0 CheckSum: 0 Number: 0 - Name: '.debug$T' Value: 0 SectionNumber: 3 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: Length: 732 NumberOfRelocations: 0 NumberOfLinenumbers: 0 CheckSum: 0 Number: 0 - Name: .data Value: 0 SectionNumber: 4 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: Length: 4 NumberOfRelocations: 0 NumberOfLinenumbers: 0 CheckSum: 3482275674 Number: 0 - Name: global_foo Value: 0 SectionNumber: 4 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL - Name: '.text$mn' Value: 0 SectionNumber: 5 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: Length: 7 NumberOfRelocations: 1 NumberOfLinenumbers: 0 CheckSum: 3635526833 Number: 0 - Name: main Value: 0 SectionNumber: 5 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_FUNCTION StorageClass: IMAGE_SYM_CLASS_EXTERNAL ... Index: vendor/lld/dist/test/COFF/pdb-type-server-missing.yaml =================================================================== --- vendor/lld/dist/test/COFF/pdb-type-server-missing.yaml (nonexistent) +++ vendor/lld/dist/test/COFF/pdb-type-server-missing.yaml (revision 321192) @@ -0,0 +1,132 @@ +# This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an +# adjacent type server PDB. Test that LLD fails gracefully on it. + +# FIXME: Ideally we'd do what MSVC does, which is to warn and drop all debug +# info in the object with the missing PDB. + +# RUN: yaml2obj %s -o %t.obj +# RUN: not lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s + +# CHECK: error: Type server PDB was not found + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Subsections: + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 3 + DbgStart: 0 + DbgEnd: 2 + FunctionType: 4199 + Flags: [ ] + DisplayName: main + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 0 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 3 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'c:\src\llvm-project\build\t.c' + Lines: + - Offset: 0 + LineStart: 1 + IsStatement: true + EndDelta: 0 + Columns: + - !FileChecksums + Checksums: + - FileName: 'c:\src\llvm-project\build\t.c' + Kind: MD5 + Checksum: 270A878DCC1B845655B162F56C4F5020 + - !StringTable + Strings: + - 'c:\src\llvm-project\build\t.c' + Relocations: + - VirtualAddress: 44 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 48 + SymbolName: main + Type: IMAGE_REL_AMD64_SECTION + - VirtualAddress: 100 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 104 + SymbolName: main + Type: IMAGE_REL_AMD64_SECTION + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Types: + - Kind: LF_TYPESERVER2 + TypeServer2: + Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}' + Age: 18 + Name: 'C:\src\llvm-project\build\definitely_not_found_for_sure.pdb' + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 33C0C3 +symbols: + - Name: '.debug$S' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 328 + NumberOfRelocations: 4 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.debug$T' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 564 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.text$mn' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 3 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 4021952397 + Number: 0 + - Name: main + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: vendor/lld/dist/test/COFF/pdb-type-server-simple.test =================================================================== --- vendor/lld/dist/test/COFF/pdb-type-server-simple.test (nonexistent) +++ vendor/lld/dist/test/COFF/pdb-type-server-simple.test (revision 321192) @@ -0,0 +1,91 @@ +Replicate this scenario: + +$ cat a.c +struct Foo { int x; }; +int g(struct Foo *p); +int main() { + struct Foo f = {42}; + return g(&f); +} + +$ cat b.c +struct Foo { int x; }; +int g(struct Foo *p) { return p->x; } + +$ cl -c a.c b.c -Zi -Fdts.pdb + +$ lld-link a.obj b.obj -debug -entry:main -nodefaultlib -out:t.exe + +RUN: rm -rf %t && mkdir -p %t && cd %t +RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj +RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj +RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb +RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib +RUN: llvm-pdbutil dump -symbols -types -ids %t/t.pdb | FileCheck %s + + +CHECK-LABEL: Types (TPI Stream) +CHECK: ============================================================ + +CHECK: [[FOO_DECL:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo` + +CHECK: [[FOO_PTR:[^ ]*]] | LF_POINTER [size = 12] +CHECK-NEXT: referent = [[FOO_DECL]] + +CHECK: [[G_ARGS:[^ ]*]] | LF_ARGLIST [size = 12] +CHECK-NEXT: [[FOO_PTR]]: `Foo*` + +CHECK: [[G_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16] +CHECK-NEXT: return type = 0x0074 (int), # args = 1, param list = [[G_ARGS]] +CHECK-NEXT: calling conv = cdecl, options = None + +CHECK: [[FOO_COMPLETE:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo` +CHECK-NEXT: unique name: `.?AUFoo@@` +CHECK-NEXT: vtable: , base list: , field list: 0x{{.*}} +CHECK: options: has unique name +CHECK: [[MAIN_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16] +CHECK: return type = 0x0074 (int), # args = 0, param list = 0x{{.*}} +CHECK: calling conv = cdecl, options = None + + +CHECK-LABEL: Types (IPI Stream) +CHECK: ============================================================ +CHECK: [[MAIN_ID:[^ ]*]] | LF_FUNC_ID [size = 20] +CHECK: name = main, type = [[MAIN_PROTO]], parent scope = +CHECK: [[G_ID:[^ ]*]] | LF_FUNC_ID [size = 16] +CHECK: name = g, type = [[G_PROTO]], parent scope = +CHECK: [[A_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28] +CHECK: {{.*}}: `a.c` +CHECK: [[B_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28] +CHECK: {{.*}}: `b.c` + +CHECK-LABEL: Symbols +CHECK: ============================================================ +CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`: +CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj` +CHECK: 104 | S_GPROC32_ID [size = 44] `main` +CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 27 +CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none +CHECK: 200 | S_UDT [size = 12] `Foo` +CHECK: original type = [[FOO_COMPLETE]] +CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` +CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`: +CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\b.obj` +CHECK: 44 | S_COMPILE3 [size = 60] +CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c +CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 +CHECK: flags = security checks | hot patchable +CHECK: 104 | S_GPROC32_ID [size = 44] `g` +CHECK: parent = 0, end = 196, addr = 0002:0032, code size = 13 +CHECK: type = {{.*}}, debug start = 5, debug end = 12, flags = none +CHECK: 148 | S_FRAMEPROC [size = 32] +CHECK: size = 0, padding size = 0, offset to padding = 0 +CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 +CHECK: flags = has async eh | opt speed +CHECK: 180 | S_REGREL32 [size = 16] `p` +CHECK: type = [[FOO_PTR]] (Foo*), register = rsp, offset = 8 +CHECK: 196 | S_END [size = 4] +CHECK: 200 | S_UDT [size = 12] `Foo` +CHECK: original type = [[FOO_COMPLETE]] +CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` +CHECK-LABEL: Mod 0002 | `* Linker *`: Index: vendor/lld/dist/test/COFF/reloc-discarded-dwarf.s =================================================================== --- vendor/lld/dist/test/COFF/reloc-discarded-dwarf.s (nonexistent) +++ vendor/lld/dist/test/COFF/reloc-discarded-dwarf.s (revision 321192) @@ -0,0 +1,15 @@ +# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t1.obj %s +# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t2.obj %s + +# LLD should not error on relocations in DWARF debug sections against symbols in +# discarded sections. +# RUN: lld-link -entry:main -debug %t1.obj %t2.obj + + .section .text,"xr",discard,main + .globl main +main: +f: + retq + + .section .debug_info,"dr" + .quad f Property changes on: vendor/lld/dist/test/COFF/reloc-discarded-dwarf.s ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: vendor/lld/dist/test/COFF/reloc-oob.yaml =================================================================== --- vendor/lld/dist/test/COFF/reloc-oob.yaml (nonexistent) +++ vendor/lld/dist/test/COFF/reloc-oob.yaml (revision 321192) @@ -0,0 +1,62 @@ +# Make sure LLD does some light relocation bounds checking. + +# RUN: yaml2obj %s -o %t.obj +# RUN: not lld-link %t.obj -entry:main -nodefaultlib -out:%t.exe 2>&1 | FileCheck %s + +# CHECK: error: relocation points beyond the end of its parent section + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 5589E550C745FC00000000A10000000083C4045DC3 + Relocations: + - VirtualAddress: 24 + SymbolName: _g + Type: IMAGE_REL_I386_DIR32 + - Name: .data + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: 2A000000 +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 21 + NumberOfRelocations: 1 + NumberOfLinenumbers: 0 + CheckSum: 662775349 + Number: 1 + - Name: .data + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 4 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 3482275674 + Number: 2 + - Name: _main + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _g + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: vendor/lld/dist/test/COFF/savetemps.ll =================================================================== --- vendor/lld/dist/test/COFF/savetemps.ll (revision 321191) +++ vendor/lld/dist/test/COFF/savetemps.ll (revision 321192) @@ -1,28 +1,29 @@ +; REQUIRES: x86 ; RUN: rm -fr %T/savetemps ; RUN: mkdir %T/savetemps ; RUN: llvm-as -o %T/savetemps/savetemps.obj %s ; RUN: lld-link /out:%T/savetemps/savetemps.exe /entry:main \ ; RUN: /subsystem:console %T/savetemps/savetemps.obj ; RUN: not llvm-dis -o - %T/savetemps/savetemps.exe.0.0.preopt.bc ; RUN: not llvm-dis -o - %T/savetemps/savetemps.exe.0.2.internalize.bc ; RUN: not llvm-dis -o - %T/savetemps/savetemps.exe.0.4.opt.bc ; RUN: not llvm-dis -o - %T/savetemps/savetemps.exe.0.5.precodegen.bc ; RUN: not llvm-objdump -s %T/savetemps/savetemps.exe.lto.obj ; RUN: lld-link /lldsavetemps /out:%T/savetemps/savetemps.exe /entry:main \ ; RUN: /subsystem:console %T/savetemps/savetemps.obj ; RUN: llvm-dis -o - %T/savetemps/savetemps.exe.0.0.preopt.bc | FileCheck %s ; RUN: llvm-dis -o - %T/savetemps/savetemps.exe.0.2.internalize.bc | FileCheck %s ; RUN: llvm-dis -o - %T/savetemps/savetemps.exe.0.4.opt.bc | FileCheck %s ; RUN: llvm-dis -o - %T/savetemps/savetemps.exe.0.5.precodegen.bc | FileCheck %s ; RUN: llvm-objdump -s %T/savetemps/savetemps.exe.lto.obj | \ ; RUN: FileCheck --check-prefix=CHECK-OBJDUMP %s ; CHECK: define i32 @main() ; CHECK-OBJDUMP: file format COFF target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" define i32 @main() { ret i32 0 } Index: vendor/lld/dist/test/COFF/thinlto-archives.ll =================================================================== --- vendor/lld/dist/test/COFF/thinlto-archives.ll (revision 321191) +++ vendor/lld/dist/test/COFF/thinlto-archives.ll (revision 321192) @@ -1,22 +1,23 @@ +; REQUIRES: x86 ; RUN: rm -fr %T/thinlto-archives ; RUN: mkdir %T/thinlto-archives %T/thinlto-archives/a %T/thinlto-archives/b ; RUN: opt -thinlto-bc -o %T/thinlto-archives/main.obj %s ; RUN: opt -thinlto-bc -o %T/thinlto-archives/a/bar.obj %S/Inputs/lto-dep.ll ; RUN: opt -thinlto-bc -o %T/thinlto-archives/b/bar.obj %S/Inputs/bar.ll ; RUN: llvm-ar crs %T/thinlto-archives/a.lib %T/thinlto-archives/a/bar.obj ; RUN: llvm-ar crs %T/thinlto-archives/b.lib %T/thinlto-archives/b/bar.obj ; RUN: lld-link /out:%T/thinlto-archives/main.exe -entry:main \ ; RUN: -subsystem:console %T/thinlto-archives/main.obj \ ; RUN: %T/thinlto-archives/a.lib %T/thinlto-archives/b.lib target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" declare void @bar() declare void @foo() define i32 @main() { call void @foo() call void @bar() ret i32 0 } Index: vendor/lld/dist/test/COFF/thinlto-mangled.ll =================================================================== --- vendor/lld/dist/test/COFF/thinlto-mangled.ll (revision 321191) +++ vendor/lld/dist/test/COFF/thinlto-mangled.ll (revision 321192) @@ -1,16 +1,17 @@ +; REQUIRES: x86 ; RUN: opt -thinlto-bc %s -o %t.obj ; RUN: opt -thinlto-bc %S/Inputs/thinlto-mangled-qux.ll -o %T/thinlto-mangled-qux.obj ; RUN: lld-link -out:%t.exe -entry:main %t.obj %T/thinlto-mangled-qux.obj target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc19.0.24215" %"class.bar" = type { i32 (...)**, i8*, i8*, i8*, i32 } define i32 @main() { ret i32 0 } define available_externally zeroext i1 @"\01?x@bar@@UEBA_NXZ"(%"class.bar"* %this) unnamed_addr align 2 { ret i1 false } Index: vendor/lld/dist/test/COFF/thinlto.ll =================================================================== --- vendor/lld/dist/test/COFF/thinlto.ll (revision 321191) +++ vendor/lld/dist/test/COFF/thinlto.ll (revision 321192) @@ -1,18 +1,19 @@ +; REQUIRES: x86 ; RUN: rm -fr %T/thinlto ; RUN: mkdir %T/thinlto ; RUN: opt -thinlto-bc -o %T/thinlto/main.obj %s ; RUN: opt -thinlto-bc -o %T/thinlto/foo.obj %S/Inputs/lto-dep.ll ; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj ; RUN: llvm-nm %T/thinlto/main.exe.lto.obj | FileCheck %s ; CHECK-NOT: U foo target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" define i32 @main() { call void @foo() ret i32 0 } declare void @foo() Index: vendor/lld/dist/test/ELF/symver-archive.s =================================================================== --- vendor/lld/dist/test/ELF/symver-archive.s (revision 321191) +++ vendor/lld/dist/test/ELF/symver-archive.s (nonexistent) @@ -1,15 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1 -# RUN: rm -f %t.a -# RUN: llvm-ar rcs %t.a %t1 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive1.s -o %t2.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive2.s -o %t3.o -# RUN: ld.lld -o %t.out %t2.o %t3.o %t.a - -.text -.globl x -.type x, @function -x: - -.globl xx -xx = x Property changes on: vendor/lld/dist/test/ELF/symver-archive.s ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: vendor/lld/dist/test/ELF/Inputs/symver-archive1.s =================================================================== --- vendor/lld/dist/test/ELF/Inputs/symver-archive1.s (revision 321191) +++ vendor/lld/dist/test/ELF/Inputs/symver-archive1.s (nonexistent) @@ -1,6 +0,0 @@ -.text -.globl x -.type x, @function -x: - -.symver x, xx@@VER Property changes on: vendor/lld/dist/test/ELF/Inputs/symver-archive1.s ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: vendor/lld/dist/test/ELF/Inputs/symver-archive2.s =================================================================== --- vendor/lld/dist/test/ELF/Inputs/symver-archive2.s (revision 321191) +++ vendor/lld/dist/test/ELF/Inputs/symver-archive2.s (nonexistent) @@ -1 +0,0 @@ -call xx@PLT Property changes on: vendor/lld/dist/test/ELF/Inputs/symver-archive2.s ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: vendor/lld/dist/test/ELF/Inputs/gdb-index-a.elf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/x-object Property changes on: vendor/lld/dist/test/ELF/Inputs/gdb-index-a.elf ___________________________________________________________________ Deleted: svn:mime-type ## -1 +0,0 ## -application/x-object \ No newline at end of property Index: vendor/lld/dist/test/ELF/Inputs/gdb-index-b.elf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/x-object Property changes on: vendor/lld/dist/test/ELF/Inputs/gdb-index-b.elf ___________________________________________________________________ Deleted: svn:mime-type ## -1 +0,0 ## -application/x-object \ No newline at end of property Index: vendor/lld/dist/test/ELF/Inputs/ctors_dtors_priority1.s =================================================================== --- vendor/lld/dist/test/ELF/Inputs/ctors_dtors_priority1.s (revision 321191) +++ vendor/lld/dist/test/ELF/Inputs/ctors_dtors_priority1.s (revision 321192) @@ -1,5 +1,5 @@ .section .ctors, "aw", @progbits - .byte 0xA1 + .quad 0xA1 .section .dtors, "aw", @progbits - .byte 0xA2 + .quad 0xA2 Index: vendor/lld/dist/test/ELF/Inputs/ctors_dtors_priority2.s =================================================================== --- vendor/lld/dist/test/ELF/Inputs/ctors_dtors_priority2.s (revision 321191) +++ vendor/lld/dist/test/ELF/Inputs/ctors_dtors_priority2.s (revision 321192) @@ -1,5 +1,5 @@ .section .ctors, "aw", @progbits - .byte 0xB1 + .quad 0xB1 .section .dtors, "aw", @progbits - .byte 0xB2 + .quad 0xB2 Index: vendor/lld/dist/test/ELF/Inputs/ctors_dtors_priority3.s =================================================================== --- vendor/lld/dist/test/ELF/Inputs/ctors_dtors_priority3.s (revision 321191) +++ vendor/lld/dist/test/ELF/Inputs/ctors_dtors_priority3.s (revision 321192) @@ -1,5 +1,5 @@ .section .ctors, "aw", @progbits - .byte 0xC1 + .quad 0xC1 .section .dtors, "aw", @progbits - .byte 0xC2 + .quad 0xC2 Index: vendor/lld/dist/test/ELF/Inputs/gdb-index.s =================================================================== --- vendor/lld/dist/test/ELF/Inputs/gdb-index.s (nonexistent) +++ vendor/lld/dist/test/ELF/Inputs/gdb-index.s (revision 321192) @@ -0,0 +1,73 @@ +.text +.Ltext0: +.globl main2 +.type main2, @function +main2: + nop + nop +.Letext0: + +.section .debug_info,"",@progbits +.long 0x30 +.value 0x4 +.long 0 +.byte 0x8 +.uleb128 0x1 +.quad .Ltext0 +.quad .Letext0-.Ltext0 +.long 0 +.long 0 +.long 0 +.long 0 +.byte 0x63 +.byte 0x88 +.byte 0xb4 +.byte 0x61 +.byte 0xaa +.byte 0xb6 +.byte 0xb0 +.byte 0x67 + +.section .debug_abbrev,"",@progbits +.uleb128 0x1 +.uleb128 0x11 +.byte 0 +.uleb128 0x11 +.uleb128 0x1 +.uleb128 0x12 +.uleb128 0x7 +.uleb128 0x10 +.uleb128 0x17 +.uleb128 0x2130 +.uleb128 0xe +.uleb128 0x1b +.uleb128 0xe +.uleb128 0x2134 +.uleb128 0x19 +.uleb128 0x2133 +.uleb128 0x17 +.uleb128 0x2131 +.uleb128 0x7 +.byte 0 +.byte 0 +.byte 0 + +.section .debug_gnu_pubnames,"",@progbits +.long 0x18 +.value 0x2 +.long 0 +.long 0x33 +.long 0x18 +.byte 0x30 +.string "main2" +.long 0 + +.section .debug_gnu_pubtypes,"",@progbits +.long 0x17 +.value 0x2 +.long 0 +.long 0x33 +.long 0x2b +.byte 0x90 +.string "int" +.long 0 Property changes on: vendor/lld/dist/test/ELF/Inputs/gdb-index.s ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: vendor/lld/dist/test/ELF/allow-shlib-undefined.s =================================================================== --- vendor/lld/dist/test/ELF/allow-shlib-undefined.s (revision 321191) +++ vendor/lld/dist/test/ELF/allow-shlib-undefined.s (revision 321192) @@ -1,25 +1,26 @@ +# REQUIRES: x86 # --allow-shlib-undefined and --no-allow-shlib-undefined are fully # ignored in linker implementation. # --allow-shlib-undefined is set by default # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ # RUN: %p/Inputs/allow-shlib-undefined.s -o %t # RUN: ld.lld -shared %t -o %t.so # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 # Executable: should link with DSO containing undefined symbols in any case. # RUN: ld.lld %t1 %t.so -o %t2 # RUN: ld.lld --no-allow-shlib-undefined %t1 %t.so -o %t2 # RUN: ld.lld --allow-shlib-undefined %t1 %t.so -o %t2 # DSO with undefines: # should link with or without any of these options. # RUN: ld.lld -shared %t -o %t.so # RUN: ld.lld -shared --allow-shlib-undefined %t -o %t.so # RUN: ld.lld -shared --no-allow-shlib-undefined %t -o %t.so # Executable still should not link when have undefines inside. # RUN: not ld.lld %t -o %t.so .globl _start _start: callq _shared@PLT Index: vendor/lld/dist/test/ELF/as-needed-no-reloc.s =================================================================== --- vendor/lld/dist/test/ELF/as-needed-no-reloc.s (revision 321191) +++ vendor/lld/dist/test/ELF/as-needed-no-reloc.s (revision 321192) @@ -1,23 +1,23 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o # RUN: ld.lld -shared %t2.o -o %t2.so # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: ld.lld -o %t %t.o --as-needed %t2.so # RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s # There must be a NEEDED entry for each undefined # CHECK: Name: bar # CHECK-NEXT: Value: 0x0 # CHECK-NEXT: Size: 0 # CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: Function # CHECK-NEXT: Other: 0 # CHECK-NEXT: Section: Undefined -# CHECK: NEEDED SharedLibrary ({{.*}}as-needed-no-reloc{{.*}}2.so) +# CHECK: NEEDED Shared library: [{{.*}}as-needed-no-reloc{{.*}}2.so] .globl _start _start: .global bar Index: vendor/lld/dist/test/ELF/as-needed.s =================================================================== --- vendor/lld/dist/test/ELF/as-needed.s (revision 321191) +++ vendor/lld/dist/test/ELF/as-needed.s (revision 321192) @@ -1,45 +1,45 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared2.s -o %t3.o // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared3.s -o %t4.o // RUN: ld.lld -shared %t2.o -soname shared1 -o %t2.so // RUN: ld.lld -shared %t3.o -soname shared2 -o %t3.so // RUN: ld.lld -shared %t4.o -soname shared3 -o %t4.so /// Check if --as-needed actually works. // RUN: ld.lld %t.o %t2.so %t3.so %t4.so -o %t2 // RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s // RUN: ld.lld --as-needed %t.o %t2.so %t3.so %t4.so -o %t2 // RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s // RUN: ld.lld --as-needed %t.o %t2.so --no-as-needed %t3.so %t4.so -o %t2 // RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s /// GROUP directive is the same as --as-needed. // RUN: echo "GROUP(\"%t2.so\" \"%t3.so\" \"%t4.so\")" > %t.script // RUN: ld.lld %t.o %t.script -o %t2 // RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s // RUN: echo "GROUP(AS_NEEDED(\"%t2.so\" \"%t3.so\" \"%t4.so\"))" > %t.script // RUN: ld.lld %t.o %t.script -o %t2 // RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s -// CHECK: NEEDED SharedLibrary (shared1) -// CHECK: NEEDED SharedLibrary (shared2) -// CHECK: NEEDED SharedLibrary (shared3) +// CHECK: NEEDED Shared library: [shared1] +// CHECK: NEEDED Shared library: [shared2] +// CHECK: NEEDED Shared library: [shared3] -// CHECK2: NEEDED SharedLibrary (shared1) -// CHECK2-NOT: NEEDED SharedLibrary (shared2) -// CHECK2-NOT: NEEDED SharedLibrary (shared3) +// CHECK2: NEEDED Shared library: [shared1] +// CHECK2-NOT: NEEDED Shared library: [shared2] +// CHECK2-NOT: NEEDED Shared library: [shared3] .global _start _start: .data .long bar .long zed .weak baz call baz Index: vendor/lld/dist/test/ELF/auxiliary.s =================================================================== --- vendor/lld/dist/test/ELF/auxiliary.s (revision 321191) +++ vendor/lld/dist/test/ELF/auxiliary.s (revision 321192) @@ -1,12 +1,13 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: ld.lld %t.o -shared -f aaa --auxiliary bbb -o %t # RUN: llvm-readobj --dynamic-table %t | FileCheck %s # CHECK: DynamicSection [ # CHECK-NEXT: Tag Type Name/Value # CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [aaa] # CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [bbb] # RUN: not ld.lld %t.o -f aaa --auxiliary bbb -o %t 2>&1 \ # RUN: | FileCheck -check-prefix=ERR %s # ERR: -f may not be used without -shared Index: vendor/lld/dist/test/ELF/compressed-debug-input.s =================================================================== --- vendor/lld/dist/test/ELF/compressed-debug-input.s (revision 321191) +++ vendor/lld/dist/test/ELF/compressed-debug-input.s (revision 321192) @@ -1,82 +1,82 @@ -# REQUIRES: zlib +# REQUIRES: zlib, x86 # RUN: llvm-mc -compress-debug-sections=zlib -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: llvm-readobj -sections %t | FileCheck -check-prefix=ZLIB %s # ZLIB: Section { # ZLIB: Index: 2 # ZLIB: Name: .debug_str # ZLIB-NEXT: Type: SHT_PROGBITS # ZLIB-NEXT: Flags [ # ZLIB-NEXT: SHF_COMPRESSED (0x800) # ZLIB-NEXT: SHF_MERGE (0x10) # ZLIB-NEXT: SHF_STRINGS (0x20) # ZLIB-NEXT: ] # ZLIB-NEXT: Address: # ZLIB-NEXT: Offset: # ZLIB-NEXT: Size: # ZLIB-NEXT: Link: # ZLIB-NEXT: Info: # ZLIB-NEXT: AddressAlignment: 1 # ZLIB-NEXT: EntrySize: 1 # ZLIB-NEXT: } # RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=x86_64-unknown-linux %s -o %t2 # RUN: llvm-readobj -sections %t2 | FileCheck -check-prefix=GNU %s # GNU: Section { # GNU: Index: 2 # GNU: Name: .zdebug_str # GNU-NEXT: Type: SHT_PROGBITS # GNU-NEXT: Flags [ # GNU-NEXT: SHF_MERGE (0x10) # GNU-NEXT: SHF_STRINGS (0x20) # GNU-NEXT: ] # GNU-NEXT: Address: # GNU-NEXT: Offset: # GNU-NEXT: Size: # GNU-NEXT: Link: # GNU-NEXT: Info: # GNU-NEXT: AddressAlignment: 1 # GNU-NEXT: EntrySize: 1 # GNU-NEXT: } # RUN: ld.lld %t -o %t.so -shared # RUN: llvm-readobj -sections -section-data %t.so | FileCheck -check-prefix=DATA %s # RUN: ld.lld %t2 -o %t2.so -shared # RUN: llvm-readobj -sections -section-data %t2.so | FileCheck -check-prefix=DATA %s # DATA: Section { # DATA: Index: 6 # DATA: Name: .debug_str # DATA-NEXT: Type: SHT_PROGBITS # DATA-NEXT: Flags [ # DATA-NEXT: SHF_MERGE (0x10) # DATA-NEXT: SHF_STRINGS (0x20) # DATA-NEXT: ] # DATA-NEXT: Address: 0x0 # DATA-NEXT: Offset: 0x1060 # DATA-NEXT: Size: 69 # DATA-NEXT: Link: 0 # DATA-NEXT: Info: 0 # DATA-NEXT: AddressAlignment: 1 # DATA-NEXT: EntrySize: 0 # DATA-NEXT: SectionData ( # DATA-NEXT: 0000: 73686F72 7420756E 7369676E 65642069 |short unsigned i| # DATA-NEXT: 0010: 6E740075 6E736967 6E656420 696E7400 |nt.unsigned int.| # DATA-NEXT: 0020: 6C6F6E67 20756E73 69676E65 6420696E |long unsigned in| # DATA-NEXT: 0030: 74006368 61720075 6E736967 6E656420 |t.char.unsigned | # DATA-NEXT: 0040: 63686172 00 |char.| # DATA-NEXT: ) # DATA-NEXT: } .section .debug_str,"MS",@progbits,1 .LASF2: .string "short unsigned int" .LASF3: .string "unsigned int" .LASF0: .string "long unsigned int" .LASF8: .string "char" .LASF1: .string "unsigned char" Index: vendor/lld/dist/test/ELF/ctors_dtors_priority.s =================================================================== --- vendor/lld/dist/test/ELF/ctors_dtors_priority.s (revision 321191) +++ vendor/lld/dist/test/ELF/ctors_dtors_priority.s (revision 321192) @@ -1,41 +1,48 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ // RUN: %p/Inputs/ctors_dtors_priority1.s -o %t-crtbegin.o // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ // RUN: %p/Inputs/ctors_dtors_priority2.s -o %t2 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ // RUN: %p/Inputs/ctors_dtors_priority3.s -o %t-crtend.o // RUN: ld.lld %t1 %t2 %t-crtend.o %t-crtbegin.o -o %t.exe // RUN: llvm-objdump -s %t.exe | FileCheck %s // REQUIRES: x86 .globl _start _start: nop .section .ctors, "aw", @progbits - .byte 1 + .quad 1 .section .ctors.100, "aw", @progbits - .byte 2 + .quad 2 .section .ctors.005, "aw", @progbits - .byte 3 + .quad 3 .section .ctors, "aw", @progbits - .byte 4 + .quad 4 .section .ctors, "aw", @progbits - .byte 5 + .quad 5 .section .dtors, "aw", @progbits - .byte 0x11 + .quad 0x11 .section .dtors.100, "aw", @progbits - .byte 0x12 + .quad 0x12 .section .dtors.005, "aw", @progbits - .byte 0x13 + .quad 0x13 .section .dtors, "aw", @progbits - .byte 0x14 + .quad 0x14 .section .dtors, "aw", @progbits - .byte 0x15 + .quad 0x15 // CHECK: Contents of section .ctors: -// CHECK-NEXT: a1010405 b10302c1 +// CHECK-NEXT: 202000 a1000000 00000000 01000000 00000000 +// CHECK-NEXT: 202010 04000000 00000000 05000000 00000000 +// CHECK-NEXT: 202020 b1000000 00000000 03000000 00000000 +// CHECK-NEXT: 202030 02000000 00000000 c1000000 00000000 + // CHECK: Contents of section .dtors: -// CHECK-NEXT: a2111415 b21312c2 +// CHECK-NEXT: 202040 a2000000 00000000 11000000 00000000 +// CHECK-NEXT: 202050 14000000 00000000 15000000 00000000 +// CHECK-NEXT: 202060 b2000000 00000000 13000000 00000000 +// CHECK-NEXT: 202070 12000000 00000000 c2000000 00000000 Index: vendor/lld/dist/test/ELF/debug-gnu-pubnames.s =================================================================== --- vendor/lld/dist/test/ELF/debug-gnu-pubnames.s (revision 321191) +++ vendor/lld/dist/test/ELF/debug-gnu-pubnames.s (revision 321192) @@ -1,10 +1,18 @@ # REQUIRES: x86 -# RUN: ld.lld -e main %p/Inputs/gdb-index-a.elf %p/Inputs/gdb-index-b.elf -o %t1.exe -# RUN: llvm-readobj -sections %t1.exe | FileCheck -check-prefix=CHECK1 %s -# CHECK1: Name: .debug_gnu_pubnames -# CHECK1: Name: .debug_gnu_pubtypes +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: ld.lld -gdb-index -e main %p/Inputs/gdb-index-a.elf %p/Inputs/gdb-index-b.elf -o %t2.exe -# RUN: llvm-readobj -sections %t2.exe | FileCheck -check-prefix=CHECK2 %s -# CHECK2-NOT: Name: .debug_gnu_pubnames -# CHECK2-NOT: Name: .debug_gnu_pubtypes +# RUN: ld.lld %t.o -o %t1.exe +# RUN: llvm-readobj -sections %t1.exe | FileCheck %s +# CHECK: .debug_gnu_pubnames +# CHECK: .debug_gnu_pubtypes + +# RUN: ld.lld -gdb-index %t.o -o %t2.exe +# RUN: llvm-readobj -sections %t2.exe | FileCheck %s --check-prefix=GDB +# GDB-NOT: .debug_gnu_pubnames +# GDB-NOT: .debug_gnu_pubtypes + +.section .debug_gnu_pubnames,"",@progbits +.long 0 + +.section .debug_gnu_pubtypes,"",@progbits +.long 0 Index: vendor/lld/dist/test/ELF/dynamic-reloc.s =================================================================== --- vendor/lld/dist/test/ELF/dynamic-reloc.s (revision 321191) +++ vendor/lld/dist/test/ELF/dynamic-reloc.s (revision 321192) @@ -1,65 +1,65 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc.s -o %t3.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld %t.o %t3.o %t2.so -o %t // RUN: llvm-readobj -dynamic-table -r --expand-relocs -s %t | FileCheck %s // REQUIRES: x86 // CHECK: Index: 1 // CHECK-NEXT: Name: .dynsym // CHECK: Name: .rela.plt // CHECK-NEXT: Type: SHT_RELA // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[RELAADDR:.*]] // CHECK-NEXT: Offset: // CHECK-NEXT: Size: [[RELASIZE:.*]] // CHECK-NEXT: Link: 1 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 8 // CHECK-NEXT: EntrySize: 24 // CHECK: Name: .text // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_EXECINSTR // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x201000 // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.plt { // CHECK-NEXT: Relocation { // CHECK-NEXT: Offset: 0x202018 // CHECK-NEXT: Type: R_X86_64_JUMP_SLOT // CHECK-NEXT: Symbol: bar // CHECK-NEXT: Addend: 0x0 // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK: DynamicSection [ // CHECK-NEXT: Tag Type Name/Value -// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so) +// CHECK-NEXT: 0x0000000000000001 NEEDED Shared library: [{{.*}}2.so] // CHECK-NEXT: 0x0000000000000015 DEBUG 0x0 // CHECK-NEXT: 0x0000000000000017 JMPREL // CHECK-NEXT: 0x0000000000000002 PLTRELSZ 24 (bytes) // CHECK-NEXT: 0x0000000000000003 PLTGOT // CHECK-NEXT: 0x0000000000000014 PLTREL RELA // CHECK-NEXT: 0x0000000000000006 SYMTAB // CHECK-NEXT: 0x000000000000000B SYMENT 24 (bytes) // CHECK-NEXT: 0x0000000000000005 STRTAB // CHECK-NEXT: 0x000000000000000A STRSZ // CHECK-NEXT: 0x0000000000000004 HASH // CHECK-NEXT: 0x0000000000000000 NULL 0x0 // CHECK-NEXT: ] .global _start _start: .quad bar + 0x42 .weak foo .quad foo call main Index: vendor/lld/dist/test/ELF/filter.s =================================================================== --- vendor/lld/dist/test/ELF/filter.s (nonexistent) +++ vendor/lld/dist/test/ELF/filter.s (revision 321192) @@ -0,0 +1,15 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -shared -F foo.so -F boo.so -o %t1 +# RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s + +# Test alias. +# RUN: ld.lld %t.o -shared --filter=foo.so --filter=boo.so -o %t2 +# RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s + +# CHECK: DynamicSection [ +# CHECK-NEXT: Tag Type Name/Value +# CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [foo.so] +# CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [boo.so] + +# RUN: not ld.lld %t.o -F x -o %t 2>&1 | FileCheck -check-prefix=ERR %s +# ERR: -F may not be used without -shared Property changes on: vendor/lld/dist/test/ELF/filter.s ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: vendor/lld/dist/test/ELF/gc-sections-shared.s =================================================================== --- vendor/lld/dist/test/ELF/gc-sections-shared.s (revision 321191) +++ vendor/lld/dist/test/ELF/gc-sections-shared.s (revision 321192) @@ -1,59 +1,59 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o # RUN: ld.lld -shared %t2.o -o %t2.so # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t %t.o --as-needed %t2.so # RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s # This test the property that we have a needed line for every undefined. # It would also be OK to drop bar2 and the need for the .so # CHECK: DynamicSymbols [ # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: # CHECK-NEXT: Value: # CHECK-NEXT: Size: # CHECK-NEXT: Binding: Local # CHECK-NEXT: Type: # CHECK-NEXT: Other: # CHECK-NEXT: Section: Undefined (0x0) # CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: bar2 # CHECK-NEXT: Value: # CHECK-NEXT: Size: # CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: # CHECK-NEXT: Other: # CHECK-NEXT: Section: Undefined # CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: foo # CHECK-NEXT: Value: # CHECK-NEXT: Size: # CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: # CHECK-NEXT: Other: # CHECK-NEXT: Section: .text # CHECK-NEXT: } # CHECK-NEXT: ] -# CHECK: NEEDED SharedLibrary ({{.*}}.so) +# CHECK: NEEDED Shared library: [{{.*}}.so] .section .text.foo, "ax" .globl foo foo: call bar .section .text.bar, "ax" .globl bar bar: ret .section .text._start, "ax" .globl _start _start: ret .section .text.unused, "ax" call bar2 Index: vendor/lld/dist/test/ELF/gdb-index-empty.s =================================================================== --- vendor/lld/dist/test/ELF/gdb-index-empty.s (revision 321191) +++ vendor/lld/dist/test/ELF/gdb-index-empty.s (revision 321192) @@ -1,80 +1,81 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s # RUN: ld.lld --gdb-index --gc-sections -o %t2 %t # RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s # CHECK: Address area offset = 0x28, has 0 entries: # Generated with: (clang r302976) # echo "void _start() { __builtin_unreachable(); }" | \ # clang -Os -g -S -o gdb-index-empty.s -x c - -Xclang -fdebug-compilation-dir -Xclang . .text .globl _start .type _start,@function _start: .Lfunc_begin0: .Lfunc_end0: .section .debug_abbrev,"",@progbits .byte 1 # Abbreviation Code .byte 17 # DW_TAG_compile_unit .byte 1 # DW_CHILDREN_yes .byte 37 # DW_AT_producer .byte 14 # DW_FORM_strp .byte 19 # DW_AT_language .byte 5 # DW_FORM_data2 .byte 3 # DW_AT_name .byte 14 # DW_FORM_strp .byte 16 # DW_AT_stmt_list .byte 23 # DW_FORM_sec_offset .byte 27 # DW_AT_comp_dir .byte 14 # DW_FORM_strp .byte 17 # DW_AT_low_pc .byte 1 # DW_FORM_addr .byte 18 # DW_AT_high_pc .byte 6 # DW_FORM_data4 .byte 0 # EOM(1) .byte 0 # EOM(2) .byte 2 # Abbreviation Code .byte 46 # DW_TAG_subprogram .byte 0 # DW_CHILDREN_no .byte 17 # DW_AT_low_pc .byte 1 # DW_FORM_addr .byte 18 # DW_AT_high_pc .byte 6 # DW_FORM_data4 .byte 64 # DW_AT_frame_base .byte 24 # DW_FORM_exprloc .byte 3 # DW_AT_name .byte 14 # DW_FORM_strp .byte 58 # DW_AT_decl_file .byte 11 # DW_FORM_data1 .byte 59 # DW_AT_decl_line .byte 11 # DW_FORM_data1 .byte 63 # DW_AT_external .byte 25 # DW_FORM_flag_present .byte 0 # EOM(1) .byte 0 # EOM(2) .byte 0 # EOM(3) .section .debug_info,"",@progbits .long 60 # Length of Unit .short 4 # DWARF version number .long .debug_abbrev # Offset Into Abbrev. Section .byte 8 # Address Size (in bytes) .byte 1 # Abbrev [1] 0xb:0x35 DW_TAG_compile_unit .long 0 # DW_AT_producer .short 12 # DW_AT_language .long 0 # DW_AT_name .long 0 # DW_AT_stmt_list .long 0 # DW_AT_comp_dir .quad .Lfunc_begin0 # DW_AT_low_pc .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_subprogram .quad .Lfunc_begin0 # DW_AT_low_pc .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc .byte 1 # DW_AT_frame_base .byte 87 .long 0 # DW_AT_name .byte 1 # DW_AT_decl_file .byte 1 # DW_AT_decl_line .byte 0 # End Of Children Mark Index: vendor/lld/dist/test/ELF/gdb-index-gc-sections.s =================================================================== --- vendor/lld/dist/test/ELF/gdb-index-gc-sections.s (revision 321191) +++ vendor/lld/dist/test/ELF/gdb-index-gc-sections.s (revision 321192) @@ -1,157 +1,158 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s # RUN: ld.lld --gdb-index --gc-sections -o %t2 %t # RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s # CHECK: Address area offset = 0x28, has 1 entries: # CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 # Generated with: (clang r302976) # echo "void _start() {} void dead() {}" | \ # clang -Os -g -S -ffunction-sections -o gdb-index-gc-sections.s -x c - -Xclang -fdebug-compilation-dir -Xclang . .text .file "-" .section .text._start,"ax",@progbits .globl _start .type _start,@function _start: # @_start .Lfunc_begin0: .file 1 "" .loc 1 1 0 # :1:0 .cfi_startproc # BB#0: # %entry .loc 1 1 16 prologue_end # :1:16 retq .Ltmp0: .Lfunc_end0: .size _start, .Lfunc_end0-_start .cfi_endproc .section .text.dead,"ax",@progbits .globl dead .type dead,@function dead: # @dead .Lfunc_begin1: .loc 1 1 0 # :1:0 .cfi_startproc # BB#0: # %entry .loc 1 1 31 prologue_end # :1:31 retq .Ltmp1: .Lfunc_end1: .size dead, .Lfunc_end1-dead .cfi_endproc .section .debug_str,"MS",@progbits,1 .Linfo_string0: .asciz "clang version 5.0.0 " # string offset=0 .Linfo_string1: .asciz "-" # string offset=21 .Linfo_string2: .asciz "." # string offset=23 .Linfo_string3: .asciz "_start" # string offset=25 .Linfo_string4: .asciz "dead" # string offset=32 .section .debug_loc,"",@progbits .section .debug_abbrev,"",@progbits .byte 1 # Abbreviation Code .byte 17 # DW_TAG_compile_unit .byte 1 # DW_CHILDREN_yes .byte 37 # DW_AT_producer .byte 14 # DW_FORM_strp .byte 19 # DW_AT_language .byte 5 # DW_FORM_data2 .byte 3 # DW_AT_name .byte 14 # DW_FORM_strp .byte 16 # DW_AT_stmt_list .byte 23 # DW_FORM_sec_offset .byte 27 # DW_AT_comp_dir .byte 14 # DW_FORM_strp .byte 17 # DW_AT_low_pc .byte 1 # DW_FORM_addr .byte 85 # DW_AT_ranges .byte 23 # DW_FORM_sec_offset .byte 0 # EOM(1) .byte 0 # EOM(2) .byte 2 # Abbreviation Code .byte 46 # DW_TAG_subprogram .byte 0 # DW_CHILDREN_no .byte 17 # DW_AT_low_pc .byte 1 # DW_FORM_addr .byte 18 # DW_AT_high_pc .byte 6 # DW_FORM_data4 .byte 64 # DW_AT_frame_base .byte 24 # DW_FORM_exprloc .byte 3 # DW_AT_name .byte 14 # DW_FORM_strp .byte 58 # DW_AT_decl_file .byte 11 # DW_FORM_data1 .byte 59 # DW_AT_decl_line .byte 11 # DW_FORM_data1 .byte 63 # DW_AT_external .byte 25 # DW_FORM_flag_present .byte 0 # EOM(1) .byte 0 # EOM(2) .byte 0 # EOM(3) .section .debug_info,"",@progbits .Lcu_begin0: .long 81 # Length of Unit .short 4 # DWARF version number .long .debug_abbrev # Offset Into Abbrev. Section .byte 8 # Address Size (in bytes) .byte 1 # Abbrev [1] 0xb:0x4a DW_TAG_compile_unit .long .Linfo_string0 # DW_AT_producer .short 12 # DW_AT_language .long .Linfo_string1 # DW_AT_name .long .Lline_table_start0 # DW_AT_stmt_list .long .Linfo_string2 # DW_AT_comp_dir .quad 0 # DW_AT_low_pc .long .Ldebug_ranges0 # DW_AT_ranges .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_subprogram .quad .Lfunc_begin0 # DW_AT_low_pc .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc .byte 1 # DW_AT_frame_base .byte 87 .long .Linfo_string3 # DW_AT_name .byte 1 # DW_AT_decl_file .byte 1 # DW_AT_decl_line # DW_AT_external .byte 2 # Abbrev [2] 0x3f:0x15 DW_TAG_subprogram .quad .Lfunc_begin1 # DW_AT_low_pc .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc .byte 1 # DW_AT_frame_base .byte 87 .long .Linfo_string4 # DW_AT_name .byte 1 # DW_AT_decl_file .byte 1 # DW_AT_decl_line # DW_AT_external .byte 0 # End Of Children Mark .section .debug_ranges,"",@progbits .Ldebug_ranges0: .quad .Lfunc_begin0 .quad .Lfunc_end0 .quad .Lfunc_begin1 .quad .Lfunc_end1 .quad 0 .quad 0 .section .debug_macinfo,"",@progbits .Lcu_macro_begin0: .byte 0 # End Of Macro List Mark .section .debug_pubnames,"",@progbits .long .LpubNames_end0-.LpubNames_begin0 # Length of Public Names Info .LpubNames_begin0: .short 2 # DWARF Version .long .Lcu_begin0 # Offset of Compilation Unit Info .long 85 # Compilation Unit Length .long 42 # DIE offset .asciz "_start" # External Name .long 63 # DIE offset .asciz "dead" # External Name .long 0 # End Mark .LpubNames_end0: .ident "clang version 5.0.0 " .section ".note.GNU-stack","",@progbits .section .debug_line,"",@progbits .Lline_table_start0: Index: vendor/lld/dist/test/ELF/gdb-index.s =================================================================== --- vendor/lld/dist/test/ELF/gdb-index.s (revision 321191) +++ vendor/lld/dist/test/ELF/gdb-index.s (revision 321192) @@ -1,49 +1,112 @@ -## gdb-index-a.elf and gdb-index-b.elf are a test.o and test2.o renamed, -## were generated in this way: -## test.cpp: -## int main() { return 0; } -## test2.cpp: -## int main2() { return 0; } -## Compiled with: -## gcc -gsplit-dwarf -c test.cpp test2.cpp -## gcc version 5.3.1 20160413 -## Info about gdb-index: https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html - # REQUIRES: x86 -# RUN: ld.lld --gdb-index -e main %p/Inputs/gdb-index-a.elf %p/Inputs/gdb-index-b.elf -o %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gdb-index.s -o %t2.o +# RUN: ld.lld --gdb-index -e main %t1.o %t2.o -o %t # RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s # RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM # DISASM: Disassembly of section .text: # DISASM: main: -# DISASM-CHECK: 11000: 55 pushq %rbp -# DISASM-CHECK: 11001: 48 89 e5 movq %rsp, %rbp -# DISASM-CHECK: 11004: b8 00 00 00 00 movl $0, %eax -# DISASM-CHECK: 11009: 5d popq %rbp -# DISASM-CHECK: 1100a: c3 retq -# DISASM: _Z5main2v: -# DISASM-CHECK: 1100b: 55 pushq %rbp -# DISASM-CHECK: 1100c: 48 89 e5 movq %rsp, %rbp -# DISASM-CHECK: 1100f: b8 00 00 00 00 movl $0, %eax -# DISASM-CHECK: 11014: 5d popq %rbp -# DISASM-CHECK: 11015: c3 retq +# DISASM-CHECK: 201000: 90 nop +# DISASM-CHECK: 201001: cc int3 +# DISASM-CHECK: 201002: cc int3 +# DISASM-CHECK: 201003: cc int3 +# DISASM: main2: +# DISASM-CHECK: 201004: 90 nop +# DISASM-CHECK: 201005: 90 nop # CHECK: .gnu_index contents: # CHECK-NEXT: Version = 7 # CHECK: CU list offset = 0x18, has 2 entries: # CHECK-NEXT: 0: Offset = 0x0, Length = 0x34 # CHECK-NEXT: 1: Offset = 0x34, Length = 0x34 # CHECK: Address area offset = 0x38, has 2 entries: -# CHECK-NEXT: Low/High address = [0x201000, 0x20100b) (Size: 0xb), CU id = 0 -# CHECK-NEXT: Low/High address = [0x20100b, 0x201016) (Size: 0xb), CU id = 1 +# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 +# CHECK-NEXT: Low/High address = [0x201004, 0x201006) (Size: 0x2), CU id = 1 # CHECK: Symbol table offset = 0x60, size = 1024, filled slots: # CHECK-NEXT: 489: Name offset = 0x1d, CU vector offset = 0x0 # CHECK-NEXT: String name: main, CU vector index: 0 # CHECK-NEXT: 754: Name offset = 0x22, CU vector offset = 0x8 # CHECK-NEXT: String name: int, CU vector index: 1 # CHECK-NEXT: 956: Name offset = 0x26, CU vector offset = 0x14 # CHECK-NEXT: String name: main2, CU vector index: 2 # CHECK: Constant pool offset = 0x2060, has 3 CU vectors: # CHECK-NEXT: 0(0x0): 0x30000000 # CHECK-NEXT: 1(0x8): 0x90000000 0x90000001 # CHECK-NEXT: 2(0x14): 0x30000001 + +## The following section contents are created by this using gcc 7.1.0: +## echo 'int main() { return 0; }' | gcc -gsplit-dwarf -xc++ -S -o- - + +.text +.Ltext0: +.globl main +.type main, @function +main: + nop +.Letext0: + +.section .debug_info,"",@progbits +.long 0x30 +.value 0x4 +.long 0 +.byte 0x8 +.uleb128 0x1 +.quad .Ltext0 +.quad .Letext0-.Ltext0 +.long 0 +.long 0 +.long 0 +.long 0 +.byte 0x63 +.byte 0x88 +.byte 0xb4 +.byte 0x61 +.byte 0xaa +.byte 0xb6 +.byte 0xb0 +.byte 0x67 + +.section .debug_abbrev,"",@progbits +.uleb128 0x1 +.uleb128 0x11 +.byte 0 +.uleb128 0x11 +.uleb128 0x1 +.uleb128 0x12 +.uleb128 0x7 +.uleb128 0x10 +.uleb128 0x17 +.uleb128 0x2130 +.uleb128 0xe +.uleb128 0x1b +.uleb128 0xe +.uleb128 0x2134 +.uleb128 0x19 +.uleb128 0x2133 +.uleb128 0x17 +.uleb128 0x2131 +.uleb128 0x7 +.byte 0 +.byte 0 +.byte 0 + +.section .debug_gnu_pubnames,"",@progbits +.long 0x18 +.value 0x2 +.long 0 +.long 0x33 +.long 0x18 +.byte 0x30 +.string "main" +.long 0 + +.section .debug_gnu_pubtypes,"",@progbits +.long 0x17 +.value 0x2 +.long 0 +.long 0x33 +.long 0x2b +.byte 0x90 +.string "int" +.long 0 Index: vendor/lld/dist/test/ELF/i386-reloc-large-addend.s =================================================================== --- vendor/lld/dist/test/ELF/i386-reloc-large-addend.s (revision 321191) +++ vendor/lld/dist/test/ELF/i386-reloc-large-addend.s (revision 321192) @@ -1,15 +1,16 @@ +// REQUIRES: x86 // RUN: llvm-mc %s -o %t.o -triple i386-pc-linux-code16 -filetype=obj // RUN: echo ".global foo; foo = 0x1" > %t1.s // RUN: llvm-mc %t1.s -o %t1.o -triple i386-pc-linux -filetype=obj // RUN: ld.lld -Ttext 0x7000 %t.o %t1.o -o %t // RUN: llvm-objdump -d -triple=i386-pc-linux-code16 %t | FileCheck %s // CHECK: Disassembly of section .text: // CHECK-NEXT: _start: // CHECK-NEXT: 7000: e9 fe 1f jmp 8190 // 0x1 + 0x9000 - 0x7003 == 8190 .global _start _start: jmp foo + 0x9000 Index: vendor/lld/dist/test/ELF/i386-reloc-range.s =================================================================== --- vendor/lld/dist/test/ELF/i386-reloc-range.s (revision 321191) +++ vendor/lld/dist/test/ELF/i386-reloc-range.s (revision 321192) @@ -1,22 +1,23 @@ +// REQUIRES: x86 // RUN: llvm-mc %s -o %t.o -triple i386-pc-linux-code16 -filetype=obj // RUN: echo ".global foo; foo = 0x10202" > %t1.s // RUN: llvm-mc %t1.s -o %t1.o -triple i386-pc-linux -filetype=obj // RUN: echo ".global foo; foo = 0x10203" > %t2.s // RUN: llvm-mc %t2.s -o %t2.o -triple i386-pc-linux -filetype=obj // RUN: ld.lld -Ttext 0x200 %t.o %t1.o -o %t1 // RUN: llvm-objdump -d -triple=i386-pc-linux-code16 %t1 | FileCheck %s // CHECK: Disassembly of section .text: // CHECK-NEXT: _start: // CHECK-NEXT: 200: {{.*}} jmp -1 // 0x10202 - 0x203 == 0xffff // RUN: not ld.lld -Ttext 0x200 %t.o %t2.o -o %t2 2>&1 | FileCheck --check-prefix=ERR %s // ERR: {{.*}}:(.text+0x1): relocation R_386_PC16 out of range .global _start _start: jmp foo Index: vendor/lld/dist/test/ELF/invalid/tls-symbol.s =================================================================== --- vendor/lld/dist/test/ELF/invalid/tls-symbol.s (revision 321191) +++ vendor/lld/dist/test/ELF/invalid/tls-symbol.s (revision 321192) @@ -1,5 +1,5 @@ # REQUIRES: x86 -## The test file contains a STT_TLS symbol but has no TLS section. +## The test file contains an STT_TLS symbol but has no TLS section. # RUN: not ld.lld %S/Inputs/tls-symbol.elf -o %t 2>&1 | FileCheck %s -# CHECK: has a STT_TLS symbol but doesn't have a PT_TLS section +# CHECK: has an STT_TLS symbol but doesn't have an SHF_TLS section Index: vendor/lld/dist/test/ELF/linkerscript/exidx-crash.s =================================================================== --- vendor/lld/dist/test/ELF/linkerscript/exidx-crash.s (nonexistent) +++ vendor/lld/dist/test/ELF/linkerscript/exidx-crash.s (revision 321192) @@ -0,0 +1,7 @@ +# REQUIRES: aarch64 + +# We used to crash on this. + +# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux +# RUN: echo "SECTIONS { .ARM.exidx : { *(.foo) } }" > %t.script +# RUN: ld.lld -T %t.script %t.o -o %t Property changes on: vendor/lld/dist/test/ELF/linkerscript/exidx-crash.s ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: vendor/lld/dist/test/ELF/linkerscript/got-write-offset.s =================================================================== --- vendor/lld/dist/test/ELF/linkerscript/got-write-offset.s (nonexistent) +++ vendor/lld/dist/test/ELF/linkerscript/got-write-offset.s (revision 321192) @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux-gnu %s -o %t +# RUN: echo "SECTIONS { \ +# RUN: .data 0x1000 : { *(.data) } \ +# RUN: .got 0x2000 : { \ +# RUN: LONG(0) \ +# RUN: *(.got) \ +# RUN: } \ +# RUN: };" > %t.script +# RUN: ld.lld -shared -o %t.out --script %t.script %t +# RUN: llvm-objdump -s %t.out | FileCheck %s +.text +.global foo +foo: + movl bar@GOT, %eax +.data +.local bar +bar: + .zero 4 +# CHECK: Contents of section .data: +# CHECK-NEXT: 1000 00000000 +# CHECK: Contents of section .got: +# CHECK-NEXT: 2000 00000000 00100000 Property changes on: vendor/lld/dist/test/ELF/linkerscript/got-write-offset.s ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: vendor/lld/dist/test/ELF/linkerscript/output-too-large.s =================================================================== --- vendor/lld/dist/test/ELF/linkerscript/output-too-large.s (revision 321191) +++ vendor/lld/dist/test/ELF/linkerscript/output-too-large.s (revision 321192) @@ -1,8 +1,9 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script # RUN: not ld.lld --script %t.script %t.o -o %t 2>&1 | FileCheck %s # CHECK: error: output file too large .global _start _start: nop Index: vendor/lld/dist/test/ELF/lto/available-externally.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/available-externally.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/available-externally.ll (revision 321192) @@ -1,22 +1,23 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t1.o ; RUN: llvm-as %p/Inputs/available-externally.ll -o %t2.o ; RUN: ld.lld %t1.o %t2.o -m elf_x86_64 -o %t.so -shared -save-temps ; RUN: llvm-dis < %t.so.0.2.internalize.bc | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" define void @foo() { call void @bar() call void @zed() ret void } define available_externally void @bar() { ret void } define available_externally void @zed() { ret void } ; CHECK: define available_externally void @bar() { ; CHECK: define void @zed() { Index: vendor/lld/dist/test/ELF/lto/comdat2.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/comdat2.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/comdat2.ll (revision 321192) @@ -1,40 +1,41 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared ; RUN: llvm-readobj -t %t.so | FileCheck %s ; RUN: ld.lld -m elf_x86_64 %t2.o %t.o -o %t2.so -shared ; RUN: llvm-readobj -t %t2.so | FileCheck %s --check-prefix=OTHER target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" $c = comdat any define protected void @foo() comdat($c) { ret void } ; CHECK: Symbol { ; CHECK: Name: foo ; CHECK-NEXT: Value: 0x1000 ; CHECK-NEXT: Size: 1 ; CHECK-NEXT: Binding: Global ; CHECK-NEXT: Type: Function ; CHECK-NEXT: Other [ ; CHECK-NEXT: STV_PROTECTED ; CHECK-NEXT: ] ; CHECK-NEXT: Section: .text ; CHECK-NEXT: } ; OTHER: Symbol { ; OTHER: Name: foo ; OTHER-NEXT: Value: 0x1000 ; OTHER-NEXT: Size: 0 ; OTHER-NEXT: Binding: Global ; OTHER-NEXT: Type: None ; OTHER-NEXT: Other [ ; OTHER-NEXT: STV_PROTECTED ; OTHER-NEXT: ] ; OTHER-NEXT: Section: .text ; OTHER-NEXT: } Index: vendor/lld/dist/test/ELF/lto/common2.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/common2.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/common2.ll (revision 321192) @@ -1,27 +1,28 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t1.o ; RUN: ld.lld -m elf_x86_64 %t1.o -o %t -shared -save-temps ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s ; RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SHARED target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @a = common global i8 0, align 8 ; CHECK-DAG: @a = common global i8 0, align 8 @b = common hidden global i32 0, align 4 define i32 @f() { %t = load i32, i32* @b, align 4 ret i32 %t } ; CHECK-DAG: @b = internal global i32 0, align 4 ; SHARED: Symbol { ; SHARED: Name: a ; SHARED-NEXT: Value: ; SHARED-NEXT: Size: 1 ; SHARED-NEXT: Binding: Global ; SHARED-NEXT: Type: Object ; SHARED-NEXT: Other: 0 ; SHARED-NEXT: Section: .bss ; SHARED-NEXT: } Index: vendor/lld/dist/test/ELF/lto/common3.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/common3.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/common3.ll (revision 321192) @@ -1,14 +1,15 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t1.o ; RUN: llvm-as %S/Inputs/common3.ll -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t -shared -save-temps ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @a = common hidden global i32 0, align 8 define i32 @f() { %t = load i32, i32* @a, align 4 ret i32 %t } ; CHECK: @a = internal global i64 0, align 8 Index: vendor/lld/dist/test/ELF/lto/discard-value-names.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/discard-value-names.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/discard-value-names.ll (revision 321192) @@ -1,23 +1,24 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 -shared -save-temps %t.o -o %t2.o ; RUN: llvm-dis < %t2.o.0.0.preopt.bc | FileCheck %s ; CHECK: @GlobalValueName ; CHECK: @foo(i32 %in) ; CHECK: somelabel: ; CHECK: %GV = load i32, i32* @GlobalValueName ; CHECK: %add = add i32 %in, %GV ; CHECK: ret i32 %add target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @GlobalValueName = global i32 0 define i32 @foo(i32 %in) { somelabel: %GV = load i32, i32* @GlobalValueName %add = add i32 %in, %GV ret i32 %add } Index: vendor/lld/dist/test/ELF/lto/opt-level.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/opt-level.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/opt-level.ll (revision 321192) @@ -1,29 +1,30 @@ +; REQUIRES: x86 ; RUN: llvm-as -o %t.o %s ; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --lto-O0 %t.o ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s ; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --lto-O2 %t.o ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s ; RUN: ld.lld -o %t2a -m elf_x86_64 -e main %t.o ; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s ; Reject invalid optimization levels. ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O6 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALID %s ; INVALID: invalid optimization level for LTO: 6 ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s ; INVALIDNEGATIVE: invalid optimization level for LTO: -1 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" ; CHECK-O0: foo ; CHECK-O2-NOT: foo define internal void @foo() { ret void } define void @main() { call void @foo() ret void } Index: vendor/lld/dist/test/ELF/lto/opt-remarks.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/opt-remarks.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/opt-remarks.ll (revision 321192) @@ -1,68 +1,69 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: rm -f %t.yaml ; RUN: ld.lld --opt-remarks-filename %t.yaml %t.o -o %t -shared -save-temps ; RUN: llvm-dis %t.0.4.opt.bc -o - | FileCheck %s ; RUN: ld.lld --opt-remarks-with-hotness --opt-remarks-filename %t.hot.yaml \ ; RUN: %t.o -o %t -shared ; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML ; RUN: cat %t.hot.yaml | FileCheck %s -check-prefix=YAML-HOT ; Check that @tinkywinky is inlined after optimizations. ; CHECK-LABEL: define i32 @main ; CHECK-NEXT: %a.i = call i32 @patatino() ; CHECK-NEXT: ret i32 %a.i ; CHECK-NEXT: } ; YAML: --- !Analysis ; YAML-NEXT: Pass: inline ; YAML-NEXT: Name: CanBeInlined ; YAML-NEXT: Function: main ; YAML-NEXT: Args: ; YAML-NEXT: - Callee: tinkywinky ; YAML-NEXT: - String: ' can be inlined into ' ; YAML-NEXT: - Caller: main ; YAML-NEXT: - String: ' with cost=' ; YAML-NEXT: - Cost: '0' ; YAML-NEXT: - String: ' (threshold=' ; YAML-NEXT: - Threshold: '337' ; YAML-NEXT: - String: ')' ; YAML-NEXT: ... ; YAML-NEXT: --- !Passed ; YAML-NEXT: Pass: inline ; YAML-NEXT: Name: Inlined ; YAML-NEXT: Function: main ; YAML-NEXT: Args: ; YAML-NEXT: - Callee: tinkywinky ; YAML-NEXT: - String: ' inlined into ' ; YAML-NEXT: - Caller: main ; YAML-NEXT: ... ; YAML-HOT: ... ; YAML-HOT: --- !Passed ; YAML-HOT: Pass: inline ; YAML-HOT-NEXT: Name: Inlined ; YAML-HOT-NEXT: Function: main ; YAML-HOT-NEXT: Hotness: 300 ; YAML-HOT-NEXT: Args: ; YAML-HOT-NEXT: - Callee: tinkywinky ; YAML-HOT-NEXT: - String: ' inlined into ' ; YAML-HOT-NEXT: - Caller: main ; YAML-HOT-NEXT: ... target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-scei-ps4" declare i32 @patatino() define i32 @tinkywinky() { %a = call i32 @patatino() ret i32 %a } define i32 @main() !prof !0 { %i = call i32 @tinkywinky() ret i32 %i } !0 = !{!"function_entry_count", i64 300} Index: vendor/lld/dist/test/ELF/lto/relax-relocs.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/relax-relocs.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/relax-relocs.ll (revision 321192) @@ -1,15 +1,16 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 -save-temps -shared %t.o -o %t.so ; RUN: llvm-readobj -r %t.so.lto.o | FileCheck %s ; Test that we produce R_X86_64_REX_GOTPCRELX instead of R_X86_64_GOTPCREL ; CHECK: R_X86_64_REX_GOTPCRELX foo target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @foo = external global i32 define i32 @bar() { %t = load i32, i32* @foo ret i32 %t } Index: vendor/lld/dist/test/ELF/lto/thin-archivecollision.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/thin-archivecollision.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/thin-archivecollision.ll (revision 321192) @@ -1,36 +1,37 @@ +; REQUIRES: x86 ; RUN: opt -module-summary %s -o %t.o ; RUN: mkdir -p %t1 %t2 ; RUN: opt -module-summary %p/Inputs/thin1.ll -o %t1/t.coll.o ; RUN: opt -module-summary %p/Inputs/thin2.ll -o %t2/t.coll.o ; RUN: rm -f %t.a ; RUN: llvm-ar rcs %t.a %t1/t.coll.o %t2/t.coll.o ; RUN: ld.lld %t.o %t.a -o %t ; RUN: llvm-nm %t | FileCheck %s ; Check without a archive symbol table ; RUN: rm -f %t.a ; RUN: llvm-ar rcS %t.a %t1/t.coll.o %t2/t.coll.o ; RUN: ld.lld %t.o %t.a -o %t ; RUN: llvm-nm %t | FileCheck %s ; Check we handle this case correctly even in presence of --whole-archive. ; RUN: ld.lld %t.o --whole-archive %t.a -o %t ; RUN: llvm-nm %t | FileCheck %s ; CHECK: T _start ; CHECK: T blah ; CHECK: T foo target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-scei-ps4" define i32 @_start() { entry: %call = call i32 @foo(i32 23) %call1 = call i32 @blah(i32 37) ret i32 0 } declare i32 @foo(i32) #1 declare i32 @blah(i32) #1 Index: vendor/lld/dist/test/ELF/lto/thinlto.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/thinlto.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/thinlto.ll (revision 321192) @@ -1,36 +1,37 @@ +; REQUIRES: x86 ; Basic ThinLTO tests. ; RUN: opt -module-summary %s -o %t.o ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o ; First force single-threaded mode ; RUN: rm -f %t.lto.o %t1.lto.o ; RUN: ld.lld -save-temps --thinlto-jobs=1 -shared %t.o %t2.o -o %t ; RUN: llvm-nm %t.lto.o | FileCheck %s --check-prefix=NM1 ; RUN: llvm-nm %t1.lto.o | FileCheck %s --check-prefix=NM2 ; Next force multi-threaded mode ; RUN: rm -f %t2.lto.o %t21.lto.o ; RUN: ld.lld -save-temps --thinlto-jobs=2 -shared %t.o %t2.o -o %t2 ; RUN: llvm-nm %t2.lto.o | FileCheck %s --check-prefix=NM1 ; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM2 ; NM1: T f ; NM1-NOT: U g ; NM2: T g ; Then check without --thinlto-jobs (which currently default to hardware_concurrency) ; We just check that we don't crash or fail (as it's not sure which tests are ; stable on the final output file itself. ; RUN: ld.lld -shared %t.o %t2.o -o %t2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" declare void @g(...) define void @f() { entry: call void (...) @g() ret void } Index: vendor/lld/dist/test/ELF/lto/type-merge2.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/type-merge2.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/type-merge2.ll (revision 321192) @@ -1,27 +1,28 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: llvm-as %p/Inputs/type-merge2.ll -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared -save-temps ; RUN: llvm-dis %t.so.0.0.preopt.bc -o - | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" %zed = type { i8 } define void @foo() { call void @bar(%zed* null) ret void } declare void @bar(%zed*) ; CHECK: %zed = type { i8 } ; CHECK-NEXT: %zed.0 = type { i16 } ; CHECK: define void @foo() { ; CHECK-NEXT: call void bitcast (void (%zed.0*)* @bar to void (%zed*)*)(%zed* null) ; CHECK-NEXT: ret void ; CHECK-NEXT: } ; CHECK: define void @bar(%zed.0* %this) { ; CHECK-NEXT: store %zed.0* %this, %zed.0** null ; CHECK-NEXT: ret void ; CHECK-NEXT: } Index: vendor/lld/dist/test/ELF/lto/unnamed-addr-comdat.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/unnamed-addr-comdat.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/unnamed-addr-comdat.ll (revision 321192) @@ -1,11 +1,12 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -save-temps -shared ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" $foo = comdat any @foo = linkonce_odr unnamed_addr constant i32 42, comdat ; CHECK: @foo = internal unnamed_addr constant i32 42, comdat Index: vendor/lld/dist/test/ELF/lto/unnamed-addr-drop.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/unnamed-addr-drop.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/unnamed-addr-drop.ll (revision 321192) @@ -1,12 +1,13 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t1.o ; RUN: llvm-as %S/Inputs/unnamed-addr-drop.ll -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -save-temps -shared ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @foo = weak constant i32 41 ; Check that unnamed_addr is dropped during the merge. ; CHECK: @foo = constant i32 42 Index: vendor/lld/dist/test/ELF/lto/unnamed-addr.ll =================================================================== --- vendor/lld/dist/test/ELF/lto/unnamed-addr.ll (revision 321191) +++ vendor/lld/dist/test/ELF/lto/unnamed-addr.ll (revision 321192) @@ -1,14 +1,15 @@ +; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -shared ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @a = internal unnamed_addr constant i8 42 define i8* @f() { ret i8* @a } ; CHECK: @a = internal unnamed_addr constant i8 42 Index: vendor/lld/dist/test/ELF/many-alloc-sections.s =================================================================== --- vendor/lld/dist/test/ELF/many-alloc-sections.s (revision 321191) +++ vendor/lld/dist/test/ELF/many-alloc-sections.s (revision 321192) @@ -1,106 +1,107 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o // RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script // FIXME: threads are disable because the test is too slow with them (PR32942). // RUN: ld.lld -T %t.script %t.o -o %t --no-threads // RUN: llvm-readobj -t %t | FileCheck %s // Test that _start is in the correct section. // CHECK: Name: _start // CHECK-NEXT: Value: 0x120 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: dm .macro gen_sections4 x .section a\x,"a" .section b\x,"a" .section c\x,"a" .section d\x,"a" .endm .macro gen_sections8 x gen_sections4 a\x gen_sections4 b\x .endm .macro gen_sections16 x gen_sections8 a\x gen_sections8 b\x .endm .macro gen_sections32 x gen_sections16 a\x gen_sections16 b\x .endm .macro gen_sections64 x gen_sections32 a\x gen_sections32 b\x .endm .macro gen_sections128 x gen_sections64 a\x gen_sections64 b\x .endm .macro gen_sections256 x gen_sections128 a\x gen_sections128 b\x .endm .macro gen_sections512 x gen_sections256 a\x gen_sections256 b\x .endm .macro gen_sections1024 x gen_sections512 a\x gen_sections512 b\x .endm .macro gen_sections2048 x gen_sections1024 a\x gen_sections1024 b\x .endm .macro gen_sections4096 x gen_sections2048 a\x gen_sections2048 b\x .endm .macro gen_sections8192 x gen_sections4096 a\x gen_sections4096 b\x .endm .macro gen_sections16384 x gen_sections8192 a\x gen_sections8192 b\x .endm .macro gen_sections32768 x gen_sections16384 a\x gen_sections16384 b\x .endm .bss .section bar gen_sections32768 a gen_sections16384 b gen_sections8192 c gen_sections4096 d gen_sections2048 e gen_sections1024 f gen_sections512 g gen_sections128 h gen_sections64 i gen_sections32 j gen_sections16 k gen_sections8 l gen_sections4 m .global _start _start: Index: vendor/lld/dist/test/ELF/many-sections.s =================================================================== --- vendor/lld/dist/test/ELF/many-sections.s (revision 321191) +++ vendor/lld/dist/test/ELF/many-sections.s (revision 321192) @@ -1,123 +1,124 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t // RUN: llvm-readobj -t %t | FileCheck %s // Verify that the symbol _start is in a section with an index >= SHN_LORESERVE. // CHECK: Name: _start // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: dm (0xFF00) // FIXME: threads are disable because the test is too slow with them (PR32942). // RUN: ld.lld %t -o %t2 --no-threads // RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s // Test also with a linker script. // RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script // FIXME: threads are disable because the test is too slow with them (PR32942). // RUN: ld.lld -T %t.script %t -o %t2 --no-threads // RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s // Test that _start is in the correct section. // LINKED: Name: _start // LINKED-NEXT: Value: 0x0 // LINKED-NEXT: Size: 0 // LINKED-NEXT: Binding: Global // LINKED-NEXT: Type: None // LINKED-NEXT: Other: 0 // LINKED-NEXT: Section: dm .macro gen_sections4 x .section a\x .section b\x .section c\x .section d\x .endm .macro gen_sections8 x gen_sections4 a\x gen_sections4 b\x .endm .macro gen_sections16 x gen_sections8 a\x gen_sections8 b\x .endm .macro gen_sections32 x gen_sections16 a\x gen_sections16 b\x .endm .macro gen_sections64 x gen_sections32 a\x gen_sections32 b\x .endm .macro gen_sections128 x gen_sections64 a\x gen_sections64 b\x .endm .macro gen_sections256 x gen_sections128 a\x gen_sections128 b\x .endm .macro gen_sections512 x gen_sections256 a\x gen_sections256 b\x .endm .macro gen_sections1024 x gen_sections512 a\x gen_sections512 b\x .endm .macro gen_sections2048 x gen_sections1024 a\x gen_sections1024 b\x .endm .macro gen_sections4096 x gen_sections2048 a\x gen_sections2048 b\x .endm .macro gen_sections8192 x gen_sections4096 a\x gen_sections4096 b\x .endm .macro gen_sections16384 x gen_sections8192 a\x gen_sections8192 b\x .endm .macro gen_sections32768 x gen_sections16384 a\x gen_sections16384 b\x .endm .bss .section bar gen_sections32768 a gen_sections16384 b gen_sections8192 c gen_sections4096 d gen_sections2048 e gen_sections1024 f gen_sections512 g gen_sections128 h gen_sections64 i gen_sections32 j gen_sections16 k gen_sections8 l gen_sections4 m .global _start _start: Index: vendor/lld/dist/test/ELF/map-gc-sections.s =================================================================== --- vendor/lld/dist/test/ELF/map-gc-sections.s (nonexistent) +++ vendor/lld/dist/test/ELF/map-gc-sections.s (revision 321192) @@ -0,0 +1,9 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t -Map=- --gc-sections | FileCheck %s + +.section .tbss,"awT",@nobits +// CHECK-NOT: foo +.globl foo +foo: +.align 8 +.long 0 Property changes on: vendor/lld/dist/test/ELF/map-gc-sections.s ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: vendor/lld/dist/test/ELF/merge-section-types.s =================================================================== --- vendor/lld/dist/test/ELF/merge-section-types.s (revision 321191) +++ vendor/lld/dist/test/ELF/merge-section-types.s (revision 321192) @@ -1,19 +1,20 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: ld.lld -shared %t.o -o %t // RUN: llvm-readobj -s %t | FileCheck %s // CHECK: Name: .foo // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x1000 // CHECK-NEXT: Offset: 0x1000 // CHECK-NEXT: Size: 16 .section .foo, "aw", @progbits, unique, 1 .quad 0 .section .foo, "aw", @nobits, unique, 2 .quad 0 Index: vendor/lld/dist/test/ELF/new-dtags.test =================================================================== --- vendor/lld/dist/test/ELF/new-dtags.test (revision 321191) +++ vendor/lld/dist/test/ELF/new-dtags.test (revision 321192) @@ -1,15 +1,16 @@ +# REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: ld.lld %t.o -rpath=/somepath -shared --disable-new-dtags -o %t // RUN: ld.lld %t.o -rpath=/somepath -shared --enable-new-dtags -o %t2 // RUN: llvm-readobj --dynamic-table %t | FileCheck --check-prefix=DISABLE %s // RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=ENABLE %s // DISABLE: DynamicSection [ // DISABLE: 0x000000000000000F RPATH /somepath // DISABLE-NOT: RUNPATH // DISABLE: ] // ENABLE: DynamicSection [ // ENABLE: 0x000000000000001D RUNPATH /somepath // ENABLE-NOT: RPATH // ENABLE: ] Index: vendor/lld/dist/test/ELF/no-obj.s =================================================================== --- vendor/lld/dist/test/ELF/no-obj.s (revision 321191) +++ vendor/lld/dist/test/ELF/no-obj.s (revision 321192) @@ -1,8 +1,9 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: llvm-ar rcs %t.a %t.o // RUN: not ld.lld -o %t2 -u _start %t.a 2>&1 | FileCheck %s // CHECK: target emulation unknown: -m or at least one .o file required .global _start _start: Index: vendor/lld/dist/test/ELF/no-soname.s =================================================================== --- vendor/lld/dist/test/ELF/no-soname.s (revision 321191) +++ vendor/lld/dist/test/ELF/no-soname.s (revision 321192) @@ -1,31 +1,32 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: mkdir -p %T/no-soname // RUN: ld.lld %t.o -shared -o %T/no-soname/libfoo.so // RUN: ld.lld %t.o %T/no-soname/libfoo.so -o %t // RUN: llvm-readobj --dynamic-table %t | FileCheck %s -// CHECK: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}/no-soname/libfoo.so) +// CHECK: 0x0000000000000001 NEEDED Shared library: [{{.*}}/no-soname/libfoo.so] // CHECK-NOT: NEEDED // RUN: ld.lld %t.o %T/no-soname/../no-soname/libfoo.so -o %t // RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK2 -// CHECK2: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}/no-soname/../no-soname/libfoo.so) +// CHECK2: 0x0000000000000001 NEEDED Shared library: [{{.*}}/no-soname/../no-soname/libfoo.so] // CHECK2-NOT: NEEDED // RUN: ld.lld %t.o -L%T/no-soname/../no-soname -lfoo -o %t // RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK3 -// CHECK3: 0x0000000000000001 NEEDED SharedLibrary (libfoo.so) +// CHECK3: 0x0000000000000001 NEEDED Shared library: [libfoo.so] // CHECK3-NOT: NEEDED // RUN: ld.lld %t.o -shared -soname libbar.so -o %T/no-soname/libbar.so // RUN: ld.lld %t.o %T/no-soname/libbar.so -o %t // RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK4 -// CHECK4: 0x0000000000000001 NEEDED SharedLibrary (libbar.so) +// CHECK4: 0x0000000000000001 NEEDED Shared library: [libbar.so] // CHECK4-NOT: NEEDED .global _start _start: Index: vendor/lld/dist/test/ELF/no-symtab.s =================================================================== --- vendor/lld/dist/test/ELF/no-symtab.s (revision 321191) +++ vendor/lld/dist/test/ELF/no-symtab.s (revision 321192) @@ -1,4 +1,5 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: ld.lld %t.o %p/Inputs/no-symtab.o -o %t .global _start _start: Index: vendor/lld/dist/test/ELF/no-undefined.s =================================================================== --- vendor/lld/dist/test/ELF/no-undefined.s (revision 321191) +++ vendor/lld/dist/test/ELF/no-undefined.s (revision 321192) @@ -1,7 +1,8 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: not ld.lld --no-undefined -shared %t -o %t.so # RUN: ld.lld -shared %t -o %t1.so .globl _shared _shared: callq _unresolved@PLT Index: vendor/lld/dist/test/ELF/pie-weak.s =================================================================== --- vendor/lld/dist/test/ELF/pie-weak.s (revision 321191) +++ vendor/lld/dist/test/ELF/pie-weak.s (revision 321192) @@ -1,16 +1,17 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -relax-relocations=false -triple=x86_64-unknown-linux %s -o %t.o # RUN: ld.lld -pie %t.o -o %t # RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOCS %s # RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s # RELOCS: Relocations [ # RELOCS-NEXT: ] .weak foo .globl _start _start: # DISASM: _start: # DISASM-NEXT: 1000: 48 8b 05 69 10 00 00 movq 4201(%rip), %rax # ^ .got - (.text + 7) mov foo@gotpcrel(%rip), %rax Index: vendor/lld/dist/test/ELF/progname.s =================================================================== --- vendor/lld/dist/test/ELF/progname.s (revision 321191) +++ vendor/lld/dist/test/ELF/progname.s (revision 321192) @@ -1,31 +1,32 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: echo .global __progname > %t2.s // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld -o %t %t.o %t2.so // RUN: llvm-readobj -dyn-symbols %t | FileCheck %s // RUN: echo "VER_1 { global: bar; };" > %t.script // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \ // RUN: %p/Inputs/progname-ver.s -o %t-ver.o // RUN: ld.lld -shared -o %t.so -version-script %t.script %t-ver.o // RUN: ld.lld -o %t %t.o %t.so // RUN: llvm-readobj -dyn-symbols %t | FileCheck %s // RUN: echo "{ _start; };" > %t.dynlist // RUN: ld.lld -dynamic-list %t.dynlist -o %t %t.o %t.so // RUN: llvm-readobj -dyn-symbols %t | FileCheck %s // CHECK: Name: __progname@ // CHECK-NEXT: Value: 0x201000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Type: None (0x0) // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .text // CHECK-NEXT: } .global _start, __progname _start: __progname: nop Index: vendor/lld/dist/test/ELF/relative-dynamic-reloc-pie.s =================================================================== --- vendor/lld/dist/test/ELF/relative-dynamic-reloc-pie.s (revision 321191) +++ vendor/lld/dist/test/ELF/relative-dynamic-reloc-pie.s (revision 321192) @@ -1,26 +1,27 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: ld.lld -pie %t.o -o %t.pie # RUN: llvm-readobj -r -dyn-symbols %t.pie | FileCheck %s ## Test that we create R_X86_64_RELATIVE relocations with -pie. # CHECK: Relocations [ # CHECK-NEXT: Section ({{.*}}) .rela.dyn { # CHECK-NEXT: 0x2000 R_X86_64_RELATIVE - 0x2000 # CHECK-NEXT: 0x2008 R_X86_64_RELATIVE - 0x2008 # CHECK-NEXT: 0x2010 R_X86_64_RELATIVE - 0x2009 # CHECK-NEXT: } # CHECK-NEXT: ] .globl _start _start: nop .data foo: .quad foo .hidden bar .global bar bar: .quad bar .quad bar + 1 Index: vendor/lld/dist/test/ELF/relative-dynamic-reloc.s =================================================================== --- vendor/lld/dist/test/ELF/relative-dynamic-reloc.s (revision 321191) +++ vendor/lld/dist/test/ELF/relative-dynamic-reloc.s (revision 321192) @@ -1,70 +1,71 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o // RUN: ld.lld -shared %t.o -o %t.so // RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s // Test that we create R_X86_64_RELATIVE relocations but don't put any // symbols in the dynamic symbol table. // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.dyn { // CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_X86_64_RELATIVE - 0x[[FOO_ADDR]] // CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_X86_64_RELATIVE - 0x[[BAR_ADDR]] // CHECK-NEXT: 0x1010 R_X86_64_RELATIVE - 0x1009 // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[ZED_ADDR:.*]] // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[FOO_ADDR]] // CHECK-NEXT: 0x1028 R_X86_64_64 external 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK: Symbols [ // CHECK: Name: foo // CHECK-NEXT: Value: 0x[[FOO_ADDR]] // CHECK: Name: bar // CHECK-NEXT: Value: 0x[[BAR_ADDR]] // CHECK: Name: zed // CHECK-NEXT: Value: 0x[[ZED_ADDR]] // CHECK: ] // CHECK: DynamicSymbols [ // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: @ // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: external@ // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: ] .data foo: .quad foo .hidden bar .global bar bar: .quad bar .quad bar + 1 .hidden zed .comm zed,1 .quad zed .section abc,"aw" .quad foo .quad external // This doesn't need a relocation. callq localfunc@PLT localfunc: Index: vendor/lld/dist/test/ELF/relocatable-compressed-input.s =================================================================== --- vendor/lld/dist/test/ELF/relocatable-compressed-input.s (revision 321191) +++ vendor/lld/dist/test/ELF/relocatable-compressed-input.s (revision 321192) @@ -1,45 +1,45 @@ -# REQUIRES: zlib +# REQUIRES: x86, zlib # RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 # RUN: llvm-readobj -sections %t1 | FileCheck -check-prefix=GNU %s # GNU: Name: .zdebug_str # RUN: ld.lld %t1 -o %t2 -r # RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s ## Check we decompress section and remove ".z" prefix specific for zlib-gnu compression. # CHECK: Section { # CHECK: Index: # CHECK: Name: .debug_str # CHECK-NEXT: Type: SHT_PROGBITS # CHECK-NEXT: Flags [ # CHECK-NEXT: SHF_MERGE # CHECK-NEXT: SHF_STRINGS # CHECK-NEXT: ] # CHECK-NEXT: Address: # CHECK-NEXT: Offset: # CHECK-NEXT: Size: # CHECK-NEXT: Link: # CHECK-NEXT: Info: # CHECK-NEXT: AddressAlignment: 1 # CHECK-NEXT: EntrySize: 1 # CHECK-NEXT: SectionData ( # CHECK-NEXT: 0000: {{.*}} |short unsigned i| # CHECK-NEXT: 0010: {{.*}} |nt.unsigned int.| # CHECK-NEXT: 0020: {{.*}} |long unsigned in| # CHECK-NEXT: 0030: {{.*}} |t.char.unsigned | # CHECK-NEXT: 0040: {{.*}} |char.| # CHECK-NEXT: ) # CHECK-NEXT: } .section .debug_str,"MS",@progbits,1 .LASF2: .string "short unsigned int" .LASF3: .string "unsigned int" .LASF0: .string "long unsigned int" .LASF8: .string "char" .LASF1: .string "unsigned char" Index: vendor/lld/dist/test/ELF/relocatable-reloc.s =================================================================== --- vendor/lld/dist/test/ELF/relocatable-reloc.s (revision 321191) +++ vendor/lld/dist/test/ELF/relocatable-reloc.s (revision 321192) @@ -1,14 +1,15 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj %s -o %t.o -triple=x86_64-pc-linux // RUN: ld.lld %t.o %t.o -r -o %t2.o // RUN: llvm-readobj -r %t2.o | FileCheck %s .weak foo foo: .quad foo // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.text { // CHECK-NEXT: 0x0 R_X86_64_64 foo 0x0 // CHECK-NEXT: 0x8 R_X86_64_64 foo 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] Index: vendor/lld/dist/test/ELF/relocatable-section-symbol.s =================================================================== --- vendor/lld/dist/test/ELF/relocatable-section-symbol.s (revision 321191) +++ vendor/lld/dist/test/ELF/relocatable-section-symbol.s (revision 321192) @@ -1,49 +1,50 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: ld.lld -r -o %t %t.o %t.o # RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELA %s # RELA: Relocations [ # RELA-NEXT: Section ({{.*}}) .rela.data { # RELA-NEXT: 0x0 R_X86_64_32 .text 0x1 # RELA-NEXT: 0x4 R_X86_64_32 .text 0x5 # RELA-NEXT: } # RELA-NEXT: ] # RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o # RUN: ld.lld -r -o %t %t.o %t.o # RUN: llvm-readobj -r -s -section-data %t | FileCheck --check-prefix=REL %s # REL: Section { # REL: Index: # REL: Name: .data # REL-NEXT: Type: SHT_PROGBITS # REL-NEXT: Flags [ # REL-NEXT: SHF_ALLOC # REL-NEXT: SHF_WRITE # REL-NEXT: ] # REL-NEXT: Address: # REL-NEXT: Offset: # REL-NEXT: Size: # REL-NEXT: Link: # REL-NEXT: Info: # REL-NEXT: AddressAlignment: # REL-NEXT: EntrySize: # REL-NEXT: SectionData ( # REL-NEXT: 0000: 01000000 05000000 | # REL-NEXT: ) # REL-NEXT: } # REL: Relocations [ # REL-NEXT: Section ({{.*}}) .rel.data { # REL-NEXT: 0x0 R_386_32 .text 0x0 # REL-NEXT: 0x4 R_386_32 .text 0x0 # REL-NEXT: } # REL-NEXT: ] .long 42 .data .long .text + 1 Index: vendor/lld/dist/test/ELF/relocatable-sections.s =================================================================== --- vendor/lld/dist/test/ELF/relocatable-sections.s (revision 321191) +++ vendor/lld/dist/test/ELF/relocatable-sections.s (revision 321192) @@ -1,30 +1,31 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o # RUN: ld.lld -r %t1.o -o %t # RUN: llvm-objdump -section-headers %t | FileCheck %s # CHECK: .text # CHECK-NEXT: .rela.text # CHECK: .text._init # CHECK-NEXT: .rela.text._init # CHECK: .text._fini # CHECK-NEXT: .rela.text._fini .globl _start _start: call foo nop .section .xxx,"a" .quad 0 .section .text._init,"ax" .quad .xxx foo: call bar nop .section .text._fini,"ax" .quad .xxx bar: nop Index: vendor/lld/dist/test/ELF/relocatable-tls.s =================================================================== --- vendor/lld/dist/test/ELF/relocatable-tls.s (revision 321191) +++ vendor/lld/dist/test/ELF/relocatable-tls.s (revision 321192) @@ -1,15 +1,16 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ # RUN: %S/Inputs/relocatable-tls.s -o %t2.o # RUN: ld.lld -r %t2.o -o %t3.r # RUN: llvm-objdump -t %t3.r | FileCheck --check-prefix=RELOCATABLE %s # RELOCATABLE: SYMBOL TABLE: # RELOCATABLE: 0000000000000000 *UND* 00000000 __tls_get_addr # RUN: ld.lld -shared %t2.o %t3.r -o %t4.out # RUN: llvm-objdump -t %t4.out | FileCheck --check-prefix=DSO %s # DSO: SYMBOL TABLE: # DSO: 0000000000000000 *UND* 00000000 __tls_get_addr callq __tls_get_addr@PLT Index: vendor/lld/dist/test/ELF/relocation-shared.s =================================================================== --- vendor/lld/dist/test/ELF/relocation-shared.s (revision 321191) +++ vendor/lld/dist/test/ELF/relocation-shared.s (revision 321192) @@ -1,35 +1,36 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: ld.lld %t.o -shared -o %t.so // RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s // CHECK: Name: foo // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x1C8 // CHECK-NEXT: Offset: // CHECK-NEXT: Size: 8 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 380E0000 00000000 // 0x1000 - 0x1C8 = 0xE38 // CHECK-NEXT: ) // CHECK: Name: .text // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_EXECINSTR // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x1000 // CHECK: Relocations [ // CHECK-NEXT: ] bar: .section foo,"a",@progbits .quad bar - . Index: vendor/lld/dist/test/ELF/shared-be.s =================================================================== --- vendor/lld/dist/test/ELF/shared-be.s (revision 321191) +++ vendor/lld/dist/test/ELF/shared-be.s (revision 321192) @@ -1,37 +1,37 @@ // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld -dynamic-linker /lib64/ld64.so.1 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t // RUN: llvm-readobj --dynamic-table -s %t | FileCheck %s // REQUIRES: ppc // CHECK: Name: .rela.dyn // CHECK-NEXT: Type: SHT_REL // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[RELADDR:.*]] // CHECK-NEXT: Offset: // CHECK-NEXT: Size: [[RELSIZE:.*]] // CHECK-NEXT: Link: // CHECK-NEXT: Info: // CHECK-NEXT: AddressAlignment: // CHECK-NEXT: EntrySize: [[RELENT:.*]] // CHECK: DynamicSection [ // CHECK-NEXT: Tag Type Name/Value // CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar -// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so) +// CHECK-NEXT: 0x0000000000000001 NEEDED Shared library: [{{.*}}2.so] // CHECK-NEXT: 0x0000000000000015 DEBUG 0x0 // CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]] // CHECK-NEXT: 0x0000000000000008 RELASZ [[RELSIZE]] (bytes) // CHECK-NEXT: 0x0000000000000009 RELAENT [[RELENT]] (bytes) // CHECK: 0x0000000000000000 NULL 0x0 // CHECK-NEXT: ] .global _start _start: .data .long bar .long zed Index: vendor/lld/dist/test/ELF/shared.s =================================================================== --- vendor/lld/dist/test/ELF/shared.s (revision 321191) +++ vendor/lld/dist/test/ELF/shared.s (revision 321192) @@ -1,305 +1,305 @@ // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: llvm-readobj -s %t2.so | FileCheck --check-prefix=SO %s // RUN: ld.lld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t // RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data -hash-table %t | FileCheck %s // RUN: ld.lld %t.o %t2.so %t2.so -o %t2 // RUN: llvm-readobj -dyn-symbols %t2 | FileCheck --check-prefix=DONT_EXPORT %s // REQUIRES: x86 // Make sure .symtab is properly aligned. // SO: Name: .symtab // SO-NEXT: Type: SHT_SYMTAB // SO-NEXT: Flags [ // SO-NEXT: ] // SO-NEXT: Address: // SO-NEXT: Offset: 0x1038 // SO-NEXT: Size: // SO-NEXT: Link: // SO-NEXT: Info: // SO-NEXT: AddressAlignment: 4 // CHECK: Name: .interp // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[INTERPADDR:.*]] // CHECK-NEXT: Offset: [[INTERPOFFSET:.*]] // CHECK-NEXT: Size: [[INTERPSIZE:.*]] // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 2F6C6962 36342F6C 642D6C69 6E75782D |/lib64/ld-linux-| // CHECK-NEXT: 0010: 7838362D 36342E73 6F2E3200 |x86-64.so.2.| // CHECK-NEXT: ) // CHECK-NEXT: } // test that .hash is linked to .dynsym // CHECK: Index: 2 // CHECK-NEXT: Name: .dynsym // CHECK-NEXT: Type: SHT_DYNSYM // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[DYNSYMADDR:.*]] // CHECK-NEXT: Offset: 0x150 // CHECK-NEXT: Size: // CHECK-NEXT: Link: [[DYNSTR:.*]] // CHECK-NEXT: Info: 1 // CHECK-NEXT: AddressAlignment: 4 // CHECK-NEXT: EntrySize: 16 // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: // CHECK-NEXT: 0010: // CHECK-NEXT: 0020: // CHECK-NEXT: 0030: // CHECK-NEXT: ) // CHECK-NEXT: } // CHECK-NEXT: Section { // CHECK-NEXT: Index: 3 // CHECK-NEXT: Name: .hash // CHECK-NEXT: Type: SHT_HASH // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[HASHADDR:.*]] // CHECK-NEXT: Offset: // CHECK-NEXT: Size: // CHECK-NEXT: Link: 2 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 4 // CHECK-NEXT: EntrySize: 4 // CHECK: Index: [[DYNSTR]] // CHECK-NEXT: Name: .dynstr // CHECK-NEXT: Type: SHT_STRTAB // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[DYNSTRADDR:.*]] // CHECK-NEXT: Offset: // CHECK-NEXT: Size: // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( // CHECK: ) // CHECK-NEXT: } // CHECK: Name: .rel.dyn // CHECK-NEXT: Type: SHT_REL // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: [[RELADDR:.*]] // CHECK-NEXT: Offset: // CHECK-NEXT: Size: [[RELSIZE:.*]] // CHECK-NEXT: Link: // CHECK-NEXT: Info: // CHECK-NEXT: AddressAlignment: // CHECK-NEXT: EntrySize: [[RELENT:.*]] // CHECK: Name: .dynamic // CHECK-NEXT: Type: SHT_DYNAMIC // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] // CHECK-NEXT: Address: [[ADDR:.*]] // CHECK-NEXT: Offset: [[OFFSET:.*]] // CHECK-NEXT: Size: [[SIZE:.*]] // CHECK-NEXT: Link: [[DYNSTR]] // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: [[ALIGN:.*]] // CHECK-NEXT: EntrySize: 8 // CHECK-NEXT: SectionData ( // CHECK: ) // CHECK: Name: .symtab // CHECK-NEXT: Type: SHT_SYMTAB // CHECK-NEXT: Flags [ // CHECK-NEXT: ] // CHECK-NEXT: Address: // CHECK-NEXT: Offset: // CHECK-NEXT: Size: // CHECK-NEXT: Link: // CHECK-NEXT: Info: // CHECK-NEXT: AddressAlignment: // CHECK-NEXT: EntrySize: [[SYMENT:.*]] // CHECK: Symbols [ // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _DYNAMIC // CHECK-NEXT: Value: 0x12000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other [ (0x2) // CHECK-NEXT: STV_HIDDEN // CHECK-NEXT: ] // CHECK-NEXT: Section: .dynamic // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start // CHECK-NEXT: Value: 0x11000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: bar // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Function // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: zed // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Type: None (0x0) // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK: DynamicSymbols [ // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: @ // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start@ // CHECK-NEXT: Value: 0x11000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Non // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: bar@ // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Function // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: zed@ // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: ] // DONT_EXPORT: DynamicSymbols [ // DONT_EXPORT-NEXT: Symbol { // DONT_EXPORT-NEXT: Name: @ // DONT_EXPORT-NEXT: Value: 0x0 // DONT_EXPORT-NEXT: Size: 0 // DONT_EXPORT-NEXT: Binding: Local (0x0) // DONT_EXPORT-NEXT: Type: None (0x0) // DONT_EXPORT-NEXT: Other: 0 // DONT_EXPORT-NEXT: Section: Undefined (0x0) // DONT_EXPORT-NEXT: } // DONT_EXPORT-NEXT: Symbol { // DONT_EXPORT-NEXT: Name: bar@ // DONT_EXPORT-NEXT: Value: 0x0 // DONT_EXPORT-NEXT: Size: 0 // DONT_EXPORT-NEXT: Binding: Global // DONT_EXPORT-NEXT: Type: Function // DONT_EXPORT-NEXT: Other: 0 // DONT_EXPORT-NEXT: Section: Undefined // DONT_EXPORT-NEXT: } // DONT_EXPORT-NEXT: Symbol { // DONT_EXPORT-NEXT: Name: zed@ // DONT_EXPORT-NEXT: Value: 0x0 // DONT_EXPORT-NEXT: Size: 0 // DONT_EXPORT-NEXT: Binding: Global // DONT_EXPORT-NEXT: Type: None // DONT_EXPORT-NEXT: Other: 0 // DONT_EXPORT-NEXT: Section: Undefined // DONT_EXPORT-NEXT: } // DONT_EXPORT-NEXT: ] // CHECK: DynamicSection [ // CHECK-NEXT: Tag Type Name/Value // CHECK-NEXT: 0x0000001D RUNPATH foo:bar -// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so) +// CHECK-NEXT: 0x00000001 NEEDED Shared library: [{{.*}}2.so] // CHECK-NEXT: 0x00000015 DEBUG 0x0 // CHECK-NEXT: 0x00000011 REL [[RELADDR]] // CHECK-NEXT: 0x00000012 RELSZ [[RELSIZE]] (bytes) // CHECK-NEXT: 0x00000013 RELENT [[RELENT]] (bytes) // CHECK-NEXT: 0x00000006 SYMTAB [[DYNSYMADDR]] // CHECK-NEXT: 0x0000000B SYMENT [[SYMENT]] (bytes) // CHECK-NEXT: 0x00000005 STRTAB [[DYNSTRADDR]] // CHECK-NEXT: 0x0000000A STRSZ // CHECK-NEXT: 0x00000004 HASH [[HASHADDR]] // CHECK-NEXT: 0x00000000 NULL 0x0 // CHECK-NEXT: ] // CHECK: ProgramHeaders [ // CHECK: Type: PT_INTERP // CHECK-NEXT: Offset: [[INTERPOFFSET]] // CHECK-NEXT: VirtualAddress: [[INTERPADDR]] // CHECK-NEXT: PhysicalAddress: [[INTERPADDR]] // CHECK-NEXT: FileSize: [[INTERPSIZE]] // CHECK-NEXT: MemSize: [[INTERPSIZE]] // CHECK-NEXT: Flags [ // CHECK-NEXT: PF_R // CHECK-NEXT: ] // CHECK-NEXT: Alignment: 1 // CHECK-NEXT: } // CHECK: Type: PT_DYNAMIC // CHECK-NEXT: Offset: [[OFFSET]] // CHECK-NEXT: VirtualAddress: [[ADDR]] // CHECK-NEXT: PhysicalAddress: [[ADDR]] // CHECK-NEXT: FileSize: [[SIZE]] // CHECK-NEXT: MemSize: [[SIZE]] // CHECK-NEXT: Flags [ // CHECK-NEXT: PF_R // CHECK-NEXT: PF_W // CHECK-NEXT: ] // CHECK-NEXT: Alignment: [[ALIGN]] // CHECK-NEXT: } // CHECK: HashTable { // CHECK-NEXT: Num Buckets: 4 // CHECK-NEXT: Num Chains: 4 // CHECK-NEXT: Buckets: [3, 0, 2, 0] // CHECK-NEXT: Chains: [0, 0, 0, 1] // CHECK-NEXT: } .global _start _start: .long bar@GOT .long zed@GOT Index: vendor/lld/dist/test/ELF/soname.s =================================================================== --- vendor/lld/dist/test/ELF/soname.s (revision 321191) +++ vendor/lld/dist/test/ELF/soname.s (revision 321192) @@ -1,11 +1,11 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: ld.lld %t.o -shared -soname=bar -o %t.so // RUN: ld.lld %t.o -shared --soname=bar -o %t2.so // RUN: ld.lld %t.o %t.so %t2.so -o %t // RUN: llvm-readobj --dynamic-table %t | FileCheck %s -// CHECK: 0x0000000000000001 NEEDED SharedLibrary (bar) +// CHECK: 0x0000000000000001 NEEDED Shared library: [bar] // CHECK-NOT: NEEDED .global _start _start: Index: vendor/lld/dist/test/ELF/soname2.s =================================================================== --- vendor/lld/dist/test/ELF/soname2.s (revision 321191) +++ vendor/lld/dist/test/ELF/soname2.s (revision 321192) @@ -1,8 +1,8 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: ld.lld %t.o -shared -soname=foo.so -o %t // RUN: llvm-readobj --dynamic-table %t | FileCheck %s -// CHECK: 0x000000000000000E SONAME LibrarySoname (foo.so) +// CHECK: 0x000000000000000E SONAME Library soname: [foo.so] .global _start _start: Index: vendor/lld/dist/test/ELF/version-script-twice.s =================================================================== --- vendor/lld/dist/test/ELF/version-script-twice.s (nonexistent) +++ vendor/lld/dist/test/ELF/version-script-twice.s (revision 321192) @@ -0,0 +1,14 @@ +# REQUIRES: x86 + +# RUN: echo "FBSD_1.1 {}; FBSD_1.2 {};" > %t.ver +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.so --version-script=%t.ver +# RUN: llvm-readobj --dyn-symbols --elf-output-style=GNU %t.so | FileCheck %s + + .weak openat +openat: +openat@FBSD_1.1 = openat +openat@@FBSD_1.2 = openat + +# CHECK-DAG: openat@FBSD_1.1 +# CHECK-DAG: openat@@FBSD_1.2 Property changes on: vendor/lld/dist/test/ELF/version-script-twice.s ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property