svn commit: r319788 - in vendor/lld/dist: COFF ELF include/lld/Core include/lld/ReaderWriter lib/Core lib/Driver lib/ReaderWriter lib/ReaderWriter/MachO lib/ReaderWriter/YAML test test/COFF test/EL...
Dimitry Andric
dim at FreeBSD.org
Sat Jun 10 13:44:53 UTC 2017
Author: dim
Date: Sat Jun 10 13:44:49 2017
New Revision: 319788
URL: https://svnweb.freebsd.org/changeset/base/319788
Log:
Vendor import of lld trunk r305145:
https://llvm.org/svn/llvm-project/lld/trunk@305145
Added:
vendor/lld/dist/test/ELF/Inputs/relocatable-comdat-multiple.s (contents, props changed)
vendor/lld/dist/test/ELF/arm-thumb-thunk-symbols.s (contents, props changed)
vendor/lld/dist/test/ELF/dso_handle.s (contents, props changed)
vendor/lld/dist/test/ELF/i386-reloc-large-addend.s (contents, props changed)
vendor/lld/dist/test/ELF/i386-reloc-range.s (contents, props changed)
vendor/lld/dist/test/ELF/icf-comdat.s (contents, props changed)
vendor/lld/dist/test/ELF/linkerscript/emit-relocs-multiple.s (contents, props changed)
vendor/lld/dist/test/ELF/linkerscript/noload.s (contents, props changed)
vendor/lld/dist/test/ELF/lto/Inputs/defsym-bar.ll
vendor/lld/dist/test/ELF/lto/Inputs/wrap-bar.ll
vendor/lld/dist/test/ELF/lto/defsym.ll
vendor/lld/dist/test/ELF/lto/wrap-1.ll
vendor/lld/dist/test/ELF/lto/wrap-2.ll
vendor/lld/dist/test/ELF/mips-npic-call-pic-script.s (contents, props changed)
vendor/lld/dist/test/ELF/relocatable-comdat-multiple.s (contents, props changed)
vendor/lld/dist/test/ELF/relocatable-compressed-input.s (contents, props changed)
vendor/lld/dist/test/ELF/relocatable-empty-archive.s (contents, props changed)
Modified:
vendor/lld/dist/COFF/CMakeLists.txt
vendor/lld/dist/COFF/Chunks.cpp
vendor/lld/dist/COFF/Driver.cpp
vendor/lld/dist/COFF/InputFiles.cpp
vendor/lld/dist/ELF/CMakeLists.txt
vendor/lld/dist/ELF/Config.h
vendor/lld/dist/ELF/Driver.cpp
vendor/lld/dist/ELF/EhFrame.cpp
vendor/lld/dist/ELF/GdbIndex.h
vendor/lld/dist/ELF/ICF.cpp
vendor/lld/dist/ELF/InputFiles.cpp
vendor/lld/dist/ELF/InputSection.cpp
vendor/lld/dist/ELF/InputSection.h
vendor/lld/dist/ELF/LTO.cpp
vendor/lld/dist/ELF/LinkerScript.cpp
vendor/lld/dist/ELF/LinkerScript.h
vendor/lld/dist/ELF/Mips.cpp
vendor/lld/dist/ELF/OutputSections.cpp
vendor/lld/dist/ELF/OutputSections.h
vendor/lld/dist/ELF/Relocations.cpp
vendor/lld/dist/ELF/Relocations.h
vendor/lld/dist/ELF/ScriptParser.cpp
vendor/lld/dist/ELF/SymbolTable.cpp
vendor/lld/dist/ELF/SymbolTable.h
vendor/lld/dist/ELF/Symbols.cpp
vendor/lld/dist/ELF/SyntheticSections.cpp
vendor/lld/dist/ELF/SyntheticSections.h
vendor/lld/dist/ELF/Target.cpp
vendor/lld/dist/ELF/Thunks.cpp
vendor/lld/dist/ELF/Writer.cpp
vendor/lld/dist/include/lld/Core/Reader.h
vendor/lld/dist/include/lld/ReaderWriter/MachOLinkingContext.h
vendor/lld/dist/lib/Core/CMakeLists.txt
vendor/lld/dist/lib/Core/Reader.cpp
vendor/lld/dist/lib/Core/SymbolTable.cpp
vendor/lld/dist/lib/Driver/DarwinLdDriver.cpp
vendor/lld/dist/lib/ReaderWriter/FileArchive.cpp
vendor/lld/dist/lib/ReaderWriter/MachO/ExecutableAtoms.h
vendor/lld/dist/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFile.h
vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
vendor/lld/dist/lib/ReaderWriter/MachO/WriterMachO.cpp
vendor/lld/dist/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
vendor/lld/dist/test/CMakeLists.txt
vendor/lld/dist/test/COFF/pdb-none.test
vendor/lld/dist/test/COFF/pdb.test
vendor/lld/dist/test/ELF/aarch64-undefined-weak.s
vendor/lld/dist/test/ELF/amdgpu-globals.s
vendor/lld/dist/test/ELF/amdgpu-kernels.s
vendor/lld/dist/test/ELF/arm-icf-exidx.s
vendor/lld/dist/test/ELF/arm-thumb-no-undefined-thunk.s
vendor/lld/dist/test/ELF/arm-thumb-undefined-weak.s
vendor/lld/dist/test/ELF/arm-undefined-weak.s
vendor/lld/dist/test/ELF/ehdr_start.s
vendor/lld/dist/test/ELF/emit-relocs-merge.s
vendor/lld/dist/test/ELF/gdb-index-empty.s
vendor/lld/dist/test/ELF/linkerscript/early-assign-symbol.s
vendor/lld/dist/test/ELF/linkerscript/expr-invalid-sec.s
vendor/lld/dist/unittests/DriverTests/DarwinLdDriverTest.cpp
vendor/lld/dist/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
vendor/lld/dist/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
vendor/lld/dist/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
vendor/lld/dist/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp
Modified: vendor/lld/dist/COFF/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/COFF/CMakeLists.txt Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/COFF/CMakeLists.txt Sat Jun 10 13:44:49 2017 (r319788)
@@ -25,6 +25,7 @@ add_lld_library(lldCOFF
LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
+ BinaryFormat
BitReader
Core
DebugInfoCodeView
Modified: vendor/lld/dist/COFF/Chunks.cpp
==============================================================================
--- vendor/lld/dist/COFF/Chunks.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/COFF/Chunks.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -12,8 +12,8 @@
#include "InputFiles.h"
#include "Symbols.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/COFF.h"
-#include "llvm/Support/COFF.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/raw_ostream.h"
Modified: vendor/lld/dist/COFF/Driver.cpp
==============================================================================
--- vendor/lld/dist/COFF/Driver.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/COFF/Driver.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -18,6 +18,7 @@
#include "lld/Driver/Driver.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Object/ArchiveWriter.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/COFFModuleDefinition.h"
@@ -40,8 +41,6 @@ using namespace llvm;
using namespace llvm::object;
using namespace llvm::COFF;
using llvm::sys::Process;
-using llvm::sys::fs::file_magic;
-using llvm::sys::fs::identify_magic;
namespace lld {
namespace coff {
@@ -457,17 +456,11 @@ static void createImportLibrary() {
static void parseModuleDefs(StringRef Path) {
std::unique_ptr<MemoryBuffer> MB = check(
MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
- MemoryBufferRef MBRef = MB->getMemBufferRef();
+ COFFModuleDefinition M =
+ check(parseCOFFModuleDefinition(MB->getMemBufferRef(), Config->Machine));
- Expected<COFFModuleDefinition> Def =
- parseCOFFModuleDefinition(MBRef, Config->Machine);
- if (!Def)
- fatal(errorToErrorCode(Def.takeError()).message());
-
- COFFModuleDefinition &M = *Def;
if (Config->OutputFile.empty())
Config->OutputFile = Saver.save(M.OutputFile);
-
if (M.ImageBase)
Config->ImageBase = M.ImageBase;
if (M.StackReserve)
Modified: vendor/lld/dist/COFF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/COFF/InputFiles.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/COFF/InputFiles.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -19,9 +19,9 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/COFF.h"
-#include "llvm/Support/COFF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
Modified: vendor/lld/dist/ELF/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/ELF/CMakeLists.txt Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/CMakeLists.txt Sat Jun 10 13:44:49 2017 (r319788)
@@ -36,6 +36,7 @@ add_lld_library(lldELF
LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
Analysis
+ BinaryFormat
BitReader
BitWriter
Codegen
Modified: vendor/lld/dist/ELF/Config.h
==============================================================================
--- vendor/lld/dist/ELF/Config.h Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/Config.h Sat Jun 10 13:44:49 2017 (r319788)
@@ -13,9 +13,9 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/CachePruning.h"
#include "llvm/Support/CodeGen.h"
-#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
#include <vector>
@@ -67,6 +67,12 @@ struct VersionDefinition {
size_t NameOff = 0; // Offset in the string table
};
+// Structure for mapping renamed symbols
+struct RenamedSymbol {
+ Symbol *Target;
+ uint8_t OrigBinding;
+};
+
// 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.
@@ -98,6 +104,7 @@ struct Configuration {
std::vector<SymbolVersion> VersionScriptGlobals;
std::vector<SymbolVersion> VersionScriptLocals;
std::vector<uint8_t> BuildIdVector;
+ llvm::MapVector<Symbol *, RenamedSymbol> RenamedSymbols;
bool AllowMultipleDefinition;
bool AsNeeded = false;
bool Bsymbolic;
Modified: vendor/lld/dist/ELF/Driver.cpp
==============================================================================
--- vendor/lld/dist/ELF/Driver.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/Driver.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -185,7 +185,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLO
// is attempting LTO and using a default ar command that doesn't
// understand the LLVM bitcode file. It is a pretty common error, so
// we'll handle it as if it had a symbol table.
- if (!File->hasSymbolTable()) {
+ if (!File->isEmpty() && !File->hasSymbolTable()) {
for (const auto &P : getArchiveMembers(MBRef))
Files.push_back(make<LazyObjectFile>(P.first, Path, P.second));
return;
@@ -970,6 +970,14 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
Symtab.scanShlibUndefined();
Symtab.scanVersionScript();
+ // Create wrapped symbols for -wrap option.
+ for (auto *Arg : Args.filtered(OPT_wrap))
+ Symtab.addSymbolWrap(Arg->getValue());
+
+ // Create alias symbols for -defsym option.
+ for (std::pair<StringRef, StringRef> &Def : getDefsym(Args))
+ Symtab.addSymbolAlias(Def.first, Def.second);
+
Symtab.addCombinedLTOObject();
if (ErrorCount)
return;
@@ -979,12 +987,8 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
for (StringRef Sym : Script->Opt.ReferencedSymbols)
Symtab.addUndefined(Sym);
- for (auto *Arg : Args.filtered(OPT_wrap))
- Symtab.wrap(Arg->getValue());
-
- // Handle --defsym=sym=alias option.
- for (std::pair<StringRef, StringRef> &Def : getDefsym(Args))
- Symtab.alias(Def.first, Def.second);
+ // Apply symbol renames for -wrap and -defsym
+ Symtab.applySymbolRenames();
// Now that we have a complete list of input files.
// Beyond this point, no new files are added.
Modified: vendor/lld/dist/ELF/EhFrame.cpp
==============================================================================
--- vendor/lld/dist/ELF/EhFrame.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/EhFrame.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -22,8 +22,8 @@
#include "Relocations.h"
#include "Strings.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Object/ELF.h"
-#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
Modified: vendor/lld/dist/ELF/GdbIndex.h
==============================================================================
--- vendor/lld/dist/ELF/GdbIndex.h Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/GdbIndex.h Sat Jun 10 13:44:49 2017 (r319788)
@@ -24,7 +24,30 @@ struct AddressEntry {
InputSection *Section;
uint64_t LowAddress;
uint64_t HighAddress;
- size_t CuIndex;
+ uint32_t CuIndex;
+};
+
+// Struct represents single entry of compilation units list area of gdb index.
+// It consist of CU offset in .debug_info section and it's size.
+struct CompilationUnitEntry {
+ uint64_t CuOffset;
+ uint64_t CuLength;
+};
+
+// Represents data about symbol and type names which are used
+// to build symbol table and constant pool area of gdb index.
+struct NameTypeEntry {
+ StringRef Name;
+ uint8_t Type;
+};
+
+// We fill one GdbIndexDataChunk for each object where scan of
+// debug information performed. That information futher used
+// for filling gdb index section areas.
+struct GdbIndexChunk {
+ std::vector<AddressEntry> AddressArea;
+ std::vector<CompilationUnitEntry> CompilationUnits;
+ std::vector<NameTypeEntry> NamesAndTypes;
};
// Element of GdbHashTab hash table.
Modified: vendor/lld/dist/ELF/ICF.cpp
==============================================================================
--- vendor/lld/dist/ELF/ICF.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/ICF.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -78,8 +78,8 @@
#include "SymbolTable.h"
#include "Threads.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
#include <algorithm>
#include <atomic>
Modified: vendor/lld/dist/ELF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputFiles.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/InputFiles.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -306,21 +306,23 @@ void elf::ObjectFile<ELFT>::initializeSections(
switch (Sec.sh_type) {
case SHT_GROUP: {
- // We discard comdat sections usually. When -r we should not do that. We
- // still do deduplication in this case to simplify implementation, because
- // otherwise merging group sections together would requre additional
- // regeneration of its contents.
- bool New = ComdatGroups
- .insert(CachedHashStringRef(
- getShtGroupSignature(ObjSections, Sec)))
- .second;
- if (New && Config->Relocatable)
- this->Sections[I] = createInputSection(Sec, SectionStringTable);
- else
- this->Sections[I] = &InputSection::Discarded;
- if (New)
+ // De-duplicate section groups by their signatures.
+ StringRef Signature = getShtGroupSignature(ObjSections, Sec);
+ bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
+ this->Sections[I] = &InputSection::Discarded;
+
+ // If it is a new section group, we want to keep group members.
+ // Group leader sections, which contain indices of group members, are
+ // discarded because they are useless beyond this point. The only
+ // exception is the -r option because in order to produce re-linkable
+ // object files, we want to pass through basically everything.
+ if (IsNew) {
+ if (Config->Relocatable)
+ this->Sections[I] = createInputSection(Sec, SectionStringTable);
continue;
+ }
+ // Otherwise, discard group members.
for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
if (SecIndex >= Size)
fatal(toString(this) +
Modified: vendor/lld/dist/ELF/InputSection.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputSection.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/InputSection.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -20,6 +20,7 @@
#include "Target.h"
#include "Thunks.h"
#include "llvm/Object/Decompressor.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Path.h"
@@ -72,6 +73,16 @@ InputSectionBase::InputSectionBase(InputFile *File, ui
this->Alignment = V;
}
+// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
+// SHF_GROUP is a marker that a section belongs to some comdat group.
+// That flag doesn't make sense in an executable.
+static uint64_t getFlags(uint64_t Flags) {
+ Flags &= ~(uint64_t)SHF_INFO_LINK;
+ if (!Config->Relocatable)
+ Flags &= ~(uint64_t)SHF_GROUP;
+ return Flags;
+}
+
// GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
// March 2017) fail to infer section types for sections starting with
// ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of
@@ -94,7 +105,7 @@ template <class ELFT>
InputSectionBase::InputSectionBase(elf::ObjectFile<ELFT> *File,
const typename ELFT::Shdr *Hdr,
StringRef Name, Kind SectionKind)
- : InputSectionBase(File, Hdr->sh_flags & ~SHF_INFO_LINK,
+ : InputSectionBase(File, getFlags(Hdr->sh_flags),
getType(Hdr->sh_type, Name), Hdr->sh_entsize,
Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
getSectionContents(File, Hdr), Name, SectionKind) {
@@ -308,23 +319,21 @@ OutputSection *InputSection::getParent() const {
return cast_or_null<OutputSection>(Parent);
}
-void InputSection::copyShtGroup(uint8_t *Buf) {
- assert(this->Type == SHT_GROUP);
+// Copy SHT_GROUP section contents. Used only for the -r option.
+template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) {
+ // ELFT::Word is the 32-bit integral type in the target endianness.
+ typedef typename ELFT::Word u32;
+ ArrayRef<u32> From = getDataAs<u32>();
+ auto *To = reinterpret_cast<u32 *>(Buf);
- ArrayRef<uint32_t> From = getDataAs<uint32_t>();
- uint32_t *To = reinterpret_cast<uint32_t *>(Buf);
-
- // First entry is a flag word, we leave it unchanged.
+ // The first entry is not a section number but a flag.
*To++ = From[0];
- // Here we adjust indices of sections that belong to group as it
- // might change during linking.
+ // Adjust section numbers because section numbers in an input object
+ // files are different in the output.
ArrayRef<InputSectionBase *> Sections = this->File->getSections();
- for (uint32_t Val : From.slice(1)) {
- uint32_t Index = read32(&Val, Config->Endianness);
- write32(To++, Sections[Index]->getOutputSection()->SectionIndex,
- Config->Endianness);
- }
+ for (uint32_t Idx : From.slice(1))
+ *To++ = Sections[Idx]->getOutputSection()->SectionIndex;
}
InputSectionBase *InputSection::getRelocatedSection() {
@@ -682,7 +691,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uin
// Patch a nop (0x60000000) to a ld.
if (BufLoc + 8 <= BufEnd && read32be(BufLoc + 4) == 0x60000000)
write32be(BufLoc + 4, 0xe8410028); // ld %r2, 40(%r1)
- // fallthrough
+ LLVM_FALLTHROUGH;
default:
Target->relocateOne(BufLoc, Type, TargetVA);
break;
@@ -712,10 +721,9 @@ template <class ELFT> void InputSection::writeTo(uint8
return;
}
- // If -r is given, linker should keep SHT_GROUP sections. We should fixup
- // them, see copyShtGroup().
+ // If -r is given, we may have a SHT_GROUP section.
if (this->Type == SHT_GROUP) {
- copyShtGroup(Buf + OutSecOff);
+ copyShtGroup<ELFT>(Buf + OutSecOff);
return;
}
Modified: vendor/lld/dist/ELF/InputSection.h
==============================================================================
--- vendor/lld/dist/ELF/InputSection.h Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/InputSection.h Sat Jun 10 13:44:49 2017 (r319788)
@@ -325,7 +325,7 @@ class InputSection : public InputSectionBase { (privat
template <class ELFT, class RelTy>
void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
- void copyShtGroup(uint8_t *Buf);
+ template <class ELFT> void copyShtGroup(uint8_t *Buf);
};
// The list of all input sections.
Modified: vendor/lld/dist/ELF/LTO.cpp
==============================================================================
--- vendor/lld/dist/ELF/LTO.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/LTO.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -17,13 +17,13 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/LTO/Caching.h"
#include "llvm/LTO/Config.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/CodeGen.h"
-#include "llvm/Support/ELF.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -136,6 +136,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {
Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym());
if (R.Prevailing)
undefine(Sym);
+ R.LinkerRedefined = Config->RenamedSymbols.count(Sym);
}
checkError(LTOObj->add(std::move(F.Obj), Resols));
}
Modified: vendor/lld/dist/ELF/LinkerScript.cpp
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/LinkerScript.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -25,9 +25,9 @@
#include "Writer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compression.h"
-#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
@@ -54,7 +54,7 @@ uint64_t ExprValue::getValue() const {
if (Sec) {
if (OutputSection *OS = Sec->getOutputSection())
return alignTo(Sec->getOffset(Val) + OS->Addr, Alignment);
- error("unable to evaluate expression: input section " + Sec->Name +
+ error(Loc + ": unable to evaluate expression: input section " + Sec->Name +
" has no output section assigned");
}
return alignTo(Val, Alignment);
@@ -431,6 +431,8 @@ void LinkerScript::processCommands(OutputSectionFactor
if (OutputSection *Sec = Cmd->Sec) {
assert(Sec->SectionIndex == INT_MAX);
Sec->SectionIndex = I;
+ if (Cmd->Noload)
+ Sec->Type = SHT_NOBITS;
SecToCommand[Sec] = Cmd;
}
}
@@ -442,7 +444,7 @@ void LinkerScript::fabricateDefaultCommands() {
std::vector<BaseCommand *> Commands;
// Define start address
- uint64_t StartAddr = Config->ImageBase + elf::getHeaderSize();
+ uint64_t StartAddr = -1;
// The Sections with -T<section> have been sorted in order of ascending
// address. We must lower StartAddr if the lowest -T<section address> as
@@ -450,8 +452,12 @@ void LinkerScript::fabricateDefaultCommands() {
for (auto& KV : Config->SectionStartMap)
StartAddr = std::min(StartAddr, KV.second);
- Commands.push_back(
- make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
+ Commands.push_back(make<SymbolAssignment>(
+ ".",
+ [=] {
+ return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize());
+ },
+ ""));
// For each OutputSection that needs a VA fabricate an OutputSectionCommand
// with an InputSectionDescription describing the InputSections
@@ -870,51 +876,6 @@ void LinkerScript::processNonSectionCommands() {
}
}
-// Do a last effort at synchronizing the linker script "AST" and the section
-// list. This is needed to account for last minute changes, like adding a
-// .ARM.exidx terminator and sorting SHF_LINK_ORDER sections.
-//
-// FIXME: We should instead create the "AST" earlier and the above changes would
-// be done directly in the "AST".
-//
-// This can only handle new sections being added and sections being reordered.
-void LinkerScript::synchronize() {
- for (BaseCommand *Base : Opt.Commands) {
- auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
- if (!Cmd)
- continue;
- ArrayRef<InputSection *> Sections = Cmd->Sec->Sections;
- std::vector<InputSection **> ScriptSections;
- DenseSet<InputSection *> ScriptSectionsSet;
- for (BaseCommand *Base : Cmd->Commands) {
- auto *ISD = dyn_cast<InputSectionDescription>(Base);
- if (!ISD)
- continue;
- for (InputSection *&IS : ISD->Sections) {
- if (IS->Live) {
- ScriptSections.push_back(&IS);
- ScriptSectionsSet.insert(IS);
- }
- }
- }
- std::vector<InputSection *> Missing;
- for (InputSection *IS : Sections)
- if (!ScriptSectionsSet.count(IS))
- Missing.push_back(IS);
- if (!Missing.empty()) {
- auto ISD = make<InputSectionDescription>("");
- ISD->Sections = Missing;
- Cmd->Commands.push_back(ISD);
- for (InputSection *&IS : ISD->Sections)
- if (IS->Live)
- ScriptSections.push_back(&IS);
- }
- assert(ScriptSections.size() == Sections.size());
- for (int I = 0, N = Sections.size(); I < N; ++I)
- *ScriptSections[I] = Sections[I];
- }
-}
-
static bool
allocateHeaders(std::vector<PhdrEntry> &Phdrs,
ArrayRef<OutputSectionCommand *> OutputSectionCommands,
@@ -1071,6 +1032,81 @@ static void writeInt(uint8_t *Buf, uint64_t Data, uint
llvm_unreachable("unsupported Size argument");
}
+static bool compareByFilePosition(InputSection *A, InputSection *B) {
+ // Synthetic doesn't have link order dependecy, stable_sort will keep it last
+ if (A->kind() == InputSectionBase::Synthetic ||
+ B->kind() == InputSectionBase::Synthetic)
+ return false;
+ InputSection *LA = A->getLinkOrderDep();
+ InputSection *LB = B->getLinkOrderDep();
+ OutputSection *AOut = LA->getParent();
+ OutputSection *BOut = LB->getParent();
+ if (AOut != BOut)
+ return AOut->SectionIndex < BOut->SectionIndex;
+ return LA->OutSecOff < LB->OutSecOff;
+}
+
+template <class ELFT>
+static void finalizeShtGroup(OutputSection *OS,
+ ArrayRef<InputSection *> Sections) {
+ // sh_link field for SHT_GROUP sections should contain the section index of
+ // the symbol table.
+ OS->Link = InX::SymTab->getParent()->SectionIndex;
+
+ // sh_info then contain index of an entry in symbol table section which
+ // provides signature of the section group.
+ elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>();
+ assert(Config->Relocatable && Sections.size() == 1);
+ ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
+ OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]);
+}
+
+template <class ELFT> void OutputSectionCommand::finalize() {
+ // Link order may be distributed across several InputSectionDescriptions
+ // but sort must consider them all at once.
+ std::vector<InputSection **> ScriptSections;
+ std::vector<InputSection *> Sections;
+ for (BaseCommand *Base : Commands)
+ if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
+ for (InputSection *&IS : ISD->Sections) {
+ ScriptSections.push_back(&IS);
+ Sections.push_back(IS);
+ }
+
+ if ((Sec->Flags & SHF_LINK_ORDER)) {
+ std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
+ for (int I = 0, N = Sections.size(); I < N; ++I)
+ *ScriptSections[I] = Sections[I];
+
+ // We must preserve the link order dependency of sections with the
+ // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
+ // need to translate the InputSection sh_link to the OutputSection sh_link,
+ // all InputSections in the OutputSection have the same dependency.
+ if (auto *D = Sections.front()->getLinkOrderDep())
+ Sec->Link = D->getParent()->SectionIndex;
+ }
+
+ uint32_t Type = Sec->Type;
+ if (Type == SHT_GROUP) {
+ finalizeShtGroup<ELFT>(Sec, Sections);
+ return;
+ }
+
+ if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
+ return;
+
+ InputSection *First = Sections[0];
+ if (isa<SyntheticSection>(First))
+ return;
+
+ Sec->Link = InX::SymTab->getParent()->SectionIndex;
+ // sh_info for SHT_REL[A] sections should contain the section header index of
+ // the section to which the relocation applies.
+ InputSectionBase *S = First->getRelocatedSection();
+ Sec->Info = S->getOutputSection()->SectionIndex;
+ Sec->Flags |= SHF_INFO_LINK;
+}
+
// Compress section contents if this section contains debug info.
template <class ELFT> void OutputSectionCommand::maybeCompress() {
typedef typename ELFT::Chdr Elf_Chdr;
@@ -1099,6 +1135,9 @@ template <class ELFT> void OutputSectionCommand::maybe
}
template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
+ if (Sec->Type == SHT_NOBITS)
+ return;
+
Sec->Loc = Buf;
// We may have already rendered compressed content when using
@@ -1110,9 +1149,6 @@ template <class ELFT> void OutputSectionCommand::write
return;
}
- if (Sec->Type == SHT_NOBITS)
- return;
-
// Write leading padding.
std::vector<InputSection *> Sections;
for (BaseCommand *Cmd : Commands)
@@ -1156,12 +1192,12 @@ bool LinkerScript::hasLMA(OutputSection *Sec) {
ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
if (S == ".")
- return {CurOutSec, Dot - CurOutSec->Addr};
+ return {CurOutSec, Dot - CurOutSec->Addr, Loc};
if (SymbolBody *B = findSymbol(S)) {
if (auto *D = dyn_cast<DefinedRegular>(B))
- return {D->Section, D->Value};
+ return {D->Section, D->Value, Loc};
if (auto *C = dyn_cast<DefinedCommon>(B))
- return {InX::Common, C->Offset};
+ return {InX::Common, C->Offset, Loc};
}
error(Loc + ": symbol not found: " + S);
return 0;
@@ -1201,3 +1237,8 @@ template void OutputSectionCommand::maybeCompress<ELF3
template void OutputSectionCommand::maybeCompress<ELF32BE>();
template void OutputSectionCommand::maybeCompress<ELF64LE>();
template void OutputSectionCommand::maybeCompress<ELF64BE>();
+
+template void OutputSectionCommand::finalize<ELF32LE>();
+template void OutputSectionCommand::finalize<ELF32BE>();
+template void OutputSectionCommand::finalize<ELF64LE>();
+template void OutputSectionCommand::finalize<ELF64BE>();
Modified: vendor/lld/dist/ELF/LinkerScript.h
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.h Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/LinkerScript.h Sat Jun 10 13:44:49 2017 (r319788)
@@ -42,15 +42,14 @@ struct ExprValue {
uint64_t Val;
bool ForceAbsolute;
uint64_t Alignment = 1;
+ std::string Loc;
ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val,
- uint64_t Alignment)
- : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Alignment(Alignment) {
- }
- ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val)
- : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute) {}
- ExprValue(SectionBase *Sec, uint64_t Val) : ExprValue(Sec, false, Val) {}
- ExprValue(uint64_t Val) : ExprValue(nullptr, Val) {}
+ const Twine &Loc)
+ : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Loc(Loc.str()) {}
+ ExprValue(SectionBase *Sec, uint64_t Val, const Twine &Loc)
+ : ExprValue(Sec, false, Val, Loc) {}
+ ExprValue(uint64_t Val) : ExprValue(nullptr, Val, "") {}
bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
uint64_t getValue() const;
uint64_t getSecAddr() const;
@@ -135,7 +134,9 @@ struct OutputSectionCommand : BaseCommand {
ConstraintKind Constraint = ConstraintKind::NoConstraint;
std::string Location;
std::string MemoryRegionName;
+ bool Noload = false;
+ template <class ELFT> void finalize();
template <class ELFT> void writeTo(uint8_t *Buf);
template <class ELFT> void maybeCompress();
uint32_t getFiller();
@@ -281,7 +282,6 @@ class LinkerScript final { (public)
void assignOffsets(OutputSectionCommand *Cmd);
void placeOrphanSections();
void processNonSectionCommands();
- void synchronize();
void assignAddresses(std::vector<PhdrEntry> &Phdrs,
ArrayRef<OutputSectionCommand *> OutputSectionCommands);
Modified: vendor/lld/dist/ELF/Mips.cpp
==============================================================================
--- vendor/lld/dist/ELF/Mips.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/Mips.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -16,8 +16,8 @@
#include "SymbolTable.h"
#include "Writer.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
#include "llvm/Support/MipsABIFlags.h"
using namespace llvm;
Modified: vendor/lld/dist/ELF/OutputSections.cpp
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/OutputSections.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -16,7 +16,7 @@
#include "SyntheticSections.h"
#include "Target.h"
#include "Threads.h"
-#include "llvm/Support/Dwarf.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SHA1.h"
@@ -70,67 +70,6 @@ OutputSection::OutputSection(StringRef Name, uint32_t
/*Link*/ 0),
SectionIndex(INT_MAX) {}
-static bool compareByFilePosition(InputSection *A, InputSection *B) {
- // Synthetic doesn't have link order dependecy, stable_sort will keep it last
- if (A->kind() == InputSectionBase::Synthetic ||
- B->kind() == InputSectionBase::Synthetic)
- return false;
- InputSection *LA = A->getLinkOrderDep();
- InputSection *LB = B->getLinkOrderDep();
- OutputSection *AOut = LA->getParent();
- OutputSection *BOut = LB->getParent();
- if (AOut != BOut)
- return AOut->SectionIndex < BOut->SectionIndex;
- return LA->OutSecOff < LB->OutSecOff;
-}
-
-template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) {
- // sh_link field for SHT_GROUP sections should contain the section index of
- // the symbol table.
- Sec->Link = InX::SymTab->getParent()->SectionIndex;
-
- // sh_info then contain index of an entry in symbol table section which
- // provides signature of the section group.
- elf::ObjectFile<ELFT> *Obj = Sec->Sections[0]->getFile<ELFT>();
- assert(Config->Relocatable && Sec->Sections.size() == 1);
- ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
- Sec->Info = InX::SymTab->getSymbolIndex(Symbols[Sec->Sections[0]->Info - 1]);
-}
-
-template <class ELFT> void OutputSection::finalize() {
- if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
- std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
- assignOffsets();
-
- // We must preserve the link order dependency of sections with the
- // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
- // need to translate the InputSection sh_link to the OutputSection sh_link,
- // all InputSections in the OutputSection have the same dependency.
- if (auto *D = this->Sections.front()->getLinkOrderDep())
- this->Link = D->getParent()->SectionIndex;
- }
-
- uint32_t Type = this->Type;
- if (Type == SHT_GROUP) {
- finalizeShtGroup<ELFT>(this);
- return;
- }
-
- if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
- return;
-
- InputSection *First = Sections[0];
- if (isa<SyntheticSection>(First))
- return;
-
- this->Link = InX::SymTab->getParent()->SectionIndex;
- // sh_info for SHT_REL[A] sections should contain the section header index of
- // the section to which the relocation applies.
- InputSectionBase *S = First->getRelocatedSection();
- Info = S->getOutputSection()->SectionIndex;
- Flags |= SHF_INFO_LINK;
-}
-
static uint64_t updateOffset(uint64_t Off, InputSection *S) {
Off = alignTo(Off, S->Alignment);
S->OutSecOff = Off;
@@ -162,9 +101,12 @@ void OutputSection::addSection(InputSection *S) {
// This function is called after we sort input sections
// and scan relocations to setup sections' offsets.
void OutputSection::assignOffsets() {
+ OutputSectionCommand *Cmd = Script->getCmd(this);
uint64_t Off = 0;
- for (InputSection *S : Sections)
- Off = updateOffset(Off, S);
+ for (BaseCommand *Base : Cmd->Commands)
+ if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
+ for (InputSection *S : ISD->Sections)
+ Off = updateOffset(Off, S);
this->Size = Off;
}
@@ -333,6 +275,31 @@ void elf::reportDiscarded(InputSectionBase *IS) {
void OutputSectionFactory::addInputSec(InputSectionBase *IS,
StringRef OutsecName) {
+ // Sections with the SHT_GROUP attribute reach here only when the - r option
+ // is given. Such sections define "section groups", and InputFiles.cpp has
+ // dedup'ed section groups by their signatures. For the -r, we want to pass
+ // through all SHT_GROUP sections without merging them because merging them
+ // creates broken section contents.
+ if (IS->Type == SHT_GROUP) {
+ OutputSection *Out = nullptr;
+ addInputSec(IS, OutsecName, Out);
+ return;
+ }
+
+ // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
+ // relocation sections .rela.foo and .rela.bar for example. Most tools do
+ // not allow multiple REL[A] sections for output section. Hence we
+ // should combine these relocation sections into single output.
+ // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
+ // other REL[A] sections created by linker itself.
+ if (!isa<SyntheticSection>(IS) &&
+ (IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
+ auto *Sec = cast<InputSection>(IS);
+ OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
+ addInputSec(IS, OutsecName, Out->RelocationSection);
+ return;
+ }
+
SectionKey Key = createKey(IS, OutsecName);
OutputSection *&Sec = Map[Key];
return addInputSec(IS, OutsecName, Sec);
@@ -346,10 +313,6 @@ void OutputSectionFactory::addInputSec(InputSectionBas
return;
}
- uint64_t Flags = IS->Flags;
- if (!Config->Relocatable)
- Flags &= ~(uint64_t)SHF_GROUP;
-
if (Sec) {
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
error("incompatible section flags for " + Sec->Name +
@@ -366,9 +329,9 @@ void OutputSectionFactory::addInputSec(InputSectionBas
"\n>>> output section " + Sec->Name + ": " +
getELFSectionTypeName(Config->EMachine, Sec->Type));
}
- Sec->Flags |= Flags;
+ Sec->Flags |= IS->Flags;
} else {
- Sec = make<OutputSection>(OutsecName, IS->Type, Flags);
+ Sec = make<OutputSection>(OutsecName, IS->Type, IS->Flags);
OutputSections.push_back(Sec);
}
@@ -405,8 +368,3 @@ template void OutputSection::writeHeaderTo<ELF32LE>(EL
template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
-
-template void OutputSection::finalize<ELF32LE>();
-template void OutputSection::finalize<ELF32BE>();
-template void OutputSection::finalize<ELF64LE>();
-template void OutputSection::finalize<ELF64BE>();
Modified: vendor/lld/dist/ELF/OutputSections.h
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.h Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/OutputSections.h Sat Jun 10 13:44:49 2017 (r319788)
@@ -67,6 +67,11 @@ class OutputSection final : public SectionBase { (publ
// formula: Off = Off_first + VA - VA_first.
OutputSection *FirstInPtLoad = nullptr;
+ // Pointer to a relocation section for this section. Usually nullptr because
+ // we consume relocations, but if --emit-relocs is specified (which is rare),
+ // it may have a non-null value.
+ OutputSection *RelocationSection = nullptr;
+
// The following fields correspond to Elf_Shdr members.
uint64_t Size = 0;
uint64_t Offset = 0;
@@ -78,7 +83,6 @@ class OutputSection final : public SectionBase { (publ
void sort(std::function<int(InputSectionBase *S)> Order);
void sortInitFini();
void sortCtorsDtors();
- template <class ELFT> void finalize();
void assignOffsets();
std::vector<InputSection *> Sections;
Modified: vendor/lld/dist/ELF/Relocations.cpp
==============================================================================
--- vendor/lld/dist/ELF/Relocations.cpp Sat Jun 10 13:44:46 2017 (r319787)
+++ vendor/lld/dist/ELF/Relocations.cpp Sat Jun 10 13:44:49 2017 (r319788)
@@ -43,6 +43,7 @@
#include "Relocations.h"
#include "Config.h"
+#include "LinkerScript.h"
#include "Memory.h"
#include "OutputSections.h"
#include "Strings.h"
@@ -967,48 +968,51 @@ template <class ELFT> void elf::scanRelocations(InputS
// in the Sections vector, and recalculate the InputSection output section
// offsets.
// This may invalidate any output section offsets stored outside of InputSection
-void ThunkCreator::mergeThunks(OutputSection *OS,
- std::vector<ThunkSection *> &Thunks) {
- // Order Thunks in ascending OutSecOff
- auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
- return A->OutSecOff < B->OutSecOff;
- };
- std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
+void ThunkCreator::mergeThunks() {
+ for (auto &KV : ThunkSections) {
+ std::vector<InputSection *> *ISR = KV.first;
+ std::vector<ThunkSection *> &Thunks = KV.second;
- // Merge sorted vectors of Thunks and InputSections by OutSecOff
- std::vector<InputSection *> Tmp;
- Tmp.reserve(OS->Sections.size() + Thunks.size());
- auto MergeCmp = [](const InputSection *A, const InputSection *B) {
- // std::merge requires a strict weak ordering.
- if (A->OutSecOff < B->OutSecOff)
- return true;
- if (A->OutSecOff == B->OutSecOff)
- // Check if Thunk is immediately before any specific Target InputSection
- // for example Mips LA25 Thunks.
- if (auto *TA = dyn_cast<ThunkSection>(A))
- if (TA && TA->getTargetInputSection() == B)
- return true;
- return false;
- };
- std::merge(OS->Sections.begin(), OS->Sections.end(), Thunks.begin(),
- Thunks.end(), std::back_inserter(Tmp), MergeCmp);
- OS->Sections = std::move(Tmp);
- OS->assignOffsets();
+ // Order Thunks in ascending OutSecOff
+ auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
+ return A->OutSecOff < B->OutSecOff;
+ };
+ std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
+
+ // Merge sorted vectors of Thunks and InputSections by OutSecOff
+ std::vector<InputSection *> Tmp;
+ Tmp.reserve(ISR->size() + Thunks.size());
+ auto MergeCmp = [](const InputSection *A, const InputSection *B) {
+ // std::merge requires a strict weak ordering.
+ if (A->OutSecOff < B->OutSecOff)
+ return true;
+ if (A->OutSecOff == B->OutSecOff)
+ // Check if Thunk is immediately before any specific Target InputSection
+ // for example Mips LA25 Thunks.
+ if (auto *TA = dyn_cast<ThunkSection>(A))
+ if (TA && TA->getTargetInputSection() == B)
+ return true;
+ return false;
+ };
+ std::merge(ISR->begin(), ISR->end(), Thunks.begin(), Thunks.end(),
+ std::back_inserter(Tmp), MergeCmp);
+ *ISR = std::move(Tmp);
+ }
}
-ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS,
- OutputSection *OS) {
- if (TS == nullptr) {
+ThunkSection *ThunkCreator::getOSThunkSec(OutputSection *OS,
+ std::vector<InputSection *> *ISR) {
+ if (CurTS == nullptr) {
uint32_t Off = 0;
for (auto *IS : OS->Sections) {
Off = IS->OutSecOff + IS->getSize();
if ((IS->Flags & SHF_EXECINSTR) == 0)
break;
}
- TS = make<ThunkSection>(OS, Off);
- ThunkSections[OS].push_back(TS);
+ CurTS = make<ThunkSection>(OS, Off);
+ ThunkSections[ISR].push_back(CurTS);
}
- return TS;
+ return CurTS;
}
ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) {
@@ -1017,7 +1021,21 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection
return TS;
auto *TOS = IS->getParent();
TS = make<ThunkSection>(TOS, IS->OutSecOff);
- ThunkSections[TOS].push_back(TS);
+
+ // Find InputSectionRange within TOS that IS is in
+ OutputSectionCommand *C = Script->getCmd(TOS);
+ std::vector<InputSection *> *Range = nullptr;
+ for (BaseCommand *BC : C->Commands)
+ if (auto *ISD = dyn_cast<InputSectionDescription> (BC)) {
+ InputSection *first = ISD->Sections.front();
+ InputSection *last = ISD->Sections.back();
+ if (IS->OutSecOff >= first->OutSecOff &&
+ IS->OutSecOff <= last->OutSecOff) {
+ Range = &ISD->Sections;
+ break;
+ }
+ }
+ ThunkSections[Range].push_back(TS);
ThunkedSections[IS] = TS;
return TS;
}
@@ -1030,6 +1048,27 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol
return std::make_pair(res.first->second, res.second);
}
+// Call Fn on every executable InputSection accessed via the linker script
+// InputSectionDescription::Sections.
+void ThunkCreator::forEachExecInputSection(
+ ArrayRef<OutputSectionCommand *> OutputSections,
+ std::function<void(OutputSection *, std::vector<InputSection *> *,
+ InputSection *)>
+ Fn) {
+ for (OutputSectionCommand *Cmd : OutputSections) {
+ OutputSection *OS = Cmd->Sec;
+ if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
+ continue;
+ if (OutputSectionCommand *C = Script->getCmd(OS))
+ for (BaseCommand *BC : C->Commands)
+ if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
+ CurTS = nullptr;
+ for (InputSection* IS : ISD->Sections)
+ Fn(OS, &ISD->Sections, IS);
+ }
+ }
+}
+
// Process all relocations from the InputSections that have been assigned
// to OutputSections and redirect through Thunks if needed.
//
@@ -1040,42 +1079,41 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol
//
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-vendor
mailing list