Date: Wed, 13 Jan 2016 20:06:04 +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: r293846 - in vendor/lld/dist: . COFF ELF lib/Config lib/Core lib/Driver lib/ReaderWriter lib/ReaderWriter/ELF lib/ReaderWriter/ELF/AArch64 lib/ReaderWriter/ELF/AMDGPU lib/ReaderWriter/E... Message-ID: <201601132006.u0DK64vn087964@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Wed Jan 13 20:06:04 2016 New Revision: 293846 URL: https://svnweb.freebsd.org/changeset/base/293846 Log: Vendor import of lld trunk r257626: https://llvm.org/svn/llvm-project/lld/trunk@257626 Added: vendor/lld/dist/test/ELF/Inputs/aarch64-condb-reloc.s (contents, props changed) vendor/lld/dist/test/ELF/Inputs/aarch64-tls-ie.s (contents, props changed) vendor/lld/dist/test/ELF/Inputs/aarch64-tstbr14-reloc.s (contents, props changed) vendor/lld/dist/test/ELF/Inputs/mips-gp-disp.so (contents, props changed) vendor/lld/dist/test/ELF/Inputs/wrap.s (contents, props changed) vendor/lld/dist/test/ELF/aarch64-condb-reloc.s (contents, props changed) vendor/lld/dist/test/ELF/aarch64-gnu-ifunc-nosym.s (contents, props changed) vendor/lld/dist/test/ELF/aarch64-gnu-ifunc.s (contents, props changed) vendor/lld/dist/test/ELF/aarch64-tls-ie.s (contents, props changed) vendor/lld/dist/test/ELF/aarch64-tstbr14-reloc.s (contents, props changed) vendor/lld/dist/test/ELF/amdgpu-entry.s (contents, props changed) vendor/lld/dist/test/ELF/amdgpu-globals.s (contents, props changed) vendor/lld/dist/test/ELF/amdgpu-kernels.s (contents, props changed) vendor/lld/dist/test/ELF/basic-ppc.s (contents, props changed) vendor/lld/dist/test/ELF/mips-gp-disp.s (contents, props changed) vendor/lld/dist/test/ELF/ppc-relocs.s (contents, props changed) vendor/lld/dist/test/ELF/wrap.s (contents, props changed) vendor/lld/dist/test/mach-o/do-not-emit-unwind-fde-arm64.yaml Deleted: vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.cpp vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.h vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.cpp vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.h vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.cpp vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.h vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.cpp vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.h vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.cpp vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.h vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/CMakeLists.txt vendor/lld/dist/test/old-elf/AMDGPU/hsa.test Modified: vendor/lld/dist/CMakeLists.txt vendor/lld/dist/COFF/CMakeLists.txt vendor/lld/dist/COFF/Chunks.cpp vendor/lld/dist/COFF/Chunks.h vendor/lld/dist/COFF/Config.h vendor/lld/dist/COFF/DLL.cpp vendor/lld/dist/COFF/Driver.cpp vendor/lld/dist/COFF/DriverUtils.cpp vendor/lld/dist/COFF/InputFiles.cpp vendor/lld/dist/COFF/Writer.cpp vendor/lld/dist/ELF/CMakeLists.txt vendor/lld/dist/ELF/Driver.cpp vendor/lld/dist/ELF/Driver.h vendor/lld/dist/ELF/DriverUtils.cpp vendor/lld/dist/ELF/InputFiles.cpp vendor/lld/dist/ELF/InputFiles.h vendor/lld/dist/ELF/InputSection.cpp vendor/lld/dist/ELF/InputSection.h vendor/lld/dist/ELF/LinkerScript.cpp vendor/lld/dist/ELF/MarkLive.cpp vendor/lld/dist/ELF/Options.td vendor/lld/dist/ELF/OutputSections.cpp vendor/lld/dist/ELF/OutputSections.h 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/Target.h vendor/lld/dist/ELF/Writer.cpp vendor/lld/dist/lib/Config/CMakeLists.txt vendor/lld/dist/lib/Core/CMakeLists.txt vendor/lld/dist/lib/Driver/CMakeLists.txt vendor/lld/dist/lib/Driver/GnuLdDriver.cpp vendor/lld/dist/lib/ReaderWriter/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/ELF/ARM/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/ELF/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/ELF/ELFLinkingContext.cpp vendor/lld/dist/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/ELF/Mips/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/ELF/X86/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp vendor/lld/dist/lib/ReaderWriter/MachO/CMakeLists.txt vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp vendor/lld/dist/lib/ReaderWriter/YAML/CMakeLists.txt vendor/lld/dist/test/COFF/export.test vendor/lld/dist/test/ELF/basic-aarch64.s vendor/lld/dist/test/ELF/basic-mips.s vendor/lld/dist/test/ELF/basic.s vendor/lld/dist/test/ELF/basic32.s vendor/lld/dist/test/ELF/basic64be.s vendor/lld/dist/test/ELF/discard-none.s vendor/lld/dist/test/ELF/linkerscript-sections.s vendor/lld/dist/test/ELF/relocation-copy.s vendor/lld/dist/test/ELF/string-table.s vendor/lld/dist/test/lit.cfg vendor/lld/dist/test/mach-o/arm64-reloc-negDelta32-fixup.yaml vendor/lld/dist/test/mach-o/parse-data-relocs-arm64.yaml Modified: vendor/lld/dist/CMakeLists.txt ============================================================================== --- vendor/lld/dist/CMakeLists.txt Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/CMakeLists.txt Wed Jan 13 20:06:04 2016 (r293846) @@ -1,4 +1,5 @@ set(LLD_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(LLD_INCLUDE_DIR ${LLD_SOURCE_DIR}/include ) set(LLD_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) # Compute the LLD version from the LLVM version. @@ -86,6 +87,12 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) ) endif() +macro(add_lld_library name) + add_llvm_library(${name} ${ARGN}) + set_target_properties(${name} PROPERTIES FOLDER "lld libraries") +endmacro(add_lld_library) + + add_subdirectory(lib) add_subdirectory(tools) Modified: vendor/lld/dist/COFF/CMakeLists.txt ============================================================================== --- vendor/lld/dist/COFF/CMakeLists.txt Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/COFF/CMakeLists.txt Wed Jan 13 20:06:04 2016 (r293846) @@ -2,7 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Options.td) tablegen(LLVM Options.inc -gen-opt-parser-defs) add_public_tablegen_target(COFFOptionsTableGen) -add_llvm_library(lldCOFF +add_lld_library(lldCOFF Chunks.cpp DLL.cpp Driver.cpp Modified: vendor/lld/dist/COFF/Chunks.cpp ============================================================================== --- vendor/lld/dist/COFF/Chunks.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/COFF/Chunks.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -310,7 +310,7 @@ void SEHTableChunk::writeTo(uint8_t *Buf BaserelChunk::BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End) { // Block header consists of 4 byte page RVA and 4 byte block size. // Each entry is 2 byte. Last entry may be padding. - Data.resize(RoundUpToAlignment((End - Begin) * 2 + 8, 4)); + Data.resize(align((End - Begin) * 2 + 8, 4)); uint8_t *P = Data.data(); write32le(P, Page); write32le(P + 4, Data.size()); Modified: vendor/lld/dist/COFF/Chunks.h ============================================================================== --- vendor/lld/dist/COFF/Chunks.h Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/COFF/Chunks.h Wed Jan 13 20:06:04 2016 (r293846) @@ -326,6 +326,10 @@ public: uint8_t Type; }; +inline uint64_t align(uint64_t Value, uint64_t Align) { + return llvm::RoundUpToAlignment(Value, Align); +} + } // namespace coff } // namespace lld Modified: vendor/lld/dist/COFF/Config.h ============================================================================== --- vendor/lld/dist/COFF/Config.h Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/COFF/Config.h Wed Jan 13 20:06:04 2016 (r293846) @@ -25,6 +25,7 @@ using llvm::COFF::WindowsSubsystem; using llvm::StringRef; class DefinedAbsolute; class DefinedRelative; +class StringChunk; class Undefined; // Short aliases. @@ -42,6 +43,12 @@ struct Export { bool Data = false; bool Private = false; + // If an export is a form of /export:foo=dllname.bar, that means + // that foo should be exported as an alias to bar in the DLL. + // ForwardTo is set to "dllname.bar" part. Usually empty. + StringRef ForwardTo; + StringChunk *ForwardChunk = nullptr; + // True if this /export option was in .drectves section. bool Directives = false; StringRef SymbolName; Modified: vendor/lld/dist/COFF/DLL.cpp ============================================================================== --- vendor/lld/dist/COFF/DLL.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/COFF/DLL.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -45,7 +45,7 @@ public: size_t getSize() const override { // Starts with 2 byte Hint field, followed by a null-terminated string, // ends with 0 or 1 byte padding. - return RoundUpToAlignment(Name.size() + 3, 2); + return align(Name.size() + 3, 2); } void writeTo(uint8_t *Buf) const override { @@ -320,8 +320,12 @@ public: void writeTo(uint8_t *Buf) const override { for (Export &E : Config->Exports) { - auto *D = cast<Defined>(E.Sym->repl()); - write32le(Buf + OutputSectionOff + E.Ordinal * 4, D->getRVA()); + uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4; + if (E.ForwardChunk) { + write32le(P, E.ForwardChunk->getRVA()); + } else { + write32le(P, cast<Defined>(E.Sym->repl())->getRVA()); + } } } @@ -539,6 +543,15 @@ EdataContents::EdataContents() { for (Export &E : Config->Exports) if (!E.Noname) Names.push_back(new StringChunk(E.ExportName)); + + std::vector<Chunk *> Forwards; + for (Export &E : Config->Exports) { + if (E.ForwardTo.empty()) + continue; + E.ForwardChunk = new StringChunk(E.ForwardTo); + Forwards.push_back(E.ForwardChunk); + } + auto *NameTab = new NamePointersChunk(Names); auto *OrdinalTab = new ExportOrdinalChunk(Names.size()); auto *Dir = new ExportDirectoryChunk(MaxOrdinal, Names.size(), DLLName, @@ -550,6 +563,8 @@ EdataContents::EdataContents() { Chunks.push_back(std::unique_ptr<Chunk>(OrdinalTab)); for (Chunk *C : Names) Chunks.push_back(std::unique_ptr<Chunk>(C)); + for (Chunk *C : Forwards) + Chunks.push_back(std::unique_ptr<Chunk>(C)); } } // namespace coff Modified: vendor/lld/dist/COFF/Driver.cpp ============================================================================== --- vendor/lld/dist/COFF/Driver.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/COFF/Driver.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -586,6 +586,8 @@ void LinkerDriver::link(llvm::ArrayRef<c // Windows specific -- Make sure we resolve all dllexported symbols. for (Export &E : Config->Exports) { + if (!E.ForwardTo.empty()) + continue; E.Sym = addUndefined(E.Name); if (!E.Directives) Symtab.mangleMaybe(E.Sym); Modified: vendor/lld/dist/COFF/DriverUtils.cpp ============================================================================== --- vendor/lld/dist/COFF/DriverUtils.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/COFF/DriverUtils.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -321,7 +321,8 @@ void createSideBySideManifest() { } // Parse a string in the form of -// "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]". +// "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]" +// or "<name>=<dllname>.<name>". // Used for parsing /export arguments. Export parseExport(StringRef Arg) { Export E; @@ -329,12 +330,25 @@ Export parseExport(StringRef Arg) { std::tie(E.Name, Rest) = Arg.split(","); if (E.Name.empty()) goto err; + if (E.Name.find('=') != StringRef::npos) { - std::tie(E.ExtName, E.Name) = E.Name.split("="); + StringRef X, Y; + std::tie(X, Y) = E.Name.split("="); + + // If "<name>=<dllname>.<name>". + if (Y.find(".") != StringRef::npos) { + E.Name = X; + E.ForwardTo = Y; + return E; + } + + E.ExtName = X; + E.Name = Y; if (E.Name.empty()) goto err; } + // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]" while (!Rest.empty()) { StringRef Tok; std::tie(Tok, Rest) = Rest.split(","); @@ -388,15 +402,22 @@ void fixupExports() { } for (Export &E : Config->Exports) { - if (Undefined *U = cast_or_null<Undefined>(E.Sym->WeakAlias)) { + if (!E.ForwardTo.empty()) { + E.SymbolName = E.Name; + } else if (Undefined *U = cast_or_null<Undefined>(E.Sym->WeakAlias)) { E.SymbolName = U->getName(); } else { E.SymbolName = E.Sym->getName(); } } - for (Export &E : Config->Exports) - E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName); + for (Export &E : Config->Exports) { + if (!E.ForwardTo.empty()) { + E.ExportName = undecorate(E.Name); + } else { + E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName); + } + } // Uniquefy by name. std::map<StringRef, Export *> Map; Modified: vendor/lld/dist/COFF/InputFiles.cpp ============================================================================== --- vendor/lld/dist/COFF/InputFiles.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/COFF/InputFiles.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -23,7 +23,6 @@ using namespace llvm::COFF; using namespace llvm::object; using namespace llvm::support::endian; -using llvm::RoundUpToAlignment; using llvm::Triple; using llvm::support::ulittle32_t; using llvm::sys::fs::file_magic; Modified: vendor/lld/dist/COFF/Writer.cpp ============================================================================== --- vendor/lld/dist/COFF/Writer.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/COFF/Writer.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -163,13 +163,13 @@ void OutputSection::addChunk(Chunk *C) { Chunks.push_back(C); C->setOutputSection(this); uint64_t Off = Header.VirtualSize; - Off = RoundUpToAlignment(Off, C->getAlign()); + Off = align(Off, C->getAlign()); C->setRVA(Off); C->setOutputSectionOff(Off); Off += C->getSize(); Header.VirtualSize = Off; if (C->hasData()) - Header.SizeOfRawData = RoundUpToAlignment(Off, SectorSize); + Header.SizeOfRawData = align(Off, SectorSize); } void OutputSection::addPermissions(uint32_t C) { @@ -448,15 +448,14 @@ void Writer::createSymbolAndStringTable( OutputSection *LastSection = OutputSections.back(); // We position the symbol table to be adjacent to the end of the last section. uint64_t FileOff = - LastSection->getFileOff() + - RoundUpToAlignment(LastSection->getRawSize(), SectorSize); + LastSection->getFileOff() + align(LastSection->getRawSize(), SectorSize); if (!OutputSymtab.empty()) { PointerToSymbolTable = FileOff; FileOff += OutputSymtab.size() * sizeof(coff_symbol16); } if (!Strtab.empty()) FileOff += Strtab.size() + 4; - FileSize = RoundUpToAlignment(FileOff, SectorSize); + FileSize = align(FileOff, SectorSize); } // Visits all sections to assign incremental, non-overlapping RVAs and @@ -467,7 +466,7 @@ void Writer::assignAddresses() { sizeof(coff_section) * OutputSections.size(); SizeOfHeaders += Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); - SizeOfHeaders = RoundUpToAlignment(SizeOfHeaders, SectorSize); + SizeOfHeaders = align(SizeOfHeaders, SectorSize); uint64_t RVA = 0x1000; // The first page is kept unmapped. FileSize = SizeOfHeaders; // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because @@ -481,10 +480,10 @@ void Writer::assignAddresses() { addBaserels(Sec); Sec->setRVA(RVA); Sec->setFileOffset(FileSize); - RVA += RoundUpToAlignment(Sec->getVirtualSize(), PageSize); - FileSize += RoundUpToAlignment(Sec->getRawSize(), SectorSize); + RVA += align(Sec->getVirtualSize(), PageSize); + FileSize += align(Sec->getRawSize(), SectorSize); } - SizeOfImage = SizeOfHeaders + RoundUpToAlignment(RVA - 0x1000, PageSize); + SizeOfImage = SizeOfHeaders + align(RVA - 0x1000, PageSize); } template <typename PEHeaderTy> void Writer::writeHeader() { Modified: vendor/lld/dist/ELF/CMakeLists.txt ============================================================================== --- vendor/lld/dist/ELF/CMakeLists.txt Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/CMakeLists.txt Wed Jan 13 20:06:04 2016 (r293846) @@ -2,7 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Options.td) tablegen(LLVM Options.inc -gen-opt-parser-defs) add_public_tablegen_target(ELFOptionsTableGen) -add_llvm_library(lldELF2 +add_lld_library(lldELF2 Driver.cpp DriverUtils.cpp Error.cpp Modified: vendor/lld/dist/ELF/Driver.cpp ============================================================================== --- vendor/lld/dist/ELF/Driver.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/Driver.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -26,10 +26,10 @@ using namespace llvm::object; using namespace lld; using namespace lld::elf2; -Configuration *lld::elf2::Config; -LinkerDriver *lld::elf2::Driver; +Configuration *elf2::Config; +LinkerDriver *elf2::Driver; -void lld::elf2::link(ArrayRef<const char *> Args) { +void elf2::link(ArrayRef<const char *> Args) { Configuration C; LinkerDriver D; Config = &C; @@ -42,9 +42,9 @@ static std::pair<ELFKind, uint16_t> pars return {ELF32BEKind, EM_MIPS}; if (S == "elf32ltsmip") return {ELF32LEKind, EM_MIPS}; - if (S == "elf32ppc") + if (S == "elf32ppc" || S == "elf32ppc_fbsd") return {ELF32BEKind, EM_PPC}; - if (S == "elf64ppc") + if (S == "elf64ppc" || S == "elf64ppc_fbsd") return {ELF64BEKind, EM_PPC64}; if (S == "elf_i386") return {ELF32LEKind, EM_386}; @@ -107,6 +107,24 @@ void LinkerDriver::addFile(StringRef Pat } } +// Some command line options or some combinations of them are not allowed. +// This function checks for such errors. +static void checkOptions(opt::InputArgList &Args) { + // Traditional linkers can generate re-linkable object files instead + // of executables or DSOs. We don't support that since the feature + // does not seem to provide more value than the static archiver. + if (Args.hasArg(OPT_relocatable)) + error("-r option is not supported. Use 'ar' command instead."); + + // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup + // table which is a relatively new feature. + if (Config->EMachine == EM_MIPS && Config->GnuHash) + error("The .gnu.hash section is not compatible with the MIPS target."); + + if (Config->EMachine == EM_AMDGPU && !Config->Entry.empty()) + error("-e option is not valid for AMDGPU."); +} + static StringRef getString(opt::InputArgList &Args, unsigned Key, StringRef Default = "") { if (auto *Arg = Args.getLastArg(Key)) @@ -125,13 +143,9 @@ void LinkerDriver::main(ArrayRef<const c initSymbols(); opt::InputArgList Args = parseArgs(&Alloc, ArgsArr); + readConfigs(Args); createFiles(Args); - - // Traditional linkers can generate re-linkable object files instead - // of executables or DSOs. We don't support that since the feature - // does not seem to provide more value than the static archiver. - if (Args.hasArg(OPT_relocatable)) - error("-r option is not supported. Use 'ar' command instead."); + checkOptions(Args); switch (Config->EKind) { case ELF32LEKind: @@ -151,7 +165,8 @@ void LinkerDriver::main(ArrayRef<const c } } -void LinkerDriver::createFiles(opt::InputArgList &Args) { +// Initializes Config members by the command line options. +void LinkerDriver::readConfigs(opt::InputArgList &Args) { for (auto *Arg : Args.filtered(OPT_L)) Config->SearchPaths.push_back(Arg->getValue()); @@ -162,10 +177,9 @@ void LinkerDriver::createFiles(opt::Inpu Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":"); if (auto *Arg = Args.getLastArg(OPT_m)) { + // Parse ELF{32,64}{LE,BE} and CPU type. StringRef S = Arg->getValue(); - std::pair<ELFKind, uint16_t> P = parseEmulation(S); - Config->EKind = P.first; - Config->EMachine = P.second; + std::tie(Config->EKind, Config->EMachine) = parseEmulation(S); Config->Emulation = S; } @@ -217,7 +231,9 @@ void LinkerDriver::createFiles(opt::Inpu for (auto *Arg : Args.filtered(OPT_undefined)) Config->Undefined.push_back(Arg->getValue()); +} +void LinkerDriver::createFiles(opt::InputArgList &Args) { for (auto *Arg : Args) { switch (Arg->getOption().getID()) { case OPT_l: @@ -250,9 +266,6 @@ void LinkerDriver::createFiles(opt::Inpu if (Files.empty()) error("no input files."); - - if (Config->GnuHash && Config->EMachine == EM_MIPS) - error("The .gnu.hash section is not compatible with the MIPS target."); } template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { @@ -261,7 +274,10 @@ template <class ELFT> void LinkerDriver: if (!Config->Shared) { // Add entry symbol. - if (Config->Entry.empty()) + // + // There is no entry symbol for AMDGPU binaries, so skip adding one to avoid + // having and undefined symbol. + if (Config->Entry.empty() && Config->EMachine != EM_AMDGPU) Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start"; // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol @@ -288,8 +304,9 @@ template <class ELFT> void LinkerDriver: if (Config->EMachine == EM_MIPS) { // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between - // start of function and gp pointer into GOT. - Config->MipsGpDisp = Symtab.addIgnored("_gp_disp"); + // start of function and gp pointer into GOT. Use 'strong' variant of + // the addIgnored to prevent '_gp_disp' substitution. + Config->MipsGpDisp = Symtab.addIgnoredStrong("_gp_disp"); // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer // so that it points to an absolute address which is relative to GOT. @@ -304,6 +321,9 @@ template <class ELFT> void LinkerDriver: for (StringRef S : Config->Undefined) Symtab.addUndefinedOpt(S); + for (auto *Arg : Args.filtered(OPT_wrap)) + Symtab.wrap(Arg->getValue()); + if (Config->OutputFile.empty()) Config->OutputFile = "a.out"; Modified: vendor/lld/dist/ELF/Driver.h ============================================================================== --- vendor/lld/dist/ELF/Driver.h Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/Driver.h Wed Jan 13 20:06:04 2016 (r293846) @@ -26,14 +26,12 @@ void link(ArrayRef<const char *> Args); class LinkerDriver { public: void main(ArrayRef<const char *> Args); - void createFiles(llvm::opt::InputArgList &Args); - template <class ELFT> void link(llvm::opt::InputArgList &Args); - void addFile(StringRef Path); private: - template <template <class> class T> - std::unique_ptr<InputFile> createELFInputFile(MemoryBufferRef MB); + void readConfigs(llvm::opt::InputArgList &Args); + void createFiles(llvm::opt::InputArgList &Args); + template <class ELFT> void link(llvm::opt::InputArgList &Args); llvm::BumpPtrAllocator Alloc; bool WholeArchive = false; Modified: vendor/lld/dist/ELF/DriverUtils.cpp ============================================================================== --- vendor/lld/dist/ELF/DriverUtils.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/DriverUtils.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -51,8 +51,8 @@ public: }; // Parses a given list of options. -opt::InputArgList lld::elf2::parseArgs(llvm::BumpPtrAllocator *A, - ArrayRef<const char *> Argv) { +opt::InputArgList elf2::parseArgs(llvm::BumpPtrAllocator *A, + ArrayRef<const char *> Argv) { // Make InputArgList from string vectors. ELFOptTable Table; unsigned MissingIndex; @@ -79,7 +79,7 @@ opt::InputArgList lld::elf2::parseArgs(l return Args; } -std::string lld::elf2::findFromSearchPaths(StringRef Path) { +std::string elf2::findFromSearchPaths(StringRef Path) { for (StringRef Dir : Config->SearchPaths) { std::string FullPath = buildSysrootedPath(Dir, Path); if (sys::fs::exists(FullPath)) @@ -90,7 +90,7 @@ std::string lld::elf2::findFromSearchPat // Searches a given library from input search paths, which are filled // from -L command line switches. Returns a path to an existent library file. -std::string lld::elf2::searchLibrary(StringRef Path) { +std::string elf2::searchLibrary(StringRef Path) { std::vector<std::string> Names; if (Path[0] == ':') { Names.push_back(Path.drop_front()); @@ -110,7 +110,7 @@ std::string lld::elf2::searchLibrary(Str // Makes a path by concatenating Dir and File. // If Dir starts with '=' the result will be preceded by Sysroot, // which can be set with --sysroot command line switch. -std::string lld::elf2::buildSysrootedPath(StringRef Dir, StringRef File) { +std::string elf2::buildSysrootedPath(StringRef Dir, StringRef File) { SmallString<128> Path; if (Dir.startswith("=")) sys::path::append(Path, Config->Sysroot, Dir.substr(1), File); Modified: vendor/lld/dist/ELF/InputFiles.cpp ============================================================================== --- vendor/lld/dist/ELF/InputFiles.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/InputFiles.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -92,7 +92,9 @@ typename ObjectFile<ELFT>::Elf_Sym_Range } template <class ELFT> uint32_t ObjectFile<ELFT>::getMipsGp0() const { - return MipsReginfo ? MipsReginfo->getGp0() : 0; + if (MipsReginfo) + return MipsReginfo->Reginfo->ri_gp_value; + return 0; } template <class ELFT> @@ -132,13 +134,13 @@ StringRef ObjectFile<ELFT>::getShtGroupS } template <class ELFT> -ArrayRef<typename ObjectFile<ELFT>::GroupEntryType> +ArrayRef<typename ObjectFile<ELFT>::uint32_X> ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { const ELFFile<ELFT> &Obj = this->ELFObj; - ErrorOr<ArrayRef<GroupEntryType>> EntriesOrErr = - Obj.template getSectionContentsAsArray<GroupEntryType>(&Sec); + ErrorOr<ArrayRef<uint32_X>> EntriesOrErr = + Obj.template getSectionContentsAsArray<uint32_X>(&Sec); error(EntriesOrErr); - ArrayRef<GroupEntryType> Entries = *EntriesOrErr; + ArrayRef<uint32_X> Entries = *EntriesOrErr; if (Entries.empty() || Entries[0] != GRP_COMDAT) error("Unsupported SHT_GROUP format"); return Entries.slice(1); @@ -187,8 +189,7 @@ void ObjectFile<ELFT>::initializeSection Sections[I] = &InputSection<ELFT>::Discarded; if (ComdatGroups.insert(getShtGroupSignature(Sec)).second) continue; - for (GroupEntryType E : getShtGroupEntries(Sec)) { - uint32_t SecIndex = E; + for (uint32_t SecIndex : getShtGroupEntries(Sec)) { if (SecIndex >= Size) error("Invalid section index in group"); Sections[SecIndex] = &InputSection<ELFT>::Discarded; Modified: vendor/lld/dist/ELF/InputFiles.h ============================================================================== --- vendor/lld/dist/ELF/InputFiles.h Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/InputFiles.h Wed Jan 13 20:06:04 2016 (r293846) @@ -91,10 +91,13 @@ template <class ELFT> class ObjectFile : typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word; typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; + // uint32 in ELFT's byte order typedef llvm::support::detail::packed_endian_specific_integral< - uint32_t, ELFT::TargetEndianness, 2> GroupEntryType; + uint32_t, ELFT::TargetEndianness, 2> + uint32_X; + StringRef getShtGroupSignature(const Elf_Shdr &Sec); - ArrayRef<GroupEntryType> getShtGroupEntries(const Elf_Shdr &Sec); + ArrayRef<uint32_X> getShtGroupEntries(const Elf_Shdr &Sec); public: static bool classof(const InputFile *F) { Modified: vendor/lld/dist/ELF/InputSection.cpp ============================================================================== --- vendor/lld/dist/ELF/InputSection.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/InputSection.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -52,7 +52,9 @@ InputSectionBase<ELFT>::getOffset(uintX_ case Merge: return cast<MergeInputSection<ELFT>>(this)->getOffset(Offset); case MipsReginfo: - return cast<MipsReginfoInputSection<ELFT>>(this)->getOffset(Offset); + // MIPS .reginfo sections are consumed by the linker, + // so it should never be copied to output. + llvm_unreachable("MIPS .reginfo reached writeTo()."); } llvm_unreachable("Invalid section kind"); } @@ -209,7 +211,6 @@ void InputSectionBase<ELFT>::relocate(ui uintX_t SymVA = getSymVA<ELFT>(*Body); if (Target->relocNeedsPlt(Type, *Body)) { SymVA = Out<ELFT>::Plt->getEntryAddr(*Body); - Type = Target->getPltRefReloc(Type); } else if (Target->relocNeedsGot(Type, *Body)) { SymVA = Out<ELFT>::Got->getEntryAddr(*Body); if (Body->isTls()) @@ -217,8 +218,13 @@ void InputSectionBase<ELFT>::relocate(ui } else if (!Target->needsCopyRel(Type, *Body) && isa<SharedSymbol<ELFT>>(*Body)) { continue; - } else if (Target->isTlsDynReloc(Type, *Body) || - Target->isSizeDynReloc(Type, *Body)) { + } else if (Target->isTlsDynReloc(Type, *Body)) { + continue; + } else if (Target->isSizeReloc(Type) && canBePreempted(Body, false)) { + // A SIZE relocation is supposed to set a symbol size, but if a symbol + // can be preempted, the size at runtime may be different than link time. + // If that's the case, we leave the field alone rather than filling it + // with a possibly incorrect value. continue; } else if (Config->EMachine == EM_MIPS) { if (Type == R_MIPS_HI16 && Body == Config->MipsGpDisp) @@ -346,22 +352,13 @@ MergeInputSection<ELFT>::getOffset(uintX template <class ELFT> MipsReginfoInputSection<ELFT>::MipsReginfoInputSection(ObjectFile<ELFT> *F, - const Elf_Shdr *Header) - : InputSectionBase<ELFT>(F, Header, InputSectionBase<ELFT>::MipsReginfo) {} - -template <class ELFT> -uint32_t MipsReginfoInputSection<ELFT>::getGeneralMask() const { - ArrayRef<uint8_t> D = this->getSectionData(); - if (D.size() != sizeof(Elf_Mips_RegInfo)) - error("Invalid size of .reginfo section"); - return reinterpret_cast<const Elf_Mips_RegInfo *>(D.data())->ri_gprmask; -} - -template <class ELFT> uint32_t MipsReginfoInputSection<ELFT>::getGp0() const { + const Elf_Shdr *Hdr) + : InputSectionBase<ELFT>(F, Hdr, InputSectionBase<ELFT>::MipsReginfo) { + // Initialize this->Reginfo. ArrayRef<uint8_t> D = this->getSectionData(); - if (D.size() != sizeof(Elf_Mips_RegInfo)) + if (D.size() != sizeof(Elf_Mips_RegInfo<ELFT>)) error("Invalid size of .reginfo section"); - return reinterpret_cast<const Elf_Mips_RegInfo *>(D.data())->ri_gp_value; + Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(D.data()); } template <class ELFT> Modified: vendor/lld/dist/ELF/InputSection.h ============================================================================== --- vendor/lld/dist/ELF/InputSection.h Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/InputSection.h Wed Jan 13 20:06:04 2016 (r293846) @@ -177,16 +177,13 @@ public: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf template <class ELFT> class MipsReginfoInputSection : public InputSectionBase<ELFT> { - typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo; typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; public: - MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header); - - uint32_t getGeneralMask() const; - uint32_t getGp0() const; - + MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr); static bool classof(const InputSectionBase<ELFT> *S); + + const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo; }; } // namespace elf2 Modified: vendor/lld/dist/ELF/LinkerScript.cpp ============================================================================== --- vendor/lld/dist/ELF/LinkerScript.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/LinkerScript.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -312,7 +312,7 @@ static bool isUnderSysroot(StringRef Pat } // Entry point. The other functions or classes are private to this file. -void lld::elf2::readLinkerScript(BumpPtrAllocator *A, MemoryBufferRef MB) { +void elf2::readLinkerScript(BumpPtrAllocator *A, MemoryBufferRef MB) { StringRef Path = MB.getBufferIdentifier(); LinkerScript(A, MB.getBuffer(), isUnderSysroot(Path)).run(); } Modified: vendor/lld/dist/ELF/MarkLive.cpp ============================================================================== --- vendor/lld/dist/ELF/MarkLive.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/MarkLive.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -79,7 +79,7 @@ template <class ELFT> static bool isRese // This is the main function of the garbage collector. // Starting from GC-root sections, this function visits all reachable // sections to set their "Live" bits. -template <class ELFT> void lld::elf2::markLive(SymbolTable<ELFT> *Symtab) { +template <class ELFT> void elf2::markLive(SymbolTable<ELFT> *Symtab) { SmallVector<InputSection<ELFT> *, 256> Q; auto Enqueue = [&](InputSectionBase<ELFT> *Sec) { @@ -116,16 +116,15 @@ template <class ELFT> void lld::elf2::ma // Preserve special sections. for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab->getObjectFiles()) for (InputSectionBase<ELFT> *Sec : F->getSections()) - if (Sec && Sec != &InputSection<ELFT>::Discarded) - if (isReserved(Sec)) - Enqueue(Sec); + if (Sec && Sec != &InputSection<ELFT>::Discarded && isReserved(Sec)) + Enqueue(Sec); // Mark all reachable sections. while (!Q.empty()) forEachSuccessor<ELFT>(Q.pop_back_val(), Enqueue); } -template void lld::elf2::markLive<ELF32LE>(SymbolTable<ELF32LE> *); -template void lld::elf2::markLive<ELF32BE>(SymbolTable<ELF32BE> *); -template void lld::elf2::markLive<ELF64LE>(SymbolTable<ELF64LE> *); -template void lld::elf2::markLive<ELF64BE>(SymbolTable<ELF64BE> *); +template void elf2::markLive<ELF32LE>(SymbolTable<ELF32LE> *); +template void elf2::markLive<ELF32BE>(SymbolTable<ELF32BE> *); +template void elf2::markLive<ELF64LE>(SymbolTable<ELF64LE> *); +template void elf2::markLive<ELF64BE>(SymbolTable<ELF64BE> *); Modified: vendor/lld/dist/ELF/Options.td ============================================================================== --- vendor/lld/dist/ELF/Options.td Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/Options.td Wed Jan 13 20:06:04 2016 (r293846) @@ -109,6 +109,9 @@ def verbose : Flag<["--"], "verbose">; def whole_archive : Flag<["--", "-"], "whole-archive">, HelpText<"Force load of all members in a static library">; +def wrap : Separate<["--", "-"], "wrap">, MetaVarName<"<symbol>">, + HelpText<"Use wrapper functions for symbol">; + def z : JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">, HelpText<"Linker option extensions">; @@ -136,6 +139,7 @@ def alias_soname_soname : Separate<["-"] def alias_script_T : Separate<["-"], "T">, Alias<script>; def alias_strip_all: Flag<["-"], "s">, Alias<strip_all>; def alias_undefined_u : Separate<["-"], "u">, Alias<undefined>; +def alias_wrap_wrap : Joined<["--", "-"], "wrap=">, Alias<wrap>; // Our symbol resolution algorithm handles symbols in archive files differently // than traditional linkers, so we don't need --start-group and --end-group. Modified: vendor/lld/dist/ELF/OutputSections.cpp ============================================================================== --- vendor/lld/dist/ELF/OutputSections.cpp Wed Jan 13 20:05:34 2016 (r293845) +++ vendor/lld/dist/ELF/OutputSections.cpp Wed Jan 13 20:06:04 2016 (r293846) @@ -21,21 +21,20 @@ using namespace llvm::ELF; using namespace lld; using namespace lld::elf2; -bool lld::elf2::HasGotOffRel = false; +bool elf2::HasGotOffRel = false; template <class ELFT> -OutputSectionBase<ELFT>::OutputSectionBase(StringRef Name, uint32_t sh_type, - uintX_t sh_flags) +OutputSectionBase<ELFT>::OutputSectionBase(StringRef Name, uint32_t Type, + uintX_t Flags) : Name(Name) { memset(&Header, 0, sizeof(Elf_Shdr)); - Header.sh_type = sh_type; - Header.sh_flags = sh_flags; + Header.sh_type = Type; + Header.sh_flags = Flags; } template <class ELFT> GotPltSection<ELFT>::GotPltSection() - : OutputSectionBase<ELFT>(".got.plt", llvm::ELF::SHT_PROGBITS, - llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE) { + : OutputSectionBase<ELFT>(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) { this->Header.sh_addralign = sizeof(uintX_t); } @@ -70,10 +69,9 @@ template <class ELFT> void GotPltSection template <class ELFT> GotSection<ELFT>::GotSection() - : OutputSectionBase<ELFT>(".got", llvm::ELF::SHT_PROGBITS, - llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE) { + : OutputSectionBase<ELFT>(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) { if (Config->EMachine == EM_MIPS) - this->Header.sh_flags |= llvm::ELF::SHF_MIPS_GPREL; + this->Header.sh_flags |= SHF_MIPS_GPREL; this->Header.sh_addralign = sizeof(uintX_t); } @@ -120,7 +118,7 @@ const SymbolBody *GotSection<ELFT>::getM template <class ELFT> unsigned GotSection<ELFT>::getMipsLocalEntriesNum() const { - // TODO: Update when the suppoort of GOT entries for local symbols is added. + // TODO: Update when the support of GOT entries for local symbols is added. return Target->getGotHeaderEntriesNum(); } @@ -151,8 +149,7 @@ template <class ELFT> void GotSection<EL template <class ELFT> PltSection<ELFT>::PltSection() - : OutputSectionBase<ELFT>(".plt", llvm::ELF::SHT_PROGBITS, - llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR) { + : OutputSectionBase<ELFT>(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) { this->Header.sh_addralign = 16; } @@ -199,9 +196,7 @@ template <class ELFT> void PltSection<EL template <class ELFT> RelocationSection<ELFT>::RelocationSection(StringRef Name, bool IsRela) - : OutputSectionBase<ELFT>(Name, - IsRela ? llvm::ELF::SHT_RELA : llvm::ELF::SHT_REL, - llvm::ELF::SHF_ALLOC), + : OutputSectionBase<ELFT>(Name, IsRela ? SHT_RELA : SHT_REL, SHF_ALLOC), IsRela(IsRela) { this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; @@ -328,15 +323,14 @@ template <class ELFT> void RelocationSec template <class ELFT> InterpSection<ELFT>::InterpSection() - : OutputSectionBase<ELFT>(".interp", llvm::ELF::SHT_PROGBITS, - llvm::ELF::SHF_ALLOC) { + : OutputSectionBase<ELFT>(".interp", SHT_PROGBITS, SHF_ALLOC) { this->Header.sh_size = Config->DynamicLinker.size() + 1; this->Header.sh_addralign = 1; } template <class ELFT> void OutputSectionBase<ELFT>::writeHeaderTo(Elf_Shdr *SHdr) { - Header.sh_name = Out<ELFT>::ShStrTab->getOffset(Name); + Header.sh_name = Out<ELFT>::ShStrTab->addString(Name); *SHdr = Header; } @@ -346,8 +340,7 @@ template <class ELFT> void InterpSection template <class ELFT> HashTableSection<ELFT>::HashTableSection() - : OutputSectionBase<ELFT>(".hash", llvm::ELF::SHT_HASH, - llvm::ELF::SHF_ALLOC) { + : OutputSectionBase<ELFT>(".hash", SHT_HASH, SHF_ALLOC) { this->Header.sh_entsize = sizeof(Elf_Word); this->Header.sh_addralign = sizeof(Elf_Word); } @@ -404,8 +397,7 @@ static uint32_t hashGnu(StringRef Name) template <class ELFT> GnuHashTableSection<ELFT>::GnuHashTableSection() - : OutputSectionBase<ELFT>(".gnu.hash", llvm::ELF::SHT_GNU_HASH, - llvm::ELF::SHF_ALLOC) { + : OutputSectionBase<ELFT>(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) { this->Header.sh_entsize = ELFT::Is64Bits ? 0 : 4; this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; } @@ -545,8 +537,7 @@ void GnuHashTableSection<ELFT>::addSymbo template <class ELFT> DynamicSection<ELFT>::DynamicSection(SymbolTable<ELFT> &SymTab) - : OutputSectionBase<ELFT>(".dynamic", llvm::ELF::SHT_DYNAMIC, - llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE), + : OutputSectionBase<ELFT>(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE), SymTab(SymTab) { Elf_Shdr &Header = this->Header; Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; @@ -556,7 +547,7 @@ DynamicSection<ELFT>::DynamicSection(Sym // See "Special Section" in Chapter 4 in the following document: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf if (Config->EMachine == EM_MIPS) - Header.sh_flags = llvm::ELF::SHF_ALLOC; + Header.sh_flags = SHF_ALLOC; } template <class ELFT> void DynamicSection<ELFT>::finalize() { @@ -590,12 +581,12 @@ template <class ELFT> void DynamicSectio if (!Config->RPath.empty()) { ++NumEntries; // DT_RUNPATH / DT_RPATH - Out<ELFT>::DynStrTab->add(Config->RPath); + Out<ELFT>::DynStrTab->reserve(Config->RPath); } if (!Config->SoName.empty()) { ++NumEntries; // DT_SONAME - Out<ELFT>::DynStrTab->add(Config->SoName); + Out<ELFT>::DynStrTab->reserve(Config->SoName); } if (PreInitArraySec) @@ -608,7 +599,7 @@ template <class ELFT> void DynamicSectio for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles()) { if (!F->isNeeded()) continue; - Out<ELFT>::DynStrTab->add(F->getSoName()); + Out<ELFT>::DynStrTab->reserve(F->getSoName()); ++NumEntries; } @@ -696,7 +687,7 @@ template <class ELFT> void DynamicSectio WritePtr(DT_SYMTAB, Out<ELFT>::DynSymTab->getVA()); WritePtr(DT_SYMENT, sizeof(Elf_Sym)); WritePtr(DT_STRTAB, Out<ELFT>::DynStrTab->getVA()); - WriteVal(DT_STRSZ, Out<ELFT>::DynStrTab->data().size()); + WriteVal(DT_STRSZ, Out<ELFT>::DynStrTab->getSize()); if (Out<ELFT>::GnuHashTab) WritePtr(DT_GNU_HASH, Out<ELFT>::GnuHashTab->getVA()); if (Out<ELFT>::HashTab) @@ -712,10 +703,10 @@ template <class ELFT> void DynamicSectio // DT_RPATH is used for indirect dependencies as well. if (!Config->RPath.empty()) WriteVal(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, - Out<ELFT>::DynStrTab->getOffset(Config->RPath)); + Out<ELFT>::DynStrTab->addString(Config->RPath)); if (!Config->SoName.empty()) - WriteVal(DT_SONAME, Out<ELFT>::DynStrTab->getOffset(Config->SoName)); + WriteVal(DT_SONAME, Out<ELFT>::DynStrTab->addString(Config->SoName)); auto WriteArray = [&](int32_t T1, int32_t T2, const OutputSectionBase<ELFT> *Sec) { @@ -730,7 +721,7 @@ template <class ELFT> void DynamicSectio for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles()) if (F->isNeeded()) - WriteVal(DT_NEEDED, Out<ELFT>::DynStrTab->getOffset(F->getSoName())); + WriteVal(DT_NEEDED, Out<ELFT>::DynStrTab->addString(F->getSoName())); if (InitSym) WritePtr(DT_INIT, getSymVA<ELFT>(*InitSym)); @@ -765,9 +756,9 @@ template <class ELFT> void DynamicSectio } template <class ELFT> -OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t sh_type, - uintX_t sh_flags) - : OutputSectionBase<ELFT>(Name, sh_type, sh_flags) {} +OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type, + uintX_t Flags) + : OutputSectionBase<ELFT>(Name, Type, Flags) {} template <class ELFT> void OutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) { @@ -779,14 +770,14 @@ void OutputSection<ELFT>::addSection(Inp this->Header.sh_addralign = Align; uintX_t Off = this->Header.sh_size; - Off = RoundUpToAlignment(Off, Align); + Off = align(Off, Align); S->OutSecOff = Off; Off += S->getSize(); this->Header.sh_size = Off; } template <class ELFT> -typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) { +typename ELFFile<ELFT>::uintX_t elf2::getSymVA(const SymbolBody &S) { switch (S.kind()) { case SymbolBody::DefinedSyntheticKind: { auto &D = cast<DefinedSynthetic<ELFT>>(S); @@ -797,6 +788,11 @@ typename ELFFile<ELFT>::uintX_t lld::elf InputSectionBase<ELFT> *SC = DR.Section; if (!SC) return DR.Sym.st_value; + + // Symbol offsets for AMDGPU need to be the offset in bytes of the symbol + // from the beginning of the section. + if (Config->EMachine == EM_AMDGPU) + return SC->getOffset(DR.Sym); if (DR.Sym.getType() == STT_TLS) return SC->OutSec->getVA() + SC->getOffset(DR.Sym) - Out<ELFT>::TlsPhdr->p_vaddr; @@ -824,9 +820,9 @@ typename ELFFile<ELFT>::uintX_t lld::elf // For non-local symbols, use getSymVA instead. template <class ELFT, bool IsRela> typename ELFFile<ELFT>::uintX_t -lld::elf2::getLocalRelTarget(const ObjectFile<ELFT> &File, - const Elf_Rel_Impl<ELFT, IsRela> &RI, - typename ELFFile<ELFT>::uintX_t Addend) { +elf2::getLocalRelTarget(const ObjectFile<ELFT> &File, + const Elf_Rel_Impl<ELFT, IsRela> &RI, + typename ELFFile<ELFT>::uintX_t Addend) { typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; typedef typename ELFFile<ELFT>::uintX_t uintX_t; @@ -868,7 +864,7 @@ lld::elf2::getLocalRelTarget(const Objec // Returns true if a symbol can be replaced at load-time by a symbol // with the same name defined in other ELF executable or DSO. -bool lld::elf2::canBePreempted(const SymbolBody *Body, bool NeedsGot) { +bool elf2::canBePreempted(const SymbolBody *Body, bool NeedsGot) { if (!Body) return false; // Body is a local symbol. if (Body->isShared()) @@ -910,9 +906,9 @@ template <class ELFT> void OutputSection } template <class ELFT> -EHOutputSection<ELFT>::EHOutputSection(StringRef Name, uint32_t sh_type, - uintX_t sh_flags) - : OutputSectionBase<ELFT>(Name, sh_type, sh_flags) {} +EHOutputSection<ELFT>::EHOutputSection(StringRef Name, uint32_t Type, + uintX_t Flags) + : OutputSectionBase<ELFT>(Name, Type, Flags) {} template <class ELFT> EHRegion<ELFT>::EHRegion(EHInputSection<ELFT> *S, unsigned Index) @@ -980,7 +976,7 @@ void EHOutputSection<ELFT>::addSectionAu auto P = CieMap.insert(std::make_pair(CieInfo, Cies.size())); if (P.second) { Cies.push_back(C); - this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t)); + this->Header.sh_size += align(Length, sizeof(uintX_t)); } OffsetToIndex[Offset] = P.first->second; } else { @@ -993,7 +989,7 @@ void EHOutputSection<ELFT>::addSectionAu if (I == OffsetToIndex.end()) error("Invalid CIE reference"); Cies[I->second].Fdes.push_back(EHRegion<ELFT>(S, Index)); - this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t)); + this->Header.sh_size += align(Length, sizeof(uintX_t)); } } @@ -1046,7 +1042,7 @@ static typename ELFFile<ELFT>::uintX_t w uint8_t *Buf) { typedef typename ELFFile<ELFT>::uintX_t uintX_t; const endianness E = ELFT::TargetEndianness; - uint64_t Len = RoundUpToAlignment(Data.size(), sizeof(uintX_t)); + uint64_t Len = align(Data.size(), sizeof(uintX_t)); write32<E>(Buf, Len - 4); memcpy(Buf + 4, Data.data() + 4, Data.size() - 4); return Len; @@ -1083,9 +1079,9 @@ template <class ELFT> void EHOutputSecti } template <class ELFT> -MergeOutputSection<ELFT>::MergeOutputSection(StringRef Name, uint32_t sh_type, - uintX_t sh_flags) - : OutputSectionBase<ELFT>(Name, sh_type, sh_flags) {} +MergeOutputSection<ELFT>::MergeOutputSection(StringRef Name, uint32_t Type, *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601132006.u0DK64vn087964>