Vendor import of lld trunk r306325:

https://llvm.org/svn/llvm-project/lld/trunk@306325
This commit is contained in:
Dimitry Andric 2017-06-26 20:33:45 +00:00
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
106 changed files with 3809 additions and 544 deletions

View File

@ -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() {

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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
};

View File

@ -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
};

View File

@ -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;
}

View File

@ -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:">;

View File

@ -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);

View File

@ -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))

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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>();

View File

@ -1,4 +1,4 @@
//===- Mips.cpp ----------------------------------------------------------===//
//===- MipsArchTree.cpp --------------------------------------------------===//
//
// The LLVM Linker
//

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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
};

View File

@ -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
};

View File

@ -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.

View File

@ -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 {

View File

@ -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

View File

@ -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);

View File

@ -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});

View File

@ -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>;

View File

@ -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,

View File

@ -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;

View File

@ -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>

View File

@ -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);

View 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;

View File

@ -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;

View File

@ -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");
}

View File

@ -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) {

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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
};

View File

@ -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;

View 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

View File

@ -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

View 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
...

View 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
...

View 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
...

View 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
...

View 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

View File

@ -1,5 +1,3 @@
# REQUIRES: winres
# RUN: rm -rf %t
# RUN: mkdir -p %t
# RUN: cd %t

View File

@ -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

View File

@ -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
View 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
...

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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 *`:

View File

@ -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.

View 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
...

View 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
...

View 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: ''

View 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
...

View File

@ -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

View File

@ -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
View 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

View 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: ]

View 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
View 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

View File

@ -0,0 +1,3 @@
.globl fn
fn:
nop

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View 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

View 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

View 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)

View 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)

View 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

View File

@ -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
View 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

View 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

View File

@ -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.

View 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

View 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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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