Date: Sat, 1 Jul 2017 13:24:45 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r320541 - in vendor/lld/dist: COFF ELF ELF/Arch lib/ReaderWriter/MachO test test/COFF test/COFF/Inputs test/ELF test/ELF/Inputs test/ELF/linkerscript Message-ID: <201707011324.v61DOjMm022416@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Sat Jul 1 13:24:45 2017 New Revision: 320541 URL: https://svnweb.freebsd.org/changeset/base/320541 Log: Vendor import of lld trunk r306956: https://llvm.org/svn/llvm-project/lld/trunk@306956 Added: vendor/lld/dist/ELF/Arch/SPARCV9.cpp (contents, props changed) vendor/lld/dist/test/COFF/Inputs/combined-resources-2.rc vendor/lld/dist/test/COFF/Inputs/combined-resources-2.res (contents, props changed) vendor/lld/dist/test/COFF/Inputs/combined-resources-cursor.bmp (contents, props changed) vendor/lld/dist/test/COFF/Inputs/combined-resources-okay.bmp (contents, props changed) vendor/lld/dist/test/COFF/Inputs/combined-resources.rc vendor/lld/dist/test/COFF/Inputs/combined-resources.res (contents, props changed) vendor/lld/dist/test/COFF/Inputs/pdb-global-gc.s (contents, props changed) vendor/lld/dist/test/COFF/Inputs/pdb-import-gc.lib (contents, props changed) vendor/lld/dist/test/COFF/combined-resources.test vendor/lld/dist/test/COFF/pdb-global-gc.yaml vendor/lld/dist/test/COFF/pdb-import-gc.yaml vendor/lld/dist/test/COFF/reloc-discarded.s (contents, props changed) vendor/lld/dist/test/ELF/Inputs/dso-undef-size.s (contents, props changed) vendor/lld/dist/test/ELF/basic-sparcv9.s (contents, props changed) vendor/lld/dist/test/ELF/dso-undef-size.s (contents, props changed) vendor/lld/dist/test/ELF/relocatable-script.s (contents, props changed) vendor/lld/dist/test/ELF/version-script-symver.s (contents, props changed) Modified: vendor/lld/dist/COFF/Chunks.cpp vendor/lld/dist/COFF/Chunks.h vendor/lld/dist/COFF/Driver.h vendor/lld/dist/COFF/MarkLive.cpp vendor/lld/dist/COFF/Symbols.h vendor/lld/dist/COFF/Writer.cpp vendor/lld/dist/ELF/CMakeLists.txt vendor/lld/dist/ELF/InputFiles.cpp vendor/lld/dist/ELF/SymbolTable.cpp vendor/lld/dist/ELF/SymbolTable.h vendor/lld/dist/ELF/Symbols.cpp vendor/lld/dist/ELF/Symbols.h vendor/lld/dist/ELF/SyntheticSections.cpp vendor/lld/dist/ELF/Target.cpp vendor/lld/dist/ELF/Target.h vendor/lld/dist/ELF/Writer.cpp vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp vendor/lld/dist/test/COFF/hello32.test vendor/lld/dist/test/COFF/pdb-comdat.test vendor/lld/dist/test/COFF/pdb-safeseh.yaml vendor/lld/dist/test/COFF/pdb-secrel-absolute.yaml vendor/lld/dist/test/COFF/pdb-symbol-types.yaml vendor/lld/dist/test/COFF/resource.test vendor/lld/dist/test/COFF/secrel-absolute.s vendor/lld/dist/test/ELF/arm-exidx-canunwind.s vendor/lld/dist/test/ELF/arm-exidx-gc.s vendor/lld/dist/test/ELF/arm-exidx-shared.s vendor/lld/dist/test/ELF/linkerscript/data-commands-gc.s vendor/lld/dist/test/lit.cfg Modified: vendor/lld/dist/COFF/Chunks.cpp ============================================================================== --- vendor/lld/dist/COFF/Chunks.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/COFF/Chunks.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -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 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); } -void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym, - uint64_t P) const { - uint64_t S = Sym->getRVA(); +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; @@ -74,23 +84,22 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t 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"); Modified: vendor/lld/dist/COFF/Chunks.h ============================================================================== --- vendor/lld/dist/COFF/Chunks.h Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/COFF/Chunks.h Sat Jul 1 13:24:45 2017 (r320541) @@ -145,9 +145,12 @@ class SectionChunk : public Chunk { (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. Modified: vendor/lld/dist/COFF/Driver.h ============================================================================== --- vendor/lld/dist/COFF/Driver.h Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/COFF/Driver.h Sat Jul 1 13:24:45 2017 (r320541) @@ -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); Modified: vendor/lld/dist/COFF/MarkLive.cpp ============================================================================== --- vendor/lld/dist/COFF/MarkLive.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/COFF/MarkLive.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -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. Modified: vendor/lld/dist/COFF/Symbols.h ============================================================================== --- vendor/lld/dist/COFF/Symbols.h Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/COFF/Symbols.h Sat Jul 1 13:24:45 2017 (r320541) @@ -110,17 +110,9 @@ class Defined : public SymbolBody { (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 @@ class DefinedRegular : public DefinedCOFF { (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 @@ class DefinedCommon : public DefinedCOFF { (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 @@ class DefinedAbsolute : public Defined { (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 @@ class DefinedSynthetic : public Defined { (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 @@ class DefinedImportData : public Defined { (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; @@ -374,6 +366,29 @@ inline uint64_t Defined::getRVA() { case LazyKind: case UndefinedKind: llvm_unreachable("Cannot get the address for an undefined symbol."); + } + 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"); } Modified: vendor/lld/dist/COFF/Writer.cpp ============================================================================== --- vendor/lld/dist/COFF/Writer.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/COFF/Writer.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -120,7 +120,6 @@ class Writer { (private) void writeSections(); void sortExceptionTable(); void writeBuildId(); - void applyRelocations(); llvm::Optional<coff_symbol16> createSymbol(Defined *D); size_t addEntryToStringTable(StringRef Str); @@ -208,55 +207,6 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) { strncpy(Hdr->Name, Name.data(), std::min(Name.size(), (size_t)COFF::NameSize)); } -} - -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 Added: vendor/lld/dist/ELF/Arch/SPARCV9.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist/ELF/Arch/SPARCV9.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -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; +} Modified: vendor/lld/dist/ELF/CMakeLists.txt ============================================================================== --- vendor/lld/dist/ELF/CMakeLists.txt Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/CMakeLists.txt Sat Jul 1 13:24:45 2017 (r320541) @@ -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 Modified: vendor/lld/dist/ELF/InputFiles.cpp ============================================================================== --- vendor/lld/dist/ELF/InputFiles.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/InputFiles.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -79,9 +79,9 @@ template <class ELFT> void elf::ObjectFile<ELFT>::init 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 Modified: vendor/lld/dist/ELF/SymbolTable.cpp ============================================================================== --- vendor/lld/dist/ELF/SymbolTable.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/SymbolTable.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -195,14 +195,8 @@ template <class ELFT> void SymbolTable<ELFT>::applySym 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(SymbolVe 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(); Modified: vendor/lld/dist/ELF/SymbolTable.h ============================================================================== --- vendor/lld/dist/ELF/SymbolTable.h Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/SymbolTable.h Sat Jul 1 13:24:45 2017 (r320541) @@ -18,7 +18,7 @@ namespace lld { namespace elf { -class Lazy; + struct Symbol; // SymbolTable is a bucket of all known symbols, including defined, Modified: vendor/lld/dist/ELF/Symbols.cpp ============================================================================== --- vendor/lld/dist/ELF/Symbols.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/Symbols.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -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; Modified: vendor/lld/dist/ELF/Symbols.h ============================================================================== --- vendor/lld/dist/ELF/Symbols.h Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/Symbols.h Sat Jul 1 13:24:45 2017 (r320541) @@ -69,9 +69,9 @@ class SymbolBody { (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; } Modified: vendor/lld/dist/ELF/SyntheticSections.cpp ============================================================================== --- vendor/lld/dist/ELF/SyntheticSections.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/SyntheticSections.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -1090,8 +1090,17 @@ template <class ELFT> void DynamicSection<ELFT>::final 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>::w } 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>::w 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>::wri 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 Modified: vendor/lld/dist/ELF/Target.cpp ============================================================================== --- vendor/lld/dist/ELF/Target.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/Target.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -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(); Modified: vendor/lld/dist/ELF/Target.h ============================================================================== --- vendor/lld/dist/ELF/Target.h Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/Target.h Sat Jul 1 13:24:45 2017 (r320541) @@ -112,6 +112,7 @@ TargetInfo *getARMTargetInfo(); TargetInfo *getAVRTargetInfo(); TargetInfo *getPPC64TargetInfo(); TargetInfo *getPPCTargetInfo(); +TargetInfo *getSPARCV9TargetInfo(); TargetInfo *getX32TargetInfo(); TargetInfo *getX86TargetInfo(); TargetInfo *getX86_64TargetInfo(); Modified: vendor/lld/dist/ELF/Writer.cpp ============================================================================== --- vendor/lld/dist/ELF/Writer.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/ELF/Writer.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -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,13 +1014,13 @@ 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)) Modified: vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp ============================================================================== --- vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp Sat Jul 1 13:24:45 2017 (r320541) @@ -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) Added: vendor/lld/dist/test/COFF/Inputs/combined-resources-2.rc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist/test/COFF/Inputs/combined-resources-2.rc Sat Jul 1 13:24:45 2017 (r320541) @@ -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 +} Added: vendor/lld/dist/test/COFF/Inputs/combined-resources-2.res ============================================================================== Binary file. No diff available. Added: vendor/lld/dist/test/COFF/Inputs/combined-resources-cursor.bmp ============================================================================== Binary file. No diff available. Added: vendor/lld/dist/test/COFF/Inputs/combined-resources-okay.bmp ============================================================================== Binary file. No diff available. Added: vendor/lld/dist/test/COFF/Inputs/combined-resources.rc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist/test/COFF/Inputs/combined-resources.rc Sat Jul 1 13:24:45 2017 (r320541) @@ -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", +} Added: vendor/lld/dist/test/COFF/Inputs/combined-resources.res ============================================================================== Binary file. No diff available. Added: vendor/lld/dist/test/COFF/Inputs/pdb-global-gc.s ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist/test/COFF/Inputs/pdb-global-gc.s Sat Jul 1 13:24:45 2017 (r320541) @@ -0,0 +1,4 @@ +.section .data,"dw",one_only,__wc_mb_cur +.global __wc_mb_cur +__wc_mb_cur: +.long 42 Added: vendor/lld/dist/test/COFF/Inputs/pdb-import-gc.lib ============================================================================== Binary file. No diff available. Added: vendor/lld/dist/test/COFF/combined-resources.test ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist/test/COFF/combined-resources.test Sat Jul 1 13:24:45 2017 (r320541) @@ -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 Modified: vendor/lld/dist/test/COFF/hello32.test ============================================================================== --- vendor/lld/dist/test/COFF/hello32.test Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/test/COFF/hello32.test Sat Jul 1 13:24:45 2017 (r320541) @@ -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 Modified: vendor/lld/dist/test/COFF/pdb-comdat.test ============================================================================== --- vendor/lld/dist/test/COFF/pdb-comdat.test Sat Jul 1 13:24:41 2017 (r320540) +++ vendor/lld/dist/test/COFF/pdb-comdat.test Sat Jul 1 13:24:45 2017 (r320541) @@ -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. Added: vendor/lld/dist/test/COFF/pdb-global-gc.yaml ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist/test/COFF/pdb-global-gc.yaml Sat Jul 1 13:24:45 2017 (r320541) @@ -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`: *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201707011324.v61DOjMm022416>