1ece8a530Spatrick //===- InputFiles.cpp -----------------------------------------------------===//
2ece8a530Spatrick //
3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information.
5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ece8a530Spatrick //
7ece8a530Spatrick //===----------------------------------------------------------------------===//
8ece8a530Spatrick
9ece8a530Spatrick #include "InputFiles.h"
10*dfe94b16Srobert #include "COFFLinkerContext.h"
11ece8a530Spatrick #include "Chunks.h"
12ece8a530Spatrick #include "Config.h"
13ece8a530Spatrick #include "DebugTypes.h"
14ece8a530Spatrick #include "Driver.h"
15ece8a530Spatrick #include "SymbolTable.h"
16ece8a530Spatrick #include "Symbols.h"
17ece8a530Spatrick #include "lld/Common/DWARF.h"
18ece8a530Spatrick #include "llvm-c/lto.h"
19ece8a530Spatrick #include "llvm/ADT/SmallVector.h"
20ece8a530Spatrick #include "llvm/ADT/Triple.h"
21ece8a530Spatrick #include "llvm/ADT/Twine.h"
22ece8a530Spatrick #include "llvm/BinaryFormat/COFF.h"
23ece8a530Spatrick #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
24ece8a530Spatrick #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
25ece8a530Spatrick #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
26ece8a530Spatrick #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
27bb684c34Spatrick #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
28bb684c34Spatrick #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
29ece8a530Spatrick #include "llvm/LTO/LTO.h"
30ece8a530Spatrick #include "llvm/Object/Binary.h"
31ece8a530Spatrick #include "llvm/Object/COFF.h"
32ece8a530Spatrick #include "llvm/Support/Casting.h"
33ece8a530Spatrick #include "llvm/Support/Endian.h"
34ece8a530Spatrick #include "llvm/Support/Error.h"
35ece8a530Spatrick #include "llvm/Support/ErrorOr.h"
36ece8a530Spatrick #include "llvm/Support/FileSystem.h"
37ece8a530Spatrick #include "llvm/Support/Path.h"
38ece8a530Spatrick #include "llvm/Target/TargetOptions.h"
39ece8a530Spatrick #include <cstring>
40*dfe94b16Srobert #include <optional>
41ece8a530Spatrick #include <system_error>
42ece8a530Spatrick #include <utility>
43ece8a530Spatrick
44ece8a530Spatrick using namespace llvm;
45ece8a530Spatrick using namespace llvm::COFF;
46ece8a530Spatrick using namespace llvm::codeview;
47ece8a530Spatrick using namespace llvm::object;
48ece8a530Spatrick using namespace llvm::support::endian;
49bb684c34Spatrick using namespace lld;
50bb684c34Spatrick using namespace lld::coff;
51ece8a530Spatrick
52ece8a530Spatrick using llvm::Triple;
53ece8a530Spatrick using llvm::support::ulittle32_t;
54ece8a530Spatrick
55ece8a530Spatrick // Returns the last element of a path, which is supposed to be a filename.
getBasename(StringRef path)56ece8a530Spatrick static StringRef getBasename(StringRef path) {
57ece8a530Spatrick return sys::path::filename(path, sys::path::Style::windows);
58ece8a530Spatrick }
59ece8a530Spatrick
60ece8a530Spatrick // Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".
toString(const coff::InputFile * file)61bb684c34Spatrick std::string lld::toString(const coff::InputFile *file) {
62ece8a530Spatrick if (!file)
63ece8a530Spatrick return "<internal>";
64ece8a530Spatrick if (file->parentName.empty() || file->kind() == coff::InputFile::ImportKind)
65bb684c34Spatrick return std::string(file->getName());
66ece8a530Spatrick
67ece8a530Spatrick return (getBasename(file->parentName) + "(" + getBasename(file->getName()) +
68ece8a530Spatrick ")")
69ece8a530Spatrick .str();
70ece8a530Spatrick }
71ece8a530Spatrick
72ece8a530Spatrick /// Checks that Source is compatible with being a weak alias to Target.
73ece8a530Spatrick /// If Source is Undefined and has no weak alias set, makes it a weak
74ece8a530Spatrick /// alias to Target.
checkAndSetWeakAlias(COFFLinkerContext & ctx,InputFile * f,Symbol * source,Symbol * target)75*dfe94b16Srobert static void checkAndSetWeakAlias(COFFLinkerContext &ctx, InputFile *f,
76ece8a530Spatrick Symbol *source, Symbol *target) {
77ece8a530Spatrick if (auto *u = dyn_cast<Undefined>(source)) {
78ece8a530Spatrick if (u->weakAlias && u->weakAlias != target) {
79ece8a530Spatrick // Weak aliases as produced by GCC are named in the form
80ece8a530Spatrick // .weak.<weaksymbol>.<othersymbol>, where <othersymbol> is the name
81ece8a530Spatrick // of another symbol emitted near the weak symbol.
82ece8a530Spatrick // Just use the definition from the first object file that defined
83ece8a530Spatrick // this weak symbol.
84*dfe94b16Srobert if (ctx.config.mingw)
85ece8a530Spatrick return;
86*dfe94b16Srobert ctx.symtab.reportDuplicate(source, f);
87ece8a530Spatrick }
88ece8a530Spatrick u->weakAlias = target;
89ece8a530Spatrick }
90ece8a530Spatrick }
91ece8a530Spatrick
ignoredSymbolName(StringRef name)92ece8a530Spatrick static bool ignoredSymbolName(StringRef name) {
93ece8a530Spatrick return name == "@feat.00" || name == "@comp.id";
94ece8a530Spatrick }
95ece8a530Spatrick
ArchiveFile(COFFLinkerContext & ctx,MemoryBufferRef m)96*dfe94b16Srobert ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m)
97*dfe94b16Srobert : InputFile(ctx, ArchiveKind, m) {}
98ece8a530Spatrick
parse()99ece8a530Spatrick void ArchiveFile::parse() {
100ece8a530Spatrick // Parse a MemoryBufferRef as an archive file.
101ece8a530Spatrick file = CHECK(Archive::create(mb), this);
102ece8a530Spatrick
103ece8a530Spatrick // Read the symbol table to construct Lazy objects.
104ece8a530Spatrick for (const Archive::Symbol &sym : file->symbols())
105*dfe94b16Srobert ctx.symtab.addLazyArchive(this, sym);
106ece8a530Spatrick }
107ece8a530Spatrick
108ece8a530Spatrick // Returns a buffer pointing to a member file containing a given symbol.
addMember(const Archive::Symbol & sym)109ece8a530Spatrick void ArchiveFile::addMember(const Archive::Symbol &sym) {
110ece8a530Spatrick const Archive::Child &c =
111ece8a530Spatrick CHECK(sym.getMember(),
112*dfe94b16Srobert "could not get the member for symbol " + toCOFFString(ctx, sym));
113ece8a530Spatrick
114ece8a530Spatrick // Return an empty buffer if we have already returned the same buffer.
115ece8a530Spatrick if (!seen.insert(c.getChildOffset()).second)
116ece8a530Spatrick return;
117ece8a530Spatrick
118*dfe94b16Srobert ctx.driver.enqueueArchiveMember(c, sym, getName());
119ece8a530Spatrick }
120ece8a530Spatrick
getArchiveMembers(Archive * file)121bb684c34Spatrick std::vector<MemoryBufferRef> lld::coff::getArchiveMembers(Archive *file) {
122ece8a530Spatrick std::vector<MemoryBufferRef> v;
123ece8a530Spatrick Error err = Error::success();
124ece8a530Spatrick for (const Archive::Child &c : file->children(err)) {
125ece8a530Spatrick MemoryBufferRef mbref =
126ece8a530Spatrick CHECK(c.getMemoryBufferRef(),
127ece8a530Spatrick file->getFileName() +
128ece8a530Spatrick ": could not get the buffer for a child of the archive");
129ece8a530Spatrick v.push_back(mbref);
130ece8a530Spatrick }
131ece8a530Spatrick if (err)
132ece8a530Spatrick fatal(file->getFileName() +
133ece8a530Spatrick ": Archive::children failed: " + toString(std::move(err)));
134ece8a530Spatrick return v;
135ece8a530Spatrick }
136ece8a530Spatrick
parseLazy()137*dfe94b16Srobert void ObjFile::parseLazy() {
138ece8a530Spatrick // Native object file.
139ece8a530Spatrick std::unique_ptr<Binary> coffObjPtr = CHECK(createBinary(mb), this);
140ece8a530Spatrick COFFObjectFile *coffObj = cast<COFFObjectFile>(coffObjPtr.get());
141ece8a530Spatrick uint32_t numSymbols = coffObj->getNumberOfSymbols();
142ece8a530Spatrick for (uint32_t i = 0; i < numSymbols; ++i) {
143ece8a530Spatrick COFFSymbolRef coffSym = check(coffObj->getSymbol(i));
144ece8a530Spatrick if (coffSym.isUndefined() || !coffSym.isExternal() ||
145ece8a530Spatrick coffSym.isWeakExternal())
146ece8a530Spatrick continue;
147bb684c34Spatrick StringRef name = check(coffObj->getSymbolName(coffSym));
148ece8a530Spatrick if (coffSym.isAbsolute() && ignoredSymbolName(name))
149ece8a530Spatrick continue;
150*dfe94b16Srobert ctx.symtab.addLazyObject(this, name);
151ece8a530Spatrick i += coffSym.getNumberOfAuxSymbols();
152ece8a530Spatrick }
153ece8a530Spatrick }
154ece8a530Spatrick
parse()155ece8a530Spatrick void ObjFile::parse() {
156ece8a530Spatrick // Parse a memory buffer as a COFF file.
157ece8a530Spatrick std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this);
158ece8a530Spatrick
159ece8a530Spatrick if (auto *obj = dyn_cast<COFFObjectFile>(bin.get())) {
160ece8a530Spatrick bin.release();
161ece8a530Spatrick coffObj.reset(obj);
162ece8a530Spatrick } else {
163ece8a530Spatrick fatal(toString(this) + " is not a COFF file");
164ece8a530Spatrick }
165ece8a530Spatrick
166ece8a530Spatrick // Read section and symbol tables.
167ece8a530Spatrick initializeChunks();
168ece8a530Spatrick initializeSymbols();
169ece8a530Spatrick initializeFlags();
170ece8a530Spatrick initializeDependencies();
171ece8a530Spatrick }
172ece8a530Spatrick
getSection(uint32_t i)173ece8a530Spatrick const coff_section *ObjFile::getSection(uint32_t i) {
174bb684c34Spatrick auto sec = coffObj->getSection(i);
175bb684c34Spatrick if (!sec)
176bb684c34Spatrick fatal("getSection failed: #" + Twine(i) + ": " + toString(sec.takeError()));
177bb684c34Spatrick return *sec;
178ece8a530Spatrick }
179ece8a530Spatrick
180ece8a530Spatrick // We set SectionChunk pointers in the SparseChunks vector to this value
181ece8a530Spatrick // temporarily to mark comdat sections as having an unknown resolution. As we
182ece8a530Spatrick // walk the object file's symbol table, once we visit either a leader symbol or
183ece8a530Spatrick // an associative section definition together with the parent comdat's leader,
184ece8a530Spatrick // we set the pointer to either nullptr (to mark the section as discarded) or a
185ece8a530Spatrick // valid SectionChunk for that section.
186ece8a530Spatrick static SectionChunk *const pendingComdat = reinterpret_cast<SectionChunk *>(1);
187ece8a530Spatrick
initializeChunks()188ece8a530Spatrick void ObjFile::initializeChunks() {
189ece8a530Spatrick uint32_t numSections = coffObj->getNumberOfSections();
190ece8a530Spatrick sparseChunks.resize(numSections + 1);
191ece8a530Spatrick for (uint32_t i = 1; i < numSections + 1; ++i) {
192ece8a530Spatrick const coff_section *sec = getSection(i);
193ece8a530Spatrick if (sec->Characteristics & IMAGE_SCN_LNK_COMDAT)
194ece8a530Spatrick sparseChunks[i] = pendingComdat;
195ece8a530Spatrick else
196ece8a530Spatrick sparseChunks[i] = readSection(i, nullptr, "");
197ece8a530Spatrick }
198ece8a530Spatrick }
199ece8a530Spatrick
readSection(uint32_t sectionNumber,const coff_aux_section_definition * def,StringRef leaderName)200ece8a530Spatrick SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
201ece8a530Spatrick const coff_aux_section_definition *def,
202ece8a530Spatrick StringRef leaderName) {
203ece8a530Spatrick const coff_section *sec = getSection(sectionNumber);
204ece8a530Spatrick
205ece8a530Spatrick StringRef name;
206ece8a530Spatrick if (Expected<StringRef> e = coffObj->getSectionName(sec))
207ece8a530Spatrick name = *e;
208ece8a530Spatrick else
209ece8a530Spatrick fatal("getSectionName failed: #" + Twine(sectionNumber) + ": " +
210ece8a530Spatrick toString(e.takeError()));
211ece8a530Spatrick
212ece8a530Spatrick if (name == ".drectve") {
213ece8a530Spatrick ArrayRef<uint8_t> data;
214ece8a530Spatrick cantFail(coffObj->getSectionContents(sec, data));
215ece8a530Spatrick directives = StringRef((const char *)data.data(), data.size());
216ece8a530Spatrick return nullptr;
217ece8a530Spatrick }
218ece8a530Spatrick
219ece8a530Spatrick if (name == ".llvm_addrsig") {
220ece8a530Spatrick addrsigSec = sec;
221ece8a530Spatrick return nullptr;
222ece8a530Spatrick }
223ece8a530Spatrick
2241cf9926bSpatrick if (name == ".llvm.call-graph-profile") {
2251cf9926bSpatrick callgraphSec = sec;
2261cf9926bSpatrick return nullptr;
2271cf9926bSpatrick }
2281cf9926bSpatrick
229ece8a530Spatrick // Object files may have DWARF debug info or MS CodeView debug info
230ece8a530Spatrick // (or both).
231ece8a530Spatrick //
232ece8a530Spatrick // DWARF sections don't need any special handling from the perspective
233ece8a530Spatrick // of the linker; they are just a data section containing relocations.
234ece8a530Spatrick // We can just link them to complete debug info.
235ece8a530Spatrick //
236ece8a530Spatrick // CodeView needs linker support. We need to interpret debug info,
237ece8a530Spatrick // and then write it to a separate .pdb file.
238ece8a530Spatrick
239ece8a530Spatrick // Ignore DWARF debug info unless /debug is given.
240*dfe94b16Srobert if (!ctx.config.debug && name.startswith(".debug_"))
241ece8a530Spatrick return nullptr;
242ece8a530Spatrick
243ece8a530Spatrick if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
244ece8a530Spatrick return nullptr;
245ece8a530Spatrick auto *c = make<SectionChunk>(this, sec);
246ece8a530Spatrick if (def)
247ece8a530Spatrick c->checksum = def->CheckSum;
248ece8a530Spatrick
249ece8a530Spatrick // CodeView sections are stored to a different vector because they are not
250ece8a530Spatrick // linked in the regular manner.
251ece8a530Spatrick if (c->isCodeView())
252ece8a530Spatrick debugChunks.push_back(c);
253ece8a530Spatrick else if (name == ".gfids$y")
254ece8a530Spatrick guardFidChunks.push_back(c);
2551cf9926bSpatrick else if (name == ".giats$y")
2561cf9926bSpatrick guardIATChunks.push_back(c);
257ece8a530Spatrick else if (name == ".gljmp$y")
258ece8a530Spatrick guardLJmpChunks.push_back(c);
2591cf9926bSpatrick else if (name == ".gehcont$y")
2601cf9926bSpatrick guardEHContChunks.push_back(c);
261ece8a530Spatrick else if (name == ".sxdata")
262bb684c34Spatrick sxDataChunks.push_back(c);
263*dfe94b16Srobert else if (ctx.config.tailMerge && sec->NumberOfRelocations == 0 &&
264ece8a530Spatrick name == ".rdata" && leaderName.startswith("??_C@"))
265ece8a530Spatrick // COFF sections that look like string literal sections (i.e. no
266ece8a530Spatrick // relocations, in .rdata, leader symbol name matches the MSVC name mangling
267ece8a530Spatrick // for string literals) are subject to string tail merging.
268*dfe94b16Srobert MergeChunk::addSection(ctx, c);
269ece8a530Spatrick else if (name == ".rsrc" || name.startswith(".rsrc$"))
270ece8a530Spatrick resourceChunks.push_back(c);
271ece8a530Spatrick else
272ece8a530Spatrick chunks.push_back(c);
273ece8a530Spatrick
274ece8a530Spatrick return c;
275ece8a530Spatrick }
276ece8a530Spatrick
includeResourceChunks()277ece8a530Spatrick void ObjFile::includeResourceChunks() {
278ece8a530Spatrick chunks.insert(chunks.end(), resourceChunks.begin(), resourceChunks.end());
279ece8a530Spatrick }
280ece8a530Spatrick
readAssociativeDefinition(COFFSymbolRef sym,const coff_aux_section_definition * def)281ece8a530Spatrick void ObjFile::readAssociativeDefinition(
282ece8a530Spatrick COFFSymbolRef sym, const coff_aux_section_definition *def) {
283ece8a530Spatrick readAssociativeDefinition(sym, def, def->getNumber(sym.isBigObj()));
284ece8a530Spatrick }
285ece8a530Spatrick
readAssociativeDefinition(COFFSymbolRef sym,const coff_aux_section_definition * def,uint32_t parentIndex)286ece8a530Spatrick void ObjFile::readAssociativeDefinition(COFFSymbolRef sym,
287ece8a530Spatrick const coff_aux_section_definition *def,
288ece8a530Spatrick uint32_t parentIndex) {
289ece8a530Spatrick SectionChunk *parent = sparseChunks[parentIndex];
290ece8a530Spatrick int32_t sectionNumber = sym.getSectionNumber();
291ece8a530Spatrick
292ece8a530Spatrick auto diag = [&]() {
293bb684c34Spatrick StringRef name = check(coffObj->getSymbolName(sym));
294ece8a530Spatrick
295bb684c34Spatrick StringRef parentName;
296ece8a530Spatrick const coff_section *parentSec = getSection(parentIndex);
297ece8a530Spatrick if (Expected<StringRef> e = coffObj->getSectionName(parentSec))
298ece8a530Spatrick parentName = *e;
299ece8a530Spatrick error(toString(this) + ": associative comdat " + name + " (sec " +
300ece8a530Spatrick Twine(sectionNumber) + ") has invalid reference to section " +
301ece8a530Spatrick parentName + " (sec " + Twine(parentIndex) + ")");
302ece8a530Spatrick };
303ece8a530Spatrick
304ece8a530Spatrick if (parent == pendingComdat) {
305ece8a530Spatrick // This can happen if an associative comdat refers to another associative
306ece8a530Spatrick // comdat that appears after it (invalid per COFF spec) or to a section
307ece8a530Spatrick // without any symbols.
308ece8a530Spatrick diag();
309ece8a530Spatrick return;
310ece8a530Spatrick }
311ece8a530Spatrick
312ece8a530Spatrick // Check whether the parent is prevailing. If it is, so are we, and we read
313ece8a530Spatrick // the section; otherwise mark it as discarded.
314ece8a530Spatrick if (parent) {
315ece8a530Spatrick SectionChunk *c = readSection(sectionNumber, def, "");
316ece8a530Spatrick sparseChunks[sectionNumber] = c;
317ece8a530Spatrick if (c) {
318ece8a530Spatrick c->selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE;
319ece8a530Spatrick parent->addAssociative(c);
320ece8a530Spatrick }
321ece8a530Spatrick } else {
322ece8a530Spatrick sparseChunks[sectionNumber] = nullptr;
323ece8a530Spatrick }
324ece8a530Spatrick }
325ece8a530Spatrick
recordPrevailingSymbolForMingw(COFFSymbolRef sym,DenseMap<StringRef,uint32_t> & prevailingSectionMap)326ece8a530Spatrick void ObjFile::recordPrevailingSymbolForMingw(
327ece8a530Spatrick COFFSymbolRef sym, DenseMap<StringRef, uint32_t> &prevailingSectionMap) {
328ece8a530Spatrick // For comdat symbols in executable sections, where this is the copy
329ece8a530Spatrick // of the section chunk we actually include instead of discarding it,
330ece8a530Spatrick // add the symbol to a map to allow using it for implicitly
331ece8a530Spatrick // associating .[px]data$<func> sections to it.
332bb684c34Spatrick // Use the suffix from the .text$<func> instead of the leader symbol
333bb684c34Spatrick // name, for cases where the names differ (i386 mangling/decorations,
334bb684c34Spatrick // cases where the leader is a weak symbol named .weak.func.default*).
335ece8a530Spatrick int32_t sectionNumber = sym.getSectionNumber();
336ece8a530Spatrick SectionChunk *sc = sparseChunks[sectionNumber];
337ece8a530Spatrick if (sc && sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) {
338bb684c34Spatrick StringRef name = sc->getSectionName().split('$').second;
339ece8a530Spatrick prevailingSectionMap[name] = sectionNumber;
340ece8a530Spatrick }
341ece8a530Spatrick }
342ece8a530Spatrick
maybeAssociateSEHForMingw(COFFSymbolRef sym,const coff_aux_section_definition * def,const DenseMap<StringRef,uint32_t> & prevailingSectionMap)343ece8a530Spatrick void ObjFile::maybeAssociateSEHForMingw(
344ece8a530Spatrick COFFSymbolRef sym, const coff_aux_section_definition *def,
345ece8a530Spatrick const DenseMap<StringRef, uint32_t> &prevailingSectionMap) {
346bb684c34Spatrick StringRef name = check(coffObj->getSymbolName(sym));
347ece8a530Spatrick if (name.consume_front(".pdata$") || name.consume_front(".xdata$") ||
348ece8a530Spatrick name.consume_front(".eh_frame$")) {
349ece8a530Spatrick // For MinGW, treat .[px]data$<func> and .eh_frame$<func> as implicitly
350ece8a530Spatrick // associative to the symbol <func>.
351ece8a530Spatrick auto parentSym = prevailingSectionMap.find(name);
352ece8a530Spatrick if (parentSym != prevailingSectionMap.end())
353ece8a530Spatrick readAssociativeDefinition(sym, def, parentSym->second);
354ece8a530Spatrick }
355ece8a530Spatrick }
356ece8a530Spatrick
createRegular(COFFSymbolRef sym)357ece8a530Spatrick Symbol *ObjFile::createRegular(COFFSymbolRef sym) {
358ece8a530Spatrick SectionChunk *sc = sparseChunks[sym.getSectionNumber()];
359ece8a530Spatrick if (sym.isExternal()) {
360bb684c34Spatrick StringRef name = check(coffObj->getSymbolName(sym));
361ece8a530Spatrick if (sc)
362*dfe94b16Srobert return ctx.symtab.addRegular(this, name, sym.getGeneric(), sc,
363ece8a530Spatrick sym.getValue());
364ece8a530Spatrick // For MinGW symbols named .weak.* that point to a discarded section,
365ece8a530Spatrick // don't create an Undefined symbol. If nothing ever refers to the symbol,
366ece8a530Spatrick // everything should be fine. If something actually refers to the symbol
367ece8a530Spatrick // (e.g. the undefined weak alias), linking will fail due to undefined
368ece8a530Spatrick // references at the end.
369*dfe94b16Srobert if (ctx.config.mingw && name.startswith(".weak."))
370ece8a530Spatrick return nullptr;
371*dfe94b16Srobert return ctx.symtab.addUndefined(name, this, false);
372ece8a530Spatrick }
373ece8a530Spatrick if (sc)
374ece8a530Spatrick return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
375ece8a530Spatrick /*IsExternal*/ false, sym.getGeneric(), sc);
376ece8a530Spatrick return nullptr;
377ece8a530Spatrick }
378ece8a530Spatrick
initializeSymbols()379ece8a530Spatrick void ObjFile::initializeSymbols() {
380ece8a530Spatrick uint32_t numSymbols = coffObj->getNumberOfSymbols();
381ece8a530Spatrick symbols.resize(numSymbols);
382ece8a530Spatrick
383ece8a530Spatrick SmallVector<std::pair<Symbol *, uint32_t>, 8> weakAliases;
384ece8a530Spatrick std::vector<uint32_t> pendingIndexes;
385ece8a530Spatrick pendingIndexes.reserve(numSymbols);
386ece8a530Spatrick
387ece8a530Spatrick DenseMap<StringRef, uint32_t> prevailingSectionMap;
388ece8a530Spatrick std::vector<const coff_aux_section_definition *> comdatDefs(
389ece8a530Spatrick coffObj->getNumberOfSections() + 1);
390ece8a530Spatrick
391ece8a530Spatrick for (uint32_t i = 0; i < numSymbols; ++i) {
392ece8a530Spatrick COFFSymbolRef coffSym = check(coffObj->getSymbol(i));
393ece8a530Spatrick bool prevailingComdat;
394ece8a530Spatrick if (coffSym.isUndefined()) {
395ece8a530Spatrick symbols[i] = createUndefined(coffSym);
396ece8a530Spatrick } else if (coffSym.isWeakExternal()) {
397ece8a530Spatrick symbols[i] = createUndefined(coffSym);
398ece8a530Spatrick uint32_t tagIndex = coffSym.getAux<coff_aux_weak_external>()->TagIndex;
399ece8a530Spatrick weakAliases.emplace_back(symbols[i], tagIndex);
400*dfe94b16Srobert } else if (std::optional<Symbol *> optSym =
401ece8a530Spatrick createDefined(coffSym, comdatDefs, prevailingComdat)) {
402ece8a530Spatrick symbols[i] = *optSym;
403*dfe94b16Srobert if (ctx.config.mingw && prevailingComdat)
404ece8a530Spatrick recordPrevailingSymbolForMingw(coffSym, prevailingSectionMap);
405ece8a530Spatrick } else {
406*dfe94b16Srobert // createDefined() returns std::nullopt if a symbol belongs to a section
407*dfe94b16Srobert // that was pending at the point when the symbol was read. This can happen
408*dfe94b16Srobert // in two cases:
409ece8a530Spatrick // 1) section definition symbol for a comdat leader;
410ece8a530Spatrick // 2) symbol belongs to a comdat section associated with another section.
411ece8a530Spatrick // In both of these cases, we can expect the section to be resolved by
412ece8a530Spatrick // the time we finish visiting the remaining symbols in the symbol
413ece8a530Spatrick // table. So we postpone the handling of this symbol until that time.
414ece8a530Spatrick pendingIndexes.push_back(i);
415ece8a530Spatrick }
416ece8a530Spatrick i += coffSym.getNumberOfAuxSymbols();
417ece8a530Spatrick }
418ece8a530Spatrick
419ece8a530Spatrick for (uint32_t i : pendingIndexes) {
420ece8a530Spatrick COFFSymbolRef sym = check(coffObj->getSymbol(i));
421ece8a530Spatrick if (const coff_aux_section_definition *def = sym.getSectionDefinition()) {
422ece8a530Spatrick if (def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
423ece8a530Spatrick readAssociativeDefinition(sym, def);
424*dfe94b16Srobert else if (ctx.config.mingw)
425ece8a530Spatrick maybeAssociateSEHForMingw(sym, def, prevailingSectionMap);
426ece8a530Spatrick }
427ece8a530Spatrick if (sparseChunks[sym.getSectionNumber()] == pendingComdat) {
428bb684c34Spatrick StringRef name = check(coffObj->getSymbolName(sym));
429ece8a530Spatrick log("comdat section " + name +
430ece8a530Spatrick " without leader and unassociated, discarding");
431ece8a530Spatrick continue;
432ece8a530Spatrick }
433ece8a530Spatrick symbols[i] = createRegular(sym);
434ece8a530Spatrick }
435ece8a530Spatrick
436ece8a530Spatrick for (auto &kv : weakAliases) {
437ece8a530Spatrick Symbol *sym = kv.first;
438ece8a530Spatrick uint32_t idx = kv.second;
439*dfe94b16Srobert checkAndSetWeakAlias(ctx, this, sym, symbols[idx]);
440ece8a530Spatrick }
441bb684c34Spatrick
442bb684c34Spatrick // Free the memory used by sparseChunks now that symbol loading is finished.
443bb684c34Spatrick decltype(sparseChunks)().swap(sparseChunks);
444ece8a530Spatrick }
445ece8a530Spatrick
createUndefined(COFFSymbolRef sym)446ece8a530Spatrick Symbol *ObjFile::createUndefined(COFFSymbolRef sym) {
447bb684c34Spatrick StringRef name = check(coffObj->getSymbolName(sym));
448*dfe94b16Srobert return ctx.symtab.addUndefined(name, this, sym.isWeakExternal());
449ece8a530Spatrick }
450ece8a530Spatrick
findSectionDef(COFFObjectFile * obj,int32_t section)4511cf9926bSpatrick static const coff_aux_section_definition *findSectionDef(COFFObjectFile *obj,
4521cf9926bSpatrick int32_t section) {
4531cf9926bSpatrick uint32_t numSymbols = obj->getNumberOfSymbols();
4541cf9926bSpatrick for (uint32_t i = 0; i < numSymbols; ++i) {
4551cf9926bSpatrick COFFSymbolRef sym = check(obj->getSymbol(i));
4561cf9926bSpatrick if (sym.getSectionNumber() != section)
4571cf9926bSpatrick continue;
4581cf9926bSpatrick if (const coff_aux_section_definition *def = sym.getSectionDefinition())
4591cf9926bSpatrick return def;
4601cf9926bSpatrick }
4611cf9926bSpatrick return nullptr;
4621cf9926bSpatrick }
4631cf9926bSpatrick
handleComdatSelection(COFFSymbolRef sym,COMDATType & selection,bool & prevailing,DefinedRegular * leader,const llvm::object::coff_aux_section_definition * def)4641cf9926bSpatrick void ObjFile::handleComdatSelection(
4651cf9926bSpatrick COFFSymbolRef sym, COMDATType &selection, bool &prevailing,
4661cf9926bSpatrick DefinedRegular *leader,
4671cf9926bSpatrick const llvm::object::coff_aux_section_definition *def) {
468ece8a530Spatrick if (prevailing)
469ece8a530Spatrick return;
470ece8a530Spatrick // There's already an existing comdat for this symbol: `Leader`.
471ece8a530Spatrick // Use the comdats's selection field to determine if the new
472ece8a530Spatrick // symbol in `Sym` should be discarded, produce a duplicate symbol
473ece8a530Spatrick // error, etc.
474ece8a530Spatrick
4751cf9926bSpatrick SectionChunk *leaderChunk = leader->getChunk();
4761cf9926bSpatrick COMDATType leaderSelection = leaderChunk->selection;
477ece8a530Spatrick
4781cf9926bSpatrick assert(leader->data && "Comdat leader without SectionChunk?");
4791cf9926bSpatrick if (isa<BitcodeFile>(leader->file)) {
4801cf9926bSpatrick // If the leader is only a LTO symbol, we don't know e.g. its final size
4811cf9926bSpatrick // yet, so we can't do the full strict comdat selection checking yet.
4821cf9926bSpatrick selection = leaderSelection = IMAGE_COMDAT_SELECT_ANY;
483ece8a530Spatrick }
484ece8a530Spatrick
485ece8a530Spatrick if ((selection == IMAGE_COMDAT_SELECT_ANY &&
486ece8a530Spatrick leaderSelection == IMAGE_COMDAT_SELECT_LARGEST) ||
487ece8a530Spatrick (selection == IMAGE_COMDAT_SELECT_LARGEST &&
488ece8a530Spatrick leaderSelection == IMAGE_COMDAT_SELECT_ANY)) {
489ece8a530Spatrick // cl.exe picks "any" for vftables when building with /GR- and
490ece8a530Spatrick // "largest" when building with /GR. To be able to link object files
491ece8a530Spatrick // compiled with each flag, "any" and "largest" are merged as "largest".
492ece8a530Spatrick leaderSelection = selection = IMAGE_COMDAT_SELECT_LARGEST;
493ece8a530Spatrick }
494ece8a530Spatrick
495ece8a530Spatrick // GCCs __declspec(selectany) doesn't actually pick "any" but "same size as".
496ece8a530Spatrick // Clang on the other hand picks "any". To be able to link two object files
497ece8a530Spatrick // with a __declspec(selectany) declaration, one compiled with gcc and the
498ece8a530Spatrick // other with clang, we merge them as proper "same size as"
499*dfe94b16Srobert if (ctx.config.mingw && ((selection == IMAGE_COMDAT_SELECT_ANY &&
500ece8a530Spatrick leaderSelection == IMAGE_COMDAT_SELECT_SAME_SIZE) ||
501ece8a530Spatrick (selection == IMAGE_COMDAT_SELECT_SAME_SIZE &&
502ece8a530Spatrick leaderSelection == IMAGE_COMDAT_SELECT_ANY))) {
503ece8a530Spatrick leaderSelection = selection = IMAGE_COMDAT_SELECT_SAME_SIZE;
504ece8a530Spatrick }
505ece8a530Spatrick
506ece8a530Spatrick // Other than that, comdat selections must match. This is a bit more
507ece8a530Spatrick // strict than link.exe which allows merging "any" and "largest" if "any"
508ece8a530Spatrick // is the first symbol the linker sees, and it allows merging "largest"
509ece8a530Spatrick // with everything (!) if "largest" is the first symbol the linker sees.
510ece8a530Spatrick // Making this symmetric independent of which selection is seen first
511ece8a530Spatrick // seems better though.
512ece8a530Spatrick // (This behavior matches ModuleLinker::getComdatResult().)
513ece8a530Spatrick if (selection != leaderSelection) {
514*dfe94b16Srobert log(("conflicting comdat type for " + toString(ctx, *leader) + ": " +
515ece8a530Spatrick Twine((int)leaderSelection) + " in " + toString(leader->getFile()) +
516ece8a530Spatrick " and " + Twine((int)selection) + " in " + toString(this))
517ece8a530Spatrick .str());
518*dfe94b16Srobert ctx.symtab.reportDuplicate(leader, this);
519ece8a530Spatrick return;
520ece8a530Spatrick }
521ece8a530Spatrick
522ece8a530Spatrick switch (selection) {
523ece8a530Spatrick case IMAGE_COMDAT_SELECT_NODUPLICATES:
524*dfe94b16Srobert ctx.symtab.reportDuplicate(leader, this);
525ece8a530Spatrick break;
526ece8a530Spatrick
527ece8a530Spatrick case IMAGE_COMDAT_SELECT_ANY:
528ece8a530Spatrick // Nothing to do.
529ece8a530Spatrick break;
530ece8a530Spatrick
531ece8a530Spatrick case IMAGE_COMDAT_SELECT_SAME_SIZE:
5321cf9926bSpatrick if (leaderChunk->getSize() != getSection(sym)->SizeOfRawData) {
533*dfe94b16Srobert if (!ctx.config.mingw) {
534*dfe94b16Srobert ctx.symtab.reportDuplicate(leader, this);
5351cf9926bSpatrick } else {
5361cf9926bSpatrick const coff_aux_section_definition *leaderDef = nullptr;
5371cf9926bSpatrick if (leaderChunk->file)
5381cf9926bSpatrick leaderDef = findSectionDef(leaderChunk->file->getCOFFObj(),
5391cf9926bSpatrick leaderChunk->getSectionNumber());
5401cf9926bSpatrick if (!leaderDef || leaderDef->Length != def->Length)
541*dfe94b16Srobert ctx.symtab.reportDuplicate(leader, this);
5421cf9926bSpatrick }
5431cf9926bSpatrick }
544ece8a530Spatrick break;
545ece8a530Spatrick
546ece8a530Spatrick case IMAGE_COMDAT_SELECT_EXACT_MATCH: {
547ece8a530Spatrick SectionChunk newChunk(this, getSection(sym));
548ece8a530Spatrick // link.exe only compares section contents here and doesn't complain
549ece8a530Spatrick // if the two comdat sections have e.g. different alignment.
550ece8a530Spatrick // Match that.
551ece8a530Spatrick if (leaderChunk->getContents() != newChunk.getContents())
552*dfe94b16Srobert ctx.symtab.reportDuplicate(leader, this, &newChunk, sym.getValue());
553ece8a530Spatrick break;
554ece8a530Spatrick }
555ece8a530Spatrick
556ece8a530Spatrick case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
557ece8a530Spatrick // createDefined() is never called for IMAGE_COMDAT_SELECT_ASSOCIATIVE.
558ece8a530Spatrick // (This means lld-link doesn't produce duplicate symbol errors for
559ece8a530Spatrick // associative comdats while link.exe does, but associate comdats
560ece8a530Spatrick // are never extern in practice.)
561ece8a530Spatrick llvm_unreachable("createDefined not called for associative comdats");
562ece8a530Spatrick
563ece8a530Spatrick case IMAGE_COMDAT_SELECT_LARGEST:
564ece8a530Spatrick if (leaderChunk->getSize() < getSection(sym)->SizeOfRawData) {
565ece8a530Spatrick // Replace the existing comdat symbol with the new one.
566bb684c34Spatrick StringRef name = check(coffObj->getSymbolName(sym));
567ece8a530Spatrick // FIXME: This is incorrect: With /opt:noref, the previous sections
568ece8a530Spatrick // make it into the final executable as well. Correct handling would
569ece8a530Spatrick // be to undo reading of the whole old section that's being replaced,
570ece8a530Spatrick // or doing one pass that determines what the final largest comdat
571ece8a530Spatrick // is for all IMAGE_COMDAT_SELECT_LARGEST comdats and then reading
572ece8a530Spatrick // only the largest one.
573ece8a530Spatrick replaceSymbol<DefinedRegular>(leader, this, name, /*IsCOMDAT*/ true,
574ece8a530Spatrick /*IsExternal*/ true, sym.getGeneric(),
575ece8a530Spatrick nullptr);
576ece8a530Spatrick prevailing = true;
577ece8a530Spatrick }
578ece8a530Spatrick break;
579ece8a530Spatrick
580ece8a530Spatrick case IMAGE_COMDAT_SELECT_NEWEST:
581ece8a530Spatrick llvm_unreachable("should have been rejected earlier");
582ece8a530Spatrick }
583ece8a530Spatrick }
584ece8a530Spatrick
createDefined(COFFSymbolRef sym,std::vector<const coff_aux_section_definition * > & comdatDefs,bool & prevailing)585*dfe94b16Srobert std::optional<Symbol *> ObjFile::createDefined(
586ece8a530Spatrick COFFSymbolRef sym,
587ece8a530Spatrick std::vector<const coff_aux_section_definition *> &comdatDefs,
588ece8a530Spatrick bool &prevailing) {
589ece8a530Spatrick prevailing = false;
590bb684c34Spatrick auto getName = [&]() { return check(coffObj->getSymbolName(sym)); };
591ece8a530Spatrick
592ece8a530Spatrick if (sym.isCommon()) {
593ece8a530Spatrick auto *c = make<CommonChunk>(sym);
594ece8a530Spatrick chunks.push_back(c);
595*dfe94b16Srobert return ctx.symtab.addCommon(this, getName(), sym.getValue(),
596*dfe94b16Srobert sym.getGeneric(), c);
597ece8a530Spatrick }
598ece8a530Spatrick
599ece8a530Spatrick if (sym.isAbsolute()) {
600ece8a530Spatrick StringRef name = getName();
601ece8a530Spatrick
602ece8a530Spatrick if (name == "@feat.00")
603ece8a530Spatrick feat00Flags = sym.getValue();
604ece8a530Spatrick // Skip special symbols.
605ece8a530Spatrick if (ignoredSymbolName(name))
606ece8a530Spatrick return nullptr;
607ece8a530Spatrick
608ece8a530Spatrick if (sym.isExternal())
609*dfe94b16Srobert return ctx.symtab.addAbsolute(name, sym);
610*dfe94b16Srobert return make<DefinedAbsolute>(ctx, name, sym);
611ece8a530Spatrick }
612ece8a530Spatrick
613ece8a530Spatrick int32_t sectionNumber = sym.getSectionNumber();
614ece8a530Spatrick if (sectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
615ece8a530Spatrick return nullptr;
616ece8a530Spatrick
617ece8a530Spatrick if (llvm::COFF::isReservedSectionNumber(sectionNumber))
618ece8a530Spatrick fatal(toString(this) + ": " + getName() +
619ece8a530Spatrick " should not refer to special section " + Twine(sectionNumber));
620ece8a530Spatrick
621ece8a530Spatrick if ((uint32_t)sectionNumber >= sparseChunks.size())
622ece8a530Spatrick fatal(toString(this) + ": " + getName() +
623ece8a530Spatrick " should not refer to non-existent section " + Twine(sectionNumber));
624ece8a530Spatrick
625ece8a530Spatrick // Comdat handling.
626ece8a530Spatrick // A comdat symbol consists of two symbol table entries.
627ece8a530Spatrick // The first symbol entry has the name of the section (e.g. .text), fixed
628ece8a530Spatrick // values for the other fields, and one auxiliary record.
629ece8a530Spatrick // The second symbol entry has the name of the comdat symbol, called the
630ece8a530Spatrick // "comdat leader".
631ece8a530Spatrick // When this function is called for the first symbol entry of a comdat,
632*dfe94b16Srobert // it sets comdatDefs and returns std::nullopt, and when it's called for the
633*dfe94b16Srobert // second symbol entry it reads comdatDefs and then sets it back to nullptr.
634ece8a530Spatrick
635ece8a530Spatrick // Handle comdat leader.
636ece8a530Spatrick if (const coff_aux_section_definition *def = comdatDefs[sectionNumber]) {
637ece8a530Spatrick comdatDefs[sectionNumber] = nullptr;
638ece8a530Spatrick DefinedRegular *leader;
639ece8a530Spatrick
640ece8a530Spatrick if (sym.isExternal()) {
641ece8a530Spatrick std::tie(leader, prevailing) =
642*dfe94b16Srobert ctx.symtab.addComdat(this, getName(), sym.getGeneric());
643ece8a530Spatrick } else {
644ece8a530Spatrick leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
645ece8a530Spatrick /*IsExternal*/ false, sym.getGeneric());
646ece8a530Spatrick prevailing = true;
647ece8a530Spatrick }
648ece8a530Spatrick
649ece8a530Spatrick if (def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES ||
650ece8a530Spatrick // Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe
651ece8a530Spatrick // doesn't understand IMAGE_COMDAT_SELECT_NEWEST either.
652ece8a530Spatrick def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) {
653ece8a530Spatrick fatal("unknown comdat type " + std::to_string((int)def->Selection) +
654ece8a530Spatrick " for " + getName() + " in " + toString(this));
655ece8a530Spatrick }
656ece8a530Spatrick COMDATType selection = (COMDATType)def->Selection;
657ece8a530Spatrick
658ece8a530Spatrick if (leader->isCOMDAT)
6591cf9926bSpatrick handleComdatSelection(sym, selection, prevailing, leader, def);
660ece8a530Spatrick
661ece8a530Spatrick if (prevailing) {
662ece8a530Spatrick SectionChunk *c = readSection(sectionNumber, def, getName());
663ece8a530Spatrick sparseChunks[sectionNumber] = c;
664ece8a530Spatrick c->sym = cast<DefinedRegular>(leader);
665ece8a530Spatrick c->selection = selection;
666ece8a530Spatrick cast<DefinedRegular>(leader)->data = &c->repl;
667ece8a530Spatrick } else {
668ece8a530Spatrick sparseChunks[sectionNumber] = nullptr;
669ece8a530Spatrick }
670ece8a530Spatrick return leader;
671ece8a530Spatrick }
672ece8a530Spatrick
673ece8a530Spatrick // Prepare to handle the comdat leader symbol by setting the section's
674ece8a530Spatrick // ComdatDefs pointer if we encounter a non-associative comdat.
675ece8a530Spatrick if (sparseChunks[sectionNumber] == pendingComdat) {
676ece8a530Spatrick if (const coff_aux_section_definition *def = sym.getSectionDefinition()) {
677ece8a530Spatrick if (def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE)
678ece8a530Spatrick comdatDefs[sectionNumber] = def;
679ece8a530Spatrick }
680*dfe94b16Srobert return std::nullopt;
681ece8a530Spatrick }
682ece8a530Spatrick
683ece8a530Spatrick return createRegular(sym);
684ece8a530Spatrick }
685ece8a530Spatrick
getMachineType()686ece8a530Spatrick MachineTypes ObjFile::getMachineType() {
687ece8a530Spatrick if (coffObj)
688ece8a530Spatrick return static_cast<MachineTypes>(coffObj->getMachine());
689ece8a530Spatrick return IMAGE_FILE_MACHINE_UNKNOWN;
690ece8a530Spatrick }
691ece8a530Spatrick
getDebugSection(StringRef secName)692ece8a530Spatrick ArrayRef<uint8_t> ObjFile::getDebugSection(StringRef secName) {
693ece8a530Spatrick if (SectionChunk *sec = SectionChunk::findByName(debugChunks, secName))
694ece8a530Spatrick return sec->consumeDebugMagic();
695ece8a530Spatrick return {};
696ece8a530Spatrick }
697ece8a530Spatrick
698ece8a530Spatrick // OBJ files systematically store critical information in a .debug$S stream,
699ece8a530Spatrick // even if the TU was compiled with no debug info. At least two records are
700ece8a530Spatrick // always there. S_OBJNAME stores a 32-bit signature, which is loaded into the
701ece8a530Spatrick // PCHSignature member. S_COMPILE3 stores compile-time cmd-line flags. This is
702ece8a530Spatrick // currently used to initialize the hotPatchable member.
initializeFlags()703ece8a530Spatrick void ObjFile::initializeFlags() {
704ece8a530Spatrick ArrayRef<uint8_t> data = getDebugSection(".debug$S");
705ece8a530Spatrick if (data.empty())
706ece8a530Spatrick return;
707ece8a530Spatrick
708ece8a530Spatrick DebugSubsectionArray subsections;
709ece8a530Spatrick
710ece8a530Spatrick BinaryStreamReader reader(data, support::little);
711ece8a530Spatrick ExitOnError exitOnErr;
712ece8a530Spatrick exitOnErr(reader.readArray(subsections, data.size()));
713ece8a530Spatrick
714ece8a530Spatrick for (const DebugSubsectionRecord &ss : subsections) {
715ece8a530Spatrick if (ss.kind() != DebugSubsectionKind::Symbols)
716ece8a530Spatrick continue;
717ece8a530Spatrick
718ece8a530Spatrick unsigned offset = 0;
719ece8a530Spatrick
720ece8a530Spatrick // Only parse the first two records. We are only looking for S_OBJNAME
721ece8a530Spatrick // and S_COMPILE3, and they usually appear at the beginning of the
722ece8a530Spatrick // stream.
723ece8a530Spatrick for (unsigned i = 0; i < 2; ++i) {
724ece8a530Spatrick Expected<CVSymbol> sym = readSymbolFromStream(ss.getRecordData(), offset);
725ece8a530Spatrick if (!sym) {
726ece8a530Spatrick consumeError(sym.takeError());
727ece8a530Spatrick return;
728ece8a530Spatrick }
729ece8a530Spatrick if (sym->kind() == SymbolKind::S_COMPILE3) {
730ece8a530Spatrick auto cs =
731ece8a530Spatrick cantFail(SymbolDeserializer::deserializeAs<Compile3Sym>(sym.get()));
732ece8a530Spatrick hotPatchable =
733ece8a530Spatrick (cs.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None;
734ece8a530Spatrick }
735ece8a530Spatrick if (sym->kind() == SymbolKind::S_OBJNAME) {
736ece8a530Spatrick auto objName = cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(
737ece8a530Spatrick sym.get()));
738*dfe94b16Srobert if (objName.Signature)
739ece8a530Spatrick pchSignature = objName.Signature;
740ece8a530Spatrick }
741ece8a530Spatrick offset += sym->length();
742ece8a530Spatrick }
743ece8a530Spatrick }
744ece8a530Spatrick }
745ece8a530Spatrick
746ece8a530Spatrick // Depending on the compilation flags, OBJs can refer to external files,
747ece8a530Spatrick // necessary to merge this OBJ into the final PDB. We currently support two
748ece8a530Spatrick // types of external files: Precomp/PCH OBJs, when compiling with /Yc and /Yu.
749ece8a530Spatrick // And PDB type servers, when compiling with /Zi. This function extracts these
750ece8a530Spatrick // dependencies and makes them available as a TpiSource interface (see
751ece8a530Spatrick // DebugTypes.h). Both cases only happen with cl.exe: clang-cl produces regular
752ece8a530Spatrick // output even with /Yc and /Yu and with /Zi.
initializeDependencies()753ece8a530Spatrick void ObjFile::initializeDependencies() {
754*dfe94b16Srobert if (!ctx.config.debug)
755ece8a530Spatrick return;
756ece8a530Spatrick
757ece8a530Spatrick bool isPCH = false;
758ece8a530Spatrick
759ece8a530Spatrick ArrayRef<uint8_t> data = getDebugSection(".debug$P");
760ece8a530Spatrick if (!data.empty())
761ece8a530Spatrick isPCH = true;
762ece8a530Spatrick else
763ece8a530Spatrick data = getDebugSection(".debug$T");
764ece8a530Spatrick
7651cf9926bSpatrick // symbols but no types, make a plain, empty TpiSource anyway, because it
7661cf9926bSpatrick // simplifies adding the symbols later.
7671cf9926bSpatrick if (data.empty()) {
7681cf9926bSpatrick if (!debugChunks.empty())
769*dfe94b16Srobert debugTypesObj = makeTpiSource(ctx, this);
770ece8a530Spatrick return;
7711cf9926bSpatrick }
772ece8a530Spatrick
773bb684c34Spatrick // Get the first type record. It will indicate if this object uses a type
774bb684c34Spatrick // server (/Zi) or a PCH file (/Yu).
775ece8a530Spatrick CVTypeArray types;
776ece8a530Spatrick BinaryStreamReader reader(data, support::little);
777ece8a530Spatrick cantFail(reader.readArray(types, reader.getLength()));
778ece8a530Spatrick CVTypeArray::Iterator firstType = types.begin();
779ece8a530Spatrick if (firstType == types.end())
780ece8a530Spatrick return;
781ece8a530Spatrick
782ece8a530Spatrick // Remember the .debug$T or .debug$P section.
783ece8a530Spatrick debugTypes = data;
784ece8a530Spatrick
785bb684c34Spatrick // This object file is a PCH file that others will depend on.
786ece8a530Spatrick if (isPCH) {
787*dfe94b16Srobert debugTypesObj = makePrecompSource(ctx, this);
788ece8a530Spatrick return;
789ece8a530Spatrick }
790ece8a530Spatrick
791bb684c34Spatrick // This object file was compiled with /Zi. Enqueue the PDB dependency.
792ece8a530Spatrick if (firstType->kind() == LF_TYPESERVER2) {
793ece8a530Spatrick TypeServer2Record ts = cantFail(
794ece8a530Spatrick TypeDeserializer::deserializeAs<TypeServer2Record>(firstType->data()));
795*dfe94b16Srobert debugTypesObj = makeUseTypeServerSource(ctx, this, ts);
796*dfe94b16Srobert enqueuePdbFile(ts.getName(), this);
797ece8a530Spatrick return;
798ece8a530Spatrick }
799ece8a530Spatrick
800bb684c34Spatrick // This object was compiled with /Yu. It uses types from another object file
801bb684c34Spatrick // with a matching signature.
802ece8a530Spatrick if (firstType->kind() == LF_PRECOMP) {
803ece8a530Spatrick PrecompRecord precomp = cantFail(
804ece8a530Spatrick TypeDeserializer::deserializeAs<PrecompRecord>(firstType->data()));
805*dfe94b16Srobert // We're better off trusting the LF_PRECOMP signature. In some cases the
806*dfe94b16Srobert // S_OBJNAME record doesn't contain a valid PCH signature.
807*dfe94b16Srobert if (precomp.Signature)
808*dfe94b16Srobert pchSignature = precomp.Signature;
809*dfe94b16Srobert debugTypesObj = makeUsePrecompSource(ctx, this, precomp);
8101cf9926bSpatrick // Drop the LF_PRECOMP record from the input stream.
8111cf9926bSpatrick debugTypes = debugTypes.drop_front(firstType->RecordData.size());
812ece8a530Spatrick return;
813ece8a530Spatrick }
814ece8a530Spatrick
815bb684c34Spatrick // This is a plain old object file.
816*dfe94b16Srobert debugTypesObj = makeTpiSource(ctx, this);
817ece8a530Spatrick }
818ece8a530Spatrick
819bb684c34Spatrick // Make a PDB path assuming the PDB is in the same folder as the OBJ
getPdbBaseName(ObjFile * file,StringRef tSPath)820bb684c34Spatrick static std::string getPdbBaseName(ObjFile *file, StringRef tSPath) {
821bb684c34Spatrick StringRef localPath =
822bb684c34Spatrick !file->parentName.empty() ? file->parentName : file->getName();
823bb684c34Spatrick SmallString<128> path = sys::path::parent_path(localPath);
824bb684c34Spatrick
825bb684c34Spatrick // Currently, type server PDBs are only created by MSVC cl, which only runs
826bb684c34Spatrick // on Windows, so we can assume type server paths are Windows style.
827bb684c34Spatrick sys::path::append(path,
828bb684c34Spatrick sys::path::filename(tSPath, sys::path::Style::windows));
829bb684c34Spatrick return std::string(path.str());
830bb684c34Spatrick }
831bb684c34Spatrick
832bb684c34Spatrick // The casing of the PDB path stamped in the OBJ can differ from the actual path
833bb684c34Spatrick // on disk. With this, we ensure to always use lowercase as a key for the
834*dfe94b16Srobert // pdbInputFileInstances map, at least on Windows.
normalizePdbPath(StringRef path)835bb684c34Spatrick static std::string normalizePdbPath(StringRef path) {
836bb684c34Spatrick #if defined(_WIN32)
837bb684c34Spatrick return path.lower();
838bb684c34Spatrick #else // LINUX
839bb684c34Spatrick return std::string(path);
840bb684c34Spatrick #endif
841bb684c34Spatrick }
842bb684c34Spatrick
843bb684c34Spatrick // If existing, return the actual PDB path on disk.
findPdbPath(StringRef pdbPath,ObjFile * dependentFile)844*dfe94b16Srobert static std::optional<std::string> findPdbPath(StringRef pdbPath,
845bb684c34Spatrick ObjFile *dependentFile) {
846bb684c34Spatrick // Ensure the file exists before anything else. In some cases, if the path
847bb684c34Spatrick // points to a removable device, Driver::enqueuePath() would fail with an
848bb684c34Spatrick // error (EAGAIN, "resource unavailable try again") which we want to skip
849bb684c34Spatrick // silently.
850bb684c34Spatrick if (llvm::sys::fs::exists(pdbPath))
851bb684c34Spatrick return normalizePdbPath(pdbPath);
852bb684c34Spatrick std::string ret = getPdbBaseName(dependentFile, pdbPath);
853bb684c34Spatrick if (llvm::sys::fs::exists(ret))
854bb684c34Spatrick return normalizePdbPath(ret);
855*dfe94b16Srobert return std::nullopt;
856bb684c34Spatrick }
857bb684c34Spatrick
PDBInputFile(COFFLinkerContext & ctx,MemoryBufferRef m)858*dfe94b16Srobert PDBInputFile::PDBInputFile(COFFLinkerContext &ctx, MemoryBufferRef m)
859*dfe94b16Srobert : InputFile(ctx, PDBKind, m) {}
860bb684c34Spatrick
861bb684c34Spatrick PDBInputFile::~PDBInputFile() = default;
862bb684c34Spatrick
findFromRecordPath(const COFFLinkerContext & ctx,StringRef path,ObjFile * fromFile)863*dfe94b16Srobert PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext &ctx,
864*dfe94b16Srobert StringRef path,
865bb684c34Spatrick ObjFile *fromFile) {
866bb684c34Spatrick auto p = findPdbPath(path.str(), fromFile);
867bb684c34Spatrick if (!p)
868bb684c34Spatrick return nullptr;
869*dfe94b16Srobert auto it = ctx.pdbInputFileInstances.find(*p);
870*dfe94b16Srobert if (it != ctx.pdbInputFileInstances.end())
871bb684c34Spatrick return it->second;
872bb684c34Spatrick return nullptr;
873bb684c34Spatrick }
874bb684c34Spatrick
parse()875bb684c34Spatrick void PDBInputFile::parse() {
876*dfe94b16Srobert ctx.pdbInputFileInstances[mb.getBufferIdentifier().str()] = this;
877bb684c34Spatrick
878bb684c34Spatrick std::unique_ptr<pdb::IPDBSession> thisSession;
879*dfe94b16Srobert Error E = pdb::NativeSession::createFromPdb(
880*dfe94b16Srobert MemoryBuffer::getMemBuffer(mb, false), thisSession);
881*dfe94b16Srobert if (E) {
882*dfe94b16Srobert loadErrorStr.emplace(toString(std::move(E)));
883bb684c34Spatrick return; // fail silently at this point - the error will be handled later,
884bb684c34Spatrick // when merging the debug type stream
885*dfe94b16Srobert }
886bb684c34Spatrick
887bb684c34Spatrick session.reset(static_cast<pdb::NativeSession *>(thisSession.release()));
888bb684c34Spatrick
889bb684c34Spatrick pdb::PDBFile &pdbFile = session->getPDBFile();
890bb684c34Spatrick auto expectedInfo = pdbFile.getPDBInfoStream();
891bb684c34Spatrick // All PDB Files should have an Info stream.
892bb684c34Spatrick if (!expectedInfo) {
893*dfe94b16Srobert loadErrorStr.emplace(toString(expectedInfo.takeError()));
894bb684c34Spatrick return;
895bb684c34Spatrick }
896*dfe94b16Srobert debugTypesObj = makeTypeServerSource(ctx, this);
897bb684c34Spatrick }
898bb684c34Spatrick
899ece8a530Spatrick // Used only for DWARF debug info, which is not common (except in MinGW
900ece8a530Spatrick // environments). This returns an optional pair of file name and line
901ece8a530Spatrick // number for where the variable was defined.
902*dfe94b16Srobert std::optional<std::pair<StringRef, uint32_t>>
getVariableLocation(StringRef var)903ece8a530Spatrick ObjFile::getVariableLocation(StringRef var) {
904ece8a530Spatrick if (!dwarf) {
905ece8a530Spatrick dwarf = make<DWARFCache>(DWARFContext::create(*getCOFFObj()));
906ece8a530Spatrick if (!dwarf)
907*dfe94b16Srobert return std::nullopt;
908ece8a530Spatrick }
909*dfe94b16Srobert if (ctx.config.machine == I386)
910ece8a530Spatrick var.consume_front("_");
911*dfe94b16Srobert std::optional<std::pair<std::string, unsigned>> ret =
912*dfe94b16Srobert dwarf->getVariableLoc(var);
913ece8a530Spatrick if (!ret)
914*dfe94b16Srobert return std::nullopt;
915*dfe94b16Srobert return std::make_pair(saver().save(ret->first), ret->second);
916ece8a530Spatrick }
917ece8a530Spatrick
918ece8a530Spatrick // Used only for DWARF debug info, which is not common (except in MinGW
919ece8a530Spatrick // environments).
getDILineInfo(uint32_t offset,uint32_t sectionIndex)920*dfe94b16Srobert std::optional<DILineInfo> ObjFile::getDILineInfo(uint32_t offset,
921ece8a530Spatrick uint32_t sectionIndex) {
922ece8a530Spatrick if (!dwarf) {
923ece8a530Spatrick dwarf = make<DWARFCache>(DWARFContext::create(*getCOFFObj()));
924ece8a530Spatrick if (!dwarf)
925*dfe94b16Srobert return std::nullopt;
926ece8a530Spatrick }
927ece8a530Spatrick
928ece8a530Spatrick return dwarf->getDILineInfo(offset, sectionIndex);
929ece8a530Spatrick }
930ece8a530Spatrick
enqueuePdbFile(StringRef path,ObjFile * fromFile)931*dfe94b16Srobert void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
932*dfe94b16Srobert auto p = findPdbPath(path.str(), fromFile);
933*dfe94b16Srobert if (!p)
934*dfe94b16Srobert return;
935*dfe94b16Srobert auto it = ctx.pdbInputFileInstances.emplace(*p, nullptr);
936*dfe94b16Srobert if (!it.second)
937*dfe94b16Srobert return; // already scheduled for load
938*dfe94b16Srobert ctx.driver.enqueuePDB(*p);
939*dfe94b16Srobert }
940*dfe94b16Srobert
ImportFile(COFFLinkerContext & ctx,MemoryBufferRef m)941*dfe94b16Srobert ImportFile::ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m)
942*dfe94b16Srobert : InputFile(ctx, ImportKind, m), live(!ctx.config.doGC), thunkLive(live) {}
943*dfe94b16Srobert
parse()944ece8a530Spatrick void ImportFile::parse() {
945ece8a530Spatrick const char *buf = mb.getBufferStart();
946ece8a530Spatrick const auto *hdr = reinterpret_cast<const coff_import_header *>(buf);
947ece8a530Spatrick
948ece8a530Spatrick // Check if the total size is valid.
949ece8a530Spatrick if (mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData)
950ece8a530Spatrick fatal("broken import library");
951ece8a530Spatrick
952ece8a530Spatrick // Read names and create an __imp_ symbol.
953*dfe94b16Srobert StringRef name = saver().save(StringRef(buf + sizeof(*hdr)));
954*dfe94b16Srobert StringRef impName = saver().save("__imp_" + name);
955ece8a530Spatrick const char *nameStart = buf + sizeof(coff_import_header) + name.size() + 1;
956bb684c34Spatrick dllName = std::string(StringRef(nameStart));
957ece8a530Spatrick StringRef extName;
958ece8a530Spatrick switch (hdr->getNameType()) {
959ece8a530Spatrick case IMPORT_ORDINAL:
960ece8a530Spatrick extName = "";
961ece8a530Spatrick break;
962ece8a530Spatrick case IMPORT_NAME:
963ece8a530Spatrick extName = name;
964ece8a530Spatrick break;
965ece8a530Spatrick case IMPORT_NAME_NOPREFIX:
966ece8a530Spatrick extName = ltrim1(name, "?@_");
967ece8a530Spatrick break;
968ece8a530Spatrick case IMPORT_NAME_UNDECORATE:
969ece8a530Spatrick extName = ltrim1(name, "?@_");
970ece8a530Spatrick extName = extName.substr(0, extName.find('@'));
971ece8a530Spatrick break;
972ece8a530Spatrick }
973ece8a530Spatrick
974ece8a530Spatrick this->hdr = hdr;
975ece8a530Spatrick externalName = extName;
976ece8a530Spatrick
977*dfe94b16Srobert impSym = ctx.symtab.addImportData(impName, this);
978ece8a530Spatrick // If this was a duplicate, we logged an error but may continue;
979ece8a530Spatrick // in this case, impSym is nullptr.
980ece8a530Spatrick if (!impSym)
981ece8a530Spatrick return;
982ece8a530Spatrick
983ece8a530Spatrick if (hdr->getType() == llvm::COFF::IMPORT_CONST)
984*dfe94b16Srobert static_cast<void>(ctx.symtab.addImportData(name, this));
985ece8a530Spatrick
986ece8a530Spatrick // If type is function, we need to create a thunk which jump to an
987ece8a530Spatrick // address pointed by the __imp_ symbol. (This allows you to call
988ece8a530Spatrick // DLL functions just like regular non-DLL functions.)
989ece8a530Spatrick if (hdr->getType() == llvm::COFF::IMPORT_CODE)
990*dfe94b16Srobert thunkSym = ctx.symtab.addImportThunk(
991ece8a530Spatrick name, cast_or_null<DefinedImportData>(impSym), hdr->Machine);
992ece8a530Spatrick }
993ece8a530Spatrick
BitcodeFile(COFFLinkerContext & ctx,MemoryBufferRef mb,StringRef archiveName,uint64_t offsetInArchive,bool lazy)994*dfe94b16Srobert BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
995*dfe94b16Srobert StringRef archiveName, uint64_t offsetInArchive,
996*dfe94b16Srobert bool lazy)
997*dfe94b16Srobert : InputFile(ctx, BitcodeKind, mb, lazy) {
998ece8a530Spatrick std::string path = mb.getBufferIdentifier().str();
999*dfe94b16Srobert if (ctx.config.thinLTOIndexOnly)
1000*dfe94b16Srobert path = replaceThinLTOSuffix(mb.getBufferIdentifier(),
1001*dfe94b16Srobert ctx.config.thinLTOObjectSuffixReplace.first,
1002*dfe94b16Srobert ctx.config.thinLTOObjectSuffixReplace.second);
1003ece8a530Spatrick
1004ece8a530Spatrick // ThinLTO assumes that all MemoryBufferRefs given to it have a unique
1005ece8a530Spatrick // name. If two archives define two members with the same name, this
1006ece8a530Spatrick // causes a collision which result in only one of the objects being taken
1007ece8a530Spatrick // into consideration at LTO time (which very likely causes undefined
1008ece8a530Spatrick // symbols later in the link stage). So we append file offset to make
1009ece8a530Spatrick // filename unique.
1010*dfe94b16Srobert MemoryBufferRef mbref(mb.getBuffer(),
1011*dfe94b16Srobert saver().save(archiveName.empty()
1012*dfe94b16Srobert ? path
1013*dfe94b16Srobert : archiveName +
1014*dfe94b16Srobert sys::path::filename(path) +
1015bb684c34Spatrick utostr(offsetInArchive)));
1016ece8a530Spatrick
1017ece8a530Spatrick obj = check(lto::InputFile::create(mbref));
1018ece8a530Spatrick }
1019ece8a530Spatrick
1020ece8a530Spatrick BitcodeFile::~BitcodeFile() = default;
1021ece8a530Spatrick
parse()1022ece8a530Spatrick void BitcodeFile::parse() {
1023*dfe94b16Srobert llvm::StringSaver &saver = lld::saver();
1024*dfe94b16Srobert
1025ece8a530Spatrick std::vector<std::pair<Symbol *, bool>> comdat(obj->getComdatTable().size());
1026ece8a530Spatrick for (size_t i = 0; i != obj->getComdatTable().size(); ++i)
10271cf9926bSpatrick // FIXME: Check nodeduplicate
10281cf9926bSpatrick comdat[i] =
1029*dfe94b16Srobert ctx.symtab.addComdat(this, saver.save(obj->getComdatTable()[i].first));
1030ece8a530Spatrick for (const lto::InputFile::Symbol &objSym : obj->symbols()) {
1031ece8a530Spatrick StringRef symName = saver.save(objSym.getName());
1032ece8a530Spatrick int comdatIndex = objSym.getComdatIndex();
1033ece8a530Spatrick Symbol *sym;
10341cf9926bSpatrick SectionChunk *fakeSC = nullptr;
10351cf9926bSpatrick if (objSym.isExecutable())
1036*dfe94b16Srobert fakeSC = &ctx.ltoTextSectionChunk.chunk;
10371cf9926bSpatrick else
1038*dfe94b16Srobert fakeSC = &ctx.ltoDataSectionChunk.chunk;
1039ece8a530Spatrick if (objSym.isUndefined()) {
1040*dfe94b16Srobert sym = ctx.symtab.addUndefined(symName, this, false);
1041ece8a530Spatrick } else if (objSym.isCommon()) {
1042*dfe94b16Srobert sym = ctx.symtab.addCommon(this, symName, objSym.getCommonSize());
1043ece8a530Spatrick } else if (objSym.isWeak() && objSym.isIndirect()) {
1044ece8a530Spatrick // Weak external.
1045*dfe94b16Srobert sym = ctx.symtab.addUndefined(symName, this, true);
1046bb684c34Spatrick std::string fallback = std::string(objSym.getCOFFWeakExternalFallback());
1047*dfe94b16Srobert Symbol *alias = ctx.symtab.addUndefined(saver.save(fallback));
1048*dfe94b16Srobert checkAndSetWeakAlias(ctx, this, sym, alias);
1049ece8a530Spatrick } else if (comdatIndex != -1) {
10501cf9926bSpatrick if (symName == obj->getComdatTable()[comdatIndex].first) {
1051ece8a530Spatrick sym = comdat[comdatIndex].first;
10521cf9926bSpatrick if (cast<DefinedRegular>(sym)->data == nullptr)
10531cf9926bSpatrick cast<DefinedRegular>(sym)->data = &fakeSC->repl;
10541cf9926bSpatrick } else if (comdat[comdatIndex].second) {
1055*dfe94b16Srobert sym = ctx.symtab.addRegular(this, symName, nullptr, fakeSC);
1056ece8a530Spatrick } else {
1057*dfe94b16Srobert sym = ctx.symtab.addUndefined(symName, this, false);
10581cf9926bSpatrick }
10591cf9926bSpatrick } else {
1060*dfe94b16Srobert sym = ctx.symtab.addRegular(this, symName, nullptr, fakeSC, 0,
1061*dfe94b16Srobert objSym.isWeak());
1062ece8a530Spatrick }
1063ece8a530Spatrick symbols.push_back(sym);
1064ece8a530Spatrick if (objSym.isUsed())
1065*dfe94b16Srobert ctx.config.gcroot.push_back(sym);
1066ece8a530Spatrick }
1067ece8a530Spatrick directives = obj->getCOFFLinkerOpts();
1068ece8a530Spatrick }
1069ece8a530Spatrick
parseLazy()1070*dfe94b16Srobert void BitcodeFile::parseLazy() {
1071*dfe94b16Srobert for (const lto::InputFile::Symbol &sym : obj->symbols())
1072*dfe94b16Srobert if (!sym.isUndefined())
1073*dfe94b16Srobert ctx.symtab.addLazyObject(this, sym.getName());
1074*dfe94b16Srobert }
1075*dfe94b16Srobert
getMachineType()1076ece8a530Spatrick MachineTypes BitcodeFile::getMachineType() {
1077ece8a530Spatrick switch (Triple(obj->getTargetTriple()).getArch()) {
1078ece8a530Spatrick case Triple::x86_64:
1079ece8a530Spatrick return AMD64;
1080ece8a530Spatrick case Triple::x86:
1081ece8a530Spatrick return I386;
1082ece8a530Spatrick case Triple::arm:
1083ece8a530Spatrick return ARMNT;
1084ece8a530Spatrick case Triple::aarch64:
1085ece8a530Spatrick return ARM64;
1086ece8a530Spatrick default:
1087ece8a530Spatrick return IMAGE_FILE_MACHINE_UNKNOWN;
1088ece8a530Spatrick }
1089ece8a530Spatrick }
1090ece8a530Spatrick
replaceThinLTOSuffix(StringRef path,StringRef suffix,StringRef repl)1091*dfe94b16Srobert std::string lld::coff::replaceThinLTOSuffix(StringRef path, StringRef suffix,
1092*dfe94b16Srobert StringRef repl) {
1093ece8a530Spatrick if (path.consume_back(suffix))
1094ece8a530Spatrick return (path + repl).str();
1095bb684c34Spatrick return std::string(path);
1096ece8a530Spatrick }
10971cf9926bSpatrick
isRVACode(COFFObjectFile * coffObj,uint64_t rva,InputFile * file)10981cf9926bSpatrick static bool isRVACode(COFFObjectFile *coffObj, uint64_t rva, InputFile *file) {
10991cf9926bSpatrick for (size_t i = 1, e = coffObj->getNumberOfSections(); i <= e; i++) {
11001cf9926bSpatrick const coff_section *sec = CHECK(coffObj->getSection(i), file);
11011cf9926bSpatrick if (rva >= sec->VirtualAddress &&
11021cf9926bSpatrick rva <= sec->VirtualAddress + sec->VirtualSize) {
11031cf9926bSpatrick return (sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE) != 0;
11041cf9926bSpatrick }
11051cf9926bSpatrick }
11061cf9926bSpatrick return false;
11071cf9926bSpatrick }
11081cf9926bSpatrick
parse()11091cf9926bSpatrick void DLLFile::parse() {
11101cf9926bSpatrick // Parse a memory buffer as a PE-COFF executable.
11111cf9926bSpatrick std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this);
11121cf9926bSpatrick
11131cf9926bSpatrick if (auto *obj = dyn_cast<COFFObjectFile>(bin.get())) {
11141cf9926bSpatrick bin.release();
11151cf9926bSpatrick coffObj.reset(obj);
11161cf9926bSpatrick } else {
11171cf9926bSpatrick error(toString(this) + " is not a COFF file");
11181cf9926bSpatrick return;
11191cf9926bSpatrick }
11201cf9926bSpatrick
11211cf9926bSpatrick if (!coffObj->getPE32Header() && !coffObj->getPE32PlusHeader()) {
11221cf9926bSpatrick error(toString(this) + " is not a PE-COFF executable");
11231cf9926bSpatrick return;
11241cf9926bSpatrick }
11251cf9926bSpatrick
11261cf9926bSpatrick for (const auto &exp : coffObj->export_directories()) {
11271cf9926bSpatrick StringRef dllName, symbolName;
11281cf9926bSpatrick uint32_t exportRVA;
11291cf9926bSpatrick checkError(exp.getDllName(dllName));
11301cf9926bSpatrick checkError(exp.getSymbolName(symbolName));
11311cf9926bSpatrick checkError(exp.getExportRVA(exportRVA));
11321cf9926bSpatrick
11331cf9926bSpatrick if (symbolName.empty())
11341cf9926bSpatrick continue;
11351cf9926bSpatrick
11361cf9926bSpatrick bool code = isRVACode(coffObj.get(), exportRVA, this);
11371cf9926bSpatrick
11381cf9926bSpatrick Symbol *s = make<Symbol>();
11391cf9926bSpatrick s->dllName = dllName;
11401cf9926bSpatrick s->symbolName = symbolName;
11411cf9926bSpatrick s->importType = code ? ImportType::IMPORT_CODE : ImportType::IMPORT_DATA;
11421cf9926bSpatrick s->nameType = ImportNameType::IMPORT_NAME;
11431cf9926bSpatrick
11441cf9926bSpatrick if (coffObj->getMachine() == I386) {
1145*dfe94b16Srobert s->symbolName = symbolName = saver().save("_" + symbolName);
11461cf9926bSpatrick s->nameType = ImportNameType::IMPORT_NAME_NOPREFIX;
11471cf9926bSpatrick }
11481cf9926bSpatrick
1149*dfe94b16Srobert StringRef impName = saver().save("__imp_" + symbolName);
1150*dfe94b16Srobert ctx.symtab.addLazyDLLSymbol(this, s, impName);
11511cf9926bSpatrick if (code)
1152*dfe94b16Srobert ctx.symtab.addLazyDLLSymbol(this, s, symbolName);
11531cf9926bSpatrick }
11541cf9926bSpatrick }
11551cf9926bSpatrick
getMachineType()11561cf9926bSpatrick MachineTypes DLLFile::getMachineType() {
11571cf9926bSpatrick if (coffObj)
11581cf9926bSpatrick return static_cast<MachineTypes>(coffObj->getMachine());
11591cf9926bSpatrick return IMAGE_FILE_MACHINE_UNKNOWN;
11601cf9926bSpatrick }
11611cf9926bSpatrick
makeImport(DLLFile::Symbol * s)11621cf9926bSpatrick void DLLFile::makeImport(DLLFile::Symbol *s) {
11631cf9926bSpatrick if (!seen.insert(s->symbolName).second)
11641cf9926bSpatrick return;
11651cf9926bSpatrick
11661cf9926bSpatrick size_t impSize = s->dllName.size() + s->symbolName.size() + 2; // +2 for NULs
11671cf9926bSpatrick size_t size = sizeof(coff_import_header) + impSize;
1168*dfe94b16Srobert char *buf = bAlloc().Allocate<char>(size);
11691cf9926bSpatrick memset(buf, 0, size);
11701cf9926bSpatrick char *p = buf;
11711cf9926bSpatrick auto *imp = reinterpret_cast<coff_import_header *>(p);
11721cf9926bSpatrick p += sizeof(*imp);
11731cf9926bSpatrick imp->Sig2 = 0xFFFF;
11741cf9926bSpatrick imp->Machine = coffObj->getMachine();
11751cf9926bSpatrick imp->SizeOfData = impSize;
11761cf9926bSpatrick imp->OrdinalHint = 0; // Only linking by name
11771cf9926bSpatrick imp->TypeInfo = (s->nameType << 2) | s->importType;
11781cf9926bSpatrick
11791cf9926bSpatrick // Write symbol name and DLL name.
11801cf9926bSpatrick memcpy(p, s->symbolName.data(), s->symbolName.size());
11811cf9926bSpatrick p += s->symbolName.size() + 1;
11821cf9926bSpatrick memcpy(p, s->dllName.data(), s->dllName.size());
11831cf9926bSpatrick MemoryBufferRef mbref = MemoryBufferRef(StringRef(buf, size), s->dllName);
1184*dfe94b16Srobert ImportFile *impFile = make<ImportFile>(ctx, mbref);
1185*dfe94b16Srobert ctx.symtab.addFile(impFile);
11861cf9926bSpatrick }
1187