Date: Wed, 6 Jan 2016 20:07:14 +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: r293258 - in vendor/lld/dist: ELF lib/ReaderWriter/MachO test/ELF test/mach-o Message-ID: <201601062007.u06K7EWq084741@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Wed Jan 6 20:07:13 2016 New Revision: 293258 URL: https://svnweb.freebsd.org/changeset/base/293258 Log: Vendor import of lld trunk r256945: https://llvm.org/svn/llvm-project/lld/trunk@256945 Added: vendor/lld/dist/test/ELF/dt_tags.s (contents, props changed) vendor/lld/dist/test/mach-o/arm64-section-order.yaml Modified: vendor/lld/dist/ELF/Config.h vendor/lld/dist/ELF/Driver.cpp vendor/lld/dist/ELF/Driver.h vendor/lld/dist/ELF/InputFiles.cpp vendor/lld/dist/ELF/InputFiles.h vendor/lld/dist/ELF/InputSection.h vendor/lld/dist/ELF/MarkLive.cpp vendor/lld/dist/ELF/OutputSections.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/Target.cpp vendor/lld/dist/ELF/Writer.cpp vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp vendor/lld/dist/test/ELF/dynamic-reloc.s vendor/lld/dist/test/ELF/got.s vendor/lld/dist/test/ELF/local-got.s vendor/lld/dist/test/ELF/relocation-i686.s vendor/lld/dist/test/ELF/relocation.s vendor/lld/dist/test/ELF/relro.s vendor/lld/dist/test/ELF/shared-be.s vendor/lld/dist/test/ELF/shared.s vendor/lld/dist/test/ELF/tls-got.s vendor/lld/dist/test/ELF/tls-opt-gdie.s vendor/lld/dist/test/ELF/tls-opt-gdiele-i686.s vendor/lld/dist/test/ELF/tls-opt-iele-i686-nopic.s vendor/lld/dist/test/mach-o/arm64-reloc-negDelta32-fixup.yaml vendor/lld/dist/test/mach-o/parse-data-relocs-x86_64.yaml Modified: vendor/lld/dist/ELF/Config.h ============================================================================== --- vendor/lld/dist/ELF/Config.h Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/Config.h Wed Jan 6 20:07:13 2016 (r293258) @@ -30,6 +30,10 @@ enum ELFKind { ELF64BEKind }; +// This struct contains the global configuration for the linker. +// Most fields are direct mapping from the command line options +// and such fields have the same name as the corresponding options. +// Most fields are initialized by the driver. struct Configuration { SymbolBody *EntrySym = nullptr; SymbolBody *MipsGpDisp = nullptr; @@ -76,6 +80,7 @@ struct Configuration { unsigned Optimize = 0; }; +// The only instance of Configuration struct. extern Configuration *Config; } // namespace elf2 Modified: vendor/lld/dist/ELF/Driver.cpp ============================================================================== --- vendor/lld/dist/ELF/Driver.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/Driver.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -57,6 +57,24 @@ static std::pair<ELFKind, uint16_t> pars error("Unknown emulation: " + S); } +// Returns slices of MB by parsing MB as an archive file. +// Each slice consists of a member file in the archive. +static std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef MB) { + ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB); + error(FileOrErr, "Failed to parse archive"); + std::unique_ptr<Archive> File = std::move(*FileOrErr); + + std::vector<MemoryBufferRef> V; + for (const ErrorOr<Archive::Child> &C : File->children()) { + error(C, "Could not get the child of the archive " + File->getFileName()); + ErrorOr<MemoryBufferRef> MbOrErr = C->getMemoryBufferRef(); + error(MbOrErr, "Could not get the buffer for a child of the archive " + + File->getFileName()); + V.push_back(*MbOrErr); + } + return V; +} + // Opens and parses a file. Path has to be resolved already. // Newly created memory buffers are owned by this driver. void LinkerDriver::addFile(StringRef Path) { @@ -75,19 +93,17 @@ void LinkerDriver::addFile(StringRef Pat return; case file_magic::archive: if (WholeArchive) { - auto File = make_unique<ArchiveFile>(MBRef); - for (MemoryBufferRef &MB : File->getMembers()) - Files.push_back(createELFFile<ObjectFile>(MB)); - OwningArchives.emplace_back(std::move(File)); + for (MemoryBufferRef MB : getArchiveMembers(MBRef)) + Files.push_back(createObjectFile(MB)); return; } Files.push_back(make_unique<ArchiveFile>(MBRef)); return; case file_magic::elf_shared_object: - Files.push_back(createELFFile<SharedFile>(MBRef)); + Files.push_back(createSharedFile(MBRef)); return; default: - Files.push_back(createELFFile<ObjectFile>(MBRef)); + Files.push_back(createObjectFile(MBRef)); } } Modified: vendor/lld/dist/ELF/Driver.h ============================================================================== --- vendor/lld/dist/ELF/Driver.h Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/Driver.h Wed Jan 6 20:07:13 2016 (r293258) @@ -38,7 +38,6 @@ private: llvm::BumpPtrAllocator Alloc; bool WholeArchive = false; std::vector<std::unique_ptr<InputFile>> Files; - std::vector<std::unique_ptr<ArchiveFile>> OwningArchives; std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs; }; Modified: vendor/lld/dist/ELF/InputFiles.cpp ============================================================================== --- vendor/lld/dist/ELF/InputFiles.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/InputFiles.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -37,10 +37,9 @@ ELFFileBase<ELFT>::ELFFileBase(Kind K, M template <class ELFT> ELFKind ELFFileBase<ELFT>::getELFKind() { - using llvm::support::little; - if (ELFT::Is64Bits) - return ELFT::TargetEndianness == little ? ELF64LEKind : ELF64BEKind; - return ELFT::TargetEndianness == little ? ELF32LEKind : ELF32BEKind; + if (ELFT::TargetEndianness == support::little) + return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind; + return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind; } template <class ELFT> @@ -63,8 +62,7 @@ template <class ELFT> uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const { uint32_t I = Sym.st_shndx; if (I == ELF::SHN_XINDEX) - return this->ELFObj.getExtendedSymbolTableIndex(&Sym, this->Symtab, - SymtabSHNDX); + return ELFObj.getExtendedSymbolTableIndex(&Sym, Symtab, SymtabSHNDX); if (I >= ELF::SHN_LORESERVE || I == ELF::SHN_ABS) return 0; return I; @@ -74,7 +72,7 @@ template <class ELFT> void ELFFileBase<E if (!Symtab) return; ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab); - error(StringTableOrErr.getError()); + error(StringTableOrErr); StringTable = *StringTableOrErr; } @@ -108,9 +106,9 @@ ObjectFile<ELFT>::getLocalSymbol(uintX_t } template <class ELFT> -void elf2::ObjectFile<ELFT>::parse(DenseSet<StringRef> &Comdats) { +void ObjectFile<ELFT>::parse(DenseSet<StringRef> &ComdatGroups) { // Read section and symbol tables. - initializeSections(Comdats); + initializeSections(ComdatGroups); initializeSymbols(); } @@ -139,7 +137,7 @@ ObjectFile<ELFT>::getShtGroupEntries(con const ELFFile<ELFT> &Obj = this->ELFObj; ErrorOr<ArrayRef<GroupEntryType>> EntriesOrErr = Obj.template getSectionContentsAsArray<GroupEntryType>(&Sec); - error(EntriesOrErr.getError()); + error(EntriesOrErr); ArrayRef<GroupEntryType> Entries = *EntriesOrErr; if (Entries.empty() || Entries[0] != GRP_COMDAT) error("Unsupported SHT_GROUP format"); @@ -174,7 +172,7 @@ static bool shouldMerge(const typename E } template <class ELFT> -void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) { +void ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &ComdatGroups) { uint64_t Size = this->ELFObj.getNumSections(); Sections.resize(Size); unsigned I = -1; @@ -187,7 +185,7 @@ void elf2::ObjectFile<ELFT>::initializeS switch (Sec.sh_type) { case SHT_GROUP: Sections[I] = &InputSection<ELFT>::Discarded; - if (Comdats.insert(getShtGroupSignature(Sec)).second) + if (ComdatGroups.insert(getShtGroupSignature(Sec)).second) continue; for (GroupEntryType E : getShtGroupEntries(Sec)) { uint32_t SecIndex = E; @@ -235,7 +233,7 @@ void elf2::ObjectFile<ELFT>::initializeS } template <class ELFT> InputSectionBase<ELFT> * -elf2::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { +ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { ErrorOr<StringRef> NameOrErr = this->ELFObj.getSectionName(&Sec); error(NameOrErr); StringRef Name = *NameOrErr; @@ -250,29 +248,29 @@ elf2::ObjectFile<ELFT>::createInputSecti // A MIPS object file has a special section that contains register // usage info, which needs to be handled by the linker specially. if (Config->EMachine == EM_MIPS && Name == ".reginfo") { - MipsReginfo = new (this->Alloc) MipsReginfoInputSection<ELFT>(this, &Sec); + MipsReginfo = new (Alloc) MipsReginfoInputSection<ELFT>(this, &Sec); return MipsReginfo; } if (Name == ".eh_frame") - return new (this->EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec); + return new (EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec); if (shouldMerge<ELFT>(Sec)) - return new (this->MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec); - return new (this->Alloc) InputSection<ELFT>(this, &Sec); + return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec); + return new (Alloc) InputSection<ELFT>(this, &Sec); } -template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() { +template <class ELFT> void ObjectFile<ELFT>::initializeSymbols() { this->initStringTable(); Elf_Sym_Range Syms = this->getNonLocalSymbols(); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); - this->SymbolBodies.reserve(NumSymbols); + SymbolBodies.reserve(NumSymbols); for (const Elf_Sym &Sym : Syms) - this->SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); + SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); } template <class ELFT> InputSectionBase<ELFT> * -elf2::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { +ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { uint32_t Index = this->getSectionIndex(Sym); if (Index == 0) return nullptr; @@ -282,19 +280,19 @@ elf2::ObjectFile<ELFT>::getSection(const } template <class ELFT> -SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, +SymbolBody *ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, const Elf_Sym *Sym) { ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable); - error(NameOrErr.getError()); + error(NameOrErr); StringRef Name = *NameOrErr; switch (Sym->st_shndx) { case SHN_UNDEF: - return new (this->Alloc) UndefinedElf<ELFT>(Name, *Sym); + return new (Alloc) UndefinedElf<ELFT>(Name, *Sym); case SHN_COMMON: - return new (this->Alloc) DefinedCommon( - Name, Sym->st_size, Sym->st_value, - Sym->getBinding() == llvm::ELF::STB_WEAK, Sym->getVisibility()); + return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value, + Sym->getBinding() == llvm::ELF::STB_WEAK, + Sym->getVisibility()); } switch (Sym->getBinding()) { @@ -305,20 +303,16 @@ SymbolBody *elf2::ObjectFile<ELFT>::crea case STB_GNU_UNIQUE: { InputSectionBase<ELFT> *Sec = getSection(*Sym); if (Sec == &InputSection<ELFT>::Discarded) - return new (this->Alloc) UndefinedElf<ELFT>(Name, *Sym); - return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec); + return new (Alloc) UndefinedElf<ELFT>(Name, *Sym); + return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec); } } } -static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) { - ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB); - error(ArchiveOrErr, "Failed to parse archive"); - return std::move(*ArchiveOrErr); -} - void ArchiveFile::parse() { - File = openArchive(MB); + ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB); + error(FileOrErr, "Failed to parse archive"); + File = std::move(*FileOrErr); // Allocate a buffer for Lazy objects. size_t NumSyms = File->getNumberOfSymbols(); @@ -345,28 +339,9 @@ MemoryBufferRef ArchiveFile::getMember(c return *RefOrErr; } -std::vector<MemoryBufferRef> ArchiveFile::getMembers() { - File = openArchive(MB); - - std::vector<MemoryBufferRef> Result; - for (auto &ChildOrErr : File->children()) { - error(ChildOrErr, - "Could not get the child of the archive " + File->getFileName()); - const Archive::Child Child(*ChildOrErr); - ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef(); - if (!MbOrErr) - error(MbOrErr, "Could not get the buffer for a child of the archive " + - File->getFileName()); - Result.push_back(MbOrErr.get()); - } - return Result; -} - template <class ELFT> SharedFile<ELFT>::SharedFile(MemoryBufferRef M) - : ELFFileBase<ELFT>(Base::SharedKind, M) { - AsNeeded = Config->AsNeeded; -} + : ELFFileBase<ELFT>(Base::SharedKind, M), AsNeeded(Config->AsNeeded) {} template <class ELFT> const typename ELFFile<ELFT>::Elf_Shdr * @@ -379,6 +354,8 @@ SharedFile<ELFT>::getSection(const Elf_S return *Ret; } +// Partially parse the shared object file so that we can call +// getSoName on this object. template <class ELFT> void SharedFile<ELFT>::parseSoName() { typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; typedef typename ELFFile<ELFT>::uintX_t uintX_t; @@ -405,7 +382,7 @@ template <class ELFT> void SharedFile<EL } this->initStringTable(); - this->SoName = this->getName(); + SoName = this->getName(); if (!DynamicSec) return; @@ -418,13 +395,14 @@ template <class ELFT> void SharedFile<EL uintX_t Val = Dyn.getVal(); if (Val >= this->StringTable.size()) error("Invalid DT_SONAME entry"); - this->SoName = StringRef(this->StringTable.data() + Val); + SoName = StringRef(this->StringTable.data() + Val); return; } } } -template <class ELFT> void SharedFile<ELFT>::parse() { +// Fully parse the shared object file. This must be called after parseSoName(). +template <class ELFT> void SharedFile<ELFT>::parseRest() { Elf_Sym_Range Syms = this->getNonLocalSymbols(); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); SymbolBodies.reserve(NumSymbols); @@ -456,7 +434,7 @@ static std::unique_ptr<InputFile> create } template <template <class> class T> -std::unique_ptr<InputFile> lld::elf2::createELFFile(MemoryBufferRef MB) { +static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) { std::pair<unsigned char, unsigned char> Type = getElfArchType(MB.getBuffer()); if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB) error("Invalid data encoding: " + MB.getBufferIdentifier()); @@ -474,6 +452,14 @@ std::unique_ptr<InputFile> lld::elf2::cr error("Invalid file class: " + MB.getBufferIdentifier()); } +std::unique_ptr<InputFile> elf2::createObjectFile(MemoryBufferRef MB) { + return createELFFile<ObjectFile>(MB); +} + +std::unique_ptr<InputFile> elf2::createSharedFile(MemoryBufferRef MB) { + return createELFFile<SharedFile>(MB); +} + template class elf2::ELFFileBase<ELF32LE>; template class elf2::ELFFileBase<ELF32BE>; template class elf2::ELFFileBase<ELF64LE>; @@ -488,9 +474,3 @@ template class elf2::SharedFile<ELF32LE> template class elf2::SharedFile<ELF32BE>; template class elf2::SharedFile<ELF64LE>; template class elf2::SharedFile<ELF64BE>; - -template std::unique_ptr<InputFile> -elf2::createELFFile<ObjectFile>(MemoryBufferRef); - -template std::unique_ptr<InputFile> -elf2::createELFFile<SharedFile>(MemoryBufferRef); Modified: vendor/lld/dist/ELF/InputFiles.h ============================================================================== --- vendor/lld/dist/ELF/InputFiles.h Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/InputFiles.h Wed Jan 6 20:07:13 2016 (r293258) @@ -101,10 +101,10 @@ public: return F->kind() == Base::ObjectKind; } - ArrayRef<SymbolBody *> getSymbols() { return this->SymbolBodies; } + ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; } explicit ObjectFile(MemoryBufferRef M); - void parse(llvm::DenseSet<StringRef> &Comdats); + void parse(llvm::DenseSet<StringRef> &ComdatGroups); ArrayRef<InputSectionBase<ELFT> *> getSections() const { return Sections; } InputSectionBase<ELFT> *getSection(const Elf_Sym &Sym) const; @@ -113,7 +113,7 @@ public: uint32_t FirstNonLocal = this->Symtab->sh_info; if (SymbolIndex < FirstNonLocal) return nullptr; - return this->SymbolBodies[SymbolIndex - FirstNonLocal]; + return SymbolBodies[SymbolIndex - FirstNonLocal]; } Elf_Sym_Range getLocalSymbols(); @@ -127,7 +127,7 @@ public: uint32_t getMipsGp0() const; private: - void initializeSections(llvm::DenseSet<StringRef> &Comdats); + void initializeSections(llvm::DenseSet<StringRef> &ComdatGroups); void initializeSymbols(); InputSectionBase<ELFT> *createInputSection(const Elf_Shdr &Sec); @@ -159,7 +159,6 @@ public: MemoryBufferRef getMember(const Archive::Symbol *Sym); llvm::MutableArrayRef<Lazy> getLazySymbols() { return LazySymbols; } - std::vector<MemoryBufferRef> getMembers(); private: std::unique_ptr<Archive> File; @@ -194,7 +193,7 @@ public: explicit SharedFile(MemoryBufferRef M); void parseSoName(); - void parse(); + void parseRest(); // Used for --as-needed bool AsNeeded = false; @@ -202,8 +201,8 @@ public: bool isNeeded() const { return !AsNeeded || IsUsed; } }; -template <template <class> class T> -std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB); +std::unique_ptr<InputFile> createObjectFile(MemoryBufferRef MB); +std::unique_ptr<InputFile> createSharedFile(MemoryBufferRef MB); } // namespace elf2 } // namespace lld Modified: vendor/lld/dist/ELF/InputSection.h ============================================================================== --- vendor/lld/dist/ELF/InputSection.h Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/InputSection.h Wed Jan 6 20:07:13 2016 (r293258) @@ -93,6 +93,10 @@ InputSectionBase<ELFT> InputSectionBase<ELFT>::Discarded(nullptr, nullptr, InputSectionBase<ELFT>::Regular); +// Usually sections are copied to the output as atomic chunks of data, +// but some special types of sections are split into small pieces of data +// and each piece is copied to a different place in the output. +// This class represents such special sections. template <class ELFT> class SplitInputSection : public InputSectionBase<ELFT> { typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; @@ -100,7 +104,11 @@ template <class ELFT> class SplitInputSe public: SplitInputSection(ObjectFile<ELFT> *File, const Elf_Shdr *Header, typename InputSectionBase<ELFT>::Kind SectionKind); + + // For each piece of data, we maintain the offsets in the input section and + // in the output section. The latter may be -1 if it is not assigned yet. std::vector<std::pair<uintX_t, uintX_t>> Offsets; + std::pair<std::pair<uintX_t, uintX_t> *, uintX_t> getRangeAndSize(uintX_t Offset); }; Modified: vendor/lld/dist/ELF/MarkLive.cpp ============================================================================== --- vendor/lld/dist/ELF/MarkLive.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/MarkLive.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -16,7 +16,7 @@ // by default. Starting with GC-root symbols or sections, markLive function // defined in this file visits all reachable sections to set their Live // bits. Writer will then ignore sections whose Live bits are off, so that -// such sections are removed from output. +// such sections are not included into output. // //===----------------------------------------------------------------------===// @@ -37,7 +37,7 @@ using namespace llvm::object; using namespace lld; using namespace lld::elf2; -// Calls Fn for each section that Sec refers to. +// Calls Fn for each section that Sec refers to via relocations. template <class ELFT> static void forEachSuccessor(InputSection<ELFT> *Sec, std::function<void(InputSectionBase<ELFT> *)> Fn) { @@ -104,7 +104,7 @@ template <class ELFT> void lld::elf2::ma MarkSymbol(Symtab->find(S)); // Preserve externally-visible symbols if the symbols defined by this - // file could override other ELF file's symbols at runtime. + // file can interrupt other ELF file's symbols at runtime. if (Config->Shared || Config->ExportDynamic) { for (const std::pair<StringRef, Symbol *> &P : Symtab->getSymbols()) { SymbolBody *B = P.second->Body; Modified: vendor/lld/dist/ELF/OutputSections.cpp ============================================================================== --- vendor/lld/dist/ELF/OutputSections.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/OutputSections.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -239,14 +239,13 @@ bool RelocationSection<ELFT>::applyTlsDy } template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { - const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); for (const DynamicReloc<ELFT> &Rel : Relocs) { auto *P = reinterpret_cast<Elf_Rel *>(Buf); - Buf += EntrySize; + Buf += IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); // Skip placeholder for global dynamic TLS relocation pair. It was already // handled by the previous relocation. - if (!Rel.C || !Rel.RI) + if (!Rel.C) continue; InputSectionBase<ELFT> &C = *Rel.C; @@ -262,16 +261,16 @@ template <class ELFT> void RelocationSec continue; bool NeedsCopy = Body && Target->needsCopyRel(Type, *Body); bool NeedsGot = Body && Target->relocNeedsGot(Type, *Body); - bool CanBePreempted = canBePreempted(Body, NeedsGot); + bool CBP = canBePreempted(Body, NeedsGot); bool LazyReloc = Body && Target->supportsLazyRelocations() && Target->relocNeedsPlt(Type, *Body); bool IsDynRelative = Type == Target->getRelativeReloc(); - unsigned Sym = CanBePreempted ? Body->DynamicSymbolTableIndex : 0; + unsigned Sym = CBP ? Body->DynamicSymbolTableIndex : 0; unsigned Reloc; - if (!CanBePreempted && Body && isGnuIFunc<ELFT>(*Body)) + if (!CBP && Body && isGnuIFunc<ELFT>(*Body)) Reloc = Target->getIRelativeReloc(); - else if (!CanBePreempted || IsDynRelative) + else if (!CBP || IsDynRelative) Reloc = Target->getRelativeReloc(); else if (LazyReloc) Reloc = Target->getPltReloc(); @@ -289,7 +288,7 @@ template <class ELFT> void RelocationSec P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body); else if (NeedsCopy) P->r_offset = Out<ELFT>::Bss->getVA() + - dyn_cast<SharedSymbol<ELFT>>(Body)->OffsetInBSS; + cast<SharedSymbol<ELFT>>(Body)->OffsetInBss; else P->r_offset = C.getOffset(RI.r_offset) + C.OutSec->getVA(); @@ -300,7 +299,7 @@ template <class ELFT> void RelocationSec uintX_t Addend; if (NeedsCopy) Addend = 0; - else if (CanBePreempted || IsDynRelative) + else if (CBP || IsDynRelative) Addend = OrigAddend; else if (Body) Addend = getSymVA<ELFT>(*Body) + OrigAddend; @@ -640,6 +639,9 @@ template <class ELFT> void DynamicSectio if (DtFlags1) ++NumEntries; // DT_FLAGS_1 + if (!Config->Entry.empty()) + ++NumEntries; // DT_DEBUG + if (Config->EMachine == EM_MIPS) { ++NumEntries; // DT_MIPS_RLD_VERSION ++NumEntries; // DT_MIPS_FLAGS @@ -738,6 +740,8 @@ template <class ELFT> void DynamicSectio WriteVal(DT_FLAGS, DtFlags); if (DtFlags1) WriteVal(DT_FLAGS_1, DtFlags1); + if (!Config->Entry.empty()) + WriteVal(DT_DEBUG, 0); // See "Dynamic Section" in Chapter 5 in the following document // for detailed description: @@ -799,11 +803,11 @@ typename ELFFile<ELFT>::uintX_t lld::elf return SC->OutSec->getVA() + SC->getOffset(DR.Sym); } case SymbolBody::DefinedCommonKind: - return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(S).OffsetInBSS; + return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(S).OffsetInBss; case SymbolBody::SharedKind: { auto &SS = cast<SharedSymbol<ELFT>>(S); if (SS.NeedsCopy) - return Out<ELFT>::Bss->getVA() + SS.OffsetInBSS; + return Out<ELFT>::Bss->getVA() + SS.OffsetInBss; return 0; } case SymbolBody::UndefinedElfKind: @@ -1119,9 +1123,9 @@ void MergeOutputSection<ELFT>::addSectio ArrayRef<uint8_t> D = S->getSectionData(); StringRef Data((const char *)D.data(), D.size()); uintX_t EntSize = S->getSectionHdr()->sh_entsize; - uintX_t Offset = 0; if (this->Header.sh_flags & SHF_STRINGS) { + uintX_t Offset = 0; while (!Data.empty()) { size_t End = findNull(Data, EntSize); if (End == StringRef::npos) @@ -1139,8 +1143,7 @@ void MergeOutputSection<ELFT>::addSectio for (unsigned I = 0, N = Data.size(); I != N; I += EntSize) { StringRef Entry = Data.substr(I, EntSize); size_t OutputOffset = Builder.add(Entry); - S->Offsets.push_back(std::make_pair(Offset, OutputOffset)); - Offset += EntSize; + S->Offsets.push_back(std::make_pair(I, OutputOffset)); } } } Modified: vendor/lld/dist/ELF/SymbolTable.cpp ============================================================================== --- vendor/lld/dist/ELF/SymbolTable.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/SymbolTable.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // Symbol table is a bag of all known symbols. We put all symbols of -// all input files to the symbol table. The symbol Table is basically +// all input files to the symbol table. The symbol table is basically // a hash table with the logic to resolve symbol name conflicts using // the symbol types. // @@ -28,6 +28,9 @@ using namespace lld::elf2; template <class ELFT> SymbolTable<ELFT>::SymbolTable() {} +// All input object files must be for the same architecture +// (e.g. it does not make sense to link x86 object files with +// MIPS object files.) This function checks for that error. template <class ELFT> static void checkCompatibility(InputFile *FileP) { auto *F = dyn_cast<ELFFileBase<ELFT>>(FileP); @@ -42,6 +45,7 @@ static void checkCompatibility(InputFile error(A + " is incompatible with " + B); } +// Add symbols in File to the symbol table. template <class ELFT> void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) { InputFile *FileP = File.get(); @@ -64,7 +68,7 @@ void SymbolTable<ELFT>::addFile(std::uni return; SharedFiles.emplace_back(cast<SharedFile<ELFT>>(File.release())); - F->parse(); + F->parseRest(); for (SharedSymbol<ELFT> &B : F->getSharedSymbols()) resolve(&B); return; @@ -73,7 +77,7 @@ void SymbolTable<ELFT>::addFile(std::uni // .o file auto *F = cast<ObjectFile<ELFT>>(FileP); ObjectFiles.emplace_back(cast<ObjectFile<ELFT>>(File.release())); - F->parse(Comdats); + F->parse(ComdatGroups); for (SymbolBody *B : F->getSymbols()) resolve(B); } @@ -109,6 +113,9 @@ void SymbolTable<ELFT>::addSynthetic(Str resolve(Sym); } +// Add Name as an "ignored" symbol. An ignored symbol is a regular +// linker-synthesized defined symbol, but it is not recorded to the output +// file's symbol table. Such symbols are useful for some linker-defined symbols. template <class ELFT> SymbolBody *SymbolTable<ELFT>::addIgnored(StringRef Name) { auto *Sym = new (Alloc) @@ -117,18 +124,10 @@ SymbolBody *SymbolTable<ELFT>::addIgnore return Sym; } -template <class ELFT> bool SymbolTable<ELFT>::isUndefined(StringRef Name) { - if (SymbolBody *Sym = find(Name)) - return Sym->isUndefined(); - return false; -} - // Returns a file from which symbol B was created. -// If B does not belong to any file in ObjectFiles, returns a nullptr. +// If B does not belong to any file, returns a nullptr. template <class ELFT> -ELFFileBase<ELFT> * -elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles, - const SymbolBody *B) { +ELFFileBase<ELFT> *SymbolTable<ELFT>::findFile(SymbolBody *B) { for (const std::unique_ptr<ObjectFile<ELFT>> &F : ObjectFiles) { ArrayRef<SymbolBody *> Syms = F->getSymbols(); if (std::find(Syms.begin(), Syms.end(), B) != Syms.end()) @@ -139,8 +138,8 @@ elf2::findFile(ArrayRef<std::unique_ptr< template <class ELFT> std::string SymbolTable<ELFT>::conflictMsg(SymbolBody *Old, SymbolBody *New) { - ELFFileBase<ELFT> *OldFile = findFile<ELFT>(ObjectFiles, Old); - ELFFileBase<ELFT> *NewFile = findFile<ELFT>(ObjectFiles, New); + ELFFileBase<ELFT> *OldFile = findFile(Old); + ELFFileBase<ELFT> *NewFile = findFile(New); StringRef Sym = Old->getName(); StringRef F1 = OldFile ? OldFile->getName() : "(internal)"; @@ -173,15 +172,15 @@ template <class ELFT> void SymbolTable<E // compare() returns -1, 0, or 1 if the lhs symbol is less preferable, // equivalent (conflicting), or more preferable, respectively. - int comp = Existing->compare<ELFT>(New); - if (comp == 0) { + int Comp = Existing->compare<ELFT>(New); + if (Comp == 0) { std::string S = "duplicate symbol: " + conflictMsg(Existing, New); if (!Config->AllowMultipleDefinition) error(S); warning(S); return; } - if (comp < 0) + if (Comp < 0) Sym->Body = New; } @@ -248,20 +247,7 @@ template <class ELFT> void SymbolTable<E Sym->setUsedInDynamicReloc(); } -template class lld::elf2::SymbolTable<ELF32LE>; -template class lld::elf2::SymbolTable<ELF32BE>; -template class lld::elf2::SymbolTable<ELF64LE>; -template class lld::elf2::SymbolTable<ELF64BE>; - -template ELFFileBase<ELF32LE> * -lld::elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELF32LE>>>, - const SymbolBody *); -template ELFFileBase<ELF32BE> * -lld::elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELF32BE>>>, - const SymbolBody *); -template ELFFileBase<ELF64LE> * -lld::elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELF64LE>>>, - const SymbolBody *); -template ELFFileBase<ELF64BE> * -lld::elf2::findFile(ArrayRef<std::unique_ptr<ObjectFile<ELF64BE>>>, - const SymbolBody *); +template class elf2::SymbolTable<ELF32LE>; +template class elf2::SymbolTable<ELF32BE>; +template class elf2::SymbolTable<ELF64LE>; +template class elf2::SymbolTable<ELF64BE>; Modified: vendor/lld/dist/ELF/SymbolTable.h ============================================================================== --- vendor/lld/dist/ELF/SymbolTable.h Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/SymbolTable.h Wed Jan 6 20:07:13 2016 (r293258) @@ -55,9 +55,9 @@ public: void addSynthetic(StringRef Name, OutputSectionBase<ELFT> &Section, typename llvm::object::ELFFile<ELFT>::uintX_t Value); SymbolBody *addIgnored(StringRef Name); - bool isUndefined(StringRef Name); void scanShlibUndefined(); SymbolBody *find(StringRef Name); + ELFFileBase<ELFT> *findFile(SymbolBody *B); private: Symbol *insert(SymbolBody *New); @@ -78,7 +78,7 @@ private: llvm::MapVector<StringRef, Symbol *> Symtab; llvm::BumpPtrAllocator Alloc; - llvm::DenseSet<StringRef> Comdats; + llvm::DenseSet<StringRef> ComdatGroups; // The writer needs to infer the machine type from the object files. std::vector<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles; @@ -87,11 +87,6 @@ private: llvm::DenseSet<StringRef> IncludedSoNames; }; -template <class ELFT> -ELFFileBase<ELFT> * -findFile(ArrayRef<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles, - const SymbolBody *B); - } // namespace elf2 } // namespace lld Modified: vendor/lld/dist/ELF/Symbols.cpp ============================================================================== --- vendor/lld/dist/ELF/Symbols.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/Symbols.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -115,8 +115,7 @@ std::unique_ptr<InputFile> Lazy::getMemb // read from the library. if (MBRef.getBuffer().empty()) return std::unique_ptr<InputFile>(nullptr); - - return createELFFile<ObjectFile>(MBRef); + return createObjectFile(MBRef); } template <class ELFT> static void doInitSymbols() { Modified: vendor/lld/dist/ELF/Symbols.h ============================================================================== --- vendor/lld/dist/ELF/Symbols.h Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/Symbols.h Wed Jan 6 20:07:13 2016 (r293258) @@ -173,7 +173,7 @@ public: // The output offset of this common symbol in the output bss. Computed by the // writer. - uint64_t OffsetInBSS; + uint64_t OffsetInBss; // The maximum alignment we have seen for this symbol. uint64_t MaxAlignment; @@ -262,9 +262,9 @@ public: SharedFile<ELFT> *File; // True if the linker has to generate a copy relocation for this shared - // symbol. OffsetInBSS is significant only when NeedsCopy is true. + // symbol. OffsetInBss is significant only when NeedsCopy is true. bool NeedsCopy = false; - uintX_t OffsetInBSS = 0; + uintX_t OffsetInBss = 0; }; // This class represents a symbol defined in an archive file. It is Modified: vendor/lld/dist/ELF/Target.cpp ============================================================================== --- vendor/lld/dist/ELF/Target.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/Target.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -320,7 +320,7 @@ void X86TargetInfo::writePltZeroEntry(ui // separate procedure linkage tables. if (Config->Shared) { const uint8_t V[] = { - 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx + 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx) 0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx) 0x90, 0x90, 0x90, 0x90 // nop;nop;nop;nop }; Modified: vendor/lld/dist/ELF/Writer.cpp ============================================================================== --- vendor/lld/dist/ELF/Writer.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/ELF/Writer.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -69,7 +69,7 @@ private: } int getPhdrsNum() const; - OutputSection<ELFT> *getBSS(); + OutputSection<ELFT> *getBss(); void addCommonSymbols(std::vector<DefinedCommon *> &Syms); void addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms); @@ -330,18 +330,17 @@ void Writer<ELFT>::scanRelocs(InputSecti } template <class ELFT> -static void reportUndefined(const SymbolTable<ELFT> &S, const SymbolBody &Sym) { +static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) { if (Config->Shared && !Config->NoUndefined) return; - ELFFileBase<ELFT> *SymFile = findFile<ELFT>(S.getObjectFiles(), &Sym); - std::string Message = "undefined symbol: " + Sym.getName().str(); - if (SymFile) - Message += " in " + SymFile->getName().str(); + std::string Msg = "undefined symbol: " + Sym->getName().str(); + if (ELFFileBase<ELFT> *File = Symtab.findFile(Sym)) + Msg += " in " + File->getName().str(); if (Config->NoInhibitExec) - warning(Message); + warning(Msg); else - error(Message); + error(Msg); } // Local symbols are not in the linker's symbol table. This function scans @@ -466,7 +465,7 @@ static bool compareOutputSections(Output return false; } -template <class ELFT> OutputSection<ELFT> *Writer<ELFT>::getBSS() { +template <class ELFT> OutputSection<ELFT> *Writer<ELFT>::getBss() { if (!Out<ELFT>::Bss) { Out<ELFT>::Bss = new OutputSection<ELFT>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); @@ -480,8 +479,6 @@ template <class ELFT> OutputSection<ELFT // This function adds them to end of BSS section. template <class ELFT> void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon *> &Syms) { - typedef typename ELFFile<ELFT>::uintX_t uintX_t; - if (Syms.empty()) return; @@ -491,11 +488,11 @@ void Writer<ELFT>::addCommonSymbols(std: return A->MaxAlignment > B->MaxAlignment; }); - uintX_t Off = getBSS()->getSize(); + uintX_t Off = getBss()->getSize(); for (DefinedCommon *C : Syms) { uintX_t Align = C->MaxAlignment; Off = RoundUpToAlignment(Off, Align); - C->OffsetInBSS = Off; + C->OffsetInBss = Off; Off += C->Size; } @@ -507,7 +504,7 @@ template <class ELFT> void Writer<ELFT>::addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms) { if (Syms.empty()) return; - uintX_t Off = getBSS()->getSize(); + uintX_t Off = getBss()->getSize(); for (SharedSymbol<ELFT> *C : Syms) { const Elf_Sym &Sym = C->Sym; const Elf_Shdr *Sec = C->File->getSection(Sym); @@ -518,7 +515,7 @@ void Writer<ELFT>::addCopyRelSymbols(std uintX_t Align = 1 << TrailingZeros; Out<ELFT>::Bss->updateAlign(Align); Off = RoundUpToAlignment(Off, Align); - C->OffsetInBSS = Off; + C->OffsetInBss = Off; Off += Sym.st_size; } Out<ELFT>::Bss->setSize(Off); @@ -803,7 +800,7 @@ template <class ELFT> void Writer<ELFT>: SymbolBody *Body = P.second->Body; if (auto *U = dyn_cast<Undefined>(Body)) if (!U->isWeak() && !U->canKeepUndefined()) - reportUndefined<ELFT>(Symtab, *Body); + reportUndefined<ELFT>(Symtab, Body); if (auto *C = dyn_cast<DefinedCommon>(Body)) CommonSymbols.push_back(C); @@ -958,10 +955,12 @@ void Writer<ELFT>::addStartStopSymbols(O StringSaver Saver(Alloc); StringRef Start = Saver.save("__start_" + S); StringRef Stop = Saver.save("__stop_" + S); - if (Symtab.isUndefined(Start)) - Symtab.addSynthetic(Start, *Sec, 0); - if (Symtab.isUndefined(Stop)) - Symtab.addSynthetic(Stop, *Sec, Sec->getSize()); + if (SymbolBody *B = Symtab.find(Start)) + if (B->isUndefined()) + Symtab.addSynthetic(Start, *Sec, 0); + if (SymbolBody *B = Symtab.find(Stop)) + if (B->isUndefined()) + Symtab.addSynthetic(Stop, *Sec, Sec->getSize()); } template <class ELFT> static bool needsPhdr(OutputSectionBase<ELFT> *Sec) { @@ -1016,7 +1015,7 @@ template <class ELFT> void Writer<ELFT>: Elf_Phdr GnuRelroPhdr = {}; Elf_Phdr TlsPhdr{}; bool RelroAligned = false; - uintX_t ThreadBSSOffset = 0; + uintX_t ThreadBssOffset = 0; // Create phdrs as we assign VAs and file offsets to all output sections. for (OutputSectionBase<ELFT> *Sec : OutputSections) { Elf_Phdr *PH = &Phdrs[PhdrIdx]; @@ -1042,11 +1041,11 @@ template <class ELFT> void Writer<ELFT>: setPhdr(&TlsPhdr, PT_TLS, PF_R, FileOff, VA, 0, Sec->getAlign()); if (Sec->getType() != SHT_NOBITS) VA = RoundUpToAlignment(VA, Sec->getAlign()); - uintX_t TVA = RoundUpToAlignment(VA + ThreadBSSOffset, Sec->getAlign()); + uintX_t TVA = RoundUpToAlignment(VA + ThreadBssOffset, Sec->getAlign()); Sec->setVA(TVA); TlsPhdr.p_memsz += Sec->getSize(); if (Sec->getType() == SHT_NOBITS) { - ThreadBSSOffset = TVA - VA + Sec->getSize(); + ThreadBssOffset = TVA - VA + Sec->getSize(); } else { TlsPhdr.p_filesz += Sec->getSize(); VA += Sec->getSize(); Modified: vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp ============================================================================== --- vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -507,6 +507,23 @@ void ArchHandler_arm64::generateAtomCont // Copy raw bytes. memcpy(atomContentBuffer, atom.rawContent().data(), atom.size()); // Apply fix-ups. +#ifndef NDEBUG + if (atom.begin() != atom.end()) { + DEBUG_WITH_TYPE("atom-content", llvm::dbgs() + << "Applying fixups to atom:\n" + << " address=" + << llvm::format(" 0x%09lX", &atom) + << ", file=#" + << atom.file().ordinal() + << ", atom=#" + << atom.ordinal() + << ", name=" + << atom.name() + << ", type=" + << atom.contentType() + << "\n"); + } +#endif for (const Reference *ref : atom) { uint32_t offset = ref->offsetInAtom(); const Atom *target = ref->target(); Modified: vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp ============================================================================== --- vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -647,13 +647,33 @@ void ArchHandler_x86_64::applyFixupReloc *loc32 = ref.addend() + inAtomAddress - fixupAddress; return; case delta32Anon: - *loc32 = (targetAddress - fixupAddress) + ref.addend(); + // The value we write here should be the the delta to the target + // after taking in to account the difference from the fixup back to the + // last defined label + // ie, if we have: + // _base: ... + // Lfixup: .quad Ltarget - . + // ... + // Ltarget: + // + // Then we want to encode the value (Ltarget + addend) - (LFixup - _base) + *loc32 = (targetAddress + ref.addend()) - (fixupAddress - inAtomAddress); return; case delta64: *loc64 = ref.addend() + inAtomAddress - fixupAddress; return; case delta64Anon: - *loc64 = (targetAddress - fixupAddress) + ref.addend(); + // The value we write here should be the the delta to the target + // after taking in to account the difference from the fixup back to the + // last defined label + // ie, if we have: + // _base: ... + // Lfixup: .quad Ltarget - . + // ... + // Ltarget: + // + // Then we want to encode the value (Ltarget + addend) - (LFixup - _base) + *loc64 = (targetAddress + ref.addend()) - (fixupAddress - inAtomAddress); return; case negDelta32: *loc32 = fixupAddress - targetAddress + ref.addend(); Modified: vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp ============================================================================== --- vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Wed Jan 6 20:06:15 2016 (r293257) +++ vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Wed Jan 6 20:07:13 2016 (r293258) @@ -406,14 +406,8 @@ bool Util::TextSectionSorter::operator() } void Util::organizeSections() { - if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601062007.u06K7EWq084741>