Vendor import of lld trunk r306325:
https://llvm.org/svn/llvm-project/lld/trunk@306325
This commit is contained in:
parent
15f7a1a379
commit
4ea16835ba
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/lld/dist/; revision=320382 svn path=/vendor/lld/lld-trunk-r306325/; revision=320383; tag=vendor/lld/lld-trunk-r306325
@ -37,8 +37,14 @@ SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H)
|
||||
|
||||
Align = Header->getAlignment();
|
||||
|
||||
// Only COMDAT sections are subject of dead-stripping.
|
||||
Live = !isCOMDAT();
|
||||
// Chunks may be discarded during comdat merging.
|
||||
Discarded = false;
|
||||
|
||||
// If linker GC is disabled, every chunk starts out alive. If linker GC is
|
||||
// enabled, treat non-comdat sections as roots. Generally optimized object
|
||||
// files will be built with -ffunction-sections or /Gy, so most things worth
|
||||
// stripping will be in a comdat.
|
||||
Live = !Config->DoGC || !isCOMDAT();
|
||||
}
|
||||
|
||||
static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
|
||||
@ -46,6 +52,15 @@ 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); }
|
||||
static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); }
|
||||
|
||||
static void applySecRel(const SectionChunk *Sec, uint8_t *Off, Defined *Sym) {
|
||||
// Don't apply section relative relocations to absolute symbols in codeview
|
||||
// debug info sections. MSVC does not treat such relocations as fatal errors,
|
||||
// and they can be found in the standard library for linker-provided symbols
|
||||
// like __guard_fids_table and __safe_se_handler_table.
|
||||
if (!(isa<DefinedAbsolute>(Sym) && Sec->isCodeView()))
|
||||
add32(Off, Sym->getSecrel());
|
||||
}
|
||||
|
||||
void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym,
|
||||
uint64_t P) const {
|
||||
uint64_t S = Sym->getRVA();
|
||||
@ -60,7 +75,7 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym,
|
||||
case IMAGE_REL_AMD64_REL32_4: add32(Off, S - P - 8); break;
|
||||
case IMAGE_REL_AMD64_REL32_5: add32(Off, S - P - 9); break;
|
||||
case IMAGE_REL_AMD64_SECTION: add16(Off, Sym->getSectionIndex()); break;
|
||||
case IMAGE_REL_AMD64_SECREL: add32(Off, Sym->getSecrel()); break;
|
||||
case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, Sym); break;
|
||||
default:
|
||||
fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
|
||||
}
|
||||
@ -75,7 +90,7 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, Defined *Sym,
|
||||
case IMAGE_REL_I386_DIR32NB: add32(Off, S); break;
|
||||
case IMAGE_REL_I386_REL32: add32(Off, S - P - 4); break;
|
||||
case IMAGE_REL_I386_SECTION: add16(Off, Sym->getSectionIndex()); break;
|
||||
case IMAGE_REL_I386_SECREL: add32(Off, Sym->getSecrel()); break;
|
||||
case IMAGE_REL_I386_SECREL: applySecRel(this, Off, Sym); break;
|
||||
default:
|
||||
fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
|
||||
}
|
||||
@ -135,7 +150,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym,
|
||||
case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, S - P - 4); break;
|
||||
case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, S - P - 4); break;
|
||||
case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, S - P - 4); break;
|
||||
case IMAGE_REL_ARM_SECREL: add32(Off, Sym->getSecrel()); break;
|
||||
case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, Sym); break;
|
||||
default:
|
||||
fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
|
||||
}
|
||||
@ -226,8 +241,12 @@ bool SectionChunk::isCOMDAT() const {
|
||||
void SectionChunk::printDiscardedMessage() const {
|
||||
// Removed by dead-stripping. If it's removed by ICF, ICF already
|
||||
// printed out the name, so don't repeat that here.
|
||||
if (Sym && this == Repl)
|
||||
message("Discarded " + Sym->getName());
|
||||
if (Sym && this == Repl) {
|
||||
if (Discarded)
|
||||
message("Discarded comdat symbol " + Sym->getName());
|
||||
else if (!Live)
|
||||
message("Discarded " + Sym->getName());
|
||||
}
|
||||
}
|
||||
|
||||
StringRef SectionChunk::getDebugName() {
|
||||
|
@ -64,7 +64,6 @@ class Chunk {
|
||||
uint64_t getRVA() const { return RVA; }
|
||||
uint32_t getAlign() const { return Align; }
|
||||
void setRVA(uint64_t V) { RVA = V; }
|
||||
void setOutputSectionOff(uint64_t V) { OutputSectionOff = V; }
|
||||
|
||||
// Returns true if this has non-zero data. BSS chunks return
|
||||
// false. If false is returned, the space occupied by this chunk
|
||||
@ -97,17 +96,19 @@ class Chunk {
|
||||
Chunk(Kind K = OtherKind) : ChunkKind(K) {}
|
||||
const Kind ChunkKind;
|
||||
|
||||
// The alignment of this chunk. The writer uses the value.
|
||||
uint32_t Align = 1;
|
||||
|
||||
// The RVA of this chunk in the output. The writer sets a value.
|
||||
uint64_t RVA = 0;
|
||||
|
||||
public:
|
||||
// The offset from beginning of the output section. The writer sets a value.
|
||||
uint64_t OutputSectionOff = 0;
|
||||
|
||||
protected:
|
||||
// The output section for this chunk.
|
||||
OutputSection *Out = nullptr;
|
||||
|
||||
// The alignment of this chunk. The writer uses the value.
|
||||
uint32_t Align = 1;
|
||||
};
|
||||
|
||||
// A chunk corresponding a section of an input file.
|
||||
@ -159,13 +160,29 @@ class SectionChunk : public Chunk {
|
||||
StringRef getDebugName() override;
|
||||
void setSymbol(DefinedRegular *S) { if (!Sym) Sym = S; }
|
||||
|
||||
// Returns true if the chunk was not dropped by GC or COMDAT deduplication.
|
||||
bool isLive() { return Live && !Discarded; }
|
||||
|
||||
// Used by the garbage collector.
|
||||
bool isLive() { return !Config->DoGC || Live; }
|
||||
void markLive() {
|
||||
assert(Config->DoGC && "should only mark things live from GC");
|
||||
assert(!isLive() && "Cannot mark an already live section!");
|
||||
Live = true;
|
||||
}
|
||||
|
||||
// Returns true if this chunk was dropped by COMDAT deduplication.
|
||||
bool isDiscarded() const { return Discarded; }
|
||||
|
||||
// Used by the SymbolTable when discarding unused comdat sections. This is
|
||||
// redundant when GC is enabled, as all comdat sections will start out dead.
|
||||
void markDiscarded() { Discarded = 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 {
|
||||
return SectionName == ".debug" || SectionName.startswith(".debug$");
|
||||
}
|
||||
|
||||
// Allow iteration over the bodies of this chunk's relocated symbols.
|
||||
llvm::iterator_range<symbol_iterator> symbols() const {
|
||||
return llvm::make_range(symbol_iterator(File, Relocs.begin()),
|
||||
@ -196,6 +213,9 @@ class SectionChunk : public Chunk {
|
||||
llvm::iterator_range<const coff_relocation *> Relocs;
|
||||
size_t NumRelocs;
|
||||
|
||||
// True if this chunk was discarded because it was a duplicate comdat section.
|
||||
bool Discarded;
|
||||
|
||||
// Used by the garbage collector.
|
||||
bool Live;
|
||||
|
||||
|
@ -161,9 +161,6 @@ struct Configuration {
|
||||
bool LargeAddressAware = false;
|
||||
bool HighEntropyVA = false;
|
||||
bool AppContainer = false;
|
||||
|
||||
// This is for debugging.
|
||||
bool DumpPdb = false;
|
||||
};
|
||||
|
||||
extern Configuration *Config;
|
||||
|
@ -905,7 +905,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
Config->TerminalServerAware = false;
|
||||
if (Args.hasArg(OPT_nosymtab))
|
||||
Config->WriteSymtab = false;
|
||||
Config->DumpPdb = Args.hasArg(OPT_dumppdb);
|
||||
|
||||
Config->MapFile = getMapFile(Args);
|
||||
|
||||
@ -936,9 +935,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
Config->Machine = AMD64;
|
||||
}
|
||||
|
||||
// Windows specific -- Input files can be Windows resource files (.res files).
|
||||
// We invoke cvtres.exe to convert resource files to a regular COFF file
|
||||
// then link the result file normally.
|
||||
// Input files can be Windows resource files (.res files). We use
|
||||
// WindowsResource to convert resource files to a regular COFF file,
|
||||
// then link the resulting file normally.
|
||||
if (!Resources.empty())
|
||||
addBuffer(convertResToCOFF(Resources));
|
||||
|
||||
@ -1027,17 +1026,21 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
if (Config->ImageBase == uint64_t(-1))
|
||||
Config->ImageBase = getDefaultImageBase();
|
||||
|
||||
Symtab.addRelative(mangle("__ImageBase"), 0);
|
||||
Symtab.addSynthetic(mangle("__ImageBase"), nullptr);
|
||||
if (Config->Machine == I386) {
|
||||
Config->SEHTable = Symtab.addRelative("___safe_se_handler_table", 0);
|
||||
Config->SEHCount = Symtab.addAbsolute("___safe_se_handler_count", 0);
|
||||
Symtab.addAbsolute("___safe_se_handler_table", 0);
|
||||
Symtab.addAbsolute("___safe_se_handler_count", 0);
|
||||
}
|
||||
|
||||
// We do not support /guard:cf (control flow protection) yet.
|
||||
// Define CFG symbols anyway so that we can link MSVC 2015 CRT.
|
||||
Symtab.addAbsolute(mangle("__guard_fids_table"), 0);
|
||||
Symtab.addAbsolute(mangle("__guard_fids_count"), 0);
|
||||
Symtab.addAbsolute(mangle("__guard_fids_table"), 0);
|
||||
Symtab.addAbsolute(mangle("__guard_flags"), 0x100);
|
||||
Symtab.addAbsolute(mangle("__guard_iat_count"), 0);
|
||||
Symtab.addAbsolute(mangle("__guard_iat_table"), 0);
|
||||
Symtab.addAbsolute(mangle("__guard_longjmp_count"), 0);
|
||||
Symtab.addAbsolute(mangle("__guard_longjmp_table"), 0);
|
||||
|
||||
// This code may add new undefined symbols to the link, which may enqueue more
|
||||
// symbol resolution tasks, so we need to continue executing tasks until we
|
||||
|
@ -178,7 +178,7 @@ void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects);
|
||||
// Create enum with OPT_xxx values for each option in Options.td
|
||||
enum {
|
||||
OPT_INVALID = 0,
|
||||
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11) OPT_##ID,
|
||||
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
|
||||
#include "Options.inc"
|
||||
#undef OPTION
|
||||
};
|
||||
|
@ -20,12 +20,15 @@
|
||||
#include "Symbols.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/BinaryFormat/COFF.h"
|
||||
#include "llvm/Object/COFF.h"
|
||||
#include "llvm/Object/WindowsResource.h"
|
||||
#include "llvm/Option/Arg.h"
|
||||
#include "llvm/Option/ArgList.h"
|
||||
#include "llvm/Option/Option.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileUtilities.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include "llvm/Support/Program.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -41,6 +44,9 @@ namespace lld {
|
||||
namespace coff {
|
||||
namespace {
|
||||
|
||||
const uint16_t SUBLANG_ENGLISH_US = 0x0409;
|
||||
const uint16_t RT_MANIFEST = 24;
|
||||
|
||||
class Executor {
|
||||
public:
|
||||
explicit Executor(StringRef S) : Prog(Saver.save(S)) {}
|
||||
@ -257,26 +263,6 @@ void parseManifestUAC(StringRef Arg) {
|
||||
}
|
||||
}
|
||||
|
||||
// Quote each line with "". Existing double-quote is converted
|
||||
// to two double-quotes.
|
||||
static void quoteAndPrint(raw_ostream &Out, StringRef S) {
|
||||
while (!S.empty()) {
|
||||
StringRef Line;
|
||||
std::tie(Line, S) = S.split("\n");
|
||||
if (Line.empty())
|
||||
continue;
|
||||
Out << '\"';
|
||||
for (int I = 0, E = Line.size(); I != E; ++I) {
|
||||
if (Line[I] == '\"') {
|
||||
Out << "\"\"";
|
||||
} else {
|
||||
Out << Line[I];
|
||||
}
|
||||
}
|
||||
Out << "\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
// An RAII temporary file class that automatically removes a temporary file.
|
||||
namespace {
|
||||
class TemporaryFile {
|
||||
@ -390,38 +376,64 @@ static std::string createManifestXml() {
|
||||
return readFile(File2.Path);
|
||||
}
|
||||
|
||||
static std::unique_ptr<MemoryBuffer>
|
||||
createMemoryBufferForManifestRes(size_t ManifestSize) {
|
||||
size_t ResSize = alignTo(object::WIN_RES_MAGIC_SIZE +
|
||||
object::WIN_RES_NULL_ENTRY_SIZE +
|
||||
sizeof(object::WinResHeaderPrefix) +
|
||||
sizeof(object::WinResIDs) +
|
||||
sizeof(object::WinResHeaderSuffix) +
|
||||
ManifestSize,
|
||||
object::WIN_RES_DATA_ALIGNMENT);
|
||||
return MemoryBuffer::getNewMemBuffer(ResSize);
|
||||
}
|
||||
|
||||
static void writeResFileHeader(char *&Buf) {
|
||||
memcpy(Buf, COFF::WinResMagic, sizeof(COFF::WinResMagic));
|
||||
Buf += sizeof(COFF::WinResMagic);
|
||||
memset(Buf, 0, object::WIN_RES_NULL_ENTRY_SIZE);
|
||||
Buf += object::WIN_RES_NULL_ENTRY_SIZE;
|
||||
}
|
||||
|
||||
static void writeResEntryHeader(char *&Buf, size_t ManifestSize) {
|
||||
// Write the prefix.
|
||||
auto *Prefix = reinterpret_cast<object::WinResHeaderPrefix *>(Buf);
|
||||
Prefix->DataSize = ManifestSize;
|
||||
Prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) +
|
||||
sizeof(object::WinResIDs) +
|
||||
sizeof(object::WinResHeaderSuffix);
|
||||
Buf += sizeof(object::WinResHeaderPrefix);
|
||||
|
||||
// Write the Type/Name IDs.
|
||||
auto *IDs = reinterpret_cast<object::WinResIDs *>(Buf);
|
||||
IDs->setType(RT_MANIFEST);
|
||||
IDs->setName(Config->ManifestID);
|
||||
Buf += sizeof(object::WinResIDs);
|
||||
|
||||
// Write the suffix.
|
||||
auto *Suffix = reinterpret_cast<object::WinResHeaderSuffix *>(Buf);
|
||||
Suffix->DataVersion = 0;
|
||||
Suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE;
|
||||
Suffix->Language = SUBLANG_ENGLISH_US;
|
||||
Suffix->Version = 0;
|
||||
Suffix->Characteristics = 0;
|
||||
Buf += sizeof(object::WinResHeaderSuffix);
|
||||
}
|
||||
|
||||
// Create a resource file containing a manifest XML.
|
||||
std::unique_ptr<MemoryBuffer> createManifestRes() {
|
||||
// Create a temporary file for the resource script file.
|
||||
TemporaryFile RCFile("manifest", "rc");
|
||||
std::string Manifest = createManifestXml();
|
||||
|
||||
// Open the temporary file for writing.
|
||||
std::error_code EC;
|
||||
raw_fd_ostream Out(RCFile.Path, EC, sys::fs::F_Text);
|
||||
if (EC)
|
||||
fatal(EC, "failed to open " + RCFile.Path);
|
||||
std::unique_ptr<MemoryBuffer> Res =
|
||||
createMemoryBufferForManifestRes(Manifest.size());
|
||||
|
||||
// Write resource script to the RC file.
|
||||
Out << "#define LANG_ENGLISH 9\n"
|
||||
<< "#define SUBLANG_DEFAULT 1\n"
|
||||
<< "#define APP_MANIFEST " << Config->ManifestID << "\n"
|
||||
<< "#define RT_MANIFEST 24\n"
|
||||
<< "LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\n"
|
||||
<< "APP_MANIFEST RT_MANIFEST {\n";
|
||||
quoteAndPrint(Out, createManifestXml());
|
||||
Out << "}\n";
|
||||
Out.close();
|
||||
char *Buf = const_cast<char *>(Res->getBufferStart());
|
||||
writeResFileHeader(Buf);
|
||||
writeResEntryHeader(Buf, Manifest.size());
|
||||
|
||||
// Create output resource file.
|
||||
TemporaryFile ResFile("output-resource", "res");
|
||||
|
||||
Executor E("rc.exe");
|
||||
E.add("/fo");
|
||||
E.add(ResFile.Path);
|
||||
E.add("/nologo");
|
||||
E.add(RCFile.Path);
|
||||
E.run();
|
||||
return ResFile.getMemoryBuffer();
|
||||
// Copy the manifest data into the .res file.
|
||||
std::copy(Manifest.begin(), Manifest.end(), Buf);
|
||||
return Res;
|
||||
}
|
||||
|
||||
void createSideBySideManifest() {
|
||||
@ -592,40 +604,22 @@ void checkFailIfMismatch(StringRef Arg) {
|
||||
// using cvtres.exe.
|
||||
std::unique_ptr<MemoryBuffer>
|
||||
convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
|
||||
// Create an output file path.
|
||||
TemporaryFile File("resource-file", "obj");
|
||||
object::WindowsResourceParser Parser;
|
||||
|
||||
// Execute cvtres.exe.
|
||||
Executor E("cvtres.exe");
|
||||
E.add("/machine:" + machineToStr(Config->Machine));
|
||||
E.add("/readonly");
|
||||
E.add("/nologo");
|
||||
E.add("/out:" + Twine(File.Path));
|
||||
|
||||
// We must create new files because the memory buffers we have may have no
|
||||
// underlying file still existing on the disk.
|
||||
// It happens if it was created from a TemporaryFile, which usually delete
|
||||
// the file just after creating the MemoryBuffer.
|
||||
std::vector<TemporaryFile> ResFiles;
|
||||
ResFiles.reserve(MBs.size());
|
||||
for (MemoryBufferRef MB : MBs) {
|
||||
// We store the temporary file in a vector to avoid deletion
|
||||
// before running cvtres
|
||||
ResFiles.emplace_back("resource-file", "res");
|
||||
TemporaryFile& ResFile = ResFiles.back();
|
||||
// Write the content of the resource in a temporary file
|
||||
std::error_code EC;
|
||||
raw_fd_ostream OS(ResFile.Path, EC, sys::fs::F_None);
|
||||
if (EC)
|
||||
fatal(EC, "failed to open " + ResFile.Path);
|
||||
OS << MB.getBuffer();
|
||||
OS.close();
|
||||
|
||||
E.add(ResFile.Path);
|
||||
std::unique_ptr<object::Binary> Bin = check(object::createBinary(MB));
|
||||
object::WindowsResource *RF = dyn_cast<object::WindowsResource>(Bin.get());
|
||||
if (!RF)
|
||||
fatal("cannot compile non-resource file as resource");
|
||||
if (auto EC = Parser.parse(RF))
|
||||
fatal(EC, "failed to parse .res file");
|
||||
}
|
||||
|
||||
E.run();
|
||||
return File.getMemoryBuffer();
|
||||
Expected<std::unique_ptr<MemoryBuffer>> E =
|
||||
llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser);
|
||||
if (!E)
|
||||
fatal(errorToErrorCode(E.takeError()), "failed to write .res to COFF");
|
||||
return std::move(E.get());
|
||||
}
|
||||
|
||||
// Run MSVC link.exe for given in-memory object files.
|
||||
@ -657,11 +651,9 @@ void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects) {
|
||||
|
||||
// Create table mapping all options defined in Options.td
|
||||
static const llvm::opt::OptTable::Info infoTable[] = {
|
||||
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
|
||||
{ \
|
||||
X1, X2, X9, X10, OPT_##ID, llvm::opt::Option::KIND##Class, X8, X7, \
|
||||
OPT_##GROUP, OPT_##ALIAS, X6 \
|
||||
},
|
||||
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
|
||||
{X1, X2, X10, X11, OPT_##ID, llvm::opt::Option::KIND##Class, \
|
||||
X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
|
||||
#include "Options.inc"
|
||||
#undef OPTION
|
||||
};
|
||||
|
@ -132,17 +132,17 @@ void ObjectFile::initializeChunks() {
|
||||
if (!Config->Debug && Name.startswith(".debug"))
|
||||
continue;
|
||||
|
||||
// CodeView sections are stored to a different vector because they are
|
||||
// not linked in the regular manner.
|
||||
if (Name == ".debug" || Name.startswith(".debug$")) {
|
||||
DebugChunks.push_back(make<SectionChunk>(this, Sec));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
|
||||
continue;
|
||||
auto *C = make<SectionChunk>(this, Sec);
|
||||
Chunks.push_back(C);
|
||||
|
||||
// CodeView sections are stored to a different vector because they are not
|
||||
// linked in the regular manner.
|
||||
if (C->isCodeView())
|
||||
DebugChunks.push_back(C);
|
||||
else
|
||||
Chunks.push_back(C);
|
||||
|
||||
SparseChunks[I] = C;
|
||||
}
|
||||
}
|
||||
@ -249,8 +249,12 @@ SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP,
|
||||
auto *Aux = reinterpret_cast<const coff_aux_section_definition *>(AuxP);
|
||||
if (Aux->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
|
||||
if (auto *ParentSC = cast_or_null<SectionChunk>(
|
||||
SparseChunks[Aux->getNumber(Sym.isBigObj())]))
|
||||
SparseChunks[Aux->getNumber(Sym.isBigObj())])) {
|
||||
ParentSC->addAssociative(SC);
|
||||
// If we already discarded the parent, discard the child.
|
||||
if (ParentSC->isDiscarded())
|
||||
SC->markDiscarded();
|
||||
}
|
||||
SC->Checksum = Aux->CheckSum;
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,6 @@ def nosymtab : F<"nosymtab">;
|
||||
def msvclto : F<"msvclto">;
|
||||
|
||||
// Flags for debugging
|
||||
def dumppdb : Joined<["/", "-"], "dumppdb">;
|
||||
def lldmap : F<"lldmap">;
|
||||
def lldmap_file : Joined<["/", "-"], "lldmap:">;
|
||||
|
||||
|
293
COFF/PDB.cpp
293
COFF/PDB.cpp
@ -15,10 +15,11 @@
|
||||
#include "Symbols.h"
|
||||
#include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
|
||||
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
|
||||
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
|
||||
#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
|
||||
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
|
||||
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
|
||||
@ -46,8 +47,6 @@ using namespace lld;
|
||||
using namespace lld::coff;
|
||||
using namespace llvm;
|
||||
using namespace llvm::codeview;
|
||||
using namespace llvm::support;
|
||||
using namespace llvm::support::endian;
|
||||
|
||||
using llvm::object::coff_section;
|
||||
|
||||
@ -68,22 +67,24 @@ static SectionChunk *findByName(std::vector<SectionChunk *> &Sections,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) {
|
||||
SectionChunk *Sec = findByName(File->getDebugChunks(), SecName);
|
||||
if (!Sec)
|
||||
return {};
|
||||
|
||||
static ArrayRef<uint8_t> consumeDebugMagic(ArrayRef<uint8_t> Data,
|
||||
StringRef SecName) {
|
||||
// First 4 bytes are section magic.
|
||||
ArrayRef<uint8_t> Data = Sec->getContents();
|
||||
if (Data.size() < 4)
|
||||
fatal(SecName + " too short");
|
||||
if (read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
|
||||
if (support::endian::read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
|
||||
fatal(SecName + " has an invalid magic");
|
||||
return Data.slice(4);
|
||||
}
|
||||
|
||||
static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) {
|
||||
if (SectionChunk *Sec = findByName(File->getDebugChunks(), SecName))
|
||||
return consumeDebugMagic(Sec->getContents(), SecName);
|
||||
return {};
|
||||
}
|
||||
|
||||
static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
|
||||
codeview::TypeTableBuilder &TypeTable) {
|
||||
TypeTableBuilder &TypeTable) {
|
||||
// Start the TPI or IPI stream header.
|
||||
TpiBuilder.setVersionHeader(pdb::PdbTpiV80);
|
||||
|
||||
@ -94,17 +95,148 @@ static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
|
||||
});
|
||||
}
|
||||
|
||||
static void mergeDebugT(ObjectFile *File,
|
||||
TypeTableBuilder &IDTable,
|
||||
TypeTableBuilder &TypeTable,
|
||||
SmallVectorImpl<TypeIndex> &TypeIndexMap,
|
||||
pdb::PDBTypeServerHandler &Handler) {
|
||||
ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
|
||||
if (Data.empty())
|
||||
return;
|
||||
|
||||
BinaryByteStream Stream(Data, support::little);
|
||||
CVTypeArray Types;
|
||||
BinaryStreamReader Reader(Stream);
|
||||
Handler.addSearchPath(sys::path::parent_path(File->getName()));
|
||||
if (auto EC = Reader.readArray(Types, Reader.getLength()))
|
||||
fatal(EC, "Reader::readArray failed");
|
||||
if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
|
||||
TypeIndexMap, &Handler, Types))
|
||||
fatal(Err, "codeview::mergeTypeStreams failed");
|
||||
}
|
||||
|
||||
static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
|
||||
if (TI.isSimple())
|
||||
return true;
|
||||
if (TI.toArrayIndex() >= TypeIndexMap.size())
|
||||
return false;
|
||||
TI = TypeIndexMap[TI.toArrayIndex()];
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool remapTypesInSymbolRecord(ObjectFile *File,
|
||||
MutableArrayRef<uint8_t> Contents,
|
||||
ArrayRef<TypeIndex> TypeIndexMap,
|
||||
ArrayRef<TiReference> TypeRefs) {
|
||||
for (const TiReference &Ref : TypeRefs) {
|
||||
unsigned ByteSize = Ref.Count * sizeof(TypeIndex);
|
||||
if (Contents.size() < Ref.Offset + ByteSize) {
|
||||
log("ignoring short symbol record");
|
||||
return false;
|
||||
}
|
||||
MutableArrayRef<TypeIndex> TIs(
|
||||
reinterpret_cast<TypeIndex *>(Contents.data() + Ref.Offset), Ref.Count);
|
||||
for (TypeIndex &TI : TIs)
|
||||
if (!remapTypeIndex(TI, TypeIndexMap)) {
|
||||
log("ignoring symbol record in " + File->getName() +
|
||||
" with bad type index 0x" + utohexstr(TI.getIndex()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// MSVC translates S_PROC_ID_END to S_END.
|
||||
uint16_t canonicalizeSymbolKind(SymbolKind Kind) {
|
||||
if (Kind == SymbolKind::S_PROC_ID_END)
|
||||
return SymbolKind::S_END;
|
||||
return Kind;
|
||||
}
|
||||
|
||||
/// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned.
|
||||
/// The object file may not be aligned.
|
||||
static MutableArrayRef<uint8_t> copySymbolForPdb(const CVSymbol &Sym,
|
||||
BumpPtrAllocator &Alloc) {
|
||||
size_t Size = alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb));
|
||||
assert(Size >= 4 && "record too short");
|
||||
assert(Size <= MaxRecordLength && "record too long");
|
||||
void *Mem = Alloc.Allocate(Size, 4);
|
||||
|
||||
// Copy the symbol record and zero out any padding bytes.
|
||||
MutableArrayRef<uint8_t> NewData(reinterpret_cast<uint8_t *>(Mem), Size);
|
||||
memcpy(NewData.data(), Sym.data().data(), Sym.length());
|
||||
memset(NewData.data() + Sym.length(), 0, Size - Sym.length());
|
||||
|
||||
// Update the record prefix length. It should point to the beginning of the
|
||||
// next record. MSVC does some canonicalization of the record kind, so we do
|
||||
// that as well.
|
||||
auto *Prefix = reinterpret_cast<RecordPrefix *>(Mem);
|
||||
Prefix->RecordKind = canonicalizeSymbolKind(Sym.kind());
|
||||
Prefix->RecordLen = Size - 2;
|
||||
return NewData;
|
||||
}
|
||||
|
||||
static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File,
|
||||
ArrayRef<TypeIndex> TypeIndexMap,
|
||||
BinaryStreamRef SymData) {
|
||||
// FIXME: Improve error recovery by warning and skipping records when
|
||||
// possible.
|
||||
CVSymbolArray Syms;
|
||||
BinaryStreamReader Reader(SymData);
|
||||
ExitOnErr(Reader.readArray(Syms, Reader.getLength()));
|
||||
for (const CVSymbol &Sym : Syms) {
|
||||
// Discover type index references in the record. Skip it if we don't know
|
||||
// where they are.
|
||||
SmallVector<TiReference, 32> TypeRefs;
|
||||
if (!discoverTypeIndices(Sym, TypeRefs)) {
|
||||
log("ignoring unknown symbol record with kind 0x" + utohexstr(Sym.kind()));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Copy the symbol record so we can mutate it.
|
||||
MutableArrayRef<uint8_t> NewData = copySymbolForPdb(Sym, Alloc);
|
||||
|
||||
// Re-map all the type index references.
|
||||
MutableArrayRef<uint8_t> Contents =
|
||||
NewData.drop_front(sizeof(RecordPrefix));
|
||||
if (!remapTypesInSymbolRecord(File, Contents, TypeIndexMap, TypeRefs))
|
||||
continue;
|
||||
|
||||
// FIXME: Fill in "Parent" and "End" fields by maintaining a stack of
|
||||
// scopes.
|
||||
|
||||
// Add the symbol to the module.
|
||||
File->ModuleDBI->addSymbol(CVSymbol(Sym.kind(), NewData));
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate memory for a .debug$S section and relocate it.
|
||||
static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
|
||||
SectionChunk *DebugChunk) {
|
||||
uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk->getSize());
|
||||
assert(DebugChunk->OutputSectionOff == 0 &&
|
||||
"debug sections should not be in output sections");
|
||||
DebugChunk->writeTo(Buffer);
|
||||
return consumeDebugMagic(makeArrayRef(Buffer, DebugChunk->getSize()),
|
||||
".debug$S");
|
||||
}
|
||||
|
||||
// Add all object files to the PDB. Merge .debug$T sections into IpiData and
|
||||
// TpiData.
|
||||
static void addObjectsToPDB(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder,
|
||||
codeview::TypeTableBuilder &TypeTable,
|
||||
codeview::TypeTableBuilder &IDTable) {
|
||||
static void addObjectsToPDB(BumpPtrAllocator &Alloc, SymbolTable *Symtab,
|
||||
pdb::PDBFileBuilder &Builder,
|
||||
TypeTableBuilder &TypeTable,
|
||||
TypeTableBuilder &IDTable) {
|
||||
// Follow type servers. If the same type server is encountered more than
|
||||
// once for this instance of `PDBTypeServerHandler` (for example if many
|
||||
// object files reference the same TypeServer), the types from the
|
||||
// TypeServer will only be visited once.
|
||||
pdb::PDBTypeServerHandler Handler;
|
||||
|
||||
// PDBs use a single global string table for filenames in the file checksum
|
||||
// table.
|
||||
auto PDBStrTab = std::make_shared<DebugStringTableSubsection>();
|
||||
|
||||
// Visit all .debug$T sections to add them to Builder.
|
||||
for (ObjectFile *File : Symtab->ObjectFiles) {
|
||||
// Add a module descriptor for every object file. We need to put an absolute
|
||||
@ -118,25 +250,74 @@ static void addObjectsToPDB(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder,
|
||||
File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));
|
||||
File->ModuleDBI->setObjFileName(Path);
|
||||
|
||||
// FIXME: Walk the .debug$S sections and add them. Do things like recording
|
||||
// source files.
|
||||
// Before we can process symbol substreams from .debug$S, we need to process
|
||||
// type information, file checksums, and the string table. Add type info to
|
||||
// the PDB first, so that we can get the map from object file type and item
|
||||
// indices to PDB type and item indices.
|
||||
SmallVector<TypeIndex, 128> TypeIndexMap;
|
||||
mergeDebugT(File, IDTable, TypeTable, TypeIndexMap, Handler);
|
||||
|
||||
ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
|
||||
if (Data.empty())
|
||||
continue;
|
||||
// Now do all line info.
|
||||
for (SectionChunk *DebugChunk : File->getDebugChunks()) {
|
||||
if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S")
|
||||
continue;
|
||||
|
||||
BinaryByteStream Stream(Data, support::little);
|
||||
codeview::CVTypeArray Types;
|
||||
BinaryStreamReader Reader(Stream);
|
||||
SmallVector<TypeIndex, 128> SourceToDest;
|
||||
Handler.addSearchPath(llvm::sys::path::parent_path(File->getName()));
|
||||
if (auto EC = Reader.readArray(Types, Reader.getLength()))
|
||||
fatal(EC, "Reader::readArray failed");
|
||||
if (auto Err = codeview::mergeTypeAndIdRecords(
|
||||
IDTable, TypeTable, SourceToDest, &Handler, Types))
|
||||
fatal(Err, "codeview::mergeTypeStreams failed");
|
||||
ArrayRef<uint8_t> RelocatedDebugContents =
|
||||
relocateDebugChunk(Alloc, DebugChunk);
|
||||
if (RelocatedDebugContents.empty())
|
||||
continue;
|
||||
|
||||
DebugSubsectionArray Subsections;
|
||||
BinaryStreamReader Reader(RelocatedDebugContents, support::little);
|
||||
ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size()));
|
||||
|
||||
DebugStringTableSubsectionRef CVStrTab;
|
||||
DebugChecksumsSubsectionRef Checksums;
|
||||
for (const DebugSubsectionRecord &SS : Subsections) {
|
||||
switch (SS.kind()) {
|
||||
case DebugSubsectionKind::StringTable:
|
||||
ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
|
||||
break;
|
||||
case DebugSubsectionKind::FileChecksums:
|
||||
ExitOnErr(Checksums.initialize(SS.getRecordData()));
|
||||
break;
|
||||
case DebugSubsectionKind::Lines:
|
||||
// We can add the relocated line table directly to the PDB without
|
||||
// modification because the file checksum offsets will stay the same.
|
||||
File->ModuleDBI->addDebugSubsection(SS);
|
||||
break;
|
||||
case DebugSubsectionKind::Symbols:
|
||||
mergeSymbolRecords(Alloc, File, TypeIndexMap, SS.getRecordData());
|
||||
break;
|
||||
default:
|
||||
// FIXME: Process the rest of the subsections.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Checksums.valid()) {
|
||||
// Make a new file checksum table that refers to offsets in the PDB-wide
|
||||
// string table. Generally the string table subsection appears after the
|
||||
// checksum table, so we have to do this after looping over all the
|
||||
// subsections.
|
||||
if (!CVStrTab.valid())
|
||||
fatal(".debug$S sections must have both a string table subsection "
|
||||
"and a checksum subsection table or neither");
|
||||
auto NewChecksums =
|
||||
make_unique<DebugChecksumsSubsection>(*PDBStrTab);
|
||||
for (FileChecksumEntry &FC : Checksums) {
|
||||
StringRef FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset));
|
||||
ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(
|
||||
*File->ModuleDBI, FileName));
|
||||
NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum);
|
||||
}
|
||||
File->ModuleDBI->addDebugSubsection(std::move(NewChecksums));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Builder.getStringTableBuilder().setStrings(*PDBStrTab);
|
||||
|
||||
// Construct TPI stream contents.
|
||||
addTypeInfo(Builder.getTpiBuilder(), TypeTable);
|
||||
|
||||
@ -144,56 +325,10 @@ static void addObjectsToPDB(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder,
|
||||
addTypeInfo(Builder.getIpiBuilder(), IDTable);
|
||||
}
|
||||
|
||||
static void dumpDebugT(ScopedPrinter &W, ObjectFile *File) {
|
||||
ListScope LS(W, "DebugT");
|
||||
ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
|
||||
if (Data.empty())
|
||||
return;
|
||||
|
||||
LazyRandomTypeCollection Types(Data, 100);
|
||||
TypeDumpVisitor TDV(Types, &W, false);
|
||||
// Use a default implementation that does not follow type servers and instead
|
||||
// just dumps the contents of the TypeServer2 record.
|
||||
if (auto EC = codeview::visitTypeStream(Types, TDV))
|
||||
fatal(EC, "CVTypeDumper::dump failed");
|
||||
}
|
||||
|
||||
static void dumpDebugS(ScopedPrinter &W, ObjectFile *File) {
|
||||
ListScope LS(W, "DebugS");
|
||||
ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$S");
|
||||
if (Data.empty())
|
||||
return;
|
||||
|
||||
BinaryByteStream Stream(Data, llvm::support::little);
|
||||
CVSymbolArray Symbols;
|
||||
BinaryStreamReader Reader(Stream);
|
||||
if (auto EC = Reader.readArray(Symbols, Reader.getLength()))
|
||||
fatal(EC, "StreamReader.readArray<CVSymbolArray> failed");
|
||||
|
||||
TypeDatabase TDB(0);
|
||||
CVSymbolDumper SymbolDumper(W, TDB, CodeViewContainer::ObjectFile, nullptr,
|
||||
false);
|
||||
if (auto EC = SymbolDumper.dump(Symbols))
|
||||
fatal(EC, "CVSymbolDumper::dump failed");
|
||||
}
|
||||
|
||||
// Dump CodeView debug info. This is for debugging.
|
||||
static void dumpCodeView(SymbolTable *Symtab) {
|
||||
ScopedPrinter W(outs());
|
||||
|
||||
for (ObjectFile *File : Symtab->ObjectFiles) {
|
||||
dumpDebugT(W, File);
|
||||
dumpDebugS(W, File);
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a PDB file.
|
||||
void coff::createPDB(StringRef Path, SymbolTable *Symtab,
|
||||
ArrayRef<uint8_t> SectionTable,
|
||||
const llvm::codeview::DebugInfo *DI) {
|
||||
if (Config->DumpPdb)
|
||||
dumpCodeView(Symtab);
|
||||
|
||||
BumpPtrAllocator Alloc;
|
||||
pdb::PDBFileBuilder Builder(Alloc);
|
||||
ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
|
||||
@ -219,9 +354,9 @@ void coff::createPDB(StringRef Path, SymbolTable *Symtab,
|
||||
pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
|
||||
DbiBuilder.setVersionHeader(pdb::PdbDbiV110);
|
||||
|
||||
codeview::TypeTableBuilder TypeTable(BAlloc);
|
||||
codeview::TypeTableBuilder IDTable(BAlloc);
|
||||
addObjectsToPDB(Symtab, Builder, TypeTable, IDTable);
|
||||
TypeTableBuilder TypeTable(BAlloc);
|
||||
TypeTableBuilder IDTable(BAlloc);
|
||||
addObjectsToPDB(Alloc, Symtab, Builder, TypeTable, IDTable);
|
||||
|
||||
// Add Section Contributions.
|
||||
addSectionContribs(Symtab, DbiBuilder);
|
||||
|
@ -8,6 +8,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Strings.h"
|
||||
#include <mutex>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <Windows.h>
|
||||
@ -21,6 +22,10 @@ using namespace llvm;
|
||||
|
||||
Optional<std::string> coff::demangle(StringRef S) {
|
||||
#if defined(_MSC_VER)
|
||||
// UnDecorateSymbolName is not thread-safe, so we need a mutex.
|
||||
static std::mutex Mu;
|
||||
std::lock_guard<std::mutex> Lock(Mu);
|
||||
|
||||
char Buf[4096];
|
||||
if (S.startswith("?"))
|
||||
if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0))
|
||||
|
@ -219,13 +219,13 @@ Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
|
||||
return S;
|
||||
}
|
||||
|
||||
Symbol *SymbolTable::addRelative(StringRef N, uint64_t VA) {
|
||||
Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
|
||||
Symbol *S;
|
||||
bool WasInserted;
|
||||
std::tie(S, WasInserted) = insert(N);
|
||||
S->IsUsedInRegularObj = true;
|
||||
if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
|
||||
replaceBody<DefinedRelative>(S, N, VA);
|
||||
replaceBody<DefinedSynthetic>(S, N, C);
|
||||
else if (!isa<DefinedCOFF>(S->body()))
|
||||
reportDuplicate(S, nullptr);
|
||||
return S;
|
||||
@ -244,6 +244,12 @@ Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT,
|
||||
reportDuplicate(S, F);
|
||||
} else if (SP == SP_NEW) {
|
||||
replaceBody<DefinedRegular>(S, F, N, IsCOMDAT, /*IsExternal*/ true, Sym, C);
|
||||
} else if (SP == SP_EXISTING && IsCOMDAT && C) {
|
||||
C->markDiscarded();
|
||||
// Discard associative chunks that we've parsed so far. No need to recurse
|
||||
// because an associative section cannot have children.
|
||||
for (SectionChunk *Child : C->children())
|
||||
Child->markDiscarded();
|
||||
}
|
||||
return S;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ class SymbolTable {
|
||||
// Creates an Undefined symbol for a given name.
|
||||
SymbolBody *addUndefined(StringRef Name);
|
||||
|
||||
Symbol *addRelative(StringRef N, uint64_t VA);
|
||||
Symbol *addSynthetic(StringRef N, Chunk *C);
|
||||
Symbol *addAbsolute(StringRef N, uint64_t VA);
|
||||
|
||||
Symbol *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias);
|
||||
|
@ -61,6 +61,8 @@ COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
|
||||
return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym));
|
||||
}
|
||||
|
||||
uint16_t DefinedAbsolute::OutputSectionIndex = 0;
|
||||
|
||||
static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) {
|
||||
if (Machine == AMD64)
|
||||
return make<ImportThunkChunkX64>(S);
|
||||
|
@ -50,13 +50,13 @@ class SymbolBody {
|
||||
DefinedImportThunkKind,
|
||||
DefinedImportDataKind,
|
||||
DefinedAbsoluteKind,
|
||||
DefinedRelativeKind,
|
||||
DefinedSyntheticKind,
|
||||
|
||||
UndefinedKind,
|
||||
LazyKind,
|
||||
|
||||
LastDefinedCOFFKind = DefinedCommonKind,
|
||||
LastDefinedKind = DefinedRelativeKind,
|
||||
LastDefinedKind = DefinedSyntheticKind,
|
||||
};
|
||||
|
||||
Kind kind() const { return static_cast<Kind>(SymbolKind); }
|
||||
@ -112,11 +112,11 @@ class Defined : public SymbolBody {
|
||||
|
||||
// Returns the RVA relative to the beginning of the output section.
|
||||
// Used to implement SECREL relocation type.
|
||||
uint64_t getSecrel();
|
||||
uint32_t getSecrel();
|
||||
|
||||
// Returns the output section index.
|
||||
// Used to implement SECTION relocation type.
|
||||
uint64_t getSectionIndex();
|
||||
uint16_t getSectionIndex();
|
||||
|
||||
// Returns true if this symbol points to an executable (e.g. .text) section.
|
||||
// Used to implement ARM relocations.
|
||||
@ -167,6 +167,7 @@ class DefinedRegular : public DefinedCOFF {
|
||||
bool isCOMDAT() { return IsCOMDAT; }
|
||||
SectionChunk *getChunk() { return *Data; }
|
||||
uint32_t getValue() { return Sym->Value; }
|
||||
uint32_t getSecrel();
|
||||
|
||||
private:
|
||||
SectionChunk **Data;
|
||||
@ -186,6 +187,8 @@ class DefinedCommon : public DefinedCOFF {
|
||||
}
|
||||
|
||||
uint64_t getRVA() { return Data->getRVA(); }
|
||||
uint32_t getSecrel() { return Data->OutputSectionOff; }
|
||||
uint16_t getSectionIndex();
|
||||
|
||||
private:
|
||||
friend SymbolTable;
|
||||
@ -212,28 +215,34 @@ class DefinedAbsolute : public Defined {
|
||||
uint64_t getRVA() { return VA - Config->ImageBase; }
|
||||
void setVA(uint64_t V) { VA = V; }
|
||||
|
||||
// The sentinel absolute symbol section index. Section index relocations
|
||||
// against absolute symbols resolve to this 16 bit number, and it is the
|
||||
// largest valid section index plus one. This is written by the Writer.
|
||||
static uint16_t OutputSectionIndex;
|
||||
|
||||
private:
|
||||
uint64_t VA;
|
||||
};
|
||||
|
||||
// This is a kind of absolute symbol but relative to the image base.
|
||||
// Unlike absolute symbols, relocations referring this kind of symbols
|
||||
// are subject of the base relocation. This type is used rarely --
|
||||
// mainly for __ImageBase.
|
||||
class DefinedRelative : public Defined {
|
||||
// This symbol is used for linker-synthesized symbols like __ImageBase and
|
||||
// __safe_se_handler_table.
|
||||
class DefinedSynthetic : public Defined {
|
||||
public:
|
||||
explicit DefinedRelative(StringRef Name, uint64_t V = 0)
|
||||
: Defined(DefinedRelativeKind, Name), RVA(V) {}
|
||||
explicit DefinedSynthetic(StringRef Name, Chunk *C)
|
||||
: Defined(DefinedSyntheticKind, Name), C(C) {}
|
||||
|
||||
static bool classof(const SymbolBody *S) {
|
||||
return S->kind() == DefinedRelativeKind;
|
||||
return S->kind() == DefinedSyntheticKind;
|
||||
}
|
||||
|
||||
uint64_t getRVA() { return RVA; }
|
||||
void setRVA(uint64_t V) { RVA = V; }
|
||||
// A null chunk indicates that this is __ImageBase. Otherwise, this is some
|
||||
// other synthesized chunk, like SEHTableChunk.
|
||||
uint32_t getRVA() const { return C ? C->getRVA() : 0; }
|
||||
uint32_t getSecrel() const { return C ? C->OutputSectionOff : 0; }
|
||||
Chunk *getChunk() const { return C; }
|
||||
|
||||
private:
|
||||
uint64_t RVA;
|
||||
Chunk *C;
|
||||
};
|
||||
|
||||
// This class represents a symbol defined in an archive file. It is
|
||||
@ -350,8 +359,8 @@ inline uint64_t Defined::getRVA() {
|
||||
switch (kind()) {
|
||||
case DefinedAbsoluteKind:
|
||||
return cast<DefinedAbsolute>(this)->getRVA();
|
||||
case DefinedRelativeKind:
|
||||
return cast<DefinedRelative>(this)->getRVA();
|
||||
case DefinedSyntheticKind:
|
||||
return cast<DefinedSynthetic>(this)->getRVA();
|
||||
case DefinedImportDataKind:
|
||||
return cast<DefinedImportData>(this)->getRVA();
|
||||
case DefinedImportThunkKind:
|
||||
@ -386,7 +395,7 @@ struct Symbol {
|
||||
// AlignedCharArrayUnion gives us a struct with a char array field that is
|
||||
// large and aligned enough to store any derived class of SymbolBody.
|
||||
llvm::AlignedCharArrayUnion<
|
||||
DefinedRegular, DefinedCommon, DefinedAbsolute, DefinedRelative, Lazy,
|
||||
DefinedRegular, DefinedCommon, DefinedAbsolute, DefinedSynthetic, Lazy,
|
||||
Undefined, DefinedImportData, DefinedImportThunk, DefinedLocalImport>
|
||||
Body;
|
||||
|
||||
|
@ -181,7 +181,7 @@ void OutputSection::addChunk(Chunk *C) {
|
||||
uint64_t Off = Header.VirtualSize;
|
||||
Off = alignTo(Off, C->getAlign());
|
||||
C->setRVA(Off);
|
||||
C->setOutputSectionOff(Off);
|
||||
C->OutputSectionOff = Off;
|
||||
Off += C->getSize();
|
||||
Header.VirtualSize = Off;
|
||||
if (C->hasData())
|
||||
@ -210,16 +210,46 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) {
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Defined::getSecrel() {
|
||||
if (auto *D = dyn_cast<DefinedRegular>(this))
|
||||
return getRVA() - D->getChunk()->getOutputSection()->getRVA();
|
||||
fatal("SECREL relocation points to a non-regular symbol");
|
||||
uint32_t Defined::getSecrel() {
|
||||
assert(this);
|
||||
switch (kind()) {
|
||||
case DefinedRegularKind:
|
||||
return cast<DefinedRegular>(this)->getSecrel();
|
||||
case DefinedCommonKind:
|
||||
return cast<DefinedCommon>(this)->getSecrel();
|
||||
case DefinedSyntheticKind:
|
||||
return cast<DefinedSynthetic>(this)->getSecrel();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fatal("SECREL relocation points to a non-regular symbol: " + toString(*this));
|
||||
}
|
||||
|
||||
uint64_t Defined::getSectionIndex() {
|
||||
uint32_t DefinedRegular::getSecrel() {
|
||||
assert(getChunk()->isLive() && "relocation against discarded section");
|
||||
uint64_t Diff = getRVA() - getChunk()->getOutputSection()->getRVA();
|
||||
assert(Diff < UINT32_MAX && "section offset too large");
|
||||
return (uint32_t)Diff;
|
||||
}
|
||||
|
||||
uint16_t Defined::getSectionIndex() {
|
||||
if (auto *D = dyn_cast<DefinedRegular>(this))
|
||||
return D->getChunk()->getOutputSection()->SectionIndex;
|
||||
fatal("SECTION relocation points to a non-regular symbol");
|
||||
if (isa<DefinedAbsolute>(this))
|
||||
return DefinedAbsolute::OutputSectionIndex;
|
||||
if (auto *D = dyn_cast<DefinedCommon>(this))
|
||||
return D->getSectionIndex();
|
||||
if (auto *D = dyn_cast<DefinedSynthetic>(this)) {
|
||||
if (!D->getChunk())
|
||||
return 0;
|
||||
return D->getChunk()->getOutputSection()->SectionIndex;
|
||||
}
|
||||
fatal("SECTION relocation points to a non-regular symbol: " +
|
||||
toString(*this));
|
||||
}
|
||||
|
||||
uint16_t DefinedCommon::getSectionIndex() {
|
||||
return Data->getOutputSection()->SectionIndex;
|
||||
}
|
||||
|
||||
bool Defined::isExecutable() {
|
||||
@ -345,12 +375,19 @@ void Writer::createMiscChunks() {
|
||||
for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) {
|
||||
if (!File->SEHCompat)
|
||||
return;
|
||||
for (SymbolBody *B : File->SEHandlers)
|
||||
Handlers.insert(cast<Defined>(B));
|
||||
for (SymbolBody *B : File->SEHandlers) {
|
||||
// Make sure the handler is still live. Assume all handlers are regular
|
||||
// symbols.
|
||||
auto *D = dyn_cast<DefinedRegular>(B);
|
||||
if (D && D->getChunk()->isLive())
|
||||
Handlers.insert(D);
|
||||
}
|
||||
}
|
||||
|
||||
SEHTable = make<SEHTableChunk>(Handlers);
|
||||
RData->addChunk(SEHTable);
|
||||
if (!Handlers.empty()) {
|
||||
SEHTable = make<SEHTableChunk>(Handlers);
|
||||
RData->addChunk(SEHTable);
|
||||
}
|
||||
}
|
||||
|
||||
// Create .idata section for the DLL-imported symbol table.
|
||||
@ -442,12 +479,15 @@ size_t Writer::addEntryToStringTable(StringRef Str) {
|
||||
|
||||
Optional<coff_symbol16> Writer::createSymbol(Defined *Def) {
|
||||
// Relative symbols are unrepresentable in a COFF symbol table.
|
||||
if (isa<DefinedRelative>(Def))
|
||||
if (isa<DefinedSynthetic>(Def))
|
||||
return None;
|
||||
|
||||
if (auto *D = dyn_cast<DefinedRegular>(Def))
|
||||
if (!D->getChunk()->isLive())
|
||||
if (auto *D = dyn_cast<DefinedRegular>(Def)) {
|
||||
// Don't write dead symbols or symbols in codeview sections to the symbol
|
||||
// table.
|
||||
if (!D->getChunk()->isLive() || D->getChunk()->isCodeView())
|
||||
return None;
|
||||
}
|
||||
|
||||
if (auto *Sym = dyn_cast<DefinedImportData>(Def))
|
||||
if (!Sym->File->Live)
|
||||
@ -599,6 +639,15 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
|
||||
auto *PE = reinterpret_cast<PEHeaderTy *>(Buf);
|
||||
Buf += sizeof(*PE);
|
||||
PE->Magic = Config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32;
|
||||
|
||||
// If {Major,Minor}LinkerVersion is left at 0.0, then for some
|
||||
// reason signing the resulting PE file with Authenticode produces a
|
||||
// signature that fails to validate on Windows 7 (but is OK on 10).
|
||||
// Set it to 14.0, which is what VS2015 outputs, and which avoids
|
||||
// that problem.
|
||||
PE->MajorLinkerVersion = 14;
|
||||
PE->MinorLinkerVersion = 0;
|
||||
|
||||
PE->ImageBase = Config->ImageBase;
|
||||
PE->SectionAlignment = PageSize;
|
||||
PE->FileAlignment = SectorSize;
|
||||
@ -743,10 +792,13 @@ void Writer::openFile(StringRef Path) {
|
||||
void Writer::fixSafeSEHSymbols() {
|
||||
if (!SEHTable)
|
||||
return;
|
||||
if (auto *T = dyn_cast<DefinedRelative>(Config->SEHTable->body()))
|
||||
T->setRVA(SEHTable->getRVA());
|
||||
if (auto *C = dyn_cast<DefinedAbsolute>(Config->SEHCount->body()))
|
||||
C->setVA(SEHTable->getSize() / 4);
|
||||
// Replace the absolute table symbol with a synthetic symbol pointing to the
|
||||
// SEHTable chunk so that we can emit base relocations for it and resolve
|
||||
// section relative relocations.
|
||||
Symbol *T = Symtab->find("___safe_se_handler_table");
|
||||
Symbol *C = Symtab->find("___safe_se_handler_count");
|
||||
replaceBody<DefinedSynthetic>(T, T->body()->getName(), SEHTable);
|
||||
cast<DefinedAbsolute>(C->body())->setVA(SEHTable->getSize() / 4);
|
||||
}
|
||||
|
||||
// Handles /section options to allow users to overwrite
|
||||
@ -762,6 +814,10 @@ void Writer::setSectionPermissions() {
|
||||
|
||||
// Write section contents to a mmap'ed file.
|
||||
void Writer::writeSections() {
|
||||
// Record the section index that should be used when resolving a section
|
||||
// relocation against an absolute symbol.
|
||||
DefinedAbsolute::OutputSectionIndex = OutputSections.size() + 1;
|
||||
|
||||
uint8_t *Buf = Buffer->getBufferStart();
|
||||
for (OutputSection *Sec : OutputSections) {
|
||||
uint8_t *SecBuf = Buf + Sec->getFileOff();
|
||||
|
@ -8,7 +8,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Error.h"
|
||||
#include "Memory.h"
|
||||
#include "Symbols.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Target.h"
|
||||
@ -371,4 +370,7 @@ void AArch64::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
|
||||
llvm_unreachable("invalid relocation for TLS IE to LE relaxation");
|
||||
}
|
||||
|
||||
TargetInfo *elf::createAArch64TargetInfo() { return make<AArch64>(); }
|
||||
TargetInfo *elf::getAArch64TargetInfo() {
|
||||
static AArch64 Target;
|
||||
return &Target;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "Error.h"
|
||||
#include "InputFiles.h"
|
||||
#include "Memory.h"
|
||||
#include "Symbols.h"
|
||||
#include "Target.h"
|
||||
#include "llvm/Object/ELF.h"
|
||||
@ -79,4 +78,7 @@ RelExpr AMDGPU::getRelExpr(uint32_t Type, const SymbolBody &S,
|
||||
}
|
||||
}
|
||||
|
||||
TargetInfo *elf::createAMDGPUTargetInfo() { return make<AMDGPU>(); }
|
||||
TargetInfo *elf::getAMDGPUTargetInfo() {
|
||||
static AMDGPU Target;
|
||||
return &Target;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "Error.h"
|
||||
#include "InputFiles.h"
|
||||
#include "Memory.h"
|
||||
#include "Symbols.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Target.h"
|
||||
@ -58,6 +57,7 @@ ARM::ARM() {
|
||||
GotPltEntrySize = 4;
|
||||
PltEntrySize = 16;
|
||||
PltHeaderSize = 20;
|
||||
TrapInstr = 0xd4d4d4d4;
|
||||
// ARM uses Variant 1 TLS
|
||||
TcbSize = 8;
|
||||
NeedsThunks = true;
|
||||
@ -429,4 +429,7 @@ int64_t ARM::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const {
|
||||
}
|
||||
}
|
||||
|
||||
TargetInfo *elf::createARMTargetInfo() { return make<ARM>(); }
|
||||
TargetInfo *elf::getARMTargetInfo() {
|
||||
static ARM Target;
|
||||
return &Target;
|
||||
}
|
||||
|
@ -28,7 +28,6 @@
|
||||
|
||||
#include "Error.h"
|
||||
#include "InputFiles.h"
|
||||
#include "Memory.h"
|
||||
#include "Symbols.h"
|
||||
#include "Target.h"
|
||||
#include "llvm/Object/ELF.h"
|
||||
@ -75,4 +74,7 @@ void AVR::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
|
||||
}
|
||||
}
|
||||
|
||||
TargetInfo *elf::createAVRTargetInfo() { return make<AVR>(); }
|
||||
TargetInfo *elf::getAVRTargetInfo() {
|
||||
static AVR Target;
|
||||
return &Target;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "Error.h"
|
||||
#include "InputFiles.h"
|
||||
#include "Memory.h"
|
||||
#include "OutputSections.h"
|
||||
#include "Symbols.h"
|
||||
#include "SyntheticSections.h"
|
||||
@ -55,6 +54,7 @@ template <class ELFT> MIPS<ELFT>::MIPS() {
|
||||
CopyRel = R_MIPS_COPY;
|
||||
PltRel = R_MIPS_JUMP_SLOT;
|
||||
NeedsThunks = true;
|
||||
TrapInstr = 0xefefefef;
|
||||
|
||||
if (ELFT::Is64Bits) {
|
||||
RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
|
||||
@ -412,11 +412,12 @@ bool MIPS<ELFT>::usesOnlyLowPageBits(uint32_t Type) const {
|
||||
return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST;
|
||||
}
|
||||
|
||||
template <class ELFT> TargetInfo *elf::createMipsTargetInfo() {
|
||||
return make<MIPS<ELFT>>();
|
||||
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
|
||||
static MIPS<ELFT> Target;
|
||||
return &Target;
|
||||
}
|
||||
|
||||
template TargetInfo *elf::createMipsTargetInfo<ELF32LE>();
|
||||
template TargetInfo *elf::createMipsTargetInfo<ELF32BE>();
|
||||
template TargetInfo *elf::createMipsTargetInfo<ELF64LE>();
|
||||
template TargetInfo *elf::createMipsTargetInfo<ELF64BE>();
|
||||
template TargetInfo *elf::getMipsTargetInfo<ELF32LE>();
|
||||
template TargetInfo *elf::getMipsTargetInfo<ELF32BE>();
|
||||
template TargetInfo *elf::getMipsTargetInfo<ELF64LE>();
|
||||
template TargetInfo *elf::getMipsTargetInfo<ELF64BE>();
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===- Mips.cpp ----------------------------------------------------------===//
|
||||
//===- MipsArchTree.cpp --------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
@ -8,7 +8,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Error.h"
|
||||
#include "Memory.h"
|
||||
#include "Symbols.h"
|
||||
#include "Target.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
@ -22,7 +21,7 @@ using namespace lld::elf;
|
||||
namespace {
|
||||
class PPC final : public TargetInfo {
|
||||
public:
|
||||
PPC() {}
|
||||
PPC() { GotBaseSymOff = 0x8000; }
|
||||
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
|
||||
const uint8_t *Loc) const override;
|
||||
@ -60,4 +59,7 @@ RelExpr PPC::getRelExpr(uint32_t Type, const SymbolBody &S,
|
||||
}
|
||||
}
|
||||
|
||||
TargetInfo *elf::createPPCTargetInfo() { return make<PPC>(); }
|
||||
TargetInfo *elf::getPPCTargetInfo() {
|
||||
static PPC Target;
|
||||
return &Target;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Error.h"
|
||||
#include "Memory.h"
|
||||
#include "Symbols.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Target.h"
|
||||
@ -212,4 +211,7 @@ void PPC64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
|
||||
}
|
||||
}
|
||||
|
||||
TargetInfo *elf::createPPC64TargetInfo() { return make<PPC64>(); }
|
||||
TargetInfo *elf::getPPC64TargetInfo() {
|
||||
static PPC64 Target;
|
||||
return &Target;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "Error.h"
|
||||
#include "InputFiles.h"
|
||||
#include "Memory.h"
|
||||
#include "Symbols.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Target.h"
|
||||
@ -47,6 +46,7 @@ class X86 final : public TargetInfo {
|
||||
} // namespace
|
||||
|
||||
X86::X86() {
|
||||
GotBaseSymOff = -1;
|
||||
CopyRel = R_386_COPY;
|
||||
GotRel = R_386_GLOB_DAT;
|
||||
PltRel = R_386_JUMP_SLOT;
|
||||
@ -60,9 +60,7 @@ X86::X86() {
|
||||
PltEntrySize = 16;
|
||||
PltHeaderSize = 16;
|
||||
TlsGdRelaxSkip = 2;
|
||||
|
||||
// 0xCC is the "int3" (call debug exception handler) instruction.
|
||||
TrapInstr = 0xcccccccc;
|
||||
TrapInstr = 0xcccccccc; // 0xcc = INT3
|
||||
}
|
||||
|
||||
RelExpr X86::getRelExpr(uint32_t Type, const SymbolBody &S,
|
||||
@ -360,4 +358,7 @@ void X86::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
|
||||
memcpy(Loc - 2, Inst, sizeof(Inst));
|
||||
}
|
||||
|
||||
TargetInfo *elf::createX86TargetInfo() { return make<X86>(); }
|
||||
TargetInfo *elf::getX86TargetInfo() {
|
||||
static X86 Target;
|
||||
return &Target;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "Error.h"
|
||||
#include "InputFiles.h"
|
||||
#include "Memory.h"
|
||||
#include "Symbols.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Target.h"
|
||||
@ -52,6 +51,7 @@ template <class ELFT> class X86_64 final : public TargetInfo {
|
||||
} // namespace
|
||||
|
||||
template <class ELFT> X86_64<ELFT>::X86_64() {
|
||||
GotBaseSymOff = -1;
|
||||
CopyRel = R_X86_64_COPY;
|
||||
GotRel = R_X86_64_GLOB_DAT;
|
||||
PltRel = R_X86_64_JUMP_SLOT;
|
||||
@ -65,13 +65,11 @@ template <class ELFT> X86_64<ELFT>::X86_64() {
|
||||
PltEntrySize = 16;
|
||||
PltHeaderSize = 16;
|
||||
TlsGdRelaxSkip = 2;
|
||||
TrapInstr = 0xcccccccc; // 0xcc = INT3
|
||||
|
||||
// Align to the large page size (known as a superpage or huge page).
|
||||
// FreeBSD automatically promotes large, superpage-aligned allocations.
|
||||
DefaultImageBase = 0x200000;
|
||||
|
||||
// 0xCC is the "int3" (call debug exception handler) instruction.
|
||||
TrapInstr = 0xcccccccc;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
@ -464,5 +462,12 @@ void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const {
|
||||
write32le(Loc - 1, Val + 1);
|
||||
}
|
||||
|
||||
TargetInfo *elf::createX32TargetInfo() { return make<X86_64<ELF32LE>>(); }
|
||||
TargetInfo *elf::createX86_64TargetInfo() { return make<X86_64<ELF64LE>>(); }
|
||||
TargetInfo *elf::getX32TargetInfo() {
|
||||
static X86_64<ELF32LE> Target;
|
||||
return &Target;
|
||||
}
|
||||
|
||||
TargetInfo *elf::getX86_64TargetInfo() {
|
||||
static X86_64<ELF64LE> Target;
|
||||
return &Target;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ add_lld_library(lldELF
|
||||
Arch/ARM.cpp
|
||||
Arch/AVR.cpp
|
||||
Arch/Mips.cpp
|
||||
Arch/MipsArchTree.cpp
|
||||
Arch/PPC.cpp
|
||||
Arch/PPC64.cpp
|
||||
Arch/X86.cpp
|
||||
@ -29,7 +30,6 @@ add_lld_library(lldELF
|
||||
LinkerScript.cpp
|
||||
MapFile.cpp
|
||||
MarkLive.cpp
|
||||
Mips.cpp
|
||||
OutputSections.cpp
|
||||
Relocations.cpp
|
||||
ScriptLexer.cpp
|
||||
|
@ -70,7 +70,7 @@ struct VersionDefinition {
|
||||
// Structure for mapping renamed symbols
|
||||
struct RenamedSymbol {
|
||||
Symbol *Target;
|
||||
uint8_t OrigBinding;
|
||||
uint8_t OriginalBinding;
|
||||
};
|
||||
|
||||
// This struct contains the global configuration for the linker.
|
||||
|
@ -200,6 +200,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
|
||||
error("attempted static link of dynamic object " + Path);
|
||||
return;
|
||||
}
|
||||
|
||||
// DSOs usually have DT_SONAME tags in their ELF headers, and the
|
||||
// sonames are used to identify DSOs. But if they are missing,
|
||||
// they are identified by filenames. We don't know whether the new
|
||||
@ -210,8 +211,8 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
|
||||
// If a file was specified by -lfoo, the directory part is not
|
||||
// significant, as a user did not specify it. This behavior is
|
||||
// compatible with GNU.
|
||||
Files.push_back(createSharedFile(
|
||||
MBRef, WithLOption ? sys::path::filename(Path) : Path));
|
||||
Files.push_back(
|
||||
createSharedFile(MBRef, WithLOption ? path::filename(Path) : Path));
|
||||
return;
|
||||
default:
|
||||
if (InLib)
|
||||
@ -301,7 +302,7 @@ static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key,
|
||||
for (auto *Arg : Args.filtered(OPT_z)) {
|
||||
std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');
|
||||
if (KV.first == Key) {
|
||||
uint64_t Result;
|
||||
uint64_t Result = Default;
|
||||
if (!to_integer(KV.second, Result))
|
||||
error("invalid " + Key + ": " + KV.second);
|
||||
return Result;
|
||||
@ -907,12 +908,47 @@ getDefsym(opt::InputArgList &Args) {
|
||||
return Ret;
|
||||
}
|
||||
|
||||
// Parses `--exclude-libs=lib,lib,...`.
|
||||
// The library names may be delimited by commas or colons.
|
||||
static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) {
|
||||
DenseSet<StringRef> Ret;
|
||||
for (auto *Arg : Args.filtered(OPT_exclude_libs)) {
|
||||
StringRef S = Arg->getValue();
|
||||
for (;;) {
|
||||
size_t Pos = S.find_first_of(",:");
|
||||
if (Pos == StringRef::npos)
|
||||
break;
|
||||
Ret.insert(S.substr(0, Pos));
|
||||
S = S.substr(Pos + 1);
|
||||
}
|
||||
Ret.insert(S);
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
// Handles the -exclude-libs option. If a static library file is specified
|
||||
// by the -exclude-libs option, all public symbols from the archive become
|
||||
// private unless otherwise specified by version scripts or something.
|
||||
// A special library name "ALL" means all archive files.
|
||||
//
|
||||
// This is not a popular option, but some programs such as bionic libc use it.
|
||||
static void excludeLibs(opt::InputArgList &Args, ArrayRef<InputFile *> Files) {
|
||||
DenseSet<StringRef> Libs = getExcludeLibs(Args);
|
||||
bool All = Libs.count("ALL");
|
||||
|
||||
for (InputFile *File : Files)
|
||||
if (auto *F = dyn_cast<ArchiveFile>(File))
|
||||
if (All || Libs.count(path::filename(F->getName())))
|
||||
for (Symbol *Sym : F->getSymbols())
|
||||
Sym->VersionId = VER_NDX_LOCAL;
|
||||
}
|
||||
|
||||
// Do actual linking. Note that when this function is called,
|
||||
// all linker scripts have already been parsed.
|
||||
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
||||
SymbolTable<ELFT> Symtab;
|
||||
elf::Symtab<ELFT>::X = &Symtab;
|
||||
Target = createTarget();
|
||||
Target = getTarget();
|
||||
|
||||
Config->MaxPageSize = getMaxPageSize(Args);
|
||||
Config->ImageBase = getImageBase(Args);
|
||||
@ -958,8 +994,17 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
||||
if (ErrorCount)
|
||||
return;
|
||||
|
||||
// Handle the `--undefined <sym>` options.
|
||||
Symtab.scanUndefinedFlags();
|
||||
|
||||
// Handle undefined symbols in DSOs.
|
||||
Symtab.scanShlibUndefined();
|
||||
|
||||
// Handle the -exclude-libs option.
|
||||
if (Args.hasArg(OPT_exclude_libs))
|
||||
excludeLibs(Args, Files);
|
||||
|
||||
// Apply version scripts.
|
||||
Symtab.scanVersionScript();
|
||||
|
||||
// Create wrapped symbols for -wrap option.
|
||||
|
@ -58,7 +58,7 @@ class ELFOptTable : public llvm::opt::OptTable {
|
||||
// Create enum with OPT_xxx values for each option in Options.td
|
||||
enum {
|
||||
OPT_INVALID = 0,
|
||||
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11) OPT_##ID,
|
||||
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
|
||||
#include "Options.inc"
|
||||
#undef OPTION
|
||||
};
|
||||
|
@ -42,9 +42,9 @@ using namespace lld::elf;
|
||||
|
||||
// Create table mapping all options defined in Options.td
|
||||
static const opt::OptTable::Info OptInfo[] = {
|
||||
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
|
||||
{X1, X2, X9, X10, OPT_##ID, opt::Option::KIND##Class, \
|
||||
X8, X7, OPT_##GROUP, OPT_##ALIAS, X6},
|
||||
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
|
||||
{X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
|
||||
X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
|
||||
#include "Options.inc"
|
||||
#undef OPTION
|
||||
};
|
||||
|
@ -632,8 +632,9 @@ ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
|
||||
File(std::move(File)) {}
|
||||
|
||||
template <class ELFT> void ArchiveFile::parse() {
|
||||
Symbols.reserve(File->getNumberOfSymbols());
|
||||
for (const Archive::Symbol &Sym : File->symbols())
|
||||
Symtab<ELFT>::X->addLazyArchive(this, Sym);
|
||||
Symbols.push_back(Symtab<ELFT>::X->addLazyArchive(this, Sym));
|
||||
}
|
||||
|
||||
// Returns a buffer pointing to a member file containing a given symbol.
|
||||
|
@ -251,6 +251,7 @@ class ArchiveFile : public InputFile {
|
||||
explicit ArchiveFile(std::unique_ptr<Archive> &&File);
|
||||
static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
|
||||
template <class ELFT> void parse();
|
||||
ArrayRef<Symbol *> getSymbols() { return Symbols; }
|
||||
|
||||
// Returns a memory buffer for a given symbol and the offset in the archive
|
||||
// for the member. An empty memory buffer and an offset of zero
|
||||
@ -261,6 +262,7 @@ class ArchiveFile : public InputFile {
|
||||
private:
|
||||
std::unique_ptr<Archive> File;
|
||||
llvm::DenseSet<uint64_t> Seen;
|
||||
std::vector<Symbol *> Symbols;
|
||||
};
|
||||
|
||||
class BitcodeFile : public InputFile {
|
||||
|
@ -399,9 +399,16 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
|
||||
}
|
||||
}
|
||||
|
||||
// The ARM and AArch64 ABI handle pc-relative relocations to undefined weak
|
||||
// references specially. The general rule is that the value of the symbol in
|
||||
// this context is the address of the place P. A further special case is that
|
||||
// branch relocations to an undefined weak reference resolve to the next
|
||||
// instruction.
|
||||
static uint32_t getARMUndefinedRelativeWeakVA(uint32_t Type, uint32_t A,
|
||||
uint32_t P) {
|
||||
switch (Type) {
|
||||
// Unresolved branch relocations to weak references resolve to next
|
||||
// instruction, this will be either 2 or 4 bytes on from P.
|
||||
case R_ARM_THM_JUMP11:
|
||||
return P + 2 + A;
|
||||
case R_ARM_CALL:
|
||||
@ -415,22 +422,38 @@ static uint32_t getARMUndefinedRelativeWeakVA(uint32_t Type, uint32_t A,
|
||||
case R_ARM_THM_CALL:
|
||||
// We don't want an interworking BLX to ARM
|
||||
return P + 5 + A;
|
||||
default:
|
||||
// Unresolved non branch pc-relative relocations
|
||||
// R_ARM_TARGET2 which can be resolved relatively is not present as it never
|
||||
// targets a weak-reference.
|
||||
case R_ARM_MOVW_PREL_NC:
|
||||
case R_ARM_MOVT_PREL:
|
||||
case R_ARM_REL32:
|
||||
case R_ARM_THM_MOVW_PREL_NC:
|
||||
case R_ARM_THM_MOVT_PREL:
|
||||
return P + A;
|
||||
}
|
||||
llvm_unreachable("ARM pc-relative relocation expected\n");
|
||||
}
|
||||
|
||||
// The comment above getARMUndefinedRelativeWeakVA applies to this function.
|
||||
static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A,
|
||||
uint64_t P) {
|
||||
switch (Type) {
|
||||
// Unresolved branch relocations to weak references resolve to next
|
||||
// instruction, this is 4 bytes on from P.
|
||||
case R_AARCH64_CALL26:
|
||||
case R_AARCH64_CONDBR19:
|
||||
case R_AARCH64_JUMP26:
|
||||
case R_AARCH64_TSTBR14:
|
||||
return P + 4 + A;
|
||||
default:
|
||||
// Unresolved non branch pc-relative relocations
|
||||
case R_AARCH64_PREL16:
|
||||
case R_AARCH64_PREL32:
|
||||
case R_AARCH64_PREL64:
|
||||
case R_AARCH64_ADR_PREL_LO21:
|
||||
return P + A;
|
||||
}
|
||||
llvm_unreachable("AArch64 pc-relative relocation expected\n");
|
||||
}
|
||||
|
||||
// ARM SBREL relocations are of the form S + A - B where B is the static base
|
||||
|
@ -338,8 +338,9 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
|
||||
void LinkerScript::discard(ArrayRef<InputSectionBase *> V) {
|
||||
for (InputSectionBase *S : V) {
|
||||
S->Live = false;
|
||||
if (S == InX::ShStrTab)
|
||||
error("discarding .shstrtab section is not allowed");
|
||||
if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab ||
|
||||
S == InX::DynStrTab)
|
||||
error("discarding " + S->Name + " section is not allowed");
|
||||
discard(S->DependentSections);
|
||||
}
|
||||
}
|
||||
@ -463,11 +464,6 @@ void LinkerScript::fabricateDefaultCommands() {
|
||||
OSCmd->Sec = Sec;
|
||||
SecToCommand[Sec] = OSCmd;
|
||||
|
||||
// Prefer user supplied address over additional alignment constraint
|
||||
auto I = Config->SectionStartMap.find(Sec->Name);
|
||||
if (I != Config->SectionStartMap.end())
|
||||
OSCmd->AddrExpr = [=] { return I->second; };
|
||||
|
||||
Commands.push_back(OSCmd);
|
||||
if (Sec->Sections.size()) {
|
||||
auto *ISD = make<InputSectionDescription>("");
|
||||
@ -953,6 +949,8 @@ static bool compareByFilePosition(InputSection *A, InputSection *B) {
|
||||
template <class ELFT>
|
||||
static void finalizeShtGroup(OutputSection *OS,
|
||||
ArrayRef<InputSection *> Sections) {
|
||||
assert(Config->Relocatable && Sections.size() == 1);
|
||||
|
||||
// sh_link field for SHT_GROUP sections should contain the section index of
|
||||
// the symbol table.
|
||||
OS->Link = InX::SymTab->getParent()->SectionIndex;
|
||||
@ -960,7 +958,6 @@ static void finalizeShtGroup(OutputSection *OS,
|
||||
// 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]);
|
||||
}
|
||||
@ -1044,8 +1041,9 @@ template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
|
||||
|
||||
Sec->Loc = Buf;
|
||||
|
||||
// We may have already rendered compressed content when using
|
||||
// -compress-debug-sections option. Write it together with header.
|
||||
// If -compress-debug-section is specified and if this is a debug seciton,
|
||||
// we've already compressed section contents. If that's the case,
|
||||
// just write it down.
|
||||
if (!Sec->CompressedData.empty()) {
|
||||
memcpy(Buf, Sec->ZDebugHeader.data(), Sec->ZDebugHeader.size());
|
||||
memcpy(Buf + Sec->ZDebugHeader.size(), Sec->CompressedData.data(),
|
||||
@ -1109,18 +1107,27 @@ ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
|
||||
|
||||
bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
|
||||
|
||||
static const size_t NoPhdr = -1;
|
||||
|
||||
// Returns indices of ELF headers containing specific section. Each index is a
|
||||
// zero based number of ELF header listed within PHDRS {} script block.
|
||||
std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) {
|
||||
if (OutputSectionCommand *Cmd = getCmd(Sec)) {
|
||||
std::vector<size_t> Ret;
|
||||
for (StringRef PhdrName : Cmd->Phdrs)
|
||||
Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
|
||||
for (StringRef PhdrName : Cmd->Phdrs) {
|
||||
size_t Index = getPhdrIndex(Cmd->Location, PhdrName);
|
||||
if (Index != NoPhdr)
|
||||
Ret.push_back(Index);
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
// Returns the index of the segment named PhdrName if found otherwise
|
||||
// NoPhdr. When not found, if PhdrName is not the special case value 'NONE'
|
||||
// (which can be used to explicitly specify that a section isn't assigned to a
|
||||
// segment) then error.
|
||||
size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
|
||||
size_t I = 0;
|
||||
for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
|
||||
@ -1128,8 +1135,9 @@ size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
|
||||
return I;
|
||||
++I;
|
||||
}
|
||||
error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
|
||||
return 0;
|
||||
if (PhdrName != "NONE")
|
||||
error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
|
||||
return NoPhdr;
|
||||
}
|
||||
|
||||
template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);
|
||||
|
@ -78,7 +78,7 @@ static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
|
||||
typename ELFT::uint Offset = D->Value;
|
||||
if (D->isSection())
|
||||
Offset += getAddend<ELFT>(Sec, Rel);
|
||||
Fn({cast<InputSectionBase>(D->Section)->Repl, Offset});
|
||||
Fn({cast<InputSectionBase>(D->Section), Offset});
|
||||
} else if (auto *U = dyn_cast<Undefined>(&B)) {
|
||||
for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
|
||||
Fn({Sec, 0});
|
||||
|
@ -92,6 +92,9 @@ def error_limit: S<"error-limit">,
|
||||
def error_unresolved_symbols: F<"error-unresolved-symbols">,
|
||||
HelpText<"Report unresolved symbols as errors">;
|
||||
|
||||
def exclude_libs: S<"exclude-libs">,
|
||||
HelpText<"Exclude static libraries from automatic export">;
|
||||
|
||||
def export_dynamic: F<"export-dynamic">,
|
||||
HelpText<"Put symbols in the dynamic symbol table">;
|
||||
|
||||
@ -298,6 +301,7 @@ def alias_emit_relocs: Flag<["-"], "q">, Alias<emit_relocs>;
|
||||
def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
|
||||
def alias_entry_entry: J<"entry=">, Alias<entry>;
|
||||
def alias_error_limit: J<"error-limit=">, Alias<error_limit>;
|
||||
def alias_exclude_libs: J<"exclude-libs=">, Alias<exclude_libs>;
|
||||
def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>;
|
||||
def alias_export_dynamic_symbol: J<"export-dynamic-symbol=">,
|
||||
Alias<export_dynamic_symbol>;
|
||||
|
@ -273,7 +273,7 @@ void elf::reportDiscarded(InputSectionBase *IS) {
|
||||
if (!Config->PrintGcSections)
|
||||
return;
|
||||
message("removing unused section from '" + IS->Name + "' in file '" +
|
||||
IS->File->getName());
|
||||
IS->File->getName() + "'");
|
||||
}
|
||||
|
||||
void OutputSectionFactory::addInputSec(InputSectionBase *IS,
|
||||
@ -305,7 +305,7 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS,
|
||||
|
||||
SectionKey Key = createKey(IS, OutsecName);
|
||||
OutputSection *&Sec = Map[Key];
|
||||
return addInputSec(IS, OutsecName, Sec);
|
||||
addInputSec(IS, OutsecName, Sec);
|
||||
}
|
||||
|
||||
void OutputSectionFactory::addInputSec(InputSectionBase *IS,
|
||||
|
@ -361,7 +361,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type,
|
||||
// These expressions always compute a constant
|
||||
if (isRelExprOneOf<R_SIZE, R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
|
||||
R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,
|
||||
R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC,
|
||||
R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
|
||||
R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_PC, R_TLSGD,
|
||||
R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E))
|
||||
return true;
|
||||
|
@ -167,8 +167,8 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolWrap(StringRef Name) {
|
||||
// Tell LTO not to eliminate this symbol
|
||||
Wrap->IsUsedInRegularObj = true;
|
||||
|
||||
Config->RenamedSymbols[Real] = RenamedSymbol{Sym, Real->Binding};
|
||||
Config->RenamedSymbols[Sym] = RenamedSymbol{Wrap, Sym->Binding};
|
||||
Config->RenamedSymbols[Real] = {Sym, Real->Binding};
|
||||
Config->RenamedSymbols[Sym] = {Wrap, Sym->Binding};
|
||||
}
|
||||
|
||||
// Creates alias for symbol. Used to implement --defsym=ALIAS=SYM.
|
||||
@ -184,7 +184,7 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias,
|
||||
|
||||
// Tell LTO not to eliminate this symbol
|
||||
Sym->IsUsedInRegularObj = true;
|
||||
Config->RenamedSymbols[AliasSym] = RenamedSymbol{Sym, AliasSym->Binding};
|
||||
Config->RenamedSymbols[AliasSym] = {Sym, AliasSym->Binding};
|
||||
}
|
||||
|
||||
// Apply symbol renames created by -wrap and -defsym. The renames are created
|
||||
@ -193,14 +193,16 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias,
|
||||
// symbols are finalized, we can perform the replacement.
|
||||
template <class ELFT> void SymbolTable<ELFT>::applySymbolRenames() {
|
||||
for (auto &KV : Config->RenamedSymbols) {
|
||||
Symbol *Sym = KV.first;
|
||||
Symbol *Rename = KV.second.Target;
|
||||
Sym->Binding = KV.second.OrigBinding;
|
||||
Symbol *Dst = KV.first;
|
||||
Symbol *Src = KV.second.Target;
|
||||
Dst->Binding = KV.second.OriginalBinding;
|
||||
|
||||
// We rename symbols by replacing the old symbol's SymbolBody with the new
|
||||
// symbol's SymbolBody. This causes all SymbolBody pointers referring to the
|
||||
// old symbol to instead refer to the new symbol.
|
||||
memcpy(Sym->Body.buffer, Rename->Body.buffer, sizeof(Sym->Body));
|
||||
// We rename symbols by replacing the old symbol's SymbolBody with
|
||||
// the new symbol's SymbolBody. The only attribute we want to keep
|
||||
// is the symbol name, so that two symbols don't have the same name.
|
||||
StringRef S = Dst->body()->getName();
|
||||
memcpy(Dst->Body.buffer, Src->Body.buffer, sizeof(Symbol::Body));
|
||||
Dst->body()->setName(S);
|
||||
}
|
||||
}
|
||||
|
||||
@ -518,18 +520,18 @@ SymbolBody *SymbolTable<ELFT>::findInCurrentDSO(StringRef Name) {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
|
||||
const object::Archive::Symbol Sym) {
|
||||
Symbol *SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
|
||||
const object::Archive::Symbol Sym) {
|
||||
Symbol *S;
|
||||
bool WasInserted;
|
||||
StringRef Name = Sym.getName();
|
||||
std::tie(S, WasInserted) = insert(Name);
|
||||
if (WasInserted) {
|
||||
replaceBody<LazyArchive>(S, *F, Sym, SymbolBody::UnknownType);
|
||||
return;
|
||||
return S;
|
||||
}
|
||||
if (!S->body()->isUndefined())
|
||||
return;
|
||||
return S;
|
||||
|
||||
// Weak undefined symbols should not fetch members from archives. If we were
|
||||
// to keep old symbol we would not know that an archive member was available
|
||||
@ -540,11 +542,12 @@ void SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
|
||||
// to preserve its type. FIXME: Move the Type field to Symbol.
|
||||
if (S->isWeak()) {
|
||||
replaceBody<LazyArchive>(S, *F, Sym, S->body()->Type);
|
||||
return;
|
||||
return S;
|
||||
}
|
||||
std::pair<MemoryBufferRef, uint64_t> MBInfo = F->getMember(&Sym);
|
||||
if (!MBInfo.first.getBuffer().empty())
|
||||
addFile(createObjectFile(MBInfo.first, F->getName(), MBInfo.second));
|
||||
return S;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -66,7 +66,7 @@ template <class ELFT> class SymbolTable {
|
||||
void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
|
||||
const typename ELFT::Verdef *Verdef);
|
||||
|
||||
void addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S);
|
||||
Symbol *addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S);
|
||||
void addLazyObject(StringRef Name, LazyObjectFile &Obj);
|
||||
Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
|
||||
uint8_t Type, bool CanOmitFromDynSym, BitcodeFile *File);
|
||||
|
@ -35,6 +35,7 @@ DefinedRegular *ElfSym::Edata1;
|
||||
DefinedRegular *ElfSym::Edata2;
|
||||
DefinedRegular *ElfSym::End1;
|
||||
DefinedRegular *ElfSym::End2;
|
||||
DefinedRegular *ElfSym::GlobalOffsetTable;
|
||||
DefinedRegular *ElfSym::MipsGp;
|
||||
DefinedRegular *ElfSym::MipsGpDisp;
|
||||
DefinedRegular *ElfSym::MipsLocalGp;
|
||||
|
@ -69,6 +69,7 @@ class SymbolBody {
|
||||
bool isLocal() const { return IsLocal; }
|
||||
bool isPreemptible() const;
|
||||
StringRef getName() const { return Name; }
|
||||
void setName(StringRef S) { Name = S; }
|
||||
uint8_t getVisibility() const { return StOther & 0x3; }
|
||||
void parseSymbolVersion();
|
||||
|
||||
@ -317,6 +318,11 @@ struct ElfSym {
|
||||
static DefinedRegular *End1;
|
||||
static DefinedRegular *End2;
|
||||
|
||||
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
|
||||
// be at some offset from the base of the .got section, usually 0 or
|
||||
// the end of the .got.
|
||||
static DefinedRegular *GlobalOffsetTable;
|
||||
|
||||
// _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
|
||||
static DefinedRegular *MipsGp;
|
||||
static DefinedRegular *MipsGpDisp;
|
||||
|
@ -47,40 +47,40 @@ std::string lld::toString(uint32_t Type) {
|
||||
return S;
|
||||
}
|
||||
|
||||
TargetInfo *elf::createTarget() {
|
||||
TargetInfo *elf::getTarget() {
|
||||
switch (Config->EMachine) {
|
||||
case EM_386:
|
||||
case EM_IAMCU:
|
||||
return createX86TargetInfo();
|
||||
return getX86TargetInfo();
|
||||
case EM_AARCH64:
|
||||
return createAArch64TargetInfo();
|
||||
return getAArch64TargetInfo();
|
||||
case EM_AMDGPU:
|
||||
return createAMDGPUTargetInfo();
|
||||
return getAMDGPUTargetInfo();
|
||||
case EM_ARM:
|
||||
return createARMTargetInfo();
|
||||
return getARMTargetInfo();
|
||||
case EM_AVR:
|
||||
return createAVRTargetInfo();
|
||||
return getAVRTargetInfo();
|
||||
case EM_MIPS:
|
||||
switch (Config->EKind) {
|
||||
case ELF32LEKind:
|
||||
return createMipsTargetInfo<ELF32LE>();
|
||||
return getMipsTargetInfo<ELF32LE>();
|
||||
case ELF32BEKind:
|
||||
return createMipsTargetInfo<ELF32BE>();
|
||||
return getMipsTargetInfo<ELF32BE>();
|
||||
case ELF64LEKind:
|
||||
return createMipsTargetInfo<ELF64LE>();
|
||||
return getMipsTargetInfo<ELF64LE>();
|
||||
case ELF64BEKind:
|
||||
return createMipsTargetInfo<ELF64BE>();
|
||||
return getMipsTargetInfo<ELF64BE>();
|
||||
default:
|
||||
fatal("unsupported MIPS target");
|
||||
}
|
||||
case EM_PPC:
|
||||
return createPPCTargetInfo();
|
||||
return getPPCTargetInfo();
|
||||
case EM_PPC64:
|
||||
return createPPC64TargetInfo();
|
||||
return getPPC64TargetInfo();
|
||||
case EM_X86_64:
|
||||
if (Config->EKind == ELF32LEKind)
|
||||
return createX32TargetInfo();
|
||||
return createX86_64TargetInfo();
|
||||
return getX32TargetInfo();
|
||||
return getX86_64TargetInfo();
|
||||
}
|
||||
fatal("unknown target machine");
|
||||
}
|
||||
|
26
ELF/Target.h
26
ELF/Target.h
@ -66,6 +66,10 @@ class TargetInfo {
|
||||
// Given that, the smallest value that can be used in here is 0x10000.
|
||||
uint64_t DefaultImageBase = 0x10000;
|
||||
|
||||
// Offset of _GLOBAL_OFFSET_TABLE_ from base of .got section. Use -1 for
|
||||
// end of .got
|
||||
uint64_t GotBaseSymOff = 0;
|
||||
|
||||
uint32_t CopyRel;
|
||||
uint32_t GotRel;
|
||||
uint32_t PltRel;
|
||||
@ -102,16 +106,16 @@ class TargetInfo {
|
||||
virtual void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
|
||||
};
|
||||
|
||||
TargetInfo *createAArch64TargetInfo();
|
||||
TargetInfo *createAMDGPUTargetInfo();
|
||||
TargetInfo *createARMTargetInfo();
|
||||
TargetInfo *createAVRTargetInfo();
|
||||
TargetInfo *createPPC64TargetInfo();
|
||||
TargetInfo *createPPCTargetInfo();
|
||||
TargetInfo *createX32TargetInfo();
|
||||
TargetInfo *createX86TargetInfo();
|
||||
TargetInfo *createX86_64TargetInfo();
|
||||
template <class ELFT> TargetInfo *createMipsTargetInfo();
|
||||
TargetInfo *getAArch64TargetInfo();
|
||||
TargetInfo *getAMDGPUTargetInfo();
|
||||
TargetInfo *getARMTargetInfo();
|
||||
TargetInfo *getAVRTargetInfo();
|
||||
TargetInfo *getPPC64TargetInfo();
|
||||
TargetInfo *getPPCTargetInfo();
|
||||
TargetInfo *getX32TargetInfo();
|
||||
TargetInfo *getX86TargetInfo();
|
||||
TargetInfo *getX86_64TargetInfo();
|
||||
template <class ELFT> TargetInfo *getMipsTargetInfo();
|
||||
|
||||
std::string getErrorLocation(const uint8_t *Loc);
|
||||
|
||||
@ -119,7 +123,7 @@ uint64_t getPPC64TocBase();
|
||||
uint64_t getAArch64Page(uint64_t Expr);
|
||||
|
||||
extern TargetInfo *Target;
|
||||
TargetInfo *createTarget();
|
||||
TargetInfo *getTarget();
|
||||
|
||||
template <unsigned N>
|
||||
static void checkInt(uint8_t *Loc, int64_t V, uint32_t Type) {
|
||||
|
@ -87,6 +87,8 @@ template <class ELFT> class Writer {
|
||||
|
||||
uint64_t FileSize;
|
||||
uint64_t SectionHeaderOff;
|
||||
|
||||
bool HasGotBaseSym = false;
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
@ -815,19 +817,13 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
|
||||
Symtab<ELFT>::X->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL);
|
||||
}
|
||||
|
||||
// In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
|
||||
// is magical and is used to produce a R_386_GOTPC relocation.
|
||||
// The R_386_GOTPC relocation value doesn't actually depend on the
|
||||
// symbol value, so it could use an index of STN_UNDEF which, according
|
||||
// to the spec, means the symbol value is 0.
|
||||
// Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in
|
||||
// the object file.
|
||||
// The situation is even stranger on x86_64 where the assembly doesn't
|
||||
// need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
|
||||
// an undefined symbol in the .o files.
|
||||
// Given that the symbol is effectively unused, we just create a dummy
|
||||
// hidden one to avoid the undefined symbol error.
|
||||
Symtab<ELFT>::X->addIgnored("_GLOBAL_OFFSET_TABLE_");
|
||||
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
|
||||
// be at some offset from the base of the .got section, usually 0 or the end
|
||||
// of the .got
|
||||
InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
|
||||
: cast<InputSection>(InX::Got);
|
||||
ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>(
|
||||
"_GLOBAL_OFFSET_TABLE_", GotSection, Target->GotBaseSymOff);
|
||||
|
||||
// __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
|
||||
// static linking the linker is required to optimize away any references to
|
||||
@ -1147,6 +1143,8 @@ static void removeUnusedSyntheticSections(std::vector<OutputSection *> &V) {
|
||||
OutputSection *OS = SS->getParent();
|
||||
if (!SS->empty() || !OS)
|
||||
continue;
|
||||
if ((SS == InX::Got || SS == InX::MipsGot) && ElfSym::GlobalOffsetTable)
|
||||
continue;
|
||||
OS->Sections.erase(std::find(OS->Sections.begin(), OS->Sections.end(), SS));
|
||||
SS->Live = false;
|
||||
// If there are no other sections in the output section, remove it from the
|
||||
@ -1231,6 +1229,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
|
||||
OutputSectionCommands.push_back(Cmd);
|
||||
|
||||
// Prefer command line supplied address over other constraints.
|
||||
for (OutputSectionCommand *Cmd : OutputSectionCommands) {
|
||||
auto I = Config->SectionStartMap.find(Cmd->Name);
|
||||
if (I != Config->SectionStartMap.end())
|
||||
Cmd->AddrExpr = [=] { return I->second; };
|
||||
}
|
||||
|
||||
// This is a bit of a hack. A value of 0 means undef, so we set it
|
||||
// to 1 t make __ehdr_start defined. The section number is not
|
||||
// particularly relevant.
|
||||
|
@ -8,3 +8,4 @@ infrastructure project.
|
||||
|
||||
lld is open source software. You may freely distribute it under the terms of
|
||||
the license agreement found in LICENSE.txt.
|
||||
|
||||
|
@ -49,7 +49,7 @@ Creating DLL
|
||||
|
||||
Windows resource files support
|
||||
:good:`Done`. If an ``.res`` file is given, LLD converts the file to a COFF
|
||||
file using ``cvtres.exe`` command and link it.
|
||||
file using LLVM's Object library.
|
||||
|
||||
Safe Structured Exception Handler (SEH)
|
||||
:good:`Done` for both x86 and x64.
|
||||
|
@ -61,9 +61,9 @@ namespace {
|
||||
// Create enum with OPT_xxx values for each option in DarwinLdOptions.td
|
||||
enum {
|
||||
OPT_INVALID = 0,
|
||||
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
|
||||
HELP, META) \
|
||||
OPT_##ID,
|
||||
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
|
||||
HELP, META, VALUES) \
|
||||
OPT_##ID,
|
||||
#include "DarwinLdOptions.inc"
|
||||
#undef OPTION
|
||||
};
|
||||
@ -75,10 +75,12 @@ enum {
|
||||
|
||||
// Create table mapping all options defined in DarwinLdOptions.td
|
||||
static const llvm::opt::OptTable::Info infoTable[] = {
|
||||
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
|
||||
HELPTEXT, METAVAR) \
|
||||
{ PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
|
||||
PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
|
||||
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
|
||||
HELPTEXT, METAVAR, VALUES) \
|
||||
{PREFIX, NAME, HELPTEXT, \
|
||||
METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
|
||||
PARAM, FLAGS, OPT_##GROUP, \
|
||||
OPT_##ALIAS, ALIASARGS, VALUES},
|
||||
#include "DarwinLdOptions.inc"
|
||||
#undef OPTION
|
||||
};
|
||||
|
@ -906,6 +906,7 @@ readCompUnit(const NormalizedFile &normalizedFile,
|
||||
abbrevData.getU8(&abbrevOffset);
|
||||
uint32_t name;
|
||||
llvm::dwarf::Form form;
|
||||
llvm::DWARFFormParams formParams = {version, addrSize, Format};
|
||||
TranslationUnitSource tu;
|
||||
while ((name = abbrevData.getULEB128(&abbrevOffset)) |
|
||||
(form = static_cast<llvm::dwarf::Form>(
|
||||
@ -929,8 +930,7 @@ readCompUnit(const NormalizedFile &normalizedFile,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm::DWARFFormValue::skipValue(form, infoData, &offset, version,
|
||||
addrSize, Format);
|
||||
llvm::DWARFFormValue::skipValue(form, infoData, &offset, formParams);
|
||||
}
|
||||
}
|
||||
return tu;
|
||||
|
13
test/COFF/Inputs/associative-comdat-2.s
Normal file
13
test/COFF/Inputs/associative-comdat-2.s
Normal file
@ -0,0 +1,13 @@
|
||||
# Defines foo and foo_assoc globals. foo is comdat, and foo_assoc is comdat
|
||||
# associative with it. foo_assoc should be discarded iff foo is discarded,
|
||||
# either by linker GC or normal comdat merging.
|
||||
|
||||
.section .rdata,"dr",associative,foo
|
||||
.p2align 3
|
||||
.quad foo
|
||||
|
||||
.section .data,"dw",discard,foo
|
||||
.globl foo # @foo
|
||||
.p2align 2
|
||||
foo:
|
||||
.long 42
|
@ -34,14 +34,10 @@ sections:
|
||||
Records:
|
||||
- Kind: S_GPROC32_ID
|
||||
ProcSym:
|
||||
PtrParent: 0
|
||||
PtrEnd: 0
|
||||
PtrNext: 0
|
||||
CodeSize: 14
|
||||
DbgStart: 4
|
||||
DbgEnd: 9
|
||||
FunctionType: 4101
|
||||
Segment: 0
|
||||
Flags: [ ]
|
||||
DisplayName: main
|
||||
- Kind: S_FRAMEPROC
|
||||
|
440
test/COFF/Inputs/pdb_comdat_bar.yaml
Normal file
440
test/COFF/Inputs/pdb_comdat_bar.yaml
Normal file
@ -0,0 +1,440 @@
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: .drectve
|
||||
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
|
||||
Alignment: 1
|
||||
SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_OBJNAME
|
||||
ObjNameSym:
|
||||
Signature: 0
|
||||
ObjectName: 'C:\src\llvm-project\build\pdb_comdat_bar.obj'
|
||||
- Kind: S_COMPILE3
|
||||
Compile3Sym:
|
||||
Flags: [ SecurityChecks, HotPatch ]
|
||||
Machine: X64
|
||||
FrontendMajor: 19
|
||||
FrontendMinor: 0
|
||||
FrontendBuild: 24215
|
||||
FrontendQFE: 1
|
||||
BackendMajor: 19
|
||||
BackendMinor: 0
|
||||
BackendBuild: 24215
|
||||
BackendQFE: 1
|
||||
Version: 'Microsoft (R) Optimizing Compiler'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GPROC32_ID
|
||||
ProcSym:
|
||||
PtrParent: 0
|
||||
PtrEnd: 0
|
||||
PtrNext: 0
|
||||
CodeSize: 14
|
||||
DbgStart: 4
|
||||
DbgEnd: 9
|
||||
FunctionType: 4102
|
||||
Segment: 0
|
||||
Flags: [ ]
|
||||
DisplayName: bar
|
||||
- Kind: S_FRAMEPROC
|
||||
FrameProcSym:
|
||||
TotalFrameBytes: 40
|
||||
PaddingFrameBytes: 0
|
||||
OffsetToPadding: 0
|
||||
BytesOfCalleeSavedRegisters: 0
|
||||
OffsetOfExceptionHandler: 0
|
||||
SectionIdOfExceptionHandler: 0
|
||||
Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
|
||||
- Kind: S_PROC_ID_END
|
||||
ScopeEndSym:
|
||||
- !Lines
|
||||
CodeSize: 14
|
||||
Flags: [ ]
|
||||
RelocOffset: 0
|
||||
RelocSegment: 0
|
||||
Blocks:
|
||||
- FileName: 'c:\src\llvm-project\build\pdb_comdat_bar.c'
|
||||
Lines:
|
||||
- Offset: 0
|
||||
LineStart: 3
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 4
|
||||
LineStart: 4
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 9
|
||||
LineStart: 5
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
Columns:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GDATA32
|
||||
DataSym:
|
||||
Type: 116
|
||||
DisplayName: global
|
||||
- !FileChecksums
|
||||
Checksums:
|
||||
- FileName: 'c:\src\llvm-project\build\pdb_comdat_bar.c'
|
||||
Kind: MD5
|
||||
Checksum: 365279DB4FCBEDD721BBFC3B14A953C2
|
||||
- FileName: 'c:\src\llvm-project\build\foo.h'
|
||||
Kind: MD5
|
||||
Checksum: D74D834EFAC3AE2B45E606A8320B1D5C
|
||||
- !StringTable
|
||||
Strings:
|
||||
- 'c:\src\llvm-project\build\pdb_comdat_bar.c'
|
||||
- 'c:\src\llvm-project\build\foo.h'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_BUILDINFO
|
||||
BuildInfoSym:
|
||||
BuildId: 4110
|
||||
Relocations:
|
||||
- VirtualAddress: 168
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 172
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 224
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 228
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 288
|
||||
SymbolName: global
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 292
|
||||
SymbolName: global
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- Name: '.debug$T'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Types:
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ 0 ]
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 3
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 0
|
||||
ArgumentList: 4096
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 4097
|
||||
Attrs: 65548
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4097
|
||||
Name: foo
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ ]
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 3
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 0
|
||||
ArgumentList: 4100
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4101
|
||||
Name: bar
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
|
||||
- Kind: LF_SUBSTR_LIST
|
||||
StringList:
|
||||
StringIndices: [ 4105 ]
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 4106
|
||||
String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: pdb_comdat_bar.c
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build\vc140.pdb'
|
||||
- Kind: LF_BUILDINFO
|
||||
BuildInfo:
|
||||
ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ]
|
||||
- Name: .bss
|
||||
Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
|
||||
Alignment: 4
|
||||
SectionData: ''
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: 4883EC28E8000000004883C428C3
|
||||
Relocations:
|
||||
- VirtualAddress: 5
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: 8B0500000000FFC0890500000000C3
|
||||
Relocations:
|
||||
- VirtualAddress: 2
|
||||
SymbolName: global
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- VirtualAddress: 10
|
||||
SymbolName: global
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GPROC32_ID
|
||||
ProcSym:
|
||||
PtrParent: 0
|
||||
PtrEnd: 0
|
||||
PtrNext: 0
|
||||
CodeSize: 15
|
||||
DbgStart: 0
|
||||
DbgEnd: 14
|
||||
FunctionType: 4099
|
||||
Segment: 0
|
||||
Flags: [ ]
|
||||
DisplayName: foo
|
||||
- Kind: S_FRAMEPROC
|
||||
FrameProcSym:
|
||||
TotalFrameBytes: 0
|
||||
PaddingFrameBytes: 0
|
||||
OffsetToPadding: 0
|
||||
BytesOfCalleeSavedRegisters: 0
|
||||
OffsetOfExceptionHandler: 0
|
||||
SectionIdOfExceptionHandler: 0
|
||||
Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
|
||||
- Kind: S_PROC_ID_END
|
||||
ScopeEndSym:
|
||||
- !Lines
|
||||
CodeSize: 15
|
||||
Flags: [ ]
|
||||
RelocOffset: 0
|
||||
RelocSegment: 0
|
||||
Blocks:
|
||||
- FileName: 'c:\src\llvm-project\build\foo.h'
|
||||
Lines:
|
||||
- Offset: 0
|
||||
LineStart: 2
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 0
|
||||
LineStart: 3
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 14
|
||||
LineStart: 4
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
Columns:
|
||||
Relocations:
|
||||
- VirtualAddress: 44
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 48
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 100
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 104
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- Name: .xdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: '0104010004420000'
|
||||
- Name: .pdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: '000000000E00000000000000'
|
||||
Relocations:
|
||||
- VirtualAddress: 0
|
||||
SymbolName: '$LN3'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- VirtualAddress: 4
|
||||
SymbolName: '$LN3'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- VirtualAddress: 8
|
||||
SymbolName: '$unwind$bar'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
symbols:
|
||||
- Name: .drectve
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 47
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 460
|
||||
NumberOfRelocations: 6
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$T'
|
||||
Value: 0
|
||||
SectionNumber: 3
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 628
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: .bss
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 4
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: global
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 14
|
||||
NumberOfRelocations: 1
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 1682752513
|
||||
Number: 0
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 6
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 15
|
||||
NumberOfRelocations: 2
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 1746394828
|
||||
Number: 0
|
||||
Selection: IMAGE_COMDAT_SELECT_ANY
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 7
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 148
|
||||
NumberOfRelocations: 4
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 6
|
||||
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
|
||||
- Name: foo
|
||||
Value: 0
|
||||
SectionNumber: 6
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: bar
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: '$LN3'
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_LABEL
|
||||
- Name: .xdata
|
||||
Value: 0
|
||||
SectionNumber: 8
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 8
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 264583633
|
||||
Number: 0
|
||||
- Name: '$unwind$bar'
|
||||
Value: 0
|
||||
SectionNumber: 8
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
- Name: .pdata
|
||||
Value: 0
|
||||
SectionNumber: 9
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 12
|
||||
NumberOfRelocations: 3
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 361370162
|
||||
Number: 0
|
||||
- Name: '$pdata$bar'
|
||||
Value: 0
|
||||
SectionNumber: 9
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
...
|
446
test/COFF/Inputs/pdb_comdat_main.yaml
Normal file
446
test/COFF/Inputs/pdb_comdat_main.yaml
Normal file
@ -0,0 +1,446 @@
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: .drectve
|
||||
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
|
||||
Alignment: 1
|
||||
SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_OBJNAME
|
||||
ObjNameSym:
|
||||
Signature: 0
|
||||
ObjectName: 'C:\src\llvm-project\build\pdb_comdat_main.obj'
|
||||
- Kind: S_COMPILE3
|
||||
Compile3Sym:
|
||||
Flags: [ SecurityChecks, HotPatch ]
|
||||
Machine: X64
|
||||
FrontendMajor: 19
|
||||
FrontendMinor: 0
|
||||
FrontendBuild: 24215
|
||||
FrontendQFE: 1
|
||||
BackendMajor: 19
|
||||
BackendMinor: 0
|
||||
BackendBuild: 24215
|
||||
BackendQFE: 1
|
||||
Version: 'Microsoft (R) Optimizing Compiler'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GPROC32_ID
|
||||
ProcSym:
|
||||
PtrParent: 0
|
||||
PtrEnd: 0
|
||||
PtrNext: 0
|
||||
CodeSize: 24
|
||||
DbgStart: 4
|
||||
DbgEnd: 19
|
||||
FunctionType: 4102
|
||||
Segment: 0
|
||||
Flags: [ ]
|
||||
DisplayName: main
|
||||
- Kind: S_FRAMEPROC
|
||||
FrameProcSym:
|
||||
TotalFrameBytes: 40
|
||||
PaddingFrameBytes: 0
|
||||
OffsetToPadding: 0
|
||||
BytesOfCalleeSavedRegisters: 0
|
||||
OffsetOfExceptionHandler: 0
|
||||
SectionIdOfExceptionHandler: 0
|
||||
Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
|
||||
- Kind: S_PROC_ID_END
|
||||
ScopeEndSym:
|
||||
- !Lines
|
||||
CodeSize: 24
|
||||
Flags: [ ]
|
||||
RelocOffset: 0
|
||||
RelocSegment: 0
|
||||
Blocks:
|
||||
- FileName: 'c:\src\llvm-project\build\pdb_comdat_main.c'
|
||||
Lines:
|
||||
- Offset: 0
|
||||
LineStart: 2
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 4
|
||||
LineStart: 3
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 9
|
||||
LineStart: 4
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 14
|
||||
LineStart: 5
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 19
|
||||
LineStart: 6
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
Columns:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GDATA32
|
||||
DataSym:
|
||||
Type: 116
|
||||
DisplayName: global
|
||||
- !FileChecksums
|
||||
Checksums:
|
||||
- FileName: 'c:\src\llvm-project\build\pdb_comdat_main.c'
|
||||
Kind: MD5
|
||||
Checksum: F969E51BBE373436D81492EB61387F36
|
||||
- FileName: 'c:\src\llvm-project\build\foo.h'
|
||||
Kind: MD5
|
||||
Checksum: D74D834EFAC3AE2B45E606A8320B1D5C
|
||||
- !StringTable
|
||||
Strings:
|
||||
- 'c:\src\llvm-project\build\pdb_comdat_main.c'
|
||||
- 'c:\src\llvm-project\build\foo.h'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_BUILDINFO
|
||||
BuildInfoSym:
|
||||
BuildId: 4111
|
||||
Relocations:
|
||||
- VirtualAddress: 168
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 172
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 224
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 228
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 304
|
||||
SymbolName: global
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 308
|
||||
SymbolName: global
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- Name: '.debug$T'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Types:
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ 0 ]
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 3
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 0
|
||||
ArgumentList: 4096
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 4097
|
||||
Attrs: 65548
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4097
|
||||
Name: foo
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ ]
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 116
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 0
|
||||
ArgumentList: 4100
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4101
|
||||
Name: main
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4097
|
||||
Name: bar
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
|
||||
- Kind: LF_SUBSTR_LIST
|
||||
StringList:
|
||||
StringIndices: [ 4106 ]
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 4107
|
||||
String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: pdb_comdat_main.c
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build\vc140.pdb'
|
||||
- Kind: LF_BUILDINFO
|
||||
BuildInfo:
|
||||
ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: 4883EC28E800000000E800000000B82A0000004883C428C3
|
||||
Relocations:
|
||||
- VirtualAddress: 5
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- VirtualAddress: 10
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: 8B0500000000FFC0890500000000C3
|
||||
Relocations:
|
||||
- VirtualAddress: 2
|
||||
SymbolName: global
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- VirtualAddress: 10
|
||||
SymbolName: global
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GPROC32_ID
|
||||
ProcSym:
|
||||
PtrParent: 0
|
||||
PtrEnd: 0
|
||||
PtrNext: 0
|
||||
CodeSize: 15
|
||||
DbgStart: 0
|
||||
DbgEnd: 14
|
||||
FunctionType: 4099
|
||||
Segment: 0
|
||||
Flags: [ ]
|
||||
DisplayName: foo
|
||||
- Kind: S_FRAMEPROC
|
||||
FrameProcSym:
|
||||
TotalFrameBytes: 0
|
||||
PaddingFrameBytes: 0
|
||||
OffsetToPadding: 0
|
||||
BytesOfCalleeSavedRegisters: 0
|
||||
OffsetOfExceptionHandler: 0
|
||||
SectionIdOfExceptionHandler: 0
|
||||
Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
|
||||
- Kind: S_PROC_ID_END
|
||||
ScopeEndSym:
|
||||
- !Lines
|
||||
CodeSize: 15
|
||||
Flags: [ ]
|
||||
RelocOffset: 0
|
||||
RelocSegment: 0
|
||||
Blocks:
|
||||
- FileName: 'c:\src\llvm-project\build\foo.h'
|
||||
Lines:
|
||||
- Offset: 0
|
||||
LineStart: 2
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 0
|
||||
LineStart: 3
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 14
|
||||
LineStart: 4
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
Columns:
|
||||
Relocations:
|
||||
- VirtualAddress: 44
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 48
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 100
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 104
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- Name: .xdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: '0104010004420000'
|
||||
- Name: .pdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: '000000001800000000000000'
|
||||
Relocations:
|
||||
- VirtualAddress: 0
|
||||
SymbolName: '$LN3'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- VirtualAddress: 4
|
||||
SymbolName: '$LN3'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- VirtualAddress: 8
|
||||
SymbolName: '$unwind$main'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
symbols:
|
||||
- Name: .drectve
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 47
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 480
|
||||
NumberOfRelocations: 6
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$T'
|
||||
Value: 0
|
||||
SectionNumber: 3
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 648
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 24
|
||||
NumberOfRelocations: 2
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 492663294
|
||||
Number: 0
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 15
|
||||
NumberOfRelocations: 2
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 1746394828
|
||||
Number: 0
|
||||
Selection: IMAGE_COMDAT_SELECT_ANY
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 6
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 148
|
||||
NumberOfRelocations: 4
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 5
|
||||
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
|
||||
- Name: foo
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: bar
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: main
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: '$LN3'
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_LABEL
|
||||
- Name: .xdata
|
||||
Value: 0
|
||||
SectionNumber: 7
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 8
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 264583633
|
||||
Number: 0
|
||||
- Name: '$unwind$main'
|
||||
Value: 0
|
||||
SectionNumber: 7
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
- Name: .pdata
|
||||
Value: 0
|
||||
SectionNumber: 8
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 12
|
||||
NumberOfRelocations: 3
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 2942184094
|
||||
Number: 0
|
||||
- Name: '$pdata$main'
|
||||
Value: 0
|
||||
SectionNumber: 8
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
- Name: global
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
480
test/COFF/Inputs/pdb_lines_1.yaml
Normal file
480
test/COFF/Inputs/pdb_lines_1.yaml
Normal file
@ -0,0 +1,480 @@
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: .drectve
|
||||
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
|
||||
Alignment: 1
|
||||
SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_OBJNAME
|
||||
ObjNameSym:
|
||||
Signature: 0
|
||||
ObjectName: 'C:\src\llvm-project\build\pdb_lines_1.obj'
|
||||
- Kind: S_COMPILE3
|
||||
Compile3Sym:
|
||||
Flags: [ SecurityChecks, HotPatch ]
|
||||
Machine: X64
|
||||
FrontendMajor: 19
|
||||
FrontendMinor: 0
|
||||
FrontendBuild: 24215
|
||||
FrontendQFE: 1
|
||||
BackendMajor: 19
|
||||
BackendMinor: 0
|
||||
BackendBuild: 24215
|
||||
BackendQFE: 1
|
||||
Version: 'Microsoft (R) Optimizing Compiler'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GPROC32_ID
|
||||
ProcSym:
|
||||
PtrParent: 0
|
||||
PtrEnd: 0
|
||||
PtrNext: 0
|
||||
CodeSize: 19
|
||||
DbgStart: 4
|
||||
DbgEnd: 14
|
||||
FunctionType: 4102
|
||||
Segment: 0
|
||||
Flags: [ ]
|
||||
DisplayName: main
|
||||
- Kind: S_FRAMEPROC
|
||||
FrameProcSym:
|
||||
TotalFrameBytes: 40
|
||||
PaddingFrameBytes: 0
|
||||
OffsetToPadding: 0
|
||||
BytesOfCalleeSavedRegisters: 0
|
||||
OffsetOfExceptionHandler: 0
|
||||
SectionIdOfExceptionHandler: 0
|
||||
Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
|
||||
- Kind: S_PROC_ID_END
|
||||
ScopeEndSym:
|
||||
- !Lines
|
||||
CodeSize: 19
|
||||
Flags: [ ]
|
||||
RelocOffset: 0
|
||||
RelocSegment: 0
|
||||
Blocks:
|
||||
- FileName: 'c:\src\llvm-project\build\pdb_lines_1.c'
|
||||
Lines:
|
||||
- Offset: 0
|
||||
LineStart: 2
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 4
|
||||
LineStart: 3
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 9
|
||||
LineStart: 4
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 14
|
||||
LineStart: 5
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
Columns:
|
||||
- !FileChecksums
|
||||
Checksums:
|
||||
- FileName: 'c:\src\llvm-project\build\pdb_lines_1.c'
|
||||
Kind: MD5
|
||||
Checksum: 4EB19DCD86C3BA2238A255C718572E7B
|
||||
- FileName: 'c:\src\llvm-project\build\foo.h'
|
||||
Kind: MD5
|
||||
Checksum: 061EB73ABB642532857A4F1D9CBAC323
|
||||
- !StringTable
|
||||
Strings:
|
||||
- 'c:\src\llvm-project\build\pdb_lines_1.c'
|
||||
- 'c:\src\llvm-project\build\foo.h'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_BUILDINFO
|
||||
BuildInfoSym:
|
||||
BuildId: 4111
|
||||
Relocations:
|
||||
- VirtualAddress: 164
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 168
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 220
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 224
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- Name: '.debug$T'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Types:
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ ]
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 3
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 0
|
||||
ArgumentList: 4096
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 4097
|
||||
Attrs: 65548
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4097
|
||||
Name: foo
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ 0 ]
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 116
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 0
|
||||
ArgumentList: 4100
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4101
|
||||
Name: main
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4097
|
||||
Name: bar
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
|
||||
- Kind: LF_SUBSTR_LIST
|
||||
StringList:
|
||||
StringIndices: [ 4106 ]
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 4107
|
||||
String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: pdb_lines_1.c
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build\vc140.pdb'
|
||||
- Kind: LF_BUILDINFO
|
||||
BuildInfo:
|
||||
ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: 4883EC28E800000000B82A0000004883C428C3
|
||||
Relocations:
|
||||
- VirtualAddress: 5
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: 4883EC28E8000000004883C428C3
|
||||
Relocations:
|
||||
- VirtualAddress: 5
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GPROC32_ID
|
||||
ProcSym:
|
||||
PtrParent: 0
|
||||
PtrEnd: 0
|
||||
PtrNext: 0
|
||||
CodeSize: 14
|
||||
DbgStart: 4
|
||||
DbgEnd: 9
|
||||
FunctionType: 4099
|
||||
Segment: 0
|
||||
Flags: [ ]
|
||||
DisplayName: foo
|
||||
- Kind: S_FRAMEPROC
|
||||
FrameProcSym:
|
||||
TotalFrameBytes: 40
|
||||
PaddingFrameBytes: 0
|
||||
OffsetToPadding: 0
|
||||
BytesOfCalleeSavedRegisters: 0
|
||||
OffsetOfExceptionHandler: 0
|
||||
SectionIdOfExceptionHandler: 0
|
||||
Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
|
||||
- Kind: S_PROC_ID_END
|
||||
ScopeEndSym:
|
||||
- !Lines
|
||||
CodeSize: 14
|
||||
Flags: [ ]
|
||||
RelocOffset: 0
|
||||
RelocSegment: 0
|
||||
Blocks:
|
||||
- FileName: 'c:\src\llvm-project\build\foo.h'
|
||||
Lines:
|
||||
- Offset: 0
|
||||
LineStart: 2
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 4
|
||||
LineStart: 3
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 9
|
||||
LineStart: 4
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
Columns:
|
||||
Relocations:
|
||||
- VirtualAddress: 44
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 48
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 100
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 104
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- Name: .xdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: '0104010004420000'
|
||||
- Name: .pdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: '000000000E00000000000000'
|
||||
Relocations:
|
||||
- VirtualAddress: 0
|
||||
SymbolName: '$LN3'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- VirtualAddress: 4
|
||||
SymbolName: '$LN3'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- VirtualAddress: 8
|
||||
SymbolName: '$unwind$foo'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- Name: .xdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: '0104010004420000'
|
||||
- Name: .pdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: '000000001300000000000000'
|
||||
Relocations:
|
||||
- VirtualAddress: 0
|
||||
SymbolName: '$LN3'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- VirtualAddress: 4
|
||||
SymbolName: '$LN3'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- VirtualAddress: 8
|
||||
SymbolName: '$unwind$main'
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
symbols:
|
||||
- Name: .drectve
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 47
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 432
|
||||
NumberOfRelocations: 4
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$T'
|
||||
Value: 0
|
||||
SectionNumber: 3
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 644
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 19
|
||||
NumberOfRelocations: 1
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 791570821
|
||||
Number: 0
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 14
|
||||
NumberOfRelocations: 1
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 1682752513
|
||||
Number: 0
|
||||
Selection: IMAGE_COMDAT_SELECT_ANY
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 6
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 148
|
||||
NumberOfRelocations: 4
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 5
|
||||
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
|
||||
- Name: bar
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: foo
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: main
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: '$LN3'
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_LABEL
|
||||
- Name: '$LN3'
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_LABEL
|
||||
- Name: .xdata
|
||||
Value: 0
|
||||
SectionNumber: 7
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 8
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 264583633
|
||||
Number: 5
|
||||
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
|
||||
- Name: '$unwind$foo'
|
||||
Value: 0
|
||||
SectionNumber: 7
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
- Name: .pdata
|
||||
Value: 0
|
||||
SectionNumber: 8
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 12
|
||||
NumberOfRelocations: 3
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 361370162
|
||||
Number: 5
|
||||
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
|
||||
- Name: '$pdata$foo'
|
||||
Value: 0
|
||||
SectionNumber: 8
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
- Name: .xdata
|
||||
Value: 0
|
||||
SectionNumber: 9
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 8
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 264583633
|
||||
Number: 0
|
||||
- Name: '$unwind$main'
|
||||
Value: 0
|
||||
SectionNumber: 9
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
- Name: .pdata
|
||||
Value: 0
|
||||
SectionNumber: 10
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 12
|
||||
NumberOfRelocations: 3
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 4063508168
|
||||
Number: 0
|
||||
- Name: '$pdata$main'
|
||||
Value: 0
|
||||
SectionNumber: 10
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
...
|
209
test/COFF/Inputs/pdb_lines_2.yaml
Normal file
209
test/COFF/Inputs/pdb_lines_2.yaml
Normal file
@ -0,0 +1,209 @@
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: .drectve
|
||||
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
|
||||
Alignment: 1
|
||||
SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_OBJNAME
|
||||
ObjNameSym:
|
||||
Signature: 0
|
||||
ObjectName: 'C:\src\llvm-project\build\pdb_lines_2.obj'
|
||||
- Kind: S_COMPILE3
|
||||
Compile3Sym:
|
||||
Flags: [ SecurityChecks, HotPatch ]
|
||||
Machine: X64
|
||||
FrontendMajor: 19
|
||||
FrontendMinor: 0
|
||||
FrontendBuild: 24215
|
||||
FrontendQFE: 1
|
||||
BackendMajor: 19
|
||||
BackendMinor: 0
|
||||
BackendBuild: 24215
|
||||
BackendQFE: 1
|
||||
Version: 'Microsoft (R) Optimizing Compiler'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GPROC32_ID
|
||||
ProcSym:
|
||||
PtrParent: 0
|
||||
PtrEnd: 0
|
||||
PtrNext: 0
|
||||
CodeSize: 1
|
||||
DbgStart: 0
|
||||
DbgEnd: 0
|
||||
FunctionType: 4098
|
||||
Segment: 0
|
||||
Flags: [ ]
|
||||
DisplayName: bar
|
||||
- Kind: S_FRAMEPROC
|
||||
FrameProcSym:
|
||||
TotalFrameBytes: 0
|
||||
PaddingFrameBytes: 0
|
||||
OffsetToPadding: 0
|
||||
BytesOfCalleeSavedRegisters: 0
|
||||
OffsetOfExceptionHandler: 0
|
||||
SectionIdOfExceptionHandler: 0
|
||||
Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
|
||||
- Kind: S_PROC_ID_END
|
||||
ScopeEndSym:
|
||||
- !Lines
|
||||
CodeSize: 1
|
||||
Flags: [ ]
|
||||
RelocOffset: 0
|
||||
RelocSegment: 0
|
||||
Blocks:
|
||||
- FileName: 'c:\src\llvm-project\build\pdb_lines_2.c'
|
||||
Lines:
|
||||
- Offset: 0
|
||||
LineStart: 1
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 0
|
||||
LineStart: 2
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
Columns:
|
||||
- !FileChecksums
|
||||
Checksums:
|
||||
- FileName: 'c:\src\llvm-project\build\pdb_lines_2.c'
|
||||
Kind: MD5
|
||||
Checksum: DF91CB3A2B8D917486574BB50CAC4CC7
|
||||
- !StringTable
|
||||
Strings:
|
||||
- 'c:\src\llvm-project\build\pdb_lines_2.c'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_BUILDINFO
|
||||
BuildInfoSym:
|
||||
BuildId: 4106
|
||||
Relocations:
|
||||
- VirtualAddress: 164
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 168
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 220
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 224
|
||||
SymbolName: bar
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- Name: '.debug$T'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Types:
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ ]
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 3
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 0
|
||||
ArgumentList: 4096
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4097
|
||||
Name: bar
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
|
||||
- Kind: LF_SUBSTR_LIST
|
||||
StringList:
|
||||
StringIndices: [ 4101 ]
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 4102
|
||||
String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: pdb_lines_2.c
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build\vc140.pdb'
|
||||
- Kind: LF_BUILDINFO
|
||||
BuildInfo:
|
||||
ArgIndices: [ 4099, 4100, 4104, 4105, 4103 ]
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: C3
|
||||
symbols:
|
||||
- Name: .drectve
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 47
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 360
|
||||
NumberOfRelocations: 4
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$T'
|
||||
Value: 0
|
||||
SectionNumber: 3
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 568
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 1
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 40735498
|
||||
Number: 0
|
||||
- Name: bar
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
46
test/COFF/associative-comdat.s
Normal file
46
test/COFF/associative-comdat.s
Normal file
@ -0,0 +1,46 @@
|
||||
# RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t1.obj
|
||||
# RUN: llvm-mc -triple=x86_64-windows-msvc %S/Inputs/associative-comdat-2.s -filetype=obj -o %t2.obj
|
||||
|
||||
# RUN: lld-link -entry:main %t1.obj %t2.obj -out:%t.gc.exe
|
||||
# RUN: llvm-readobj -sections %t.gc.exe | FileCheck %s
|
||||
|
||||
# RUN: lld-link -entry:main %t1.obj %t2.obj -opt:noref -out:%t.nogc.exe
|
||||
# RUN: llvm-readobj -sections %t.nogc.exe | FileCheck %s
|
||||
|
||||
# CHECK: Sections [
|
||||
# CHECK: Section {
|
||||
# CHECK: Number: 1
|
||||
# CHECK-LABEL: Name: .data (2E 64 61 74 61 00 00 00)
|
||||
# CHECK-NEXT: VirtualSize: 0x4
|
||||
# CHECK: Section {
|
||||
# CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00)
|
||||
# This is the critical check to show that only *one* definition of
|
||||
# foo_assoc was retained. This *must* be 8, not 16.
|
||||
# CHECK-NEXT: VirtualSize: 0x8
|
||||
|
||||
.text
|
||||
.def main;
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.globl main # -- Begin function main
|
||||
.p2align 4, 0x90
|
||||
main: # @main
|
||||
# BB#0:
|
||||
movl foo(%rip), %eax
|
||||
retq
|
||||
# -- End function
|
||||
|
||||
# Defines foo and foo_assoc globals. foo is comdat, and foo_assoc is comdat
|
||||
# associative with it. foo_assoc should be discarded iff foo is discarded,
|
||||
# either by linker GC or normal comdat merging.
|
||||
|
||||
.section .rdata,"dr",associative,foo
|
||||
.p2align 3
|
||||
.quad foo
|
||||
|
||||
.section .data,"dw",discard,foo
|
||||
.globl foo # @foo
|
||||
.p2align 2
|
||||
foo:
|
||||
.long 42
|
@ -1,5 +1,3 @@
|
||||
# REQUIRES: winres
|
||||
|
||||
# RUN: rm -rf %t
|
||||
# RUN: mkdir -p %t
|
||||
# RUN: cd %t
|
||||
|
@ -1,5 +1,3 @@
|
||||
# REQUIRES: winres
|
||||
|
||||
# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
|
||||
# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \
|
||||
# RUN: /export:mangled
|
||||
|
@ -1,5 +1,3 @@
|
||||
# REQUIRES: winres
|
||||
|
||||
# RUN: yaml2obj < %p/Inputs/export.yaml > %t-lib.obj
|
||||
# RUN: lld-link /out:%t.dll /dll %t-lib.obj /implib:%t.lib /export:exportfn1
|
||||
|
||||
|
74
test/COFF/guardcf.test
Normal file
74
test/COFF/guardcf.test
Normal file
@ -0,0 +1,74 @@
|
||||
# RUN: yaml2obj < %s > %t.obj
|
||||
# RUN: lld-link /entry:main /out:%t.exe %t.obj
|
||||
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
Characteristics: []
|
||||
sections:
|
||||
- Name: .text
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: 000000000000
|
||||
symbols:
|
||||
- Name: .text
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 6
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: main
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: __guard_fids_count
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: __guard_fids_table
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: __guard_flags
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: __guard_iat_count
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: __guard_iat_table
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: __guard_longjmp_count
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: __guard_longjmp_table
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
@ -21,7 +21,7 @@ HEADER-NEXT: IMAGE_FILE_EXECUTABLE_IMAGE (0x2)
|
||||
HEADER-NEXT: ]
|
||||
HEADER-NEXT: }
|
||||
HEADER-NEXT: ImageOptionalHeader {
|
||||
HEADER-NEXT: MajorLinkerVersion: 0
|
||||
HEADER-NEXT: MajorLinkerVersion: 14
|
||||
HEADER-NEXT: MinorLinkerVersion: 0
|
||||
HEADER-NEXT: SizeOfCode: 512
|
||||
HEADER-NEXT: SizeOfInitializedData: 1536
|
||||
|
@ -16,7 +16,7 @@ sections:
|
||||
Alignment: 16
|
||||
SectionData: 4883EC28E8000000004883C428C3
|
||||
|
||||
- Name: '.debug$S'
|
||||
- Name: '.debug_blah'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
SectionData: 0000000000000000000000000000
|
||||
@ -26,7 +26,7 @@ sections:
|
||||
Alignment: 16
|
||||
SectionData: 4883EC28E8000000004883C428C3
|
||||
|
||||
- Name: '.debug$S'
|
||||
- Name: '.debug_blah'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
SectionData: FFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
@ -46,7 +46,7 @@ symbols:
|
||||
Number: 0
|
||||
Selection: IMAGE_COMDAT_SELECT_ANY
|
||||
|
||||
- Name: '.debug$S'
|
||||
- Name: '.debug_blah'
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
@ -74,7 +74,7 @@ symbols:
|
||||
Number: 0
|
||||
Selection: IMAGE_COMDAT_SELECT_ANY
|
||||
|
||||
- Name: '.debug$S'
|
||||
- Name: '.debug_blah'
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
|
@ -1,4 +1,4 @@
|
||||
# REQUIRES: winres
|
||||
# REQUIRES: win_mt
|
||||
|
||||
# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
|
||||
# RUN: lld-link /out:%t.exe /entry:main \
|
||||
@ -8,3 +8,28 @@
|
||||
|
||||
CHECK: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
CHECK: <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity></dependentAssembly></dependency><trustInfo><security><requestedPrivileges><requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo></assembly>
|
||||
|
||||
# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
|
||||
# RUN: lld-link /out:%t.exe /entry:main \
|
||||
# RUN: /manifest:embed \
|
||||
# RUN: /manifestuac:"level='requireAdministrator'" \
|
||||
# RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj
|
||||
# RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s \
|
||||
# RUN: -check-prefix TEST_EMBED
|
||||
|
||||
TEST_EMBED: ResourceTableRVA: 0x1000
|
||||
TEST_EMBED-NEXT: ResourceTableSize: 0x298
|
||||
TEST_EMBED-DAG: Resources [
|
||||
TEST_EMBED-NEXT: Total Number of Resources: 1
|
||||
TEST_EMBED-DAG: Number of String Entries: 0
|
||||
TEST_EMBED-NEXT: Number of ID Entries: 1
|
||||
TEST_EMBED-NEXT: Type: kRT_MANIFEST (ID 24) [
|
||||
TEST_EMBED-NEXT: Table Offset: 0x18
|
||||
TEST_EMBED-NEXT: Number of String Entries: 0
|
||||
TEST_EMBED-NEXT: Number of ID Entries: 1
|
||||
TEST_EMBED-NEXT: Name: (ID 1) [
|
||||
TEST_EMBED-NEXT: Table Offset: 0x30
|
||||
TEST_EMBED-NEXT: Number of String Entries: 0
|
||||
TEST_EMBED-NEXT: Number of ID Entries: 1
|
||||
TEST_EMBED-NEXT: Language: (ID 1033) [
|
||||
TEST_EMBED-NEXT: Entry Offset: 0x48
|
||||
|
@ -1,5 +1,3 @@
|
||||
# REQUIRES: winres
|
||||
|
||||
# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
|
||||
# RUN: lld-link /out:%t.dll /dll %t.obj
|
||||
# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=ENTRY %s
|
||||
|
@ -1,4 +1,3 @@
|
||||
# REQUIRES: winres
|
||||
# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
|
||||
|
||||
# RUN: mkdir -p %T/out/tmp
|
||||
|
100
test/COFF/pdb-comdat.test
Normal file
100
test/COFF/pdb-comdat.test
Normal file
@ -0,0 +1,100 @@
|
||||
Consider this example program with an inline function "foo":
|
||||
|
||||
==> foo.h <==
|
||||
extern int global;
|
||||
__inline void foo() {
|
||||
++global;
|
||||
}
|
||||
void bar();
|
||||
==> pdb_comdat_main.c <==
|
||||
#include "foo.h"
|
||||
int main(void) {
|
||||
foo();
|
||||
bar();
|
||||
return 42;
|
||||
}
|
||||
==> pdb_comdat_bar.c <==
|
||||
#include "foo.h"
|
||||
void bar(void) {
|
||||
foo();
|
||||
}
|
||||
|
||||
Both object files will contain debug info for foo, but only the debug info from
|
||||
pdb_comdat_main.obj should be included in the PDB.
|
||||
|
||||
RUN: rm -rf %t && mkdir -p %t && cd %t
|
||||
RUN: yaml2obj %S/Inputs/pdb_comdat_main.yaml -o pdb_comdat_main.obj
|
||||
RUN: yaml2obj %S/Inputs/pdb_comdat_bar.yaml -o pdb_comdat_bar.obj
|
||||
RUN: lld-link pdb_comdat_main.obj pdb_comdat_bar.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main
|
||||
RUN: llvm-pdbutil dump -l -symbols t.pdb | FileCheck %s
|
||||
|
||||
CHECK: Lines
|
||||
CHECK: ============================================================
|
||||
CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`:
|
||||
CHECK: c:\src\llvm-project\build\pdb_comdat_main.c (MD5: F969E51BBE373436D81492EB61387F36)
|
||||
CHECK: c:\src\llvm-project\build\foo.h (MD5: D74D834EFAC3AE2B45E606A8320B1D5C)
|
||||
CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`:
|
||||
CHECK: c:\src\llvm-project\build\pdb_comdat_bar.c (MD5: 365279DB4FCBEDD721BBFC3B14A953C2)
|
||||
CHECK-NOT: c:\src\llvm-project\build\foo.h
|
||||
CHECK-LABEL: Mod 0002 | `* Linker *`:
|
||||
|
||||
CHECK: Symbols
|
||||
CHECK: ============================================================
|
||||
CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`:
|
||||
CHECK: - S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_main.obj`
|
||||
CHECK: - S_COMPILE3 [size = 60]
|
||||
CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
|
||||
CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1
|
||||
CHECK: flags = security checks | hot patchable
|
||||
CHECK: - S_GPROC32_ID [size = 44] `main`
|
||||
FIXME: We need to fill in "end".
|
||||
CHECK: parent = 0, addr = 0002:0000, code size = 24, end = 0
|
||||
CHECK: debug start = 4, debug end = 19, flags = none
|
||||
CHECK: - S_FRAMEPROC [size = 32]
|
||||
CHECK: size = 40, padding size = 0, offset to padding = 0
|
||||
CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
|
||||
CHECK: flags = has async eh | opt speed
|
||||
CHECK: - S_END [size = 4]
|
||||
CHECK: - S_GDATA32 [size = 24] `global`
|
||||
CHECK: type = 0x0074 (int), addr = 0000:0000
|
||||
CHECK: - S_BUILDINFO [size = 8] BuildId = `4106`
|
||||
CHECK: - S_GPROC32_ID [size = 44] `foo`
|
||||
CHECK: parent = 0, addr = 0002:0032, code size = 15, end = 0
|
||||
CHECK: debug start = 0, debug end = 14, flags = none
|
||||
CHECK: - S_FRAMEPROC [size = 32]
|
||||
CHECK: size = 0, padding size = 0, offset to padding = 0
|
||||
CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
|
||||
CHECK: flags = marked inline | has async eh | opt speed
|
||||
CHECK: - S_END [size = 4]
|
||||
CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`:
|
||||
CHECK: - S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_bar.obj`
|
||||
CHECK: - S_COMPILE3 [size = 60]
|
||||
CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
|
||||
CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1
|
||||
CHECK: flags = security checks | hot patchable
|
||||
CHECK: - S_GPROC32_ID [size = 44] `bar`
|
||||
CHECK: parent = 0, addr = 0002:0048, code size = 14, end = 0
|
||||
CHECK: debug start = 4, debug end = 9, flags = none
|
||||
CHECK: - S_FRAMEPROC [size = 32]
|
||||
CHECK: size = 40, padding size = 0, offset to padding = 0
|
||||
CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
|
||||
CHECK: flags = has async eh | opt speed
|
||||
CHECK: - S_END [size = 4]
|
||||
CHECK: - S_GDATA32 [size = 24] `global`
|
||||
CHECK: type = 0x0074 (int), addr = 0000:0000
|
||||
CHECK: - S_BUILDINFO [size = 8] BuildId = `4109`
|
||||
CHECK-NOT: - S_GPROC32_ID {{.*}} `foo`
|
||||
CHECK-LABEL: Mod 0002 | `* Linker *`:
|
||||
|
||||
Reorder the object files and verify that the other table is selected.
|
||||
|
||||
RUN: lld-link pdb_comdat_bar.obj pdb_comdat_main.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main
|
||||
RUN: llvm-pdbutil dump -l t.pdb | FileCheck %s --check-prefix=REORDER
|
||||
|
||||
REORDER-LABEL: Mod 0000 | `{{.*}}pdb_comdat_bar.obj`:
|
||||
REORDER: c:\src\llvm-project\build\pdb_comdat_bar.c (MD5: 365279DB4FCBEDD721BBFC3B14A953C2)
|
||||
REORDER: c:\src\llvm-project\build\foo.h (MD5: D74D834EFAC3AE2B45E606A8320B1D5C)
|
||||
REORDER-LABEL: Mod 0001 | `{{.*}}pdb_comdat_main.obj`:
|
||||
REORDER: c:\src\llvm-project\build\pdb_comdat_main.c
|
||||
REORDER-NOT: c:\src\llvm-project\build\foo.h
|
||||
REORDER-LABEL: Mod 0002 | `* Linker *`:
|
@ -3,7 +3,7 @@
|
||||
# RUN: llc %S/Inputs/bar.ll -filetype=obj -mtriple=i686-windows-msvc -o bar.obj
|
||||
# RUN: llvm-lib bar.obj -out:bar.lib
|
||||
# RUN: lld-link -debug -pdb:foo.pdb foo.obj bar.lib -out:foo.exe -entry:main
|
||||
# RUN: llvm-pdbutil raw -modules %t/foo.pdb | FileCheck %s
|
||||
# RUN: llvm-pdbutil dump -modules %t/foo.pdb | FileCheck %s
|
||||
|
||||
# Make sure that the PDB has module descriptors. foo.obj and bar.lib should be
|
||||
# absolute paths, and bar.obj should be the relative path passed to llvm-lib.
|
||||
|
85
test/COFF/pdb-safeseh.yaml
Normal file
85
test/COFF/pdb-safeseh.yaml
Normal file
@ -0,0 +1,85 @@
|
||||
# RUN: yaml2obj %s -o %t.obj
|
||||
# RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj
|
||||
# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
|
||||
|
||||
# There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in
|
||||
# it in this debug info. This is similar to the relocations in the loadcfg.obj
|
||||
# file in the MSVC CRT. We need to make sure that our relocation logic matches
|
||||
# MSVC's for these absolute, linker-provided symbols.
|
||||
|
||||
# CHECK: Mod 0000 |
|
||||
# CHECK-NEXT: - S_GDATA32 [size = 40] `___safe_se_handler_table`
|
||||
# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000
|
||||
# CHECK-NEXT: Mod 0001 | `* Linker *`:
|
||||
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_I386
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GDATA32
|
||||
DataSym:
|
||||
Type: 34
|
||||
DisplayName: ___safe_se_handler_table
|
||||
- !StringTable
|
||||
Strings:
|
||||
Relocations:
|
||||
- VirtualAddress: 20
|
||||
SymbolName: ___safe_se_handler_table
|
||||
Type: IMAGE_REL_I386_SECREL
|
||||
- VirtualAddress: 24
|
||||
SymbolName: ___safe_se_handler_table
|
||||
Type: IMAGE_REL_I386_SECTION
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: 488D0500000000C3
|
||||
Relocations:
|
||||
- VirtualAddress: 3
|
||||
SymbolName: ___safe_se_handler_table
|
||||
Type: IMAGE_REL_I386_REL32
|
||||
symbols:
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 372
|
||||
NumberOfRelocations: 6
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 8
|
||||
NumberOfRelocations: 1
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 1092178131
|
||||
Number: 0
|
||||
- Name: _main
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: ___safe_se_handler_table
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
||||
|
84
test/COFF/pdb-secrel-absolute.yaml
Normal file
84
test/COFF/pdb-secrel-absolute.yaml
Normal file
@ -0,0 +1,84 @@
|
||||
# RUN: yaml2obj %s -o %t.obj
|
||||
# RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj
|
||||
# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
|
||||
|
||||
# There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in
|
||||
# it in this debug info. This is similar to the relocations in the loadcfg.obj
|
||||
# file in the MSVC CRT. We need to make sure that our relocation logic matches
|
||||
# MSVC's for these absolute, linker-provided symbols.
|
||||
|
||||
# CHECK: Mod 0000 |
|
||||
# CHECK-NEXT: - S_GDATA32 [size = 36] `__guard_fids_table`
|
||||
# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000
|
||||
# CHECK-NEXT: Mod 0001 | `* Linker *`:
|
||||
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GDATA32
|
||||
DataSym:
|
||||
Type: 34
|
||||
DisplayName: __guard_fids_table
|
||||
- !StringTable
|
||||
Strings:
|
||||
Relocations:
|
||||
- VirtualAddress: 20
|
||||
SymbolName: __guard_fids_table
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 24
|
||||
SymbolName: __guard_fids_table
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: 488D0500000000C3
|
||||
Relocations:
|
||||
- VirtualAddress: 3
|
||||
SymbolName: __guard_fids_table
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
symbols:
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 372
|
||||
NumberOfRelocations: 6
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 8
|
||||
NumberOfRelocations: 1
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 1092178131
|
||||
Number: 0
|
||||
- Name: main
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: __guard_fids_table
|
||||
Value: 0
|
||||
SectionNumber: 0
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
124
test/COFF/pdb-source-lines.test
Normal file
124
test/COFF/pdb-source-lines.test
Normal file
@ -0,0 +1,124 @@
|
||||
Test the linker line tables on roughly the following example:
|
||||
|
||||
==> foo.h <==
|
||||
void bar(void);
|
||||
inline void foo(void) {
|
||||
bar();
|
||||
}
|
||||
==> pdb_lines_1.c <==
|
||||
#include "foo.h"
|
||||
int main(void) {
|
||||
foo();
|
||||
return 42;
|
||||
}
|
||||
==> pdb_lines_2.c <==
|
||||
void bar(void) {
|
||||
}
|
||||
|
||||
$ cl -c -Z7 pdb_lines*.c
|
||||
|
||||
RUN: yaml2obj %S/Inputs/pdb_lines_1.yaml -o %t.pdb_lines_1.obj
|
||||
RUN: yaml2obj %S/Inputs/pdb_lines_2.yaml -o %t.pdb_lines_2.obj
|
||||
RUN: lld-link -debug -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1.obj %t.pdb_lines_2.obj
|
||||
RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s
|
||||
|
||||
CHECK-LABEL: DbiStream:
|
||||
CHECK-NEXT: VerHeader: V110
|
||||
CHECK-NEXT: Age: 1
|
||||
CHECK-NEXT: BuildNumber: 0
|
||||
CHECK-NEXT: PdbDllVersion: 0
|
||||
CHECK-NEXT: PdbDllRbld: 0
|
||||
CHECK-NEXT: Flags: 0
|
||||
CHECK-NEXT: MachineType: x86
|
||||
CHECK-NEXT: Modules:
|
||||
|
||||
CHECK-LABEL: - Module: {{.*}}pdb_lines_1.obj
|
||||
CHECK-NEXT: ObjFile: {{.*}}pdb_lines_1.obj
|
||||
CHECK-NEXT: SourceFiles:
|
||||
CHECK-NEXT: - '{{.*}}pdb_lines_1.c'
|
||||
CHECK-NEXT: - '{{.*}}foo.h'
|
||||
CHECK-NEXT: Subsections:
|
||||
CHECK-NEXT: - !Lines
|
||||
CHECK-NEXT: CodeSize: 19
|
||||
CHECK-NEXT: Flags: [ ]
|
||||
CHECK-NEXT: RelocOffset: 0
|
||||
CHECK-NEXT: RelocSegment: 2
|
||||
CHECK-NEXT: Blocks:
|
||||
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
|
||||
CHECK-NEXT: Lines:
|
||||
CHECK-NEXT: - Offset: 0
|
||||
CHECK-NEXT: LineStart: 2
|
||||
CHECK-NEXT: IsStatement: true
|
||||
CHECK-NEXT: EndDelta: 0
|
||||
CHECK-NEXT: - Offset: 4
|
||||
CHECK-NEXT: LineStart: 3
|
||||
CHECK-NEXT: IsStatement: true
|
||||
CHECK-NEXT: EndDelta: 0
|
||||
CHECK-NEXT: - Offset: 9
|
||||
CHECK-NEXT: LineStart: 4
|
||||
CHECK-NEXT: IsStatement: true
|
||||
CHECK-NEXT: EndDelta: 0
|
||||
CHECK-NEXT: - Offset: 14
|
||||
CHECK-NEXT: LineStart: 5
|
||||
CHECK-NEXT: IsStatement: true
|
||||
CHECK-NEXT: EndDelta: 0
|
||||
CHECK-NEXT: Columns:
|
||||
CHECK-NEXT: - !FileChecksums
|
||||
CHECK-NEXT: Checksums:
|
||||
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
|
||||
CHECK-NEXT: Kind: MD5
|
||||
CHECK-NEXT: Checksum: 4EB19DCD86C3BA2238A255C718572E7B
|
||||
CHECK-NEXT: - FileName: '{{.*}}foo.h'
|
||||
CHECK-NEXT: Kind: MD5
|
||||
CHECK-NEXT: Checksum: 061EB73ABB642532857A4F1D9CBAC323
|
||||
CHECK-NEXT: - !Lines
|
||||
CHECK-NEXT: CodeSize: 14
|
||||
CHECK-NEXT: Flags: [ ]
|
||||
CHECK-NEXT: RelocOffset: 32
|
||||
CHECK-NEXT: RelocSegment: 2
|
||||
CHECK-NEXT: Blocks:
|
||||
CHECK-NEXT: - FileName: '{{.*}}foo.h'
|
||||
CHECK-NEXT: Lines:
|
||||
CHECK-NEXT: - Offset: 0
|
||||
CHECK-NEXT: LineStart: 2
|
||||
CHECK-NEXT: IsStatement: true
|
||||
CHECK-NEXT: EndDelta: 0
|
||||
CHECK-NEXT: - Offset: 4
|
||||
CHECK-NEXT: LineStart: 3
|
||||
CHECK-NEXT: IsStatement: true
|
||||
CHECK-NEXT: EndDelta: 0
|
||||
CHECK-NEXT: - Offset: 9
|
||||
CHECK-NEXT: LineStart: 4
|
||||
CHECK-NEXT: IsStatement: true
|
||||
CHECK-NEXT: EndDelta: 0
|
||||
CHECK-NEXT: Columns:
|
||||
|
||||
CHECK-LABEL: - Module: {{.*}}pdb_lines_2.obj
|
||||
CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2.obj
|
||||
CHECK-NEXT: SourceFiles:
|
||||
CHECK-NEXT: - '{{.*}}pdb_lines_2.c'
|
||||
CHECK-NEXT: Subsections:
|
||||
CHECK-NEXT: - !Lines
|
||||
CHECK-NEXT: CodeSize: 1
|
||||
CHECK-NEXT: Flags: [ ]
|
||||
CHECK-NEXT: RelocOffset: 48
|
||||
CHECK-NEXT: RelocSegment: 2
|
||||
CHECK-NEXT: Blocks:
|
||||
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
|
||||
CHECK-NEXT: Lines:
|
||||
CHECK-NEXT: - Offset: 0
|
||||
CHECK-NEXT: LineStart: 1
|
||||
CHECK-NEXT: IsStatement: true
|
||||
CHECK-NEXT: EndDelta: 0
|
||||
CHECK-NEXT: - Offset: 0
|
||||
CHECK-NEXT: LineStart: 2
|
||||
CHECK-NEXT: IsStatement: true
|
||||
CHECK-NEXT: EndDelta: 0
|
||||
CHECK-NEXT: Columns:
|
||||
CHECK-NEXT: - !FileChecksums
|
||||
CHECK-NEXT: Checksums:
|
||||
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
|
||||
CHECK-NEXT: Kind: MD5
|
||||
CHECK-NEXT: Checksum: DF91CB3A2B8D917486574BB50CAC4CC7
|
||||
CHECK-NEXT: - Module: '* Linker *'
|
||||
CHECK-NEXT: ObjFile: ''
|
344
test/COFF/pdb-symbol-types.yaml
Normal file
344
test/COFF/pdb-symbol-types.yaml
Normal file
@ -0,0 +1,344 @@
|
||||
# RUN: yaml2obj %s -o %t.obj
|
||||
# RUN: lld-link %t.obj -nodefaultlib -entry:main -debug -out:%t.exe -pdb:%t.pdb
|
||||
# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
|
||||
|
||||
# To regenerate the object file:
|
||||
# $ cat symbol-types.c
|
||||
# struct Foo { int x; };
|
||||
# typedef struct Foo UDT_Foo;
|
||||
# UDT_Foo global_foo = {42};
|
||||
# int main() { return global_foo.x; }
|
||||
# $ cl -c -Z7 symbol-types.c
|
||||
|
||||
# Note that the type of 'global' goes from 0x1005 in the object file to 0x1004
|
||||
# in the PDB because the LF_FUNC_ID is moved to the id stream.
|
||||
|
||||
# CHECK: Symbols
|
||||
# CHECK: ============================================================
|
||||
# CHECK-LABEL: Mod 0000 | `{{.*}}pdb-symbol-types.yaml.tmp.obj`:
|
||||
# CHECK: - S_OBJNAME [size = 52] sig=0, `C:\src\llvm-project\build\symbol-types.obj`
|
||||
# CHECK: - S_COMPILE3 [size = 60]
|
||||
# CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
|
||||
# CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1
|
||||
# CHECK: flags = security checks | hot patchable
|
||||
# CHECK: - S_GPROC32_ID [size = 44] `main`
|
||||
# CHECK: parent = 0, addr = 0002:0000, code size = 7, end = 0
|
||||
# CHECK: debug start = 0, debug end = 6, flags = none
|
||||
# CHECK: - S_FRAMEPROC [size = 32]
|
||||
# CHECK: size = 0, padding size = 0, offset to padding = 0
|
||||
# CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
|
||||
# CHECK: flags = has async eh | opt speed
|
||||
# CHECK: - S_END [size = 4]
|
||||
# CHECK: - S_GDATA32 [size = 28] `global_foo`
|
||||
# CHECK: type = 0x1004 (Foo), addr = 0001:0000
|
||||
# CHECK: - S_UDT [size = 16] `UDT_Foo`
|
||||
# CHECK: original type = 0x1004
|
||||
# CHECK: - S_UDT [size = 12] `Foo`
|
||||
# CHECK: original type = 0x1004
|
||||
# CHECK: - S_BUILDINFO [size = 8] BuildId = `4106`
|
||||
# CHECK-LABEL: Mod 0001 | `* Linker *`:
|
||||
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: .drectve
|
||||
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
|
||||
Alignment: 1
|
||||
SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
|
||||
- Name: '.debug$S'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Subsections:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_OBJNAME
|
||||
ObjNameSym:
|
||||
Signature: 0
|
||||
ObjectName: 'C:\src\llvm-project\build\symbol-types.obj'
|
||||
- Kind: S_COMPILE3
|
||||
Compile3Sym:
|
||||
Flags: [ SecurityChecks, HotPatch ]
|
||||
Machine: X64
|
||||
FrontendMajor: 19
|
||||
FrontendMinor: 0
|
||||
FrontendBuild: 24215
|
||||
FrontendQFE: 1
|
||||
BackendMajor: 19
|
||||
BackendMinor: 0
|
||||
BackendBuild: 24215
|
||||
BackendQFE: 1
|
||||
Version: 'Microsoft (R) Optimizing Compiler'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GPROC32_ID
|
||||
ProcSym:
|
||||
CodeSize: 7
|
||||
DbgStart: 0
|
||||
DbgEnd: 6
|
||||
FunctionType: 4098
|
||||
Flags: [ ]
|
||||
DisplayName: main
|
||||
- Kind: S_FRAMEPROC
|
||||
FrameProcSym:
|
||||
TotalFrameBytes: 0
|
||||
PaddingFrameBytes: 0
|
||||
OffsetToPadding: 0
|
||||
BytesOfCalleeSavedRegisters: 0
|
||||
OffsetOfExceptionHandler: 0
|
||||
SectionIdOfExceptionHandler: 0
|
||||
Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
|
||||
- Kind: S_PROC_ID_END
|
||||
ScopeEndSym:
|
||||
- !Lines
|
||||
CodeSize: 7
|
||||
Flags: [ ]
|
||||
RelocOffset: 0
|
||||
RelocSegment: 0
|
||||
Blocks:
|
||||
- FileName: 'c:\src\llvm-project\build\symbol-types.c'
|
||||
Lines:
|
||||
- Offset: 0
|
||||
LineStart: 4
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 0
|
||||
LineStart: 5
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
- Offset: 6
|
||||
LineStart: 6
|
||||
IsStatement: true
|
||||
EndDelta: 0
|
||||
Columns:
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_GDATA32
|
||||
DataSym:
|
||||
Type: 4101
|
||||
DisplayName: global_foo
|
||||
- Kind: S_UDT
|
||||
UDTSym:
|
||||
Type: 4101
|
||||
UDTName: UDT_Foo
|
||||
- Kind: S_UDT
|
||||
UDTSym:
|
||||
Type: 4101
|
||||
UDTName: Foo
|
||||
- !FileChecksums
|
||||
Checksums:
|
||||
- FileName: 'c:\src\llvm-project\build\symbol-types.c'
|
||||
Kind: MD5
|
||||
Checksum: F833E1A4909FF6FEC5689A664F3BE725
|
||||
- !StringTable
|
||||
Strings:
|
||||
- 'c:\src\llvm-project\build\symbol-types.c'
|
||||
- !Symbols
|
||||
Records:
|
||||
- Kind: S_BUILDINFO
|
||||
BuildInfoSym:
|
||||
BuildId: 4111
|
||||
Relocations:
|
||||
- VirtualAddress: 164
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 168
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 220
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 224
|
||||
SymbolName: main
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 284
|
||||
SymbolName: global_foo
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- VirtualAddress: 288
|
||||
SymbolName: global_foo
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- Name: '.debug$T'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 1
|
||||
Types:
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ 0 ]
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 116
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 0
|
||||
ArgumentList: 4096
|
||||
- Kind: LF_FUNC_ID
|
||||
FuncId:
|
||||
ParentScope: 0
|
||||
FunctionType: 4097
|
||||
Name: main
|
||||
- Kind: LF_STRUCTURE
|
||||
Class:
|
||||
MemberCount: 0
|
||||
Options: [ None, ForwardReference, HasUniqueName ]
|
||||
FieldList: 0
|
||||
Name: Foo
|
||||
UniqueName: '.?AUFoo@@'
|
||||
DerivationList: 0
|
||||
VTableShape: 0
|
||||
Size: 0
|
||||
- Kind: LF_FIELDLIST
|
||||
FieldList:
|
||||
- Kind: LF_MEMBER
|
||||
DataMember:
|
||||
Attrs: 3
|
||||
Type: 116
|
||||
FieldOffset: 0
|
||||
Name: x
|
||||
- Kind: LF_STRUCTURE
|
||||
Class:
|
||||
MemberCount: 1
|
||||
Options: [ None, HasUniqueName ]
|
||||
FieldList: 4100
|
||||
Name: Foo
|
||||
UniqueName: '.?AUFoo@@'
|
||||
DerivationList: 0
|
||||
VTableShape: 0
|
||||
Size: 4
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'c:\src\llvm-project\build\symbol-types.c'
|
||||
- Kind: LF_UDT_SRC_LINE
|
||||
UdtSourceLine:
|
||||
UDT: 4101
|
||||
SourceFile: 4102
|
||||
LineNumber: 1
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
|
||||
- Kind: LF_SUBSTR_LIST
|
||||
StringList:
|
||||
StringIndices: [ 4106 ]
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 4107
|
||||
String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: symbol-types.c
|
||||
- Kind: LF_STRING_ID
|
||||
StringId:
|
||||
Id: 0
|
||||
String: 'C:\src\llvm-project\build\vc140.pdb'
|
||||
- Kind: LF_BUILDINFO
|
||||
BuildInfo:
|
||||
ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
|
||||
- Name: .data
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
|
||||
Alignment: 4
|
||||
SectionData: 2A000000
|
||||
- Name: '.text$mn'
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 16
|
||||
SectionData: 8B0500000000C3
|
||||
Relocations:
|
||||
- VirtualAddress: 2
|
||||
SymbolName: global_foo
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
symbols:
|
||||
- Name: '@comp.id'
|
||||
Value: 17063575
|
||||
SectionNumber: -1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
- Name: '@feat.00'
|
||||
Value: 2147484048
|
||||
SectionNumber: -1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
- Name: .drectve
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 47
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$S'
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 432
|
||||
NumberOfRelocations: 6
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: '.debug$T'
|
||||
Value: 0
|
||||
SectionNumber: 3
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 732
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: .data
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 4
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 3482275674
|
||||
Number: 0
|
||||
- Name: global_foo
|
||||
Value: 0
|
||||
SectionNumber: 4
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: '.text$mn'
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 7
|
||||
NumberOfRelocations: 1
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 3635526833
|
||||
Number: 0
|
||||
- Name: main
|
||||
Value: 0
|
||||
SectionNumber: 5
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
@ -6,7 +6,7 @@
|
||||
# RUN: llvm-pdbutil pdb2yaml -stream-metadata -stream-directory -pdb-stream \
|
||||
# RUN: -dbi-stream -ipi-stream -tpi-stream %t.pdb | FileCheck %s
|
||||
|
||||
# RUN: llvm-pdbutil raw -modules -section-map -section-contribs \
|
||||
# RUN: llvm-pdbutil dump -modules -section-map -section-contribs \
|
||||
# RUN: -types -ids %t.pdb | FileCheck -check-prefix RAW %s
|
||||
|
||||
# CHECK: MSF:
|
||||
@ -22,7 +22,7 @@
|
||||
# CHECK-NEXT: NumStreams:
|
||||
# CHECK-NEXT: FileSize:
|
||||
# CHECK-NEXT: StreamSizes:
|
||||
# CHECK-NEXT: StreamMap:
|
||||
# CHECK: StreamMap:
|
||||
# CHECK: PdbStream:
|
||||
# CHECK-NEXT: Age: 1
|
||||
# CHECK-NEXT: Guid:
|
||||
@ -119,10 +119,10 @@ RAW: Modules
|
||||
RAW-NEXT: ============================================================
|
||||
RAW-NEXT: Mod 0000 | Name: `{{.*}}pdb.test.tmp1.obj`:
|
||||
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`:
|
||||
RAW-NEXT: debug stream: 9, # files: 0, has ec info: false
|
||||
RAW-NEXT: debug stream: 9, # files: 1, has ec info: false
|
||||
RAW-NEXT: Mod 0001 | Name: `{{.*}}pdb.test.tmp2.obj`:
|
||||
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`:
|
||||
RAW-NEXT: debug stream: 10, # files: 0, has ec info: false
|
||||
RAW-NEXT: debug stream: 10, # files: 1, has ec info: false
|
||||
RAW-NEXT: Mod 0002 | Name: `* Linker *`:
|
||||
RAW-NEXT: Obj: ``:
|
||||
RAW-NEXT: debug stream: 11, # files: 0, has ec info: false
|
||||
|
@ -1,5 +1,3 @@
|
||||
# REQUIRES: winres
|
||||
|
||||
# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
|
||||
# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res
|
||||
|
||||
|
60
test/COFF/safeseh.s
Normal file
60
test/COFF/safeseh.s
Normal file
@ -0,0 +1,60 @@
|
||||
# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
|
||||
# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main
|
||||
# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
|
||||
# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:ref -entry:main
|
||||
# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC
|
||||
|
||||
# CHECK-NOGC: LoadConfig [
|
||||
# CHECK-NOGC: Size: 0x48
|
||||
# CHECK-NOGC: SEHandlerTable: 0x401048
|
||||
# CHECK-NOGC: SEHandlerCount: 1
|
||||
# CHECK-NOGC: ]
|
||||
# CHECK-NOGC: SEHTable [
|
||||
# CHECK-NOGC-NEXT: 0x402006
|
||||
# CHECK-NOGC-NEXT: ]
|
||||
|
||||
# CHECK-GC: LoadConfig [
|
||||
# CHECK-GC: Size: 0x48
|
||||
# CHECK-GC: SEHandlerTable: 0x0
|
||||
# CHECK-GC: SEHandlerCount: 0
|
||||
# CHECK-GC: ]
|
||||
# CHECK-GC-NOT: SEHTable
|
||||
|
||||
|
||||
.def @feat.00;
|
||||
.scl 3;
|
||||
.type 0;
|
||||
.endef
|
||||
.globl @feat.00
|
||||
@feat.00 = 1
|
||||
|
||||
.def _main;
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.section .text,"xr",one_only,_main
|
||||
.globl _main
|
||||
_main:
|
||||
movl $42, %eax
|
||||
ret
|
||||
|
||||
# This handler can be GCd, which will make the safeseh table empty, so it should
|
||||
# appear null.
|
||||
.def _my_handler;
|
||||
.scl 3;
|
||||
.type 32;
|
||||
.endef
|
||||
.section .text,"xr",one_only,_my_handler
|
||||
_my_handler:
|
||||
ret
|
||||
|
||||
.safeseh _my_handler
|
||||
|
||||
|
||||
.section .rdata,"dr"
|
||||
.globl __load_config_used
|
||||
__load_config_used:
|
||||
.long 72
|
||||
.fill 60, 1, 0
|
||||
.long ___safe_se_handler_table
|
||||
.long ___safe_se_handler_count
|
33
test/COFF/secidx-absolute.s
Normal file
33
test/COFF/secidx-absolute.s
Normal file
@ -0,0 +1,33 @@
|
||||
# RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj
|
||||
# RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe
|
||||
# RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s
|
||||
|
||||
# Section relocations against absolute symbols resolve to the last real ouput
|
||||
# section index plus one.
|
||||
|
||||
.text
|
||||
.global main
|
||||
main:
|
||||
ret
|
||||
|
||||
.section .rdata,"dr"
|
||||
.secidx __guard_fids_table
|
||||
|
||||
# CHECK: Sections [
|
||||
# CHECK: Section {
|
||||
# CHECK: Number: 1
|
||||
# CHECK: Name: .rdata (2E 72 64 61 74 61 00 00)
|
||||
# CHECK: SectionData (
|
||||
# CHECK: 0000: 0300 |..|
|
||||
# CHECK: )
|
||||
# CHECK: }
|
||||
# CHECK: Section {
|
||||
# CHECK: Number: 2
|
||||
# CHECK: Name: .text (2E 74 65 78 74 00 00 00)
|
||||
# CHECK: VirtualSize: 0x1
|
||||
# CHECK: SectionData (
|
||||
# CHECK: 0000: C3 |.|
|
||||
# CHECK: )
|
||||
# CHECK: }
|
||||
# CHECK-NOT: Section
|
||||
# CHECK: ]
|
14
test/COFF/secrel-absolute.s
Normal file
14
test/COFF/secrel-absolute.s
Normal file
@ -0,0 +1,14 @@
|
||||
# RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj
|
||||
# RUN: not lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe 2>&1 | FileCheck %s
|
||||
|
||||
# secrel relocations against absolute symbols are errors.
|
||||
|
||||
# CHECK: SECREL relocation points to a non-regular symbol: __guard_fids_table
|
||||
|
||||
.text
|
||||
.global main
|
||||
main:
|
||||
ret
|
||||
|
||||
.section .rdata,"dr"
|
||||
.secrel32 __guard_fids_table
|
41
test/COFF/secrel-common.s
Normal file
41
test/COFF/secrel-common.s
Normal file
@ -0,0 +1,41 @@
|
||||
# RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj
|
||||
# RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe
|
||||
# RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s
|
||||
|
||||
# Section relocations against common symbols resolve to .bss.
|
||||
|
||||
# CHECK: Sections [
|
||||
# CHECK: Section {
|
||||
# CHECK: Number: 1
|
||||
# CHECK: Name: .bss (2E 62 73 73 00 00 00 00)
|
||||
# CHECK: VirtualSize: 0x4
|
||||
# CHECK: }
|
||||
# CHECK: Section {
|
||||
# CHECK: Number: 2
|
||||
# CHECK: Name: .rdata (2E 72 64 61 74 61 00 00)
|
||||
# CHECK: SectionData (
|
||||
# CHECK: 0000: 00000000 01000000 |........|
|
||||
# CHECK: )
|
||||
# CHECK: }
|
||||
# CHECK: Section {
|
||||
# CHECK: Number: 3
|
||||
# CHECK: Name: .text (2E 74 65 78 74 00 00 00)
|
||||
# CHECK: VirtualSize: 0x1
|
||||
# CHECK: SectionData (
|
||||
# CHECK: 0000: C3 |.|
|
||||
# CHECK: )
|
||||
# CHECK: }
|
||||
# CHECK-NOT: Section
|
||||
# CHECK: ]
|
||||
|
||||
.text
|
||||
.global main
|
||||
main:
|
||||
ret
|
||||
|
||||
.comm common_global,4,2
|
||||
|
||||
.section .rdata,"dr"
|
||||
.secrel32 common_global
|
||||
.secidx common_global
|
||||
.short 0
|
3
test/ELF/Inputs/exclude-libs.s
Normal file
3
test/ELF/Inputs/exclude-libs.s
Normal file
@ -0,0 +1,3 @@
|
||||
.globl fn
|
||||
fn:
|
||||
nop
|
@ -61,9 +61,9 @@
|
||||
// DISASM: $d:
|
||||
// DISASM-NEXT: 11050: c0 0f 00 00 .word 0x00000fc0
|
||||
// Alignment to 16 byte boundary not strictly necessary on ARM, but harmless
|
||||
// DISASM-NEXT: 11054: 00 00 00 00 .word 0x00000000
|
||||
// DISASM-NEXT: 11058: 00 00 00 00 .word 0x00000000
|
||||
// DISASM-NEXT: 1105c: 00 00 00 00 .word 0x00000000
|
||||
// DISASM-NEXT: 11054: d4 d4 d4 d4 .word 0xd4d4d4d4
|
||||
// DISASM-NEXT: 11058: d4 d4 d4 d4 .word 0xd4d4d4d4
|
||||
// DISASM-NEXT: 1105c: d4 d4 d4 d4 .word 0xd4d4d4d4
|
||||
// DISASM: $a:
|
||||
// DISASM-NEXT: 11060: 04 c0 9f e5 ldr r12, [pc, #4]
|
||||
// DISASM-NEXT: 11064: 0f c0 8c e0 add r12, r12, pc
|
||||
|
@ -16,9 +16,9 @@ _start:
|
||||
bx lr
|
||||
.align 2
|
||||
.LGOT:
|
||||
// gas implicitly uses (GOT_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC
|
||||
// llvm-mc needs the (GOT_PREL) suffix or it generates R_ARM_REL32
|
||||
.word _GLOBAL_OFFSET_TABLE_(GOT_PREL) - (.LPIC+8)
|
||||
// gas implicitly uses (R_ARM_BASE_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC
|
||||
// llvm-mc generates R_ARM_REL32, this will need updating when MC changes
|
||||
.word _GLOBAL_OFFSET_TABLE_ - (.LPIC+8)
|
||||
.word function(GOT)
|
||||
|
||||
.globl function
|
||||
@ -28,17 +28,17 @@ function:
|
||||
bx lr
|
||||
|
||||
// CHECK: Dynamic Relocations {
|
||||
// CHECK-NEXT: 0x204C R_ARM_GLOB_DAT function 0x0
|
||||
// CHECK-NEXT: 0x2048 R_ARM_GLOB_DAT function 0x0
|
||||
|
||||
// CHECK: Name: _GLOBAL_OFFSET_TABLE_
|
||||
// CHECK-NEXT: Value: 0x0
|
||||
// CHECK-NEXT: Value: 0x2048
|
||||
// CHECK-NEXT: Size:
|
||||
// CHECK-NEXT: Binding: Local
|
||||
// CHECK-NEXT: Type: None
|
||||
// CHECK-NEXT: Other [
|
||||
// CHECK-NEXT: STV_HIDDEN
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Section: Absolute
|
||||
// CHECK-NEXT: Section: .got
|
||||
|
||||
// CODE: Disassembly of section .text:
|
||||
// CODE-NEXT: _start:
|
||||
@ -49,5 +49,5 @@ function:
|
||||
// CODE:$d.1:
|
||||
// (_GLOBAL_OFFSET_TABLE_ = 0x2048) - (0x1008 + 8) 0x1038
|
||||
// CODE-NEXT: 1010: 38 10 00 00
|
||||
// (Got(function) - GotBase = 0x4
|
||||
// CODE-NEXT: 1014: 04 00 00 00
|
||||
// (Got(function) - GotBase = 0x0
|
||||
// CODE-NEXT: 1014: 00 00 00 00
|
||||
|
@ -54,7 +54,7 @@ callee_high:
|
||||
// CHECK-NEXT: 1001c: ff f3 fd 97 b.w #16777210
|
||||
// CHECK-NEXT: 10020: 3f f3 ff af bgt.w #1048574
|
||||
// CHECK-NEXT: 10024: 70 47 bx lr
|
||||
// CHECK-NEXT: 10026: 00 00 movs r0, r0
|
||||
// CHECK-NEXT: 10026:
|
||||
// CHECK-NEXT: Disassembly of section .callee2:
|
||||
// CHECK-NEXT: callee_high:
|
||||
// CHECK-NEXT: 10028: 70 47 bx lr
|
||||
|
@ -30,7 +30,7 @@ _start:
|
||||
// CHECK-NEXT: 11002: 70 47 bx lr
|
||||
// CHECK: func3:
|
||||
// CHECK-NEXT: 11004: 70 47 bx lr
|
||||
// CHECK-NEXT: 11006: 00 00 movs r0, r0
|
||||
// CHECK-NEXT: 11006: d4 d4
|
||||
// CHECK: _start:
|
||||
// 11008 + 4 -12 = 0x11000 = func1
|
||||
// CHECK-NEXT: 11008: ff f7 fa ff bl #-12
|
||||
@ -49,7 +49,7 @@ _start:
|
||||
// DSOTHUMB-NEXT: 1002: 70 47 bx lr
|
||||
// DSOTHUMB: func3:
|
||||
// DSOTHUMB-NEXT: 1004: 70 47 bx lr
|
||||
// DSOTHUMB-NEXT: 1006: 00 00 movs r0, r0
|
||||
// DSOTHUMB-NEXT: 1006: d4 d4
|
||||
// DSOTHUMB: _start:
|
||||
// 0x1008 + 0x28 + 4 = 0x1034 = PLT func1
|
||||
// DSOTHUMB-NEXT: 1008: 00 f0 14 e8 blx #40
|
||||
|
@ -9,8 +9,6 @@
|
||||
# RUN: llvm-readobj -t -s %t2 | FileCheck %s
|
||||
# RUN: llvm-objdump -d -print-imm-hex %t2 | FileCheck %s --check-prefix=USE
|
||||
|
||||
## In compare with GNU linkers, symbol defined with --defsym does
|
||||
## not get aliased name in symbol table:
|
||||
# CHECK: Symbol {
|
||||
# CHECK: Name: foo1
|
||||
# CHECK-NEXT: Value: 0x123
|
||||
@ -21,7 +19,7 @@
|
||||
# CHECK-NEXT: Section: Absolute
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: foo1
|
||||
# CHECK-NEXT: Name: foo2
|
||||
# CHECK-NEXT: Value: 0x123
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Binding: Global
|
||||
|
30
test/ELF/exclude-libs.s
Normal file
30
test/ELF/exclude-libs.s
Normal file
@ -0,0 +1,30 @@
|
||||
// REQUIRES: x86
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
|
||||
// RUN: %p/Inputs/exclude-libs.s -o %t2.o
|
||||
// RUN: mkdir -p %t.dir
|
||||
// RUN: rm -f %t.dir/exc.a
|
||||
// RUN: llvm-ar rcs %t.dir/exc.a %t2.o
|
||||
|
||||
// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe
|
||||
// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s
|
||||
|
||||
// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=foo,bar
|
||||
// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s
|
||||
|
||||
// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo,bar,exc.a
|
||||
// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
|
||||
|
||||
// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo:bar:exc.a
|
||||
// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
|
||||
|
||||
// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL
|
||||
// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
|
||||
|
||||
// DEFAULT: Name: fn
|
||||
// EXCLUDE-NOT: Name: fn
|
||||
|
||||
.globl fn
|
||||
foo:
|
||||
call fn@PLT
|
30
test/ELF/global-offset-table-position-aarch64.s
Normal file
30
test/ELF/global-offset-table-position-aarch64.s
Normal file
@ -0,0 +1,30 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t
|
||||
// RUN: ld.lld -shared %t -o %t2
|
||||
// RUN: llvm-readobj -t %t2 | FileCheck %s
|
||||
// REQUIRES: aarch64
|
||||
.globl a
|
||||
.type a,@object
|
||||
.comm a,4,4
|
||||
|
||||
.globl f
|
||||
.type f,@function
|
||||
f:
|
||||
adrp x0, :got:a
|
||||
ldr x0, [x0, #:got_lo12:a]
|
||||
|
||||
.global _start
|
||||
.type _start,@function
|
||||
_start:
|
||||
bl f
|
||||
.data
|
||||
.long _GLOBAL_OFFSET_TABLE_ - .
|
||||
|
||||
// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11)
|
||||
// CHECK-NEXT: Value: 0x30090
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Local (0x0)
|
||||
// CHECK-NEXT: Type: None (0x0)
|
||||
// CHECK-NEXT: Other [ (0x2)
|
||||
// CHECK-NEXT: STV_HIDDEN (0x2)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Section: .got
|
35
test/ELF/global-offset-table-position-arm.s
Normal file
35
test/ELF/global-offset-table-position-arm.s
Normal file
@ -0,0 +1,35 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t
|
||||
// RUN: ld.lld -shared %t -o %t2
|
||||
// RUN: llvm-readobj -t %t2 | FileCheck %s
|
||||
// REQUIRES: arm
|
||||
|
||||
// The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
|
||||
.globl a
|
||||
.type a,%object
|
||||
.comm a,4,4
|
||||
|
||||
.globl f
|
||||
.type f,%function
|
||||
f:
|
||||
ldr r2, .L1
|
||||
.L0:
|
||||
add r2, pc
|
||||
.L1:
|
||||
.word _GLOBAL_OFFSET_TABLE_ - (.L0+4)
|
||||
.word a(GOT)
|
||||
|
||||
.global _start
|
||||
.type _start,%function
|
||||
_start:
|
||||
bl f
|
||||
.data
|
||||
|
||||
// CHECK: Name: _GLOBAL_OFFSET_TABLE_
|
||||
// CHECK-NEXT: Value: 0x3068
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Local
|
||||
// CHECK-NEXT: Type: None
|
||||
// CHECK-NEXT: Other [ (0x2)
|
||||
// CHECK-NEXT: STV_HIDDEN (0x2)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Section: .got
|
31
test/ELF/global-offset-table-position-i386.s
Normal file
31
test/ELF/global-offset-table-position-i386.s
Normal file
@ -0,0 +1,31 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
|
||||
// RUN: ld.lld -shared %t -o %t2
|
||||
// RUN: llvm-readobj -t %t2 | FileCheck %s
|
||||
// REQUIRES: x86
|
||||
|
||||
// The X86 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
|
||||
.globl a
|
||||
.type a,@object
|
||||
.comm a,4,4
|
||||
|
||||
.globl f
|
||||
.type f,@function
|
||||
f:
|
||||
addl $_GLOBAL_OFFSET_TABLE_, %eax
|
||||
movl a@GOT(%eax), %eax
|
||||
|
||||
.global _start
|
||||
.type _start,@function
|
||||
_start:
|
||||
addl $_GLOBAL_OFFSET_TABLE_, %eax
|
||||
calll f@PLT
|
||||
|
||||
// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (1)
|
||||
// CHECK-NEXT: Value: 0x306C
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Local (0x0)
|
||||
// CHECK-NEXT: Type: None (0x0)
|
||||
// CHECK-NEXT: Other [ (0x2)
|
||||
// CHECK-NEXT: STV_HIDDEN (0x2)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Section: .got (0xA)
|
33
test/ELF/global-offset-table-position-mips.s
Normal file
33
test/ELF/global-offset-table-position-mips.s
Normal file
@ -0,0 +1,33 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t
|
||||
// RUN: ld.lld -shared %t -o %t2
|
||||
// RUN: llvm-readobj -t %t2 | FileCheck %s
|
||||
|
||||
// REQUIRES: mips
|
||||
|
||||
// The Mips _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
|
||||
|
||||
.globl a
|
||||
.hidden a
|
||||
.type a,@object
|
||||
.comm a,4,4
|
||||
|
||||
.globl f
|
||||
.type f,@function
|
||||
f:
|
||||
ld $v0,%got_page(a)($gp)
|
||||
daddiu $v0,$v0,%got_ofst(a)
|
||||
|
||||
.global _start
|
||||
.type _start,@function
|
||||
_start:
|
||||
lw $t0,%call16(f)($gp)
|
||||
.word _GLOBAL_OFFSET_TABLE_ - .
|
||||
// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (1)
|
||||
// CHECK-NEXT: Value: 0x20000
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Local (0x0)
|
||||
// CHECK-NEXT: Type: None (0x0)
|
||||
// CHECK-NEXT: Other [ (0x2)
|
||||
// CHECK-NEXT: STV_HIDDEN (0x2)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Section: .got (0x9)
|
31
test/ELF/global-offset-table-position.s
Normal file
31
test/ELF/global-offset-table-position.s
Normal file
@ -0,0 +1,31 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
|
||||
// RUN: ld.lld -shared %t -o %t2
|
||||
// RUN: llvm-readobj -t %t2 | FileCheck %s
|
||||
// REQUIRES: x86
|
||||
|
||||
// The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
|
||||
.globl a
|
||||
.type a,@object
|
||||
.comm a,4,4
|
||||
|
||||
.globl f
|
||||
.type f,@function
|
||||
f:
|
||||
movq a@GOTPCREL(%rip), %rax
|
||||
|
||||
.global _start
|
||||
.type _start,@function
|
||||
_start:
|
||||
callq f@PLT
|
||||
.data
|
||||
.long _GLOBAL_OFFSET_TABLE_ - .
|
||||
|
||||
// CHECK: Name: _GLOBAL_OFFSET_TABLE_
|
||||
// CHECK-NEXT: Value: 0x30D8
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Local
|
||||
// CHECK-NEXT: Type: None (0x0)
|
||||
// CHECK-NEXT: Other [
|
||||
// CHECK-NEXT: STV_HIDDEN
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Section: .got
|
@ -1,9 +1,14 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
|
||||
// RUN: ld.lld -shared %t -o %t2
|
||||
// RUN: llvm-readobj -t %t2 | FileCheck %s
|
||||
.long _GLOBAL_OFFSET_TABLE_
|
||||
.long _GLOBAL_OFFSET_TABLE_ - .
|
||||
|
||||
// CHECK: Name: _GLOBAL_OFFSET_TABLE_
|
||||
// CHECK-NEXT: Value:
|
||||
// CHECK-NEXT: Value: 0x2060
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Local
|
||||
// CHECK-NEXT: Type: None
|
||||
// CHECK-NEXT: Other [ (0x2)
|
||||
// CHECK-NEXT: STV_HIDDEN (0x2)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Section: .got
|
||||
|
9
test/ELF/invalid-z.s
Normal file
9
test/ELF/invalid-z.s
Normal file
@ -0,0 +1,9 @@
|
||||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
# RUN: not ld.lld %t.o -o %t -z max-page-size 2>&1 | FileCheck %s
|
||||
# CHECK: invalid max-page-size
|
||||
# CHECK-NOT: error
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
nop
|
23
test/ELF/linkerscript/discard-section-err.s
Normal file
23
test/ELF/linkerscript/discard-section-err.s
Normal file
@ -0,0 +1,23 @@
|
||||
# REQUIRES: x86
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
|
||||
|
||||
# RUN: echo "SECTIONS { /DISCARD/ : { *(.shstrtab) } }" > %t.script
|
||||
# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | \
|
||||
# RUN: FileCheck -check-prefix=SHSTRTAB %s
|
||||
# SHSTRTAB: discarding .shstrtab section is not allowed
|
||||
|
||||
# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynamic) } }" > %t.script
|
||||
# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
|
||||
# RUN: FileCheck -check-prefix=DYNAMIC %s
|
||||
# DYNAMIC: discarding .dynamic section is not allowed
|
||||
|
||||
# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynsym) } }" > %t.script
|
||||
# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
|
||||
# RUN: FileCheck -check-prefix=DYNSYM %s
|
||||
# DYNSYM: discarding .dynsym section is not allowed
|
||||
|
||||
# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynstr) } }" > %t.script
|
||||
# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
|
||||
# RUN: FileCheck -check-prefix=DYNSTR %s
|
||||
# DYNSTR: discarding .dynstr section is not allowed
|
@ -67,12 +67,6 @@
|
||||
# SEC-SWAP-NAMES: 7 .shstrtab 0000003b {{[0-9a-f]*}}
|
||||
# SEC-SWAP-NAMES: 8 .strtab 00000008 {{[0-9a-f]*}}
|
||||
|
||||
# Attemp to discard .shstrtab section.
|
||||
# RUN: echo "SECTIONS { /DISCARD/ : { *(.shstrtab) } }" > %t.script
|
||||
# RUN: not ld.lld -o %t5 --script %t.script %t 2>&1 | \
|
||||
# RUN: FileCheck -check-prefix=SEC-DISCARD %s
|
||||
# SEC-DISCARD: discarding .shstrtab section is not allowed
|
||||
|
||||
# Multiple SECTIONS command specifying additional input section descriptions
|
||||
# for the same output section description - input sections are merged into
|
||||
# one output section.
|
||||
|
39
test/ELF/linkerscript/segment-none.s
Normal file
39
test/ELF/linkerscript/segment-none.s
Normal file
@ -0,0 +1,39 @@
|
||||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
|
||||
|
||||
## Test that section .foo is not placed in any segment when assigned to segment
|
||||
## NONE in the linker script and segment NONE is not defined.
|
||||
# RUN: echo "PHDRS {text PT_LOAD;} \
|
||||
# RUN: SECTIONS { \
|
||||
# RUN: .text : {*(.text .text*)} :text \
|
||||
# RUN: .foo : {*(.foo)} :NONE \
|
||||
# RUN: }" > %t.script
|
||||
# RUN: ld.lld -o %t --script %t.script %t.o
|
||||
# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s
|
||||
|
||||
## Test that section .foo is placed in segment NONE when assigned to segment
|
||||
## NONE in the linker script and segment NONE is defined.
|
||||
# RUN: echo "PHDRS {text PT_LOAD; NONE PT_LOAD;} \
|
||||
# RUN: SECTIONS { \
|
||||
# RUN: .text : {*(.text .text*)} :text \
|
||||
# RUN: .foo : {*(.foo)} :NONE \
|
||||
# RUN: }" > %t.script
|
||||
# RUN: ld.lld -o %t --script %t.script %t.o
|
||||
# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck --check-prefix=DEFINED %s
|
||||
|
||||
# CHECK: Section to Segment mapping:
|
||||
# CHECK-NEXT: Segment Sections...
|
||||
# CHECK-NOT: .foo
|
||||
|
||||
# DEFINED: Section to Segment mapping:
|
||||
# DEFINED-NEXT: Segment Sections...
|
||||
# DEFINED-NEXT: 00 .text
|
||||
# DEFINED-NEXT: 01 .foo
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
nop
|
||||
|
||||
.section .foo,"a"
|
||||
foo:
|
||||
.long 0
|
11
test/ELF/linkerscript/ttext-script.s
Normal file
11
test/ELF/linkerscript/ttext-script.s
Normal file
@ -0,0 +1,11 @@
|
||||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
# RUN: echo "SECTIONS { .text 0x200000 : { *(.text) } }" > %t.script
|
||||
# RUN: ld.lld -T %t.script -Ttext 0x100000 %t.o -o %t
|
||||
# RUN: llvm-readobj --elf-output-style=GNU -s %t | FileCheck %s
|
||||
|
||||
# CHECK: .text PROGBITS 0000000000100000
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
nop
|
@ -12,6 +12,17 @@
|
||||
; Two cached objects, plus a timestamp file and "foo", minus the file we removed.
|
||||
; RUN: ls %t.cache | count 4
|
||||
|
||||
; Create a file of size 64KB.
|
||||
; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo
|
||||
|
||||
; This should leave the file in place.
|
||||
; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k -o %t3 %t2.o %t.o
|
||||
; RUN: ls %t.cache | count 5
|
||||
|
||||
; This should remove it.
|
||||
; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k -o %t3 %t2.o %t.o
|
||||
; RUN: ls %t.cache | count 4
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
; CHECK: foo:
|
||||
; CHECK-NEXT: pushq %rax
|
||||
; CHECK-NEXT: callq{{.*}}<__wrap_bar>
|
||||
; CHECK-NEXT: callq{{.*}}<bar>
|
||||
; CHECK-NEXT: callq{{.*}}<__real_bar>
|
||||
|
||||
; Check that bar and __wrap_bar retain their original binding.
|
||||
; BIND: Name: bar
|
||||
|
@ -15,8 +15,8 @@
|
||||
# OBJ-NEXT: 00000000: R_MIPS_GOT16 .data
|
||||
# OBJ-NEXT: 4: 27 24 00 00 addiu $4, $25, 0
|
||||
# OBJ-NEXT: 00000004: R_MIPS_LO16 .data
|
||||
# OBJ-NEXT: 8: 00 00 00 00 nop
|
||||
# OBJ-NEXT: c: 00 00 00 00 nop
|
||||
# OBJ-NEXT: 8: ef ef ef ef <unknown>
|
||||
# OBJ-NEXT: c: ef ef ef ef <unknown>
|
||||
# OBJ-NEXT: 10: 8f 99 00 00 lw $25, 0($gp)
|
||||
# OBJ-NEXT: 00000010: R_MIPS_GOT16 .data
|
||||
# OBJ-NEXT: 14: 27 24 00 10 addiu $4, $25, 16
|
||||
@ -26,8 +26,8 @@
|
||||
# SO-NEXT: .text:
|
||||
# SO-NEXT: 10000: 8f 99 80 18 lw $25, -32744($gp)
|
||||
# SO-NEXT: 10004: 27 24 00 00 addiu $4, $25, 0
|
||||
# SO-NEXT: 10008: 00 00 00 00 nop
|
||||
# SO-NEXT: 1000c: 00 00 00 00 nop
|
||||
# SO-NEXT: 10008: ef ef ef ef <unknown>
|
||||
# SO-NEXT: 1000c: ef ef ef ef <unknown>
|
||||
# SO-NEXT: 10010: 8f 99 80 18 lw $25, -32744($gp)
|
||||
# SO-NEXT: 10014: 27 24 00 10 addiu $4, $25, 16
|
||||
|
||||
|
@ -33,8 +33,8 @@
|
||||
# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
|
||||
# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
|
||||
# CHECK-NEXT: 20034: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 20038: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 2003c: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 20038: ef ef ef ef <unknown>
|
||||
# CHECK-NEXT: 2003c: ef ef ef ef <unknown>
|
||||
# CHECK: foo2:
|
||||
# CHECK-NEXT: 20040: 00 00 00 00 nop
|
||||
# CHECK: __LA25Thunk_fpic:
|
||||
@ -42,14 +42,14 @@
|
||||
# CHECK-NEXT: 20048: 08 00 80 18 j 131168 <fpic>
|
||||
# CHECK-NEXT: 2004c: 27 39 00 60 addiu $25, $25, 96
|
||||
# CHECK-NEXT: 20050: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 20054: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 20058: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 2005c: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 20054: ef ef ef ef <unknown>
|
||||
# CHECK-NEXT: 20058: ef ef ef ef <unknown>
|
||||
# CHECK-NEXT: 2005c: ef ef ef ef <unknown>
|
||||
# CHECK: fpic:
|
||||
# CHECK-NEXT: 20060: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 20064: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 20068: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 2006c: 00 00 00 00 nop
|
||||
# CHECK-NEXT: 20064: ef ef ef ef <unknown>
|
||||
# CHECK-NEXT: 20068: ef ef ef ef <unknown>
|
||||
# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
|
||||
# CHECK: fnpic:
|
||||
# CHECK-NEXT: 20070: 00 00 00 00 nop
|
||||
# CHECK-NEXT: Disassembly of section differentos:
|
||||
@ -93,13 +93,13 @@
|
||||
# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
|
||||
# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
|
||||
# REVERSE-NEXT: 20034: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 20038: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 2003c: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 20038: ef ef ef ef <unknown>
|
||||
# REVERSE-NEXT: 2003c: ef ef ef ef <unknown>
|
||||
# REVERSE: foo2:
|
||||
# REVERSE-NEXT: 20040: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 20044: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 20048: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 2004c: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 20044: ef ef ef ef <unknown>
|
||||
# REVERSE-NEXT: 20048: ef ef ef ef <unknown>
|
||||
# REVERSE-NEXT: 2004c: ef ef ef ef <unknown>
|
||||
# REVERSE: __LA25Thunk_fpic:
|
||||
# REVERSE-NEXT: 20050: 3c 19 00 02 lui $25, 2
|
||||
# REVERSE-NEXT: 20054: 08 00 80 18 j 131168 <fpic>
|
||||
@ -107,9 +107,9 @@
|
||||
# REVERSE-NEXT: 2005c: 00 00 00 00 nop
|
||||
# REVERSE: fpic:
|
||||
# REVERSE-NEXT: 20060: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 20064: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 20068: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 2006c: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: 20064: ef ef ef ef <unknown>
|
||||
# REVERSE-NEXT: 20068: ef ef ef ef <unknown>
|
||||
# REVERSE-NEXT: 2006c: ef ef ef ef <unknown>
|
||||
# REVERSE: fnpic:
|
||||
# REVERSE-NEXT: 20070: 00 00 00 00 nop
|
||||
# REVERSE-NEXT: Disassembly of section differentos:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user