diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-07-01 13:24:45 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-07-01 13:24:45 +0000 |
commit | 0317860f00ca8e821989c92c8a6cc461fd5f2009 (patch) | |
tree | ba31f275eb4dfa527c0cd564ba6c5016e2318b16 | |
parent | 4ea16835ba66f2240d050ffcaee44cee6c97cab9 (diff) |
Vendor import of lld trunk r306956:vendor/lld/lld-trunk-r306956
Notes
Notes:
svn path=/vendor/lld/dist/; revision=320541
svn path=/vendor/lld/lld-trunk-r306956/; revision=320542; tag=vendor/lld/lld-trunk-r306956
47 files changed, 1127 insertions, 269 deletions
diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp index 56124acaf9a1..9b642dcaf137 100644 --- a/COFF/Chunks.cpp +++ b/COFF/Chunks.cpp @@ -11,6 +11,7 @@ #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" @@ -52,18 +53,27 @@ 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 applySecRel(const SectionChunk *Sec, uint8_t *Off, Defined *Sym) { - // Don't apply section relative relocations to absolute symbols in codeview - // debug info sections. MSVC does not treat such relocations as fatal errors, - // and they can be found in the standard library for linker-provided symbols - // like __guard_fids_table and __safe_se_handler_table. - if (!(isa<DefinedAbsolute>(Sym) && Sec->isCodeView())) - add32(Off, Sym->getSecrel()); +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, Defined *Sym, - uint64_t P) const { - uint64_t S = Sym->getRVA(); +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; @@ -74,23 +84,22 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym, 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: add16(Off, Sym->getSectionIndex()); break; - case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, Sym); 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, Defined *Sym, - uint64_t P) const { - uint64_t S = Sym->getRVA(); +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: add16(Off, Sym->getSectionIndex()); break; - case IMAGE_REL_I386_SECREL: applySecRel(this, Off, Sym); 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)); } @@ -137,20 +146,21 @@ static void applyBranch24T(uint8_t *Off, int32_t V) { write16le(Off + 2, (read16le(Off + 2) & 0xd000) | (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); } -void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym, - uint64_t P) const { - uint64_t S = Sym->getRVA(); +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. - if (Sym->isExecutable()) - S |= 1; + uint64_t SX = S; + if (OS && (OS->getPermissions() & IMAGE_SCN_MEM_EXECUTE)) + SX |= 1; switch (Type) { - case IMAGE_REL_ARM_ADDR32: add32(Off, S + Config->ImageBase); break; - case IMAGE_REL_ARM_ADDR32NB: add32(Off, S); break; - case IMAGE_REL_ARM_MOV32T: applyMOV32T(Off, S + Config->ImageBase); break; - case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, S - P - 4); break; - case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, S - P - 4); break; - case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, S - P - 4); break; - case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, Sym); break; + 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)); } @@ -166,18 +176,39 @@ void SectionChunk::writeTo(uint8_t *Buf) const { // Apply relocations. for (const coff_relocation &Rel : Relocs) { 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<Defined>(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<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym)) { + if (isCodeView()) + 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, Sym, P); + applyRelX64(Off, Rel.Type, OS, S, P); break; case I386: - applyRelX86(Off, Rel.Type, Sym, P); + applyRelX86(Off, Rel.Type, OS, S, P); break; case ARMNT: - applyRelARM(Off, Rel.Type, Sym, P); + applyRelARM(Off, Rel.Type, OS, S, P); break; default: llvm_unreachable("unknown machine type"); diff --git a/COFF/Chunks.h b/COFF/Chunks.h index 54fffc5f6d08..6e1bf94da1a5 100644 --- a/COFF/Chunks.h +++ b/COFF/Chunks.h @@ -145,9 +145,12 @@ public: StringRef getSectionName() const override { return SectionName; } void getBaserels(std::vector<Baserel> *Res) override; bool isCOMDAT() const; - void applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym, uint64_t P) const; - void applyRelX86(uint8_t *Off, uint16_t Type, Defined *Sym, uint64_t P) const; - void applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym, uint64_t P) 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; // 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. diff --git a/COFF/Driver.h b/COFF/Driver.h index 2b5d1e7ae28b..6879be2eb0c7 100644 --- a/COFF/Driver.h +++ b/COFF/Driver.h @@ -34,7 +34,6 @@ extern LinkerDriver *Driver; using llvm::COFF::MachineTypes; using llvm::COFF::WindowsSubsystem; using llvm::Optional; -class InputFile; // Implemented in MarkLive.cpp. void markLive(const std::vector<Chunk *> &Chunks); diff --git a/COFF/MarkLive.cpp b/COFF/MarkLive.cpp index 25e5cc350673..a2756e5c89e0 100644 --- a/COFF/MarkLive.cpp +++ b/COFF/MarkLive.cpp @@ -52,6 +52,13 @@ void markLive(const std::vector<Chunk *> &Chunks) { while (!Worklist.empty()) { SectionChunk *SC = Worklist.pop_back_val(); + + // If this section was discarded, there are relocations referring to + // discarded sections. Ignore these sections to avoid crashing. They will be + // diagnosed during relocation processing. + if (SC->isDiscarded()) + continue; + assert(SC->isLive() && "We mark as live when pushing onto the worklist!"); // Mark all symbols listed in the relocation table for this section. diff --git a/COFF/Symbols.h b/COFF/Symbols.h index 8c1390c45876..a12ae1c01e07 100644 --- a/COFF/Symbols.h +++ b/COFF/Symbols.h @@ -110,17 +110,9 @@ public: // writer sets and uses RVAs. uint64_t getRVA(); - // Returns the RVA relative to the beginning of the output section. - // Used to implement SECREL relocation type. - uint32_t getSecrel(); - - // Returns the output section index. - // Used to implement SECTION relocation type. - uint16_t getSectionIndex(); - - // Returns true if this symbol points to an executable (e.g. .text) section. - // Used to implement ARM relocations. - bool isExecutable(); + // Returns the chunk containing this symbol. Absolute symbols and __ImageBase + // do not have chunks, so this may return null. + Chunk *getChunk(); }; // Symbols defined via a COFF object file or bitcode file. For COFF files, this @@ -167,7 +159,6 @@ public: bool isCOMDAT() { return IsCOMDAT; } SectionChunk *getChunk() { return *Data; } uint32_t getValue() { return Sym->Value; } - uint32_t getSecrel(); private: SectionChunk **Data; @@ -187,8 +178,7 @@ public: } uint64_t getRVA() { return Data->getRVA(); } - uint32_t getSecrel() { return Data->OutputSectionOff; } - uint16_t getSectionIndex(); + Chunk *getChunk() { return Data; } private: friend SymbolTable; @@ -219,6 +209,7 @@ public: // against absolute symbols resolve to this 16 bit number, and it is the // largest valid section index plus one. This is written by the Writer. static uint16_t OutputSectionIndex; + uint16_t getSecIdx() { return OutputSectionIndex; } private: uint64_t VA; @@ -237,9 +228,8 @@ public: // A null chunk indicates that this is __ImageBase. Otherwise, this is some // other synthesized chunk, like SEHTableChunk. - uint32_t getRVA() const { return C ? C->getRVA() : 0; } - uint32_t getSecrel() const { return C ? C->OutputSectionOff : 0; } - Chunk *getChunk() const { return C; } + uint32_t getRVA() { return C ? C->getRVA() : 0; } + Chunk *getChunk() { return C; } private: Chunk *C; @@ -304,9 +294,11 @@ public: } uint64_t getRVA() { return File->Location->getRVA(); } + Chunk *getChunk() { return File->Location; } + void setLocation(Chunk *AddressTable) { File->Location = AddressTable; } + StringRef getDLLName() { return File->DLLName; } StringRef getExternalName() { return File->ExternalName; } - void setLocation(Chunk *AddressTable) { File->Location = AddressTable; } uint16_t getOrdinal() { return File->Hdr->OrdinalHint; } ImportFile *File; @@ -378,6 +370,29 @@ inline uint64_t Defined::getRVA() { llvm_unreachable("unknown symbol kind"); } +inline Chunk *Defined::getChunk() { + switch (kind()) { + case DefinedRegularKind: + return cast<DefinedRegular>(this)->getChunk(); + case DefinedAbsoluteKind: + return nullptr; + case DefinedSyntheticKind: + return cast<DefinedSynthetic>(this)->getChunk(); + case DefinedImportDataKind: + return cast<DefinedImportData>(this)->getChunk(); + case DefinedImportThunkKind: + return cast<DefinedImportThunk>(this)->getChunk(); + case DefinedLocalImportKind: + return cast<DefinedLocalImport>(this)->getChunk(); + case DefinedCommonKind: + return cast<DefinedCommon>(this)->getChunk(); + case LazyKind: + case UndefinedKind: + llvm_unreachable("Cannot get the chunk of an undefined symbol."); + } + llvm_unreachable("unknown symbol kind"); +} + // A real symbol object, SymbolBody, is usually stored within a Symbol. There's // always one Symbol for each symbol name. The resolver updates the SymbolBody // stored in the Body field of this object as it resolves symbols. Symbol also diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp index d32577b361fa..4cf718a48d8b 100644 --- a/COFF/Writer.cpp +++ b/COFF/Writer.cpp @@ -120,7 +120,6 @@ private: void writeSections(); void sortExceptionTable(); void writeBuildId(); - void applyRelocations(); llvm::Optional<coff_symbol16> createSymbol(Defined *D); size_t addEntryToStringTable(StringRef Str); @@ -210,55 +209,6 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) { } } -uint32_t Defined::getSecrel() { - assert(this); - switch (kind()) { - case DefinedRegularKind: - return cast<DefinedRegular>(this)->getSecrel(); - case DefinedCommonKind: - return cast<DefinedCommon>(this)->getSecrel(); - case DefinedSyntheticKind: - return cast<DefinedSynthetic>(this)->getSecrel(); - default: - break; - } - fatal("SECREL relocation points to a non-regular symbol: " + toString(*this)); -} - -uint32_t DefinedRegular::getSecrel() { - assert(getChunk()->isLive() && "relocation against discarded section"); - uint64_t Diff = getRVA() - getChunk()->getOutputSection()->getRVA(); - assert(Diff < UINT32_MAX && "section offset too large"); - return (uint32_t)Diff; -} - -uint16_t Defined::getSectionIndex() { - if (auto *D = dyn_cast<DefinedRegular>(this)) - return D->getChunk()->getOutputSection()->SectionIndex; - if (isa<DefinedAbsolute>(this)) - return DefinedAbsolute::OutputSectionIndex; - if (auto *D = dyn_cast<DefinedCommon>(this)) - return D->getSectionIndex(); - if (auto *D = dyn_cast<DefinedSynthetic>(this)) { - if (!D->getChunk()) - return 0; - return D->getChunk()->getOutputSection()->SectionIndex; - } - fatal("SECTION relocation points to a non-regular symbol: " + - toString(*this)); -} - -uint16_t DefinedCommon::getSectionIndex() { - return Data->getOutputSection()->SectionIndex; -} - -bool Defined::isExecutable() { - const auto X = IMAGE_SCN_MEM_EXECUTE; - if (auto *D = dyn_cast<DefinedRegular>(this)) - return D->getChunk()->getOutputSection()->getPermissions() & X; - return isa<DefinedImportThunk>(this); -} - } // namespace coff } // namespace lld diff --git a/ELF/Arch/SPARCV9.cpp b/ELF/Arch/SPARCV9.cpp new file mode 100644 index 000000000000..1f977c1e9cf2 --- /dev/null +++ b/ELF/Arch/SPARCV9.cpp @@ -0,0 +1,149 @@ +//===- SPARCV9.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 "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 SPARCV9 final : public TargetInfo { +public: + SPARCV9(); + RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, + const uint8_t *Loc) const override; + void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr, + int32_t Index, unsigned RelOff) const override; + void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; +}; +} // namespace + +SPARCV9::SPARCV9() { + CopyRel = R_SPARC_COPY; + GotRel = R_SPARC_GLOB_DAT; + PltRel = R_SPARC_JMP_SLOT; + RelativeRel = R_SPARC_RELATIVE; + GotEntrySize = 8; + PltEntrySize = 32; + PltHeaderSize = 4 * PltEntrySize; + + PageSize = 8192; + DefaultMaxPageSize = 0x100000; + DefaultImageBase = 0x100000; +} + +RelExpr SPARCV9::getRelExpr(uint32_t Type, const SymbolBody &S, + const uint8_t *Loc) const { + switch (Type) { + case R_SPARC_32: + case R_SPARC_UA32: + case R_SPARC_64: + case R_SPARC_UA64: + return R_ABS; + case R_SPARC_PC10: + case R_SPARC_PC22: + case R_SPARC_DISP32: + case R_SPARC_WDISP30: + return R_PC; + case R_SPARC_GOT10: + return R_GOT_OFF; + case R_SPARC_GOT22: + return R_GOT_OFF; + case R_SPARC_WPLT30: + return R_PLT_PC; + case R_SPARC_NONE: + return R_NONE; + default: + error(toString(S.File) + ": unknown relocation type: " + toString(Type)); + return R_HINT; + } +} + +void SPARCV9::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { + switch (Type) { + case R_SPARC_32: + case R_SPARC_UA32: + // V-word32 + checkUInt<32>(Loc, Val, Type); + write32be(Loc, Val); + break; + case R_SPARC_DISP32: + // V-disp32 + checkInt<32>(Loc, Val, Type); + write32be(Loc, Val); + break; + case R_SPARC_WDISP30: + case R_SPARC_WPLT30: + // V-disp30 + checkInt<32>(Loc, Val, Type); + write32be(Loc, (read32be(Loc) & ~0x3fffffff) | ((Val >> 2) & 0x3fffffff)); + break; + case R_SPARC_22: + // V-imm22 + checkUInt<22>(Loc, Val, Type); + write32be(Loc, (read32be(Loc) & ~0x003fffff) | (Val & 0x003fffff)); + break; + case R_SPARC_GOT22: + case R_SPARC_PC22: + // T-imm22 + write32be(Loc, (read32be(Loc) & ~0x003fffff) | ((Val >> 10) & 0x003fffff)); + break; + case R_SPARC_WDISP19: + // V-disp19 + checkInt<21>(Loc, Val, Type); + write32be(Loc, (read32be(Loc) & ~0x0007ffff) | ((Val >> 2) & 0x0007ffff)); + break; + case R_SPARC_GOT10: + case R_SPARC_PC10: + // T-simm10 + write32be(Loc, (read32be(Loc) & ~0x000003ff) | (Val & 0x000003ff)); + break; + case R_SPARC_64: + case R_SPARC_UA64: + case R_SPARC_GLOB_DAT: + // V-xword64 + write64be(Loc, Val); + break; + default: + error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); + } +} + +void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr, int32_t Index, + unsigned RelOff) const { + const uint8_t PltData[] = { + 0x03, 0x00, 0x00, 0x00, // sethi (. - .PLT0), %g1 + 0x30, 0x68, 0x00, 0x00, // ba,a %xcc, .PLT1 + 0x01, 0x00, 0x00, 0x00, // nop + 0x01, 0x00, 0x00, 0x00, // nop + 0x01, 0x00, 0x00, 0x00, // nop + 0x01, 0x00, 0x00, 0x00, // nop + 0x01, 0x00, 0x00, 0x00, // nop + 0x01, 0x00, 0x00, 0x00 // nop + }; + memcpy(Buf, PltData, sizeof(PltData)); + + uint64_t Off = PltHeaderSize + Index * PltEntrySize; + relocateOne(Buf, R_SPARC_22, Off); + relocateOne(Buf + 4, R_SPARC_WDISP19, -(Off + 4 - PltEntrySize)); +} + +TargetInfo *elf::getSPARCV9TargetInfo() { + static SPARCV9 Target; + return &Target; +} diff --git a/ELF/CMakeLists.txt b/ELF/CMakeLists.txt index b4bc215a77eb..77243bd494d1 100644 --- a/ELF/CMakeLists.txt +++ b/ELF/CMakeLists.txt @@ -15,6 +15,7 @@ add_lld_library(lldELF Arch/MipsArchTree.cpp Arch/PPC.cpp Arch/PPC64.cpp + Arch/SPARCV9.cpp Arch/X86.cpp Arch/X86_64.cpp Driver.cpp diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp index 1ff0b4224e70..e07f24d665df 100644 --- a/ELF/InputFiles.cpp +++ b/ELF/InputFiles.cpp @@ -79,9 +79,9 @@ template <class ELFT> void elf::ObjectFile<ELFT>::initializeDwarfLine() { ObjectInfo ObjInfo; DWARFContextInMemory Dwarf(*Obj, &ObjInfo); - DwarfLine.reset(new DWARFDebugLine(&Dwarf.getLineSection().Relocs)); - DataExtractor LineData(Dwarf.getLineSection().Data, Config->IsLE, - Config->Wordsize); + DwarfLine.reset(new DWARFDebugLine); + DWARFDataExtractor LineData(Dwarf.getLineSection(), Config->IsLE, + Config->Wordsize); // The second parameter is offset in .debug_line section // for compilation unit (CU) of interest. We have only one diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp index ab8802c86d8e..d75b89f17527 100644 --- a/ELF/SymbolTable.cpp +++ b/ELF/SymbolTable.cpp @@ -195,14 +195,8 @@ template <class ELFT> void SymbolTable<ELFT>::applySymbolRenames() { for (auto &KV : Config->RenamedSymbols) { Symbol *Dst = KV.first; Symbol *Src = KV.second.Target; + Dst->body()->copy(Src->body()); Dst->Binding = KV.second.OriginalBinding; - - // We rename symbols by replacing the old symbol's SymbolBody with - // the new symbol's SymbolBody. The only attribute we want to keep - // is the symbol name, so that two symbols don't have the same name. - StringRef S = Dst->body()->getName(); - memcpy(Dst->Body.buffer, Src->Body.buffer, sizeof(Symbol::Body)); - Dst->body()->setName(S); } } @@ -718,15 +712,31 @@ void SymbolTable<ELFT>::assignWildcardVersion(SymbolVersion Ver, B->symbol()->VersionId = VersionId; } +static bool isDefaultVersion(SymbolBody *B) { + return B->isInCurrentDSO() && B->getName().find("@@") != StringRef::npos; +} + // This function processes version scripts by updating VersionId // member of symbols. template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() { // Symbol themselves might know their versions because symbols // can contain versions in the form of <name>@<version>. - // Let them parse their names. - if (!Config->VersionDefinitions.empty()) - for (Symbol *Sym : SymVector) - Sym->body()->parseSymbolVersion(); + // Let them parse and update their names to exclude version suffix. + for (Symbol *Sym : SymVector) { + SymbolBody *Body = Sym->body(); + bool IsDefault = isDefaultVersion(Body); + Body->parseSymbolVersion(); + + if (!IsDefault) + continue; + + // <name>@@<version> means the symbol is the default version. If that's the + // case, the symbol is not used only to resolve <name> of version <version> + // but also undefined unversioned symbols with name <name>. + SymbolBody *S = find(Body->getName()); + if (S && S->isUndefined()) + S->copy(Body); + } // Handle edge cases first. handleAnonymousVersion(); diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h index 316d9c9bf373..4ba101fa5d50 100644 --- a/ELF/SymbolTable.h +++ b/ELF/SymbolTable.h @@ -18,7 +18,7 @@ namespace lld { namespace elf { -class Lazy; + struct Symbol; // SymbolTable is a bucket of all known symbols, including defined, diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp index 5dce71a32c9c..e8cd662c69ac 100644 --- a/ELF/Symbols.cpp +++ b/ELF/Symbols.cpp @@ -159,6 +159,21 @@ bool SymbolBody::isPreemptible() const { return true; } +// Overwrites all attributes except symbol name with Other's so that +// this symbol becomes an alias to Other. This is useful for handling +// some options such as --wrap. +// +// The reason why we want to keep the symbol name is because, if we +// copy symbol names, we'll end up having symbol tables in resulting +// executables or DSOs containing two or more identical symbols, which +// is just inconvenient. +void SymbolBody::copy(SymbolBody *Other) { + StringRef S = Name; + memcpy(symbol()->Body.buffer, Other->symbol()->Body.buffer, + sizeof(Symbol::Body)); + Name = S; +} + uint64_t SymbolBody::getVA(int64_t Addend) const { uint64_t OutVA = getSymVA(*this, Addend); return OutVA + Addend; diff --git a/ELF/Symbols.h b/ELF/Symbols.h index 406fd8e0f57b..773e1ad9588a 100644 --- a/ELF/Symbols.h +++ b/ELF/Symbols.h @@ -69,9 +69,9 @@ public: bool isLocal() const { return IsLocal; } bool isPreemptible() const; StringRef getName() const { return Name; } - void setName(StringRef S) { Name = S; } uint8_t getVisibility() const { return StOther & 0x3; } void parseSymbolVersion(); + void copy(SymbolBody *Other); bool isInGot() const { return GotIndex != -1U; } bool isInPlt() const { return PltIndex != -1U; } diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp index cb1494d427a0..995d05692ee2 100644 --- a/ELF/SyntheticSections.cpp +++ b/ELF/SyntheticSections.cpp @@ -1090,8 +1090,17 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { if (In<ELFT>::RelaPlt->getParent()->Size > 0) { add({DT_JMPREL, In<ELFT>::RelaPlt}); add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getParent()->Size}); - add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT, - InX::GotPlt}); + switch (Config->EMachine) { + case EM_MIPS: + add({DT_MIPS_PLTGOT, In<ELFT>::GotPlt}); + break; + case EM_SPARCV9: + add({DT_PLTGOT, In<ELFT>::Plt}); + break; + default: + add({DT_PLTGOT, In<ELFT>::GotPlt}); + break; + } add({DT_PLTREL, uint64_t(Config->IsRela ? DT_RELA : DT_REL)}); } @@ -1376,7 +1385,6 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { } ESym->st_name = Ent.StrTabOffset; - ESym->st_size = Body->getSize<ELFT>(); // Set a section index. if (const OutputSection *OutSec = Body->getOutputSection()) @@ -1386,6 +1394,14 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { else if (isa<DefinedCommon>(Body)) ESym->st_shndx = SHN_COMMON; + // Copy symbol size if it is a defined symbol. st_size is not significant + // for undefined symbols, so whether copying it or not is up to us if that's + // the case. We'll leave it as zero because by not setting a value, we can + // get the exact same outputs for two sets of input files that differ only + // in undefined symbol size in DSOs. + if (ESym->st_shndx != SHN_UNDEF) + ESym->st_size = Body->getSize<ELFT>(); + // st_value is usually an address of a symbol, but that has a // special meaining for uninstantiated common symbols (this can // occur if -r is given). @@ -1625,7 +1641,12 @@ template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) { PltSection::PltSection(size_t S) : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt"), - HeaderSize(S) {} + HeaderSize(S) { + // The PLT needs to be writable on SPARC as the dynamic linker will + // modify the instructions in the PLT entries. + if (Config->EMachine == EM_SPARCV9) + this->Flags |= SHF_WRITE; +} void PltSection::writeTo(uint8_t *Buf) { // At beginning of PLT but not the IPLT, we have code to call the dynamic diff --git a/ELF/Target.cpp b/ELF/Target.cpp index c1a85e165258..c886419971bc 100644 --- a/ELF/Target.cpp +++ b/ELF/Target.cpp @@ -77,6 +77,8 @@ TargetInfo *elf::getTarget() { return getPPCTargetInfo(); case EM_PPC64: return getPPC64TargetInfo(); + case EM_SPARCV9: + return getSPARCV9TargetInfo(); case EM_X86_64: if (Config->EKind == ELF32LEKind) return getX32TargetInfo(); diff --git a/ELF/Target.h b/ELF/Target.h index bf703fd0086a..5914d9bbb7ef 100644 --- a/ELF/Target.h +++ b/ELF/Target.h @@ -112,6 +112,7 @@ TargetInfo *getARMTargetInfo(); TargetInfo *getAVRTargetInfo(); TargetInfo *getPPC64TargetInfo(); TargetInfo *getPPCTargetInfo(); +TargetInfo *getSPARCV9TargetInfo(); TargetInfo *getX32TargetInfo(); TargetInfo *getX86TargetInfo(); TargetInfo *getX86_64TargetInfo(); diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp index 4c12b18836bf..080d8e787301 100644 --- a/ELF/Writer.cpp +++ b/ELF/Writer.cpp @@ -104,7 +104,7 @@ StringRef elf::getOutputSectionName(StringRef Name) { for (StringRef V : {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.", ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", - ".gcc_except_table.", ".tdata.", ".ARM.exidx."}) { + ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) { StringRef Prefix = V.drop_back(); if (Name.startswith(V) || Name == Prefix) return Prefix; @@ -1014,14 +1014,14 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B, } template <class ELFT> void Writer<ELFT>::sortSections() { + if (Script->Opt.HasSections) + Script->adjustSectionsBeforeSorting(); + // Don't sort if using -r. It is not necessary and we want to preserve the // relative order for SHF_LINK_ORDER sections. if (Config->Relocatable) return; - if (Script->Opt.HasSections) - Script->adjustSectionsBeforeSorting(); - for (BaseCommand *Base : Script->Opt.Commands) if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) if (OutputSection *Sec = Cmd->Sec) diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp index fe67fc88c467..5233e42e5fc5 100644 --- a/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp +++ b/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp @@ -44,7 +44,6 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(DependentDylib) LLVM_YAML_IS_SEQUENCE_VECTOR(RebaseLocation) LLVM_YAML_IS_SEQUENCE_VECTOR(BindLocation) LLVM_YAML_IS_SEQUENCE_VECTOR(Export) -LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) LLVM_YAML_IS_SEQUENCE_VECTOR(DataInCode) diff --git a/test/COFF/Inputs/combined-resources-2.rc b/test/COFF/Inputs/combined-resources-2.rc new file mode 100644 index 000000000000..081b3a77bebc --- /dev/null +++ b/test/COFF/Inputs/combined-resources-2.rc @@ -0,0 +1,36 @@ +#include "windows.h"
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+randomdat RCDATA
+{
+ "this is a random bit of data that means nothing\0",
+ 0x23a9,
+ 0x140e,
+ 194292,
+}
+
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+randomdat RCDATA
+{
+ "zhe4 shi4 yi1ge4 sui2ji1 de shu4ju4, zhe4 yi4wei4zhe shen2me\0",
+ 0x23a9,
+ 0x140e,
+ 194292,
+}
+
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_LUXEMBOURG
+randomdat RCDATA
+{
+ "Dies ist ein zufälliges Bit von Daten, die nichts bedeutet\0",
+ 0x23a9,
+ 0x140e,
+ 194292,
+}
+
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+myaccelerators ACCELERATORS
+{
+ "^C", 999, VIRTKEY, ALT
+ "D", 1100, VIRTKEY, CONTROL, SHIFT
+ "^R", 444, ASCII, NOINVERT
+}
diff --git a/test/COFF/Inputs/combined-resources-2.res b/test/COFF/Inputs/combined-resources-2.res Binary files differnew file mode 100644 index 000000000000..31da6166d7f6 --- /dev/null +++ b/test/COFF/Inputs/combined-resources-2.res diff --git a/test/COFF/Inputs/combined-resources-cursor.bmp b/test/COFF/Inputs/combined-resources-cursor.bmp Binary files differnew file mode 100644 index 000000000000..ce513261bc2c --- /dev/null +++ b/test/COFF/Inputs/combined-resources-cursor.bmp diff --git a/test/COFF/Inputs/combined-resources-okay.bmp b/test/COFF/Inputs/combined-resources-okay.bmp Binary files differnew file mode 100644 index 000000000000..e4005bf5ef97 --- /dev/null +++ b/test/COFF/Inputs/combined-resources-okay.bmp diff --git a/test/COFF/Inputs/combined-resources.rc b/test/COFF/Inputs/combined-resources.rc new file mode 100644 index 000000000000..08bfb94c44ae --- /dev/null +++ b/test/COFF/Inputs/combined-resources.rc @@ -0,0 +1,50 @@ +#include "windows.h"
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+myaccelerators ACCELERATORS
+{
+ "^C", 999, VIRTKEY, ALT
+ "D", 1100, VIRTKEY, CONTROL, SHIFT
+ "^R", 444, ASCII, NOINVERT
+}
+
+cursor BITMAP "combined-resources-cursor.bmp"
+okay BITMAP "combined-resources-okay.bmp"
+
+14432 MENU
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+{
+ MENUITEM "yu", 100
+ MENUITEM "shala", 101
+ MENUITEM "kaoya", 102
+}
+
+testdialog DIALOG 10, 10, 200, 300
+STYLE WS_POPUP | WS_BORDER
+CAPTION "Test"
+{
+ CTEXT "Continue:", 1, 10, 10, 230, 14
+ PUSHBUTTON "&OK", 2, 66, 134, 161, 13
+}
+
+12 ACCELERATORS
+{
+ "X", 164, VIRTKEY, ALT
+ "H", 5678, VIRTKEY, CONTROL, SHIFT
+ "^R", 444, ASCII, NOINVERT
+}
+
+"eat" MENU
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
+{
+ MENUITEM "fish", 100
+ MENUITEM "salad", 101
+ MENUITEM "duck", 102
+}
+
+
+myresource stringarray {
+ "this is a user defined resource\0",
+ "it contains many strings\0",
+}
diff --git a/test/COFF/Inputs/combined-resources.res b/test/COFF/Inputs/combined-resources.res Binary files differnew file mode 100644 index 000000000000..d422bb4904da --- /dev/null +++ b/test/COFF/Inputs/combined-resources.res diff --git a/test/COFF/Inputs/pdb-global-gc.s b/test/COFF/Inputs/pdb-global-gc.s new file mode 100644 index 000000000000..4c931dca015c --- /dev/null +++ b/test/COFF/Inputs/pdb-global-gc.s @@ -0,0 +1,4 @@ +.section .data,"dw",one_only,__wc_mb_cur +.global __wc_mb_cur +__wc_mb_cur: +.long 42 diff --git a/test/COFF/Inputs/pdb-import-gc.lib b/test/COFF/Inputs/pdb-import-gc.lib Binary files differnew file mode 100644 index 000000000000..f4682eddb6e8 --- /dev/null +++ b/test/COFF/Inputs/pdb-import-gc.lib diff --git a/test/COFF/combined-resources.test b/test/COFF/combined-resources.test new file mode 100644 index 000000000000..dc6c87af0f77 --- /dev/null +++ b/test/COFF/combined-resources.test @@ -0,0 +1,17 @@ +// Check that lld properly handles merging multiple .res files. +// The inputs were generated with the following commands, using the original +// Windows rc.exe +// > rc /fo combined-resources.res /nologo combined-resources.rc +// > rc /fo combined-resources-2.res /nologo combined-resources-2.rc + +# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj +# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res \ +# RUN: %p/Inputs/combined-resources.res %p/Inputs/combined-resources-2.res + +# RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s + + +CHECK: ResourceTableRVA: 0x1000 +CHECK-NEXT: ResourceTableSize: 0xC1C +CHECK-DAG: Resources [ +CHECK-NEXT: Total Number of Resources: 13 diff --git a/test/COFF/hello32.test b/test/COFF/hello32.test index 9464a3c114eb..e987bb953890 100644 --- a/test/COFF/hello32.test +++ b/test/COFF/hello32.test @@ -21,6 +21,7 @@ HEADER-NEXT: IMAGE_FILE_EXECUTABLE_IMAGE (0x2) HEADER-NEXT: ] HEADER-NEXT: } HEADER-NEXT: ImageOptionalHeader { +HEADER-NEXT: Magic: 0x10B HEADER-NEXT: MajorLinkerVersion: 14 HEADER-NEXT: MinorLinkerVersion: 0 HEADER-NEXT: SizeOfCode: 512 diff --git a/test/COFF/pdb-comdat.test b/test/COFF/pdb-comdat.test index 769b630d0e8d..a7b5c401ab92 100644 --- a/test/COFF/pdb-comdat.test +++ b/test/COFF/pdb-comdat.test @@ -41,49 +41,48 @@ CHECK-LABEL: Mod 0002 | `* Linker *`: CHECK: Symbols CHECK: ============================================================ CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`: -CHECK: - S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_main.obj` -CHECK: - 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: - S_GPROC32_ID [size = 44] `main` - FIXME: We need to fill in "end". -CHECK: parent = 0, addr = 0002:0000, code size = 24, end = 0 -CHECK: debug start = 4, debug end = 19, flags = none -CHECK: - 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: - S_END [size = 4] -CHECK: - S_GDATA32 [size = 24] `global` -CHECK: type = 0x0074 (int), addr = 0000:0000 -CHECK: - S_BUILDINFO [size = 8] BuildId = `4106` -CHECK: - S_GPROC32_ID [size = 44] `foo` -CHECK: parent = 0, addr = 0002:0032, code size = 15, end = 0 -CHECK: debug start = 0, debug end = 14, flags = none -CHECK: - 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: - S_END [size = 4] +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 = 0, 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: 232 | S_GPROC32_ID [size = 44] `foo` +CHECK: parent = 0, end = 0, 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: - S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_bar.obj` -CHECK: - S_COMPILE3 [size = 60] +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: - S_GPROC32_ID [size = 44] `bar` -CHECK: parent = 0, addr = 0002:0048, code size = 14, end = 0 +CHECK: 120 | S_GPROC32_ID [size = 44] `bar` +CHECK: parent = 0, end = 0, addr = 0002:0048, code size = 14 CHECK: debug start = 4, debug end = 9, flags = none -CHECK: - S_FRAMEPROC [size = 32] +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: - S_END [size = 4] -CHECK: - S_GDATA32 [size = 24] `global` +CHECK: 196 | S_END [size = 4] +CHECK: 200 | S_GDATA32 [size = 24] `global` CHECK: type = 0x0074 (int), addr = 0000:0000 -CHECK: - S_BUILDINFO [size = 8] BuildId = `4109` -CHECK-NOT: - S_GPROC32_ID {{.*}} `foo` +CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `4109` +CHECK-NOT: S_GPROC32_ID {{.*}} `foo` CHECK-LABEL: Mod 0002 | `* Linker *`: Reorder the object files and verify that the other table is selected. diff --git a/test/COFF/pdb-global-gc.yaml b/test/COFF/pdb-global-gc.yaml new file mode 100644 index 000000000000..b66b3f2ca7b8 --- /dev/null +++ b/test/COFF/pdb-global-gc.yaml @@ -0,0 +1,116 @@ +# RUN: yaml2obj %s -o %t.obj +# RUN: llvm-mc %S/Inputs/pdb-global-gc.s -triple x86_64-windows-msvc -filetype=obj -o %t2.obj +# RUN: lld-link %t.obj %t2.obj -debug -entry:main \ +# RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb -verbose +# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s + +# This tests the case where an __imp_ chunk is discarded by linker GC. The debug +# info may refer to the __imp_ symbol still. + +# Compile this code with MSVC to regenerate the test case: +# extern char __declspec(dllimport) __wc_mb_cur; +# int discarded() { return __wc_mb_cur; } +# int main() { return g2; } + +# CHECK: Symbols +# CHECK: ============================================================ +# CHECK: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`: +# CHECK: 4 | S_GDATA32 [size = 28] `__wc_mb_cur` +# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 +# CHECK: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`: +# CHECK: Mod 0002 | `* Linker *`: + +--- !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_GDATA32 + DataSym: + Type: 112 + DisplayName: __wc_mb_cur + - !StringTable + Strings: + Relocations: + - VirtualAddress: 20 + SymbolName: __wc_mb_cur + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 24 + SymbolName: __wc_mb_cur + Type: IMAGE_REL_AMD64_SECTION + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 0FBE0500000000C3 + Relocations: + - VirtualAddress: 3 + SymbolName: __wc_mb_cur + Type: IMAGE_REL_AMD64_REL32 + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: B82A000000C3 +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: 240 + NumberOfRelocations: 2 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.text$mn' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 11 + NumberOfRelocations: 1 + NumberOfLinenumbers: 0 + CheckSum: 2906070869 + Number: 0 + Selection: IMAGE_COMDAT_SELECT_NODUPLICATES + - Name: '.text$mn' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 6 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2139436471 + Number: 0 + Selection: IMAGE_COMDAT_SELECT_NODUPLICATES + - Name: discarded + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: main + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: __wc_mb_cur + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/test/COFF/pdb-import-gc.yaml b/test/COFF/pdb-import-gc.yaml new file mode 100644 index 000000000000..80484cb75f4f --- /dev/null +++ b/test/COFF/pdb-import-gc.yaml @@ -0,0 +1,114 @@ +# RUN: yaml2obj %s -o %t.obj +# RUN: lld-link %t.obj %S/Inputs/pdb-import-gc.lib -debug -entry:main \ +# RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb +# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s + +# This tests the case where an __imp_ chunk is discarded by linker GC. The debug +# info may refer to the __imp_ symbol still. + +# Compile this code with MSVC to regenerate the test case: +# extern char __declspec(dllimport) __wc_mb_cur; +# int discarded() { return __wc_mb_cur; } +# int main() { return g2; } + +# CHECK: Symbols +# CHECK: ============================================================ +# CHECK: Mod 0000 | `{{.*}}pdb-import-gc.yaml.tmp.obj`: +# CHECK: 4 | S_GDATA32 [size = 32] `__imp___wc_mb_cur` +# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 +# CHECK: Mod 0001 | `* Linker *`: + +--- !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_GDATA32 + DataSym: + Type: 112 + DisplayName: __imp___wc_mb_cur + - !StringTable + Strings: + Relocations: + - VirtualAddress: 20 + SymbolName: __imp___wc_mb_cur + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 24 + SymbolName: __imp___wc_mb_cur + Type: IMAGE_REL_AMD64_SECTION + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 488B05000000000FBE00C3 + Relocations: + - VirtualAddress: 3 + SymbolName: __imp___wc_mb_cur + Type: IMAGE_REL_AMD64_REL32 + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: B82A000000C3 +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: 240 + NumberOfRelocations: 2 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.text$mn' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 11 + NumberOfRelocations: 1 + NumberOfLinenumbers: 0 + CheckSum: 2906070869 + Number: 0 + Selection: IMAGE_COMDAT_SELECT_NODUPLICATES + - Name: '.text$mn' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 6 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2139436471 + Number: 0 + Selection: IMAGE_COMDAT_SELECT_NODUPLICATES + - Name: discarded + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: main + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: __imp___wc_mb_cur + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/test/COFF/pdb-safeseh.yaml b/test/COFF/pdb-safeseh.yaml index 9faa5042924d..24215bd11dbe 100644 --- a/test/COFF/pdb-safeseh.yaml +++ b/test/COFF/pdb-safeseh.yaml @@ -8,28 +8,28 @@ # MSVC's for these absolute, linker-provided symbols. # CHECK: Mod 0000 | -# CHECK-NEXT: - S_GDATA32 [size = 40] `___safe_se_handler_table` +# CHECK-NEXT: 4 | S_GDATA32 [size = 40] `___safe_se_handler_table` # CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 # CHECK-NEXT: Mod 0001 | `* Linker *`: --- !COFF -header: +header: Machine: IMAGE_FILE_MACHINE_I386 Characteristics: [ ] -sections: +sections: - Name: '.debug$S' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 1 - Subsections: + Subsections: - !Symbols - Records: + Records: - Kind: S_GDATA32 - DataSym: + DataSym: Type: 34 DisplayName: ___safe_se_handler_table - !StringTable - Strings: - Relocations: + Strings: + Relocations: - VirtualAddress: 20 SymbolName: ___safe_se_handler_table Type: IMAGE_REL_I386_SECREL @@ -40,18 +40,18 @@ sections: Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] Alignment: 16 SectionData: 488D0500000000C3 - Relocations: + Relocations: - VirtualAddress: 3 SymbolName: ___safe_se_handler_table Type: IMAGE_REL_I386_REL32 -symbols: +symbols: - Name: '.debug$S' Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: + SectionDefinition: Length: 372 NumberOfRelocations: 6 NumberOfLinenumbers: 0 @@ -63,7 +63,7 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: + SectionDefinition: Length: 8 NumberOfRelocations: 1 NumberOfLinenumbers: 0 diff --git a/test/COFF/pdb-secrel-absolute.yaml b/test/COFF/pdb-secrel-absolute.yaml index d74f07e32b98..c514e54e99f1 100644 --- a/test/COFF/pdb-secrel-absolute.yaml +++ b/test/COFF/pdb-secrel-absolute.yaml @@ -8,28 +8,28 @@ # MSVC's for these absolute, linker-provided symbols. # CHECK: Mod 0000 | -# CHECK-NEXT: - S_GDATA32 [size = 36] `__guard_fids_table` +# CHECK-NEXT: 4 | S_GDATA32 [size = 36] `__guard_fids_table` # CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 # CHECK-NEXT: Mod 0001 | `* Linker *`: --- !COFF -header: +header: Machine: IMAGE_FILE_MACHINE_AMD64 Characteristics: [ ] -sections: +sections: - Name: '.debug$S' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 1 - Subsections: + Subsections: - !Symbols - Records: + Records: - Kind: S_GDATA32 - DataSym: + DataSym: Type: 34 DisplayName: __guard_fids_table - !StringTable - Strings: - Relocations: + Strings: + Relocations: - VirtualAddress: 20 SymbolName: __guard_fids_table Type: IMAGE_REL_AMD64_SECREL @@ -40,18 +40,18 @@ sections: Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] Alignment: 16 SectionData: 488D0500000000C3 - Relocations: + Relocations: - VirtualAddress: 3 SymbolName: __guard_fids_table Type: IMAGE_REL_AMD64_REL32 -symbols: +symbols: - Name: '.debug$S' Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: + SectionDefinition: Length: 372 NumberOfRelocations: 6 NumberOfLinenumbers: 0 @@ -63,7 +63,7 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: + SectionDefinition: Length: 8 NumberOfRelocations: 1 NumberOfLinenumbers: 0 diff --git a/test/COFF/pdb-symbol-types.yaml b/test/COFF/pdb-symbol-types.yaml index 4951aa8be379..eceb434f0d0f 100644 --- a/test/COFF/pdb-symbol-types.yaml +++ b/test/COFF/pdb-symbol-types.yaml @@ -16,33 +16,33 @@ # CHECK: Symbols # CHECK: ============================================================ # CHECK-LABEL: Mod 0000 | `{{.*}}pdb-symbol-types.yaml.tmp.obj`: -# CHECK: - S_OBJNAME [size = 52] sig=0, `C:\src\llvm-project\build\symbol-types.obj` -# CHECK: - 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: - S_GPROC32_ID [size = 44] `main` -# CHECK: parent = 0, addr = 0002:0000, code size = 7, end = 0 -# CHECK: debug start = 0, debug end = 6, flags = none -# CHECK: - 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: - S_END [size = 4] -# CHECK: - S_GDATA32 [size = 28] `global_foo` -# CHECK: type = 0x1004 (Foo), addr = 0001:0000 -# CHECK: - S_UDT [size = 16] `UDT_Foo` -# CHECK: original type = 0x1004 -# CHECK: - S_UDT [size = 12] `Foo` -# CHECK: original type = 0x1004 -# CHECK: - S_BUILDINFO [size = 8] BuildId = `4106` +# 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 = 0, 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-LABEL: Mod 0001 | `* Linker *`: --- !COFF -header: +header: Machine: IMAGE_FILE_MACHINE_AMD64 Characteristics: [ ] -sections: +sections: - Name: .drectve Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] Alignment: 1 @@ -50,15 +50,15 @@ sections: - Name: '.debug$S' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 1 - Subsections: + Subsections: - !Symbols - Records: + Records: - Kind: S_OBJNAME - ObjNameSym: + ObjNameSym: Signature: 0 ObjectName: 'C:\src\llvm-project\build\symbol-types.obj' - Kind: S_COMPILE3 - Compile3Sym: + Compile3Sym: Flags: [ SecurityChecks, HotPatch ] Machine: X64 FrontendMajor: 19 @@ -71,9 +71,9 @@ sections: BackendQFE: 1 Version: 'Microsoft (R) Optimizing Compiler' - !Symbols - Records: + Records: - Kind: S_GPROC32_ID - ProcSym: + ProcSym: CodeSize: 7 DbgStart: 0 DbgEnd: 6 @@ -81,7 +81,7 @@ sections: Flags: [ ] DisplayName: main - Kind: S_FRAMEPROC - FrameProcSym: + FrameProcSym: TotalFrameBytes: 0 PaddingFrameBytes: 0 OffsetToPadding: 0 @@ -90,15 +90,15 @@ sections: SectionIdOfExceptionHandler: 0 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] - Kind: S_PROC_ID_END - ScopeEndSym: + ScopeEndSym: - !Lines CodeSize: 7 Flags: [ ] RelocOffset: 0 RelocSegment: 0 - Blocks: + Blocks: - FileName: 'c:\src\llvm-project\build\symbol-types.c' - Lines: + Lines: - Offset: 0 LineStart: 4 IsStatement: true @@ -111,35 +111,35 @@ sections: LineStart: 6 IsStatement: true EndDelta: 0 - Columns: + Columns: - !Symbols - Records: + Records: - Kind: S_GDATA32 - DataSym: + DataSym: Type: 4101 DisplayName: global_foo - Kind: S_UDT - UDTSym: + UDTSym: Type: 4101 UDTName: UDT_Foo - Kind: S_UDT - UDTSym: + UDTSym: Type: 4101 UDTName: Foo - !FileChecksums - Checksums: + Checksums: - FileName: 'c:\src\llvm-project\build\symbol-types.c' Kind: MD5 Checksum: F833E1A4909FF6FEC5689A664F3BE725 - !StringTable - Strings: + Strings: - 'c:\src\llvm-project\build\symbol-types.c' - !Symbols - Records: + Records: - Kind: S_BUILDINFO - BuildInfoSym: + BuildInfoSym: BuildId: 4111 - Relocations: + Relocations: - VirtualAddress: 164 SymbolName: main Type: IMAGE_REL_AMD64_SECREL @@ -161,24 +161,24 @@ sections: - Name: '.debug$T' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 1 - Types: + Types: - Kind: LF_ARGLIST - ArgList: + ArgList: ArgIndices: [ 0 ] - Kind: LF_PROCEDURE - Procedure: + Procedure: ReturnType: 116 CallConv: NearC Options: [ None ] ParameterCount: 0 ArgumentList: 4096 - Kind: LF_FUNC_ID - FuncId: + FuncId: ParentScope: 0 FunctionType: 4097 Name: main - Kind: LF_STRUCTURE - Class: + Class: MemberCount: 0 Options: [ None, ForwardReference, HasUniqueName ] FieldList: 0 @@ -188,15 +188,15 @@ sections: VTableShape: 0 Size: 0 - Kind: LF_FIELDLIST - FieldList: + FieldList: - Kind: LF_MEMBER - DataMember: + DataMember: Attrs: 3 Type: 116 FieldOffset: 0 Name: x - Kind: LF_STRUCTURE - Class: + Class: MemberCount: 1 Options: [ None, HasUniqueName ] FieldList: 4100 @@ -206,43 +206,43 @@ sections: VTableShape: 0 Size: 4 - Kind: LF_STRING_ID - StringId: + StringId: Id: 0 String: 'c:\src\llvm-project\build\symbol-types.c' - Kind: LF_UDT_SRC_LINE - UdtSourceLine: + UdtSourceLine: UDT: 4101 SourceFile: 4102 LineNumber: 1 - Kind: LF_STRING_ID - StringId: + StringId: Id: 0 String: 'C:\src\llvm-project\build' - Kind: LF_STRING_ID - StringId: + StringId: Id: 0 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe' - Kind: LF_STRING_ID - StringId: + 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: + StringList: StringIndices: [ 4106 ] - Kind: LF_STRING_ID - StringId: + StringId: Id: 4107 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X' - Kind: LF_STRING_ID - StringId: + StringId: Id: 0 String: symbol-types.c - Kind: LF_STRING_ID - StringId: + StringId: Id: 0 String: 'C:\src\llvm-project\build\vc140.pdb' - Kind: LF_BUILDINFO - BuildInfo: + BuildInfo: ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ] - Name: .data Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] @@ -252,11 +252,11 @@ sections: Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] Alignment: 16 SectionData: 8B0500000000C3 - Relocations: + Relocations: - VirtualAddress: 2 SymbolName: global_foo Type: IMAGE_REL_AMD64_REL32 -symbols: +symbols: - Name: '@comp.id' Value: 17063575 SectionNumber: -1 @@ -275,7 +275,7 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: + SectionDefinition: Length: 47 NumberOfRelocations: 0 NumberOfLinenumbers: 0 @@ -287,7 +287,7 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: + SectionDefinition: Length: 432 NumberOfRelocations: 6 NumberOfLinenumbers: 0 @@ -299,7 +299,7 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: + SectionDefinition: Length: 732 NumberOfRelocations: 0 NumberOfLinenumbers: 0 @@ -311,7 +311,7 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: + SectionDefinition: Length: 4 NumberOfRelocations: 0 NumberOfLinenumbers: 0 @@ -329,7 +329,7 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: + SectionDefinition: Length: 7 NumberOfRelocations: 1 NumberOfLinenumbers: 0 diff --git a/test/COFF/reloc-discarded.s b/test/COFF/reloc-discarded.s new file mode 100644 index 000000000000..94eaba998330 --- /dev/null +++ b/test/COFF/reloc-discarded.s @@ -0,0 +1,30 @@ +# RUN: echo -e '.section .bss,"bw",discard,main_global\n.global main_global\n main_global:\n .long 0' | \ +# RUN: llvm-mc - -filetype=obj -o %t1.obj -triple x86_64-windows-msvc +# RUN: llvm-mc %s -filetype=obj -o %t2.obj -triple x86_64-windows-msvc + +# LLD should report an error and not assert regardless of whether we are doing +# GC. + +# RUN: not lld-link -entry:main -nodefaultlib %t1.obj %t2.obj -out:%t.exe -opt:ref 2>&1 | FileCheck %s +# RUN: not lld-link -entry:main -nodefaultlib %t1.obj %t2.obj -out:%t.exe -opt:noref 2>&1 | FileCheck %s + +# CHECK: error: relocation against symbol in discarded section: assoc_global + + .section .bss,"bw",discard,main_global + .globl main_global + .p2align 2 +main_global: + .long 0 + + .section .CRT$XCU,"dr",associative,main_global + .p2align 3 + .globl assoc_global +assoc_global: + .quad main_global + + .text + .globl main +main: + movq assoc_global(%rip), %rax + movl (%rax), %eax + retq diff --git a/test/COFF/resource.test b/test/COFF/resource.test index a73a20258201..53242cdcb63a 100644 --- a/test/COFF/resource.test +++ b/test/COFF/resource.test @@ -6,7 +6,39 @@ EXE: {{H.e.l.l.o}} -# RUN: llvm-readobj -file-headers %t.exe | FileCheck --check-prefix=HEADER %s +# Verify the resource tree layout in the final executable. +# RUN: llvm-readobj -file-headers -coff-resources -section-data %t.exe | \ +# RUN: FileCheck --check-prefix=RESOURCE_INFO %s -HEADER: ResourceTableRVA: 0x1000 -HEADER: ResourceTableSize: 0x88 +RESOURCE_INFO: ResourceTableRVA: 0x1000 +RESOURCE_INFO-NEXT: ResourceTableSize: 0x88 +RESOURCE_INFO-DAG: Resources [ +RESOURCE_INFO-NEXT: Total Number of Resources: 1 +RESOURCE_INFO-NEXT: Base Table Address: 0x400 +RESOURCE_INFO-DAG: Number of String Entries: 0 +RESOURCE_INFO-NEXT: Number of ID Entries: 1 +RESOURCE_INFO-NEXT: Type: kRT_STRING (ID 6) [ +RESOURCE_INFO-NEXT: Table Offset: 0x18 +RESOURCE_INFO-NEXT: Number of String Entries: 0 +RESOURCE_INFO-NEXT: Number of ID Entries: 1 +RESOURCE_INFO-NEXT: Name: (ID 1) [ +RESOURCE_INFO-NEXT: Table Offset: 0x30 +RESOURCE_INFO-NEXT: Number of String Entries: 0 +RESOURCE_INFO-NEXT: Number of ID Entries: 1 +RESOURCE_INFO-NEXT: Language: (ID 1033) [ +RESOURCE_INFO-NEXT: Entry Offset: 0x48 +RESOURCE_INFO-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +RESOURCE_INFO-NEXT: Major Version: 0 +RESOURCE_INFO-NEXT: Minor Version: 0 +RESOURCE_INFO-NEXT: Characteristics: 0 +RESOURCE_INFO-DAG: .rsrc Data ( +RESOURCE_INFO-NEXT: 0000: 00000000 00000000 00000000 00000100 |................| +RESOURCE_INFO-NEXT: 0010: 06000000 18000080 00000000 00000000 |................| +RESOURCE_INFO-NEXT: 0020: 00000000 00000100 01000000 30000080 |............0...| +RESOURCE_INFO-NEXT: 0030: 00000000 00000000 00000000 00000100 |................| +RESOURCE_INFO-NEXT: 0040: 09040000 48000000 58100000 2A000000 |....H...X...*...| +RESOURCE_INFO-NEXT: 0050: 00000000 00000000 00000500 48006500 |............H.e.| +RESOURCE_INFO-NEXT: 0060: 6C006C00 6F000000 00000000 00000000 |l.l.o...........| +RESOURCE_INFO-NEXT: 0070: 00000000 00000000 00000000 00000000 |................| +RESOURCE_INFO-NEXT: 0080: 00000000 00000000 |........| +RESOURCE_INFO-NEXT: ) diff --git a/test/COFF/secrel-absolute.s b/test/COFF/secrel-absolute.s index 69b5ab92991b..bc61fb94b6b0 100644 --- a/test/COFF/secrel-absolute.s +++ b/test/COFF/secrel-absolute.s @@ -3,7 +3,7 @@ # secrel relocations against absolute symbols are errors. -# CHECK: SECREL relocation points to a non-regular symbol: __guard_fids_table +# CHECK: SECREL relocation cannot be applied to absolute symbols .text .global main diff --git a/test/ELF/Inputs/dso-undef-size.s b/test/ELF/Inputs/dso-undef-size.s new file mode 100644 index 000000000000..424f56f82b72 --- /dev/null +++ b/test/ELF/Inputs/dso-undef-size.s @@ -0,0 +1,4 @@ +.text +.global foo +.size foo, 4 +foo: diff --git a/test/ELF/arm-exidx-canunwind.s b/test/ELF/arm-exidx-canunwind.s index e98ec0ec8978..96a7808e8e84 100644 --- a/test/ELF/arm-exidx-canunwind.s +++ b/test/ELF/arm-exidx-canunwind.s @@ -72,7 +72,7 @@ _start: // CHECK-EXIDX-NEXT: 100d4 380f0000 08849780 340f0000 0c000000 // 100e4 + f30 = 11014 = terminate = func2 + sizeof(func2) // CHECK-EXIDX-NEXT: 100e4 300f0000 01000000 -// CHECK-EXIDX-NEXT: Contents of section .ARM.extab.text.func2: +// CHECK-EXIDX-NEXT: Contents of section .ARM.extab: // 100ec + f28 = 11014 = __gxx_personality_v0 // CHECK-EXIDX-NEXT: 100ec 280f0000 b0b0b000 00000000 diff --git a/test/ELF/arm-exidx-gc.s b/test/ELF/arm-exidx-gc.s index b1a5be54aa2b..1336c256f7c1 100644 --- a/test/ELF/arm-exidx-gc.s +++ b/test/ELF/arm-exidx-gc.s @@ -110,16 +110,15 @@ _start: // CHECK-NOT: unusedfunc2 // CHECK-NOT: __gxx_personality_v1 -// CHECK-EXIDX-NOT: Contents of section .ARM.extab.text.unusedfunc2: // CHECK-EXIDX: Contents of section .ARM.exidx: // 100d4 + f38 = 1100c = func1 -// 100dc + f34 = 11010 = func2 (100e0 + 1c = 100fc = .ARM.extab.text.func2) +// 100dc + f34 = 11010 = func2 (100e0 + 1c = 100fc = .ARM.extab) // CHECK-EXIDX-NEXT: 100d4 380f0000 08849780 340f0000 1c000000 // 100e4 + f30 = 11014 = __gxx_personality_v0 // 100ec + f2c = 11018 = __aeabi_unwind_cpp_pr0 // CHECK-EXIDX-NEXT: 100e4 300f0000 01000000 2c0f0000 01000000 // 100f4 + f28 = 1101c = __aeabi_unwind_cpp_pr0 + sizeof(__aeabi_unwind_cpp_pr0) // CHECK-EXIDX-NEXT: 100f4 280f0000 01000000 -// CHECK-EXIDX-NEXT: Contents of section .ARM.extab.text.func2: +// CHECK-EXIDX-NEXT: Contents of section .ARM.extab: // 100fc + f18 = 11014 = __gxx_personality_v0 // CHECK-EXIDX-NEXT: 100fc 180f0000 b0b0b000 diff --git a/test/ELF/arm-exidx-shared.s b/test/ELF/arm-exidx-shared.s index 13628405ed35..e06733352a37 100644 --- a/test/ELF/arm-exidx-shared.s +++ b/test/ELF/arm-exidx-shared.s @@ -40,6 +40,6 @@ __aeabi_unwind_cpp_pr0: // CHECK-NEXT: Section (6) .rel.plt { // CHECK-NEXT: 0x200C R_ARM_JUMP_SLOT __gxx_personality_v0 -// CHECK-EXTAB: Contents of section .ARM.extab.text.func2: +// CHECK-EXTAB: Contents of section .ARM.extab: // 014c + 0ed8 = 0x1024 = __gxx_personality_v0(PLT) // CHECK-EXTAB-NEXT: 014c d80e0000 b0b0b000 00000000 diff --git a/test/ELF/basic-sparcv9.s b/test/ELF/basic-sparcv9.s new file mode 100644 index 000000000000..983224c52913 --- /dev/null +++ b/test/ELF/basic-sparcv9.s @@ -0,0 +1,200 @@ +# RUN: llvm-mc -filetype=obj -triple=sparc64-unknown-openbsd %s -o %t +# RUN: ld.lld %t -o %t2 +# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \ +# RUN: | FileCheck %s +# REQUIRES: sparc + +# exits with return code 42 on OpenBSD/sparc64 +.global _start +_start: + mov 42, %o0 + mov 1, %g1 + ta 0 + +# CHECK: ElfHeader { +# CHECK-NEXT: Ident { +# CHECK-NEXT: Magic: (7F 45 4C 46) +# CHECK-NEXT: Class: 64-bit (0x2) +# CHECK-NEXT: DataEncoding: BigEndian (0x2) +# CHECK-NEXT: FileVersion: 1 +# CHECK-NEXT: OS/ABI: SystemV (0x0) +# CHECK-NEXT: ABIVersion: 0 +# CHECK-NEXT: Unused: (00 00 00 00 00 00 00) +# CHECK-NEXT: } +# CHECK-NEXT: Type: Executable (0x2) +# CHECK-NEXT: Machine: EM_SPARCV9 (0x2B) +# CHECK-NEXT: Version: 1 +# CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]] +# CHECK-NEXT: ProgramHeaderOffset: 0x40 +# CHECK-NEXT: SectionHeaderOffset: 0x100080 +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: HeaderSize: 64 +# CHECK-NEXT: ProgramHeaderEntrySize: 56 +# CHECK-NEXT: ProgramHeaderCount: 4 +# CHECK-NEXT: SectionHeaderEntrySize: 64 +# CHECK-NEXT: SectionHeaderCount: 6 +# CHECK-NEXT: StringTableSectionIndex: 4 +# CHECK-NEXT: } +# CHECK-NEXT: Sections [ +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 0 +# CHECK-NEXT: Name: (0) +# CHECK-NEXT: Type: SHT_NULL (0x0) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 0 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 1 +# CHECK-NEXT: Name: .text +# CHECK-NEXT: Type: SHT_PROGBITS (0x1) +# CHECK-NEXT: Flags [ (0x6) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: SHF_EXECINSTR (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x200000 +# CHECK-NEXT: Offset: 0x100000 +# CHECK-NEXT: Size: 12 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 4 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .comment +# CHECK-NEXT: Type: SHT_PROGBITS (0x1) +# CHECK-NEXT: Flags [ (0x30) +# CHECK-NEXT: SHF_MERGE (0x10) +# CHECK-NEXT: SHF_STRINGS (0x20) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x10000C +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Name: .symtab +# CHECK-NEXT: Type: SHT_SYMTAB (0x2) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x100018 +# CHECK-NEXT: Size: 48 +# CHECK-NEXT: Link: 5 +# CHECK-NEXT: Info: 1 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 24 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 4 +# CHECK-NEXT: Name: .shstrtab +# CHECK-NEXT: Type: SHT_STRTAB (0x3) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x100048 +# CHECK-NEXT: Size: 42 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 5 +# CHECK-NEXT: Name: .strtab +# CHECK-NEXT: Type: SHT_STRTAB (0x3) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x100072 +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Symbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: (0) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local (0x0) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _start +# CHECK-NEXT: Value: [[ENTRY]] +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0x100040 +# CHECK-NEXT: PhysicalAddress: 0x100040 +# CHECK-NEXT: FileSize: 224 +# CHECK-NEXT: MemSize: 224 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x100000 +# CHECK-NEXT: PhysicalAddress: 0x100000 +# CHECK-NEXT: FileSize: 288 +# CHECK-NEXT: MemSize: 288 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 1048576 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x100000 +# CHECK-NEXT: VirtualAddress: 0x200000 +# CHECK-NEXT: PhysicalAddress: 0x200000 +# CHECK-NEXT: FileSize: 12 +# CHECK-NEXT: MemSize: 12 +# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_X (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 1048576 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_GNU_STACK +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x0 +# CHECK-NEXT: PhysicalAddress: 0x0 +# CHECK-NEXT: FileSize: 0 +# CHECK-NEXT: MemSize: 0 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_W +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 0 +# CHECK-NEXT: } +# CHECK-NEXT: ] diff --git a/test/ELF/dso-undef-size.s b/test/ELF/dso-undef-size.s new file mode 100644 index 000000000000..5a235565bbc9 --- /dev/null +++ b/test/ELF/dso-undef-size.s @@ -0,0 +1,32 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/dso-undef-size.s -o %t1.o +# RUN: ld.lld -shared %t1.o -o %t1.so +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o +# RUN: ld.lld -shared %t2.o %t1.so -o %t2.so +# RUN: llvm-readobj -symbols -dyn-symbols %t2.so + +# CHECK: Symbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: foo +# CHECK-NEXT: Value: +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: +# CHECK-NEXT: Type: +# CHECK-NEXT: Other: +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: foo +# CHECK-NEXT: Value: +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: +# CHECK-NEXT: Type: +# CHECK-NEXT: Other: +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.text +.global foo diff --git a/test/ELF/linkerscript/data-commands-gc.s b/test/ELF/linkerscript/data-commands-gc.s index 46ce6a97cf75..1afcc9a3bb81 100644 --- a/test/ELF/linkerscript/data-commands-gc.s +++ b/test/ELF/linkerscript/data-commands-gc.s @@ -1,9 +1,10 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { .text : { *(.text*) QUAD(bar) } }" > %t.script -# RUN: ld.lld --gc-sections -o %t %t.o --script %t.script | FileCheck -allow-empty %s +# RUN: ld.lld --gc-sections -o %t %t.o --script %t.script +# RUN: llvm-objdump -t %t | FileCheck %s -# CHECK-NOT: unable to evaluate expression: input section .rodata.bar has no output section assigned +# CHECK: 0000000000000011 .rodata 00000000 bar .section .rodata.bar .quad 0x1122334455667788 diff --git a/test/ELF/relocatable-script.s b/test/ELF/relocatable-script.s new file mode 100644 index 000000000000..133d61f48056 --- /dev/null +++ b/test/ELF/relocatable-script.s @@ -0,0 +1,7 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t1.o %s +# RUN: echo "SECTIONS { .foo : { BYTE(0x0) } }" > %t.script +# RUN: ld.lld -r %t1.o -script %t.script -o %t2.o +# RUN: llvm-readobj -sections %t2.o | FileCheck %s + +# CHECK: Name: .foo diff --git a/test/ELF/version-script-symver.s b/test/ELF/version-script-symver.s new file mode 100644 index 000000000000..7798330b053d --- /dev/null +++ b/test/ELF/version-script-symver.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "VERSION { global: *; };" > %t.map +# RUN: ld.lld %t.o --version-script %t.map -o %t + +.global _start +.global bar +.symver _start, bar@@VERSION +_start: + jmp bar diff --git a/test/lit.cfg b/test/lit.cfg index 0cb62d4cab97..cba56c642907 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -245,18 +245,20 @@ if re.search(r'ON', llvm_config_output_list[1]): archs = llvm_config_output_list[2] if re.search(r'AArch64', archs): config.available_features.add('aarch64') +if re.search(r'AMDGPU', archs): + config.available_features.add('amdgpu') if re.search(r'ARM', archs): config.available_features.add('arm') if re.search(r'AVR', archs): config.available_features.add('avr') if re.search(r'Mips', archs): config.available_features.add('mips') -if re.search(r'X86', archs): - config.available_features.add('x86') if re.search(r'PowerPC', archs): config.available_features.add('ppc') -if re.search(r'AMDGPU', archs): - config.available_features.add('amdgpu') +if re.search(r'Sparc', archs): + config.available_features.add('sparc') +if re.search(r'X86', archs): + config.available_features.add('x86') llvm_config_cmd.wait() # Set a fake constant version so that we get consitent output. |