svn commit: r343217 - in projects/clang800-import/contrib/llvm/tools/lld: . COFF Common ELF ELF/Arch docs include/lld/Common include/lld/Core lib/Driver lib/ReaderWriter/MachO tools/lld
Dimitry Andric
dim at FreeBSD.org
Sun Jan 20 14:43:01 UTC 2019
Author: dim
Date: Sun Jan 20 14:42:59 2019
New Revision: 343217
URL: https://svnweb.freebsd.org/changeset/base/343217
Log:
Merge lld trunk r351319, resolve conflicts, and update FREEBSD-Xlist.
Added:
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/MSP430.cpp
- copied unchanged from r343214, vendor/lld/dist/ELF/Arch/MSP430.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/RISCV.cpp
- copied unchanged from r343214, vendor/lld/dist/ELF/Arch/RISCV.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/DWARF.cpp
- copied unchanged from r343214, vendor/lld/dist/ELF/DWARF.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/DWARF.h
- copied unchanged from r343214, vendor/lld/dist/ELF/DWARF.h
projects/clang800-import/contrib/llvm/tools/lld/docs/missingkeyfunction.rst
- copied unchanged from r343214, vendor/lld/dist/docs/missingkeyfunction.rst
Deleted:
projects/clang800-import/contrib/llvm/tools/lld/ELF/GdbIndex.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/GdbIndex.h
projects/clang800-import/contrib/llvm/tools/lld/include/lld/Core/TODO.txt
Modified:
projects/clang800-import/contrib/llvm/tools/lld/COFF/Chunks.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/Chunks.h
projects/clang800-import/contrib/llvm/tools/lld/COFF/Config.h
projects/clang800-import/contrib/llvm/tools/lld/COFF/DLL.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/DLL.h
projects/clang800-import/contrib/llvm/tools/lld/COFF/Driver.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/Driver.h
projects/clang800-import/contrib/llvm/tools/lld/COFF/DriverUtils.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/ICF.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/InputFiles.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/InputFiles.h
projects/clang800-import/contrib/llvm/tools/lld/COFF/LTO.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/MapFile.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/MarkLive.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/MinGW.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/MinGW.h
projects/clang800-import/contrib/llvm/tools/lld/COFF/Options.td
projects/clang800-import/contrib/llvm/tools/lld/COFF/PDB.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/PDB.h
projects/clang800-import/contrib/llvm/tools/lld/COFF/SymbolTable.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/SymbolTable.h
projects/clang800-import/contrib/llvm/tools/lld/COFF/Symbols.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/Symbols.h
projects/clang800-import/contrib/llvm/tools/lld/COFF/Writer.cpp
projects/clang800-import/contrib/llvm/tools/lld/COFF/Writer.h
projects/clang800-import/contrib/llvm/tools/lld/Common/Args.cpp
projects/clang800-import/contrib/llvm/tools/lld/Common/ErrorHandler.cpp
projects/clang800-import/contrib/llvm/tools/lld/Common/Strings.cpp
projects/clang800-import/contrib/llvm/tools/lld/Common/TargetOptionsCommandFlags.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/AArch64ErrataFix.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/AArch64.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/AMDGPU.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/AVR.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/Hexagon.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/Mips.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/PPC.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/PPC64.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/SPARCV9.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/X86.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Arch/X86_64.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/CMakeLists.txt
projects/clang800-import/contrib/llvm/tools/lld/ELF/CallGraphSort.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Config.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/Driver.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Driver.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/DriverUtils.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/EhFrame.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/ICF.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/InputFiles.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/InputFiles.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/InputSection.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/InputSection.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/LTO.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/LTO.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/LinkerScript.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/LinkerScript.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/MapFile.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/MarkLive.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Options.td
projects/clang800-import/contrib/llvm/tools/lld/ELF/OutputSections.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/OutputSections.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/Relocations.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Relocations.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/ScriptLexer.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/ScriptLexer.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/ScriptParser.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/SymbolTable.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/SymbolTable.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/Symbols.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Symbols.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/SyntheticSections.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/Target.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Target.h
projects/clang800-import/contrib/llvm/tools/lld/ELF/Thunks.cpp
projects/clang800-import/contrib/llvm/tools/lld/ELF/Writer.cpp
projects/clang800-import/contrib/llvm/tools/lld/FREEBSD-Xlist
projects/clang800-import/contrib/llvm/tools/lld/LICENSE.TXT
projects/clang800-import/contrib/llvm/tools/lld/docs/NewLLD.rst
projects/clang800-import/contrib/llvm/tools/lld/docs/README.txt
projects/clang800-import/contrib/llvm/tools/lld/docs/Readers.rst
projects/clang800-import/contrib/llvm/tools/lld/docs/ReleaseNotes.rst
projects/clang800-import/contrib/llvm/tools/lld/docs/WebAssembly.rst
projects/clang800-import/contrib/llvm/tools/lld/docs/conf.py
projects/clang800-import/contrib/llvm/tools/lld/docs/index.rst
projects/clang800-import/contrib/llvm/tools/lld/docs/ld.lld.1
projects/clang800-import/contrib/llvm/tools/lld/docs/open_projects.rst
projects/clang800-import/contrib/llvm/tools/lld/docs/windows_support.rst
projects/clang800-import/contrib/llvm/tools/lld/include/lld/Common/Args.h
projects/clang800-import/contrib/llvm/tools/lld/include/lld/Common/ErrorHandler.h
projects/clang800-import/contrib/llvm/tools/lld/include/lld/Common/LLVM.h
projects/clang800-import/contrib/llvm/tools/lld/include/lld/Common/Strings.h
projects/clang800-import/contrib/llvm/tools/lld/include/lld/Common/TargetOptionsCommandFlags.h
projects/clang800-import/contrib/llvm/tools/lld/include/lld/Common/Threads.h
projects/clang800-import/contrib/llvm/tools/lld/lib/Driver/DarwinLdDriver.cpp
projects/clang800-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
projects/clang800-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
projects/clang800-import/contrib/llvm/tools/lld/tools/lld/lld.cpp
Directory Properties:
projects/clang800-import/contrib/llvm/tools/lld/ (props changed)
Modified: projects/clang800-import/contrib/llvm/tools/lld/COFF/Chunks.cpp
==============================================================================
--- projects/clang800-import/contrib/llvm/tools/lld/COFF/Chunks.cpp Sun Jan 20 14:33:29 2019 (r343216)
+++ projects/clang800-import/contrib/llvm/tools/lld/COFF/Chunks.cpp Sun Jan 20 14:42:59 2019 (r343217)
@@ -11,6 +11,7 @@
#include "InputFiles.h"
#include "Symbols.h"
#include "Writer.h"
+#include "SymbolTable.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/COFF.h"
@@ -44,6 +45,22 @@ SectionChunk::SectionChunk(ObjFile *F, const coff_sect
Live = !Config->DoGC || !isCOMDAT();
}
+// Initialize the RelocTargets vector, to allow redirecting certain relocations
+// to a thunk instead of the actual symbol the relocation's symbol table index
+// indicates.
+void SectionChunk::readRelocTargets() {
+ assert(RelocTargets.empty());
+ RelocTargets.reserve(Relocs.size());
+ for (const coff_relocation &Rel : Relocs)
+ RelocTargets.push_back(File->getSymbol(Rel.SymbolTableIndex));
+}
+
+// Reset RelocTargets to their original targets before thunks were added.
+void SectionChunk::resetRelocTargets() {
+ for (size_t I = 0, E = Relocs.size(); I < E; ++I)
+ RelocTargets[I] = File->getSymbol(Relocs[I].SymbolTableIndex);
+}
+
static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
@@ -58,7 +75,8 @@ static bool checkSecRel(const SectionChunk *Sec, Outpu
return true;
if (Sec->isCodeView())
return false;
- fatal("SECREL relocation cannot be applied to absolute symbols");
+ error("SECREL relocation cannot be applied to absolute symbols");
+ return false;
}
static void applySecRel(const SectionChunk *Sec, uint8_t *Off,
@@ -98,7 +116,7 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t
case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break;
case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break;
default:
- fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
+ error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
toString(File));
}
}
@@ -113,7 +131,7 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t
case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break;
case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break;
default:
- fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
+ error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
toString(File));
}
}
@@ -123,16 +141,22 @@ static void applyMOV(uint8_t *Off, uint16_t V) {
write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
}
-static uint16_t readMOV(uint8_t *Off) {
+static uint16_t readMOV(uint8_t *Off, bool MOVT) {
uint16_t Op1 = read16le(Off);
+ if ((Op1 & 0xfbf0) != (MOVT ? 0xf2c0 : 0xf240))
+ error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
+ " instruction in MOV32T relocation");
uint16_t Op2 = read16le(Off + 2);
+ if ((Op2 & 0x8000) != 0)
+ error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
+ " instruction in MOV32T relocation");
return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) |
((Op1 & 0x000f) << 12);
}
void applyMOV32T(uint8_t *Off, uint32_t V) {
- uint16_t ImmW = readMOV(Off); // read MOVW operand
- uint16_t ImmT = readMOV(Off + 4); // read MOVT operand
+ uint16_t ImmW = readMOV(Off, false); // read MOVW operand
+ uint16_t ImmT = readMOV(Off + 4, true); // read MOVT operand
uint32_t Imm = ImmW | (ImmT << 16);
V += Imm; // add the immediate offset
applyMOV(Off, V); // set MOVW operand
@@ -141,7 +165,7 @@ void applyMOV32T(uint8_t *Off, uint32_t V) {
static void applyBranch20T(uint8_t *Off, int32_t V) {
if (!isInt<21>(V))
- fatal("relocation out of range");
+ error("relocation out of range");
uint32_t S = V < 0 ? 1 : 0;
uint32_t J1 = (V >> 19) & 1;
uint32_t J2 = (V >> 18) & 1;
@@ -151,7 +175,7 @@ static void applyBranch20T(uint8_t *Off, int32_t V) {
void applyBranch24T(uint8_t *Off, int32_t V) {
if (!isInt<25>(V))
- fatal("relocation out of range");
+ error("relocation out of range");
uint32_t S = V < 0 ? 1 : 0;
uint32_t J1 = ((~V >> 23) & 1) ^ S;
uint32_t J2 = ((~V >> 22) & 1) ^ S;
@@ -176,7 +200,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t
case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break;
case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break;
default:
- fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
+ error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
toString(File));
}
}
@@ -184,7 +208,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t
// Interpret the existing immediate value as a byte offset to the
// target symbol, then update the instruction with the immediate as
// the page offset from the current instruction to the target.
-static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
+void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
uint32_t Orig = read32le(Off);
uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC);
S += Imm;
@@ -198,7 +222,7 @@ static void applyArm64Addr(uint8_t *Off, uint64_t S, u
// Update the immediate field in a AARCH64 ldr, str, and add instruction.
// Optionally limit the range of the written immediate by one or more bits
// (RangeLimit).
-static void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
+void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
uint32_t Orig = read32le(Off);
Imm += (Orig >> 10) & 0xFFF;
Orig &= ~(0xFFF << 10);
@@ -221,7 +245,7 @@ static void applyArm64Ldr(uint8_t *Off, uint64_t Imm)
if ((Orig & 0x4800000) == 0x4800000)
Size += 4;
if ((Imm & ((1 << Size) - 1)) != 0)
- fatal("misaligned ldr/str offset");
+ error("misaligned ldr/str offset");
applyArm64Imm(Off, Imm >> Size, Size);
}
@@ -250,21 +274,21 @@ static void applySecRelLdr(const SectionChunk *Sec, ui
applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff);
}
-static void applyArm64Branch26(uint8_t *Off, int64_t V) {
+void applyArm64Branch26(uint8_t *Off, int64_t V) {
if (!isInt<28>(V))
- fatal("relocation out of range");
+ error("relocation out of range");
or32(Off, (V & 0x0FFFFFFC) >> 2);
}
static void applyArm64Branch19(uint8_t *Off, int64_t V) {
if (!isInt<21>(V))
- fatal("relocation out of range");
+ error("relocation out of range");
or32(Off, (V & 0x001FFFFC) << 3);
}
static void applyArm64Branch14(uint8_t *Off, int64_t V) {
if (!isInt<16>(V))
- fatal("relocation out of range");
+ error("relocation out of range");
or32(Off, (V & 0x0000FFFC) << 3);
}
@@ -287,11 +311,37 @@ void SectionChunk::applyRelARM64(uint8_t *Off, uint16_
case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, Off, OS, S); break;
case IMAGE_REL_ARM64_SECTION: applySecIdx(Off, OS); break;
default:
- fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
+ error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
toString(File));
}
}
+static void maybeReportRelocationToDiscarded(const SectionChunk *FromChunk,
+ Defined *Sym,
+ const coff_relocation &Rel) {
+ // Don't report these errors when the relocation comes from a debug info
+ // section or in mingw mode. MinGW mode object files (built by GCC) can
+ // have leftover sections with relocations against discarded comdat
+ // sections. Such sections are left as is, with relocations untouched.
+ if (FromChunk->isCodeView() || FromChunk->isDWARF() || Config->MinGW)
+ return;
+
+ // Get the name of the symbol. If it's null, it was discarded early, so we
+ // have to go back to the object file.
+ ObjFile *File = FromChunk->File;
+ StringRef Name;
+ if (Sym) {
+ Name = Sym->getName();
+ } else {
+ COFFSymbolRef COFFSym =
+ check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
+ File->getCOFFObj()->getSymbolName(COFFSym, Name);
+ }
+
+ error("relocation against symbol in discarded section: " + Name +
+ getSymbolLocations(File, Rel.SymbolTableIndex));
+}
+
void SectionChunk::writeTo(uint8_t *Buf) const {
if (!hasData())
return;
@@ -302,46 +352,40 @@ void SectionChunk::writeTo(uint8_t *Buf) const {
// Apply relocations.
size_t InputSize = getSize();
- for (const coff_relocation &Rel : Relocs) {
+ for (size_t I = 0, E = Relocs.size(); I < E; I++) {
+ const coff_relocation &Rel = Relocs[I];
+
// Check for an invalid relocation offset. This check isn't perfect, because
// we don't have the relocation size, which is only known after checking the
// machine and relocation type. As a result, a relocation may overwrite the
// beginning of the following input section.
- if (Rel.VirtualAddress >= InputSize)
- fatal("relocation points beyond the end of its parent section");
+ if (Rel.VirtualAddress >= InputSize) {
+ error("relocation points beyond the end of its parent section");
+ continue;
+ }
uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
+ // Use the potentially remapped Symbol instead of the one that the
+ // relocation points to.
+ auto *Sym = dyn_cast_or_null<Defined>(RelocTargets[I]);
+
// Get the output section of the symbol for this relocation. The output
// section is needed to compute SECREL and SECTION relocations used in debug
// info.
- auto *Sym =
- dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
- if (!Sym) {
- if (isCodeView() || isDWARF())
- continue;
- // Symbols in early discarded sections are represented using null pointers,
- // so we need to retrieve the name from the object file.
- COFFSymbolRef Sym =
- check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
- StringRef Name;
- File->getCOFFObj()->getSymbolName(Sym, Name);
- fatal("relocation against symbol in discarded section: " + Name);
- }
- Chunk *C = Sym->getChunk();
+ Chunk *C = Sym ? Sym->getChunk() : nullptr;
OutputSection *OS = C ? C->getOutputSection() : nullptr;
- // Only absolute and __ImageBase symbols lack an output section. For any
- // other symbol, this indicates that the chunk was discarded. Normally
- // relocations against discarded sections are an error. However, debug info
- // sections are not GC roots and can end up with these kinds of relocations.
- // Skip these relocations.
- if (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym)) {
- if (isCodeView() || isDWARF())
- continue;
- fatal("relocation against symbol in discarded section: " +
- Sym->getName());
+ // Skip the relocation if it refers to a discarded section, and diagnose it
+ // as an error if appropriate. If a symbol was discarded early, it may be
+ // null. If it was discarded late, the output section will be null, unless
+ // it was an absolute or synthetic symbol.
+ if (!Sym ||
+ (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym))) {
+ maybeReportRelocationToDiscarded(this, Sym, Rel);
+ continue;
}
+
uint64_t S = Sym->getRVA();
// Compute the RVA of the relocation for relative relocations.
@@ -399,17 +443,125 @@ static uint8_t getBaserelType(const coff_relocation &R
// fixed by the loader if load-time relocation is needed.
// Only called when base relocation is enabled.
void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
- for (const coff_relocation &Rel : Relocs) {
+ for (size_t I = 0, E = Relocs.size(); I < E; I++) {
+ const coff_relocation &Rel = Relocs[I];
uint8_t Ty = getBaserelType(Rel);
if (Ty == IMAGE_REL_BASED_ABSOLUTE)
continue;
- Symbol *Target = File->getSymbol(Rel.SymbolTableIndex);
+ // Use the potentially remapped Symbol instead of the one that the
+ // relocation points to.
+ Symbol *Target = RelocTargets[I];
if (!Target || isa<DefinedAbsolute>(Target))
continue;
Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
}
}
+// MinGW specific.
+// Check whether a static relocation of type Type can be deferred and
+// handled at runtime as a pseudo relocation (for references to a module
+// local variable, which turned out to actually need to be imported from
+// another DLL) This returns the size the relocation is supposed to update,
+// in bits, or 0 if the relocation cannot be handled as a runtime pseudo
+// relocation.
+static int getRuntimePseudoRelocSize(uint16_t Type) {
+ // Relocations that either contain an absolute address, or a plain
+ // relative offset, since the runtime pseudo reloc implementation
+ // adds 8/16/32/64 bit values to a memory address.
+ //
+ // Given a pseudo relocation entry,
+ //
+ // typedef struct {
+ // DWORD sym;
+ // DWORD target;
+ // DWORD flags;
+ // } runtime_pseudo_reloc_item_v2;
+ //
+ // the runtime relocation performs this adjustment:
+ // *(base + .target) += *(base + .sym) - (base + .sym)
+ //
+ // This works for both absolute addresses (IMAGE_REL_*_ADDR32/64,
+ // IMAGE_REL_I386_DIR32, where the memory location initially contains
+ // the address of the IAT slot, and for relative addresses (IMAGE_REL*_REL32),
+ // where the memory location originally contains the relative offset to the
+ // IAT slot.
+ //
+ // This requires the target address to be writable, either directly out of
+ // the image, or temporarily changed at runtime with VirtualProtect.
+ // Since this only operates on direct address values, it doesn't work for
+ // ARM/ARM64 relocations, other than the plain ADDR32/ADDR64 relocations.
+ switch (Config->Machine) {
+ case AMD64:
+ switch (Type) {
+ case IMAGE_REL_AMD64_ADDR64:
+ return 64;
+ case IMAGE_REL_AMD64_ADDR32:
+ case IMAGE_REL_AMD64_REL32:
+ case IMAGE_REL_AMD64_REL32_1:
+ case IMAGE_REL_AMD64_REL32_2:
+ case IMAGE_REL_AMD64_REL32_3:
+ case IMAGE_REL_AMD64_REL32_4:
+ case IMAGE_REL_AMD64_REL32_5:
+ return 32;
+ default:
+ return 0;
+ }
+ case I386:
+ switch (Type) {
+ case IMAGE_REL_I386_DIR32:
+ case IMAGE_REL_I386_REL32:
+ return 32;
+ default:
+ return 0;
+ }
+ case ARMNT:
+ switch (Type) {
+ case IMAGE_REL_ARM_ADDR32:
+ return 32;
+ default:
+ return 0;
+ }
+ case ARM64:
+ switch (Type) {
+ case IMAGE_REL_ARM64_ADDR64:
+ return 64;
+ case IMAGE_REL_ARM64_ADDR32:
+ return 32;
+ default:
+ return 0;
+ }
+ default:
+ llvm_unreachable("unknown machine type");
+ }
+}
+
+// MinGW specific.
+// Append information to the provided vector about all relocations that
+// need to be handled at runtime as runtime pseudo relocations (references
+// to a module local variable, which turned out to actually need to be
+// imported from another DLL).
+void SectionChunk::getRuntimePseudoRelocs(
+ std::vector<RuntimePseudoReloc> &Res) {
+ for (const coff_relocation &Rel : Relocs) {
+ auto *Target =
+ dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
+ if (!Target || !Target->IsRuntimePseudoReloc)
+ continue;
+ int SizeInBits = getRuntimePseudoRelocSize(Rel.Type);
+ if (SizeInBits == 0) {
+ error("unable to automatically import from " + Target->getName() +
+ " with relocation type " +
+ File->getCOFFObj()->getRelocationTypeName(Rel.Type) + " in " +
+ toString(File));
+ continue;
+ }
+ // SizeInBits is used to initialize the Flags field; currently no
+ // other flags are defined.
+ Res.emplace_back(
+ RuntimePseudoReloc(Target, this, Rel.VirtualAddress, SizeInBits));
+ }
+}
+
bool SectionChunk::hasData() const {
return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
}
@@ -447,6 +599,13 @@ void SectionChunk::replace(SectionChunk *Other) {
Other->Live = false;
}
+uint32_t SectionChunk::getSectionNumber() const {
+ DataRefImpl R;
+ R.p = reinterpret_cast<uintptr_t>(Header);
+ SectionRef S(R, File->getCOFFObj());
+ return S.getIndex() + 1;
+}
+
CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
// Common symbols are aligned on natural boundaries up to 32 bytes.
// This is what MSVC link.exe does.
@@ -460,6 +619,7 @@ uint32_t CommonChunk::getOutputCharacteristics() const
void StringChunk::writeTo(uint8_t *Buf) const {
memcpy(Buf + OutputSectionOff, Str.data(), Str.size());
+ Buf[OutputSectionOff + Str.size()] = '\0';
}
ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
@@ -502,13 +662,30 @@ void ImportThunkChunkARM64::writeTo(uint8_t *Buf) cons
applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
}
+// A Thumb2, PIC, non-interworking range extension thunk.
+const uint8_t ArmThunk[] = {
+ 0x40, 0xf2, 0x00, 0x0c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
+ 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4)
+ 0xe7, 0x44, // L1: add pc, ip
+};
+
+size_t RangeExtensionThunk::getSize() const {
+ assert(Config->Machine == ARMNT);
+ return sizeof(ArmThunk);
+}
+
+void RangeExtensionThunk::writeTo(uint8_t *Buf) const {
+ assert(Config->Machine == ARMNT);
+ uint64_t Offset = Target->getRVA() - RVA - 12;
+ memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk));
+ applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset));
+}
+
void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
Res->emplace_back(getRVA());
}
-size_t LocalImportChunk::getSize() const {
- return Config->is64() ? 8 : 4;
-}
+size_t LocalImportChunk::getSize() const { return Config->Wordsize; }
void LocalImportChunk::writeTo(uint8_t *Buf) const {
if (Config->is64()) {
@@ -528,6 +705,34 @@ void RVATableChunk::writeTo(uint8_t *Buf) const {
"RVA tables should be de-duplicated");
}
+// MinGW specific, for the "automatic import of variables from DLLs" feature.
+size_t PseudoRelocTableChunk::getSize() const {
+ if (Relocs.empty())
+ return 0;
+ return 12 + 12 * Relocs.size();
+}
+
+// MinGW specific.
+void PseudoRelocTableChunk::writeTo(uint8_t *Buf) const {
+ if (Relocs.empty())
+ return;
+
+ ulittle32_t *Table = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
+ // This is the list header, to signal the runtime pseudo relocation v2
+ // format.
+ Table[0] = 0;
+ Table[1] = 0;
+ Table[2] = 1;
+
+ size_t Idx = 3;
+ for (const RuntimePseudoReloc &RPR : Relocs) {
+ Table[Idx + 0] = RPR.Sym->getRVA();
+ Table[Idx + 1] = RPR.Target->getRVA() + RPR.TargetOffset;
+ Table[Idx + 2] = RPR.Flags;
+ Idx += 3;
+ }
+}
+
// Windows-specific. This class represents a block in .reloc section.
// The format is described here.
//
@@ -613,13 +818,16 @@ void MergeChunk::addSection(SectionChunk *C) {
}
void MergeChunk::finalizeContents() {
- for (SectionChunk *C : Sections)
- if (C->isLive())
- Builder.add(toStringRef(C->getContents()));
- Builder.finalize();
+ if (!Finalized) {
+ for (SectionChunk *C : Sections)
+ if (C->Live)
+ Builder.add(toStringRef(C->getContents()));
+ Builder.finalize();
+ Finalized = true;
+ }
for (SectionChunk *C : Sections) {
- if (!C->isLive())
+ if (!C->Live)
continue;
size_t Off = Builder.getOffset(toStringRef(C->getContents()));
C->setOutputSection(Out);
@@ -638,6 +846,17 @@ size_t MergeChunk::getSize() const {
void MergeChunk::writeTo(uint8_t *Buf) const {
Builder.write(Buf + OutputSectionOff);
+}
+
+// MinGW specific.
+size_t AbsolutePointerChunk::getSize() const { return Config->Wordsize; }
+
+void AbsolutePointerChunk::writeTo(uint8_t *Buf) const {
+ if (Config->is64()) {
+ write64le(Buf + OutputSectionOff, Value);
+ } else {
+ write32le(Buf + OutputSectionOff, Value);
+ }
}
} // namespace coff
Modified: projects/clang800-import/contrib/llvm/tools/lld/COFF/Chunks.h
==============================================================================
--- projects/clang800-import/contrib/llvm/tools/lld/COFF/Chunks.h Sun Jan 20 14:33:29 2019 (r343216)
+++ projects/clang800-import/contrib/llvm/tools/lld/COFF/Chunks.h Sun Jan 20 14:42:59 2019 (r343217)
@@ -36,6 +36,7 @@ class DefinedImportData;
class DefinedRegular;
class ObjFile;
class OutputSection;
+class RuntimePseudoReloc;
class Symbol;
// Mask for permissions (discardable, writable, readable, executable, etc).
@@ -63,6 +64,13 @@ class Chunk { (public)
// before calling this function.
virtual void writeTo(uint8_t *Buf) const {}
+ // Called by the writer once before assigning addresses and writing
+ // the output.
+ virtual void readRelocTargets() {}
+
+ // Called if restarting thunk addition.
+ virtual void resetRelocTargets() {}
+
// Called by the writer after an RVA is assigned, but before calling
// getSize().
virtual void finalizeContents() {}
@@ -114,6 +122,10 @@ class Chunk { (public)
public:
// The offset from beginning of the output section. The writer sets a value.
uint64_t OutputSectionOff = 0;
+
+ // Whether this section needs to be kept distinct from other sections during
+ // ICF. This is set by the driver using address-significance tables.
+ bool KeepUnique = false;
};
// A chunk corresponding a section of an input file.
@@ -140,6 +152,8 @@ class SectionChunk final : public Chunk { (public)
SectionChunk(ObjFile *File, const coff_section *Header);
static bool classof(const Chunk *C) { return C->kind() == SectionKind; }
+ void readRelocTargets() override;
+ void resetRelocTargets() override;
size_t getSize() const override { return Header->SizeOfRawData; }
ArrayRef<uint8_t> getContents() const;
void writeTo(uint8_t *Buf) const override;
@@ -157,6 +171,8 @@ class SectionChunk final : public Chunk { (public)
void applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
uint64_t P) const;
+ void getRuntimePseudoRelocs(std::vector<RuntimePseudoReloc> &Res);
+
// Called if the garbage collector decides to not include this chunk
// in a final output. It's supposed to print out a log message to stdout.
void printDiscardedMessage() const;
@@ -167,16 +183,6 @@ class SectionChunk final : public Chunk { (public)
StringRef getDebugName() override;
- // Returns true if the chunk was not dropped by GC.
- bool isLive() { return Live; }
-
- // Used by the garbage collector.
- void markLive() {
- assert(Config->DoGC && "should only mark things live from GC");
- assert(!isLive() && "Cannot mark an already live section!");
- Live = true;
- }
-
// True if this is a codeview debug info chunk. These will not be laid out in
// the image. Instead they will end up in the PDB, if one is requested.
bool isCodeView() const {
@@ -197,10 +203,13 @@ class SectionChunk final : public Chunk { (public)
// Allow iteration over the associated child chunks for this section.
ArrayRef<SectionChunk *> children() const { return AssocChildren; }
+ // The section ID this chunk belongs to in its Obj.
+ uint32_t getSectionNumber() const;
+
// A pointer pointing to a replacement for this chunk.
// Initially it points to "this" object. If this chunk is merged
// with other chunk by ICF, it points to another chunk,
- // and this chunk is considrered as dead.
+ // and this chunk is considered as dead.
SectionChunk *Repl;
// The CRC of the contents as described in the COFF spec 4.5.5.
@@ -217,13 +226,17 @@ class SectionChunk final : public Chunk { (public)
ArrayRef<coff_relocation> Relocs;
+ // Used by the garbage collector.
+ bool Live;
+
+ // When inserting a thunk, we need to adjust a relocation to point to
+ // the thunk instead of the actual original target Symbol.
+ std::vector<Symbol *> RelocTargets;
+
private:
StringRef SectionName;
std::vector<SectionChunk *> AssocChildren;
- // Used by the garbage collector.
- bool Live;
-
// Used for ICF (Identical COMDAT Folding)
void replace(SectionChunk *Other);
uint32_t Class[2] = {0, 0};
@@ -254,6 +267,7 @@ class MergeChunk : public Chunk { (public)
private:
llvm::StringTableBuilder Builder;
+ bool Finalized = false;
};
// A chunk for common symbols. Common chunks don't have actual data.
@@ -297,7 +311,7 @@ static const uint8_t ImportThunkARM64[] = {
};
// Windows-specific.
-// A chunk for DLL import jump table entry. In a final output, it's
+// A chunk for DLL import jump table entry. In a final output, its
// contents will be a JMP instruction to some __imp_ symbol.
class ImportThunkChunkX64 : public Chunk {
public:
@@ -341,12 +355,21 @@ class ImportThunkChunkARM64 : public Chunk { (private)
Defined *ImpSymbol;
};
+class RangeExtensionThunk : public Chunk {
+public:
+ explicit RangeExtensionThunk(Defined *T) : Target(T) {}
+ size_t getSize() const override;
+ void writeTo(uint8_t *Buf) const override;
+
+ Defined *Target;
+};
+
// Windows-specific.
// See comments for DefinedLocalImport class.
class LocalImportChunk : public Chunk {
public:
explicit LocalImportChunk(Defined *S) : Sym(S) {
- Alignment = Config->is64() ? 8 : 4;
+ Alignment = Config->Wordsize;
}
size_t getSize() const override;
void getBaserels(std::vector<Baserel> *Res) override;
@@ -416,8 +439,72 @@ class Baserel { (public)
uint8_t Type;
};
+// This is a placeholder Chunk, to allow attaching a DefinedSynthetic to a
+// specific place in a section, without any data. This is used for the MinGW
+// specific symbol __RUNTIME_PSEUDO_RELOC_LIST_END__, even though the concept
+// of an empty chunk isn't MinGW specific.
+class EmptyChunk : public Chunk {
+public:
+ EmptyChunk() {}
+ size_t getSize() const override { return 0; }
+ void writeTo(uint8_t *Buf) const override {}
+};
+
+// MinGW specific, for the "automatic import of variables from DLLs" feature.
+// This provides the table of runtime pseudo relocations, for variable
+// references that turned out to need to be imported from a DLL even though
+// the reference didn't use the dllimport attribute. The MinGW runtime will
+// process this table after loading, before handling control over to user
+// code.
+class PseudoRelocTableChunk : public Chunk {
+public:
+ PseudoRelocTableChunk(std::vector<RuntimePseudoReloc> &Relocs)
+ : Relocs(std::move(Relocs)) {
+ Alignment = 4;
+ }
+ size_t getSize() const override;
+ void writeTo(uint8_t *Buf) const override;
+
+private:
+ std::vector<RuntimePseudoReloc> Relocs;
+};
+
+// MinGW specific; information about one individual location in the image
+// that needs to be fixed up at runtime after loading. This represents
+// one individual element in the PseudoRelocTableChunk table.
+class RuntimePseudoReloc {
+public:
+ RuntimePseudoReloc(Defined *Sym, SectionChunk *Target, uint32_t TargetOffset,
+ int Flags)
+ : Sym(Sym), Target(Target), TargetOffset(TargetOffset), Flags(Flags) {}
+
+ Defined *Sym;
+ SectionChunk *Target;
+ uint32_t TargetOffset;
+ // The Flags field contains the size of the relocation, in bits. No other
+ // flags are currently defined.
+ int Flags;
+};
+
+// MinGW specific. A Chunk that contains one pointer-sized absolute value.
+class AbsolutePointerChunk : public Chunk {
+public:
+ AbsolutePointerChunk(uint64_t Value) : Value(Value) {
+ Alignment = getSize();
+ }
+ size_t getSize() const override;
+ void writeTo(uint8_t *Buf) const override;
+
+private:
+ uint64_t Value;
+};
+
void applyMOV32T(uint8_t *Off, uint32_t V);
void applyBranch24T(uint8_t *Off, int32_t V);
+
+void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift);
+void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit);
+void applyArm64Branch26(uint8_t *Off, int64_t V);
} // namespace coff
} // namespace lld
Modified: projects/clang800-import/contrib/llvm/tools/lld/COFF/Config.h
==============================================================================
--- projects/clang800-import/contrib/llvm/tools/lld/COFF/Config.h Sun Jan 20 14:33:29 2019 (r343216)
+++ projects/clang800-import/contrib/llvm/tools/lld/COFF/Config.h Sun Jan 20 14:42:59 2019 (r343217)
@@ -84,6 +84,7 @@ struct Configuration {
bool is64() { return Machine == AMD64 || Machine == ARM64; }
llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;
+ size_t Wordsize;
bool Verbose = false;
WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
Symbol *Entry = nullptr;
@@ -94,7 +95,8 @@ struct Configuration {
bool DoICF = true;
bool TailMerge;
bool Relocatable = true;
- bool Force = false;
+ bool ForceMultiple = false;
+ bool ForceUnresolved = false;
bool Debug = false;
bool DebugDwarf = false;
bool DebugGHashes = false;
@@ -195,6 +197,7 @@ struct Configuration {
bool MinGW = false;
bool WarnMissingOrderSymbol = true;
bool WarnLocallyDefinedImported = true;
+ bool WarnDebugInfoUnusable = true;
bool Incremental = true;
bool IntegrityCheck = false;
bool KillAt = false;
Modified: projects/clang800-import/contrib/llvm/tools/lld/COFF/DLL.cpp
==============================================================================
--- projects/clang800-import/contrib/llvm/tools/lld/COFF/DLL.cpp Sun Jan 20 14:33:29 2019 (r343216)
+++ projects/clang800-import/contrib/llvm/tools/lld/COFF/DLL.cpp Sun Jan 20 14:42:59 2019 (r343217)
@@ -35,8 +35,6 @@ namespace {
// Import table
-static int ptrSize() { return Config->is64() ? 8 : 4; }
-
// A chunk for the import descriptor table.
class HintNameChunk : public Chunk {
public:
@@ -61,8 +59,8 @@ class HintNameChunk : public Chunk { (private)
// A chunk for the import descriptor table.
class LookupChunk : public Chunk {
public:
- explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = ptrSize(); }
- size_t getSize() const override { return ptrSize(); }
+ explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = Config->Wordsize; }
+ size_t getSize() const override { return Config->Wordsize; }
void writeTo(uint8_t *Buf) const override {
write32le(Buf + OutputSectionOff, HintName->getRVA());
@@ -76,8 +74,10 @@ class LookupChunk : public Chunk { (public)
// See Microsoft PE/COFF spec 7.1. Import Header for details.
class OrdinalOnlyChunk : public Chunk {
public:
- explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) { Alignment = ptrSize(); }
- size_t getSize() const override { return ptrSize(); }
+ explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {
+ Alignment = Config->Wordsize;
+ }
+ size_t getSize() const override { return Config->Wordsize; }
void writeTo(uint8_t *Buf) const override {
// An import-by-ordinal slot has MSB 1 to indicate that
@@ -230,6 +230,36 @@ static const uint8_t ThunkARM[] = {
0x60, 0x47, // bx ip
};
+static const uint8_t ThunkARM64[] = {
+ 0x11, 0x00, 0x00, 0x90, // adrp x17, #0 __imp_<FUNCNAME>
+ 0x31, 0x02, 0x00, 0x91, // add x17, x17, #0 :lo12:__imp_<FUNCNAME>
+ 0xfd, 0x7b, 0xb3, 0xa9, // stp x29, x30, [sp, #-208]!
+ 0xfd, 0x03, 0x00, 0x91, // mov x29, sp
+ 0xe0, 0x07, 0x01, 0xa9, // stp x0, x1, [sp, #16]
+ 0xe2, 0x0f, 0x02, 0xa9, // stp x2, x3, [sp, #32]
+ 0xe4, 0x17, 0x03, 0xa9, // stp x4, x5, [sp, #48]
+ 0xe6, 0x1f, 0x04, 0xa9, // stp x6, x7, [sp, #64]
+ 0xe0, 0x87, 0x02, 0xad, // stp q0, q1, [sp, #80]
+ 0xe2, 0x8f, 0x03, 0xad, // stp q2, q3, [sp, #112]
+ 0xe4, 0x97, 0x04, 0xad, // stp q4, q5, [sp, #144]
+ 0xe6, 0x9f, 0x05, 0xad, // stp q6, q7, [sp, #176]
+ 0xe1, 0x03, 0x11, 0xaa, // mov x1, x17
+ 0x00, 0x00, 0x00, 0x90, // adrp x0, #0 DELAY_IMPORT_DESCRIPTOR
+ 0x00, 0x00, 0x00, 0x91, // add x0, x0, #0 :lo12:DELAY_IMPORT_DESCRIPTOR
+ 0x00, 0x00, 0x00, 0x94, // bl #0 __delayLoadHelper2
+ 0xf0, 0x03, 0x00, 0xaa, // mov x16, x0
+ 0xe6, 0x9f, 0x45, 0xad, // ldp q6, q7, [sp, #176]
+ 0xe4, 0x97, 0x44, 0xad, // ldp q4, q5, [sp, #144]
+ 0xe2, 0x8f, 0x43, 0xad, // ldp q2, q3, [sp, #112]
+ 0xe0, 0x87, 0x42, 0xad, // ldp q0, q1, [sp, #80]
+ 0xe6, 0x1f, 0x44, 0xa9, // ldp x6, x7, [sp, #64]
+ 0xe4, 0x17, 0x43, 0xa9, // ldp x4, x5, [sp, #48]
+ 0xe2, 0x0f, 0x42, 0xa9, // ldp x2, x3, [sp, #32]
+ 0xe0, 0x07, 0x41, 0xa9, // ldp x0, x1, [sp, #16]
+ 0xfd, 0x7b, 0xcd, 0xa8, // ldp x29, x30, [sp], #208
+ 0x00, 0x02, 0x1f, 0xd6, // br x16
+};
+
// A chunk for the delay import thunk.
class ThunkChunkX64 : public Chunk {
public:
@@ -298,11 +328,35 @@ class ThunkChunkARM : public Chunk { (public)
Defined *Helper = nullptr;
};
+class ThunkChunkARM64 : public Chunk {
+public:
+ ThunkChunkARM64(Defined *I, Chunk *D, Defined *H)
+ : Imp(I), Desc(D), Helper(H) {}
+
+ size_t getSize() const override { return sizeof(ThunkARM64); }
+
+ void writeTo(uint8_t *Buf) const override {
+ memcpy(Buf + OutputSectionOff, ThunkARM64, sizeof(ThunkARM64));
+ applyArm64Addr(Buf + OutputSectionOff + 0, Imp->getRVA(), RVA + 0, 12);
+ applyArm64Imm(Buf + OutputSectionOff + 4, Imp->getRVA() & 0xfff, 0);
+ applyArm64Addr(Buf + OutputSectionOff + 52, Desc->getRVA(), RVA + 52, 12);
+ applyArm64Imm(Buf + OutputSectionOff + 56, Desc->getRVA() & 0xfff, 0);
+ applyArm64Branch26(Buf + OutputSectionOff + 60,
+ Helper->getRVA() - RVA - 60);
+ }
+
+ Defined *Imp = nullptr;
+ Chunk *Desc = nullptr;
+ Defined *Helper = nullptr;
+};
+
// A chunk for the import descriptor table.
class DelayAddressChunk : public Chunk {
public:
- explicit DelayAddressChunk(Chunk *C) : Thunk(C) { Alignment = ptrSize(); }
- size_t getSize() const override { return ptrSize(); }
+ explicit DelayAddressChunk(Chunk *C) : Thunk(C) {
+ Alignment = Config->Wordsize;
+ }
+ size_t getSize() const override { return Config->Wordsize; }
void writeTo(uint8_t *Buf) const override {
if (Config->is64()) {
@@ -362,6 +416,8 @@ class AddressTableChunk : public Chunk { (public)
size_t getSize() const override { return Size * 4; }
void writeTo(uint8_t *Buf) const override {
+ memset(Buf + OutputSectionOff, 0, getSize());
+
for (const Export &E : Config->Exports) {
uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
uint32_t Bit = 0;
@@ -418,30 +474,6 @@ class ExportOrdinalChunk : public Chunk { (private)
} // anonymous namespace
-uint64_t IdataContents::getDirSize() {
- return Dirs.size() * sizeof(ImportDirectoryTableEntry);
-}
-
-uint64_t IdataContents::getIATSize() {
- return Addresses.size() * ptrSize();
-}
-
-// Returns a list of .idata contents.
-// See Microsoft PE/COFF spec 5.4 for details.
-std::vector<Chunk *> IdataContents::getChunks() {
- create();
-
- // The loader assumes a specific order of data.
- // Add each type in the correct order.
- std::vector<Chunk *> V;
- V.insert(V.end(), Dirs.begin(), Dirs.end());
- V.insert(V.end(), Lookups.begin(), Lookups.end());
- V.insert(V.end(), Addresses.begin(), Addresses.end());
- V.insert(V.end(), Hints.begin(), Hints.end());
- V.insert(V.end(), DLLNames.begin(), DLLNames.end());
- return V;
-}
-
void IdataContents::create() {
std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
@@ -465,8 +497,8 @@ void IdataContents::create() {
Hints.push_back(C);
}
// Terminate with null values.
- Lookups.push_back(make<NullChunk>(ptrSize()));
- Addresses.push_back(make<NullChunk>(ptrSize()));
+ Lookups.push_back(make<NullChunk>(Config->Wordsize));
+ Addresses.push_back(make<NullChunk>(Config->Wordsize));
for (int I = 0, E = Syms.size(); I < E; ++I)
Syms[I]->setLocation(Addresses[Base + I]);
@@ -555,6 +587,8 @@ Chunk *DelayLoadContents::newThunkChunk(DefinedImportD
return make<ThunkChunkX86>(S, Dir, Helper);
case ARMNT:
return make<ThunkChunkARM>(S, Dir, Helper);
+ case ARM64:
+ return make<ThunkChunkARM64>(S, Dir, Helper);
default:
llvm_unreachable("unsupported machine type");
}
Modified: projects/clang800-import/contrib/llvm/tools/lld/COFF/DLL.h
==============================================================================
--- projects/clang800-import/contrib/llvm/tools/lld/COFF/DLL.h Sun Jan 20 14:33:29 2019 (r343216)
+++ projects/clang800-import/contrib/llvm/tools/lld/COFF/DLL.h Sun Jan 20 14:42:59 2019 (r343217)
@@ -19,19 +19,12 @@ namespace coff {
// Windows-specific.
// IdataContents creates all chunks for the DLL import table.
// You are supposed to call add() to add symbols and then
-// call getChunks() to get a list of chunks.
+// call create() to populate the chunk vectors.
class IdataContents {
public:
void add(DefinedImportData *Sym) { Imports.push_back(Sym); }
bool empty() { return Imports.empty(); }
- std::vector<Chunk *> getChunks();
- uint64_t getDirRVA() { return Dirs[0]->getRVA(); }
- uint64_t getDirSize();
- uint64_t getIATRVA() { return Addresses[0]->getRVA(); }
- uint64_t getIATSize();
-
-private:
void create();
std::vector<DefinedImportData *> Imports;
Modified: projects/clang800-import/contrib/llvm/tools/lld/COFF/Driver.cpp
==============================================================================
--- projects/clang800-import/contrib/llvm/tools/lld/COFF/Driver.cpp Sun Jan 20 14:33:29 2019 (r343216)
+++ projects/clang800-import/contrib/llvm/tools/lld/COFF/Driver.cpp Sun Jan 20 14:42:59 2019 (r343217)
@@ -32,6 +32,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/TarWriter.h"
@@ -56,7 +57,7 @@ Configuration *Config;
LinkerDriver *Driver;
bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {
- errorHandler().LogName = sys::path::filename(Args[0]);
+ errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
errorHandler().ErrorOS = &Diag;
errorHandler().ColorDiagnostics = Diag.has_colors();
errorHandler().ErrorLimitExceededMsg =
@@ -370,13 +371,30 @@ Optional<StringRef> LinkerDriver::findFile(StringRef F
return Path;
}
+// MinGW specific. If an embedded directive specified to link to
+// foo.lib, but it isn't found, try libfoo.a instead.
+StringRef LinkerDriver::doFindLibMinGW(StringRef Filename) {
+ if (Filename.contains('/') || Filename.contains('\\'))
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list