Bug Summary

File:tools/lld/COFF/InputFiles.cpp
Warning:line 195, column 11
Called C++ object pointer is null

Annotated Source Code

1//===- InputFiles.cpp -----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "InputFiles.h"
11#include "Chunks.h"
12#include "Config.h"
13#include "Driver.h"
14#include "Memory.h"
15#include "SymbolTable.h"
16#include "Symbols.h"
17#include "lld/Common/ErrorHandler.h"
18#include "llvm-c/lto.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/Triple.h"
21#include "llvm/ADT/Twine.h"
22#include "llvm/BinaryFormat/COFF.h"
23#include "llvm/Object/Binary.h"
24#include "llvm/Object/COFF.h"
25#include "llvm/Support/Casting.h"
26#include "llvm/Support/Endian.h"
27#include "llvm/Support/Error.h"
28#include "llvm/Support/ErrorOr.h"
29#include "llvm/Support/FileSystem.h"
30#include "llvm/Target/TargetOptions.h"
31#include <cstring>
32#include <system_error>
33#include <utility>
34
35using namespace llvm;
36using namespace llvm::COFF;
37using namespace llvm::object;
38using namespace llvm::support::endian;
39
40using llvm::Triple;
41using llvm::support::ulittle32_t;
42
43namespace lld {
44namespace coff {
45
46std::vector<ObjFile *> ObjFile::Instances;
47std::vector<ImportFile *> ImportFile::Instances;
48std::vector<BitcodeFile *> BitcodeFile::Instances;
49
50/// Checks that Source is compatible with being a weak alias to Target.
51/// If Source is Undefined and has no weak alias set, makes it a weak
52/// alias to Target.
53static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F,
54 Symbol *Source, Symbol *Target) {
55 if (auto *U = dyn_cast<Undefined>(Source)) {
56 if (U->WeakAlias && U->WeakAlias != Target)
57 Symtab->reportDuplicate(Source, F);
58 U->WeakAlias = Target;
59 }
60}
61
62ArchiveFile::ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
63
64void ArchiveFile::parse() {
65 // Parse a MemoryBufferRef as an archive file.
66 File = check(Archive::create(MB), toString(this));
67
68 // Read the symbol table to construct Lazy objects.
69 for (const Archive::Symbol &Sym : File->symbols())
70 Symtab->addLazy(this, Sym);
71}
72
73// Returns a buffer pointing to a member file containing a given symbol.
74void ArchiveFile::addMember(const Archive::Symbol *Sym) {
75 const Archive::Child &C =
76 check(Sym->getMember(),
77 "could not get the member for symbol " + Sym->getName());
78
79 // Return an empty buffer if we have already returned the same buffer.
80 if (!Seen.insert(C.getChildOffset()).second)
81 return;
82
83 Driver->enqueueArchiveMember(C, Sym->getName(), getName());
84}
85
86std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) {
87 std::vector<MemoryBufferRef> V;
88 Error Err = Error::success();
89 for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
90 Archive::Child C =
91 check(COrErr,
92 File->getFileName() + ": could not get the child of the archive");
93 MemoryBufferRef MBRef =
94 check(C.getMemoryBufferRef(),
95 File->getFileName() +
96 ": could not get the buffer for a child of the archive");
97 V.push_back(MBRef);
98 }
99 if (Err)
100 fatal(File->getFileName() +
101 ": Archive::children failed: " + toString(std::move(Err)));
102 return V;
103}
104
105void ObjFile::parse() {
106 // Parse a memory buffer as a COFF file.
107 std::unique_ptr<Binary> Bin = check(createBinary(MB), toString(this));
108
109 if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) {
1
Assuming 'Obj' is non-null
2
Taking true branch
110 Bin.release();
111 COFFObj.reset(Obj);
112 } else {
113 fatal(toString(this) + " is not a COFF file");
114 }
115
116 // Read section and symbol tables.
117 initializeChunks();
118 initializeSymbols();
3
Calling 'ObjFile::initializeSymbols'
119 initializeSEH();
120}
121
122void ObjFile::initializeChunks() {
123 uint32_t NumSections = COFFObj->getNumberOfSections();
124 Chunks.reserve(NumSections);
125 SparseChunks.resize(NumSections + 1);
126 for (uint32_t I = 1; I < NumSections + 1; ++I) {
127 const coff_section *Sec;
128 StringRef Name;
129 if (auto EC = COFFObj->getSection(I, Sec))
130 fatal("getSection failed: #" + Twine(I) + ": " + EC.message());
131 if (auto EC = COFFObj->getSectionName(Sec, Name))
132 fatal("getSectionName failed: #" + Twine(I) + ": " + EC.message());
133 if (Name == ".sxdata") {
134 SXData = Sec;
135 continue;
136 }
137 if (Name == ".drectve") {
138 ArrayRef<uint8_t> Data;
139 COFFObj->getSectionContents(Sec, Data);
140 Directives = std::string((const char *)Data.data(), Data.size());
141 continue;
142 }
143
144 // Object files may have DWARF debug info or MS CodeView debug info
145 // (or both).
146 //
147 // DWARF sections don't need any special handling from the perspective
148 // of the linker; they are just a data section containing relocations.
149 // We can just link them to complete debug info.
150 //
151 // CodeView needs a linker support. We need to interpret and debug
152 // info, and then write it to a separate .pdb file.
153
154 // Ignore debug info unless /debug is given.
155 if (!Config->Debug && Name.startswith(".debug"))
156 continue;
157
158 if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
159 continue;
160 auto *C = make<SectionChunk>(this, Sec);
161
162 // CodeView sections are stored to a different vector because they are not
163 // linked in the regular manner.
164 if (C->isCodeView())
165 DebugChunks.push_back(C);
166 else
167 Chunks.push_back(C);
168
169 SparseChunks[I] = C;
170 }
171}
172
173void ObjFile::initializeSymbols() {
174 uint32_t NumSymbols = COFFObj->getNumberOfSymbols();
175 SymbolBodies.reserve(NumSymbols);
176 SparseSymbolBodies.resize(NumSymbols);
177
178 SmallVector<std::pair<Symbol *, uint32_t>, 8> WeakAliases;
179 int32_t LastSectionNumber = 0;
180
181 for (uint32_t I = 0; I < NumSymbols; ++I) {
4
Assuming 'I' is < 'NumSymbols'
5
Loop condition is true. Entering loop body
12
Loop condition is true. Entering loop body
18
Loop condition is true. Entering loop body
24
Loop condition is true. Entering loop body
182 COFFSymbolRef COFFSym = check(COFFObj->getSymbol(I));
183
184 const void *AuxP = nullptr;
25
'AuxP' initialized to a null pointer value
185 if (COFFSym.getNumberOfAuxSymbols())
6
Taking false branch
13
Taking false branch
19
Taking false branch
26
Taking false branch
186 AuxP = check(COFFObj->getSymbol(I + 1)).getRawPtr();
187 bool IsFirst = (LastSectionNumber != COFFSym.getSectionNumber());
7
Assuming the condition is false
188
189 Symbol *Sym = nullptr;
190 if (COFFSym.isUndefined()) {
8
Taking false branch
14
Taking false branch
20
Taking false branch
27
Taking false branch
191 Sym = createUndefined(COFFSym);
192 } else if (COFFSym.isWeakExternal()) {
9
Taking false branch
15
Taking false branch
21
Taking false branch
28
Taking true branch
193 Sym = createUndefined(COFFSym);
194 uint32_t TagIndex =
195 static_cast<const coff_aux_weak_external *>(AuxP)->TagIndex;
29
Called C++ object pointer is null
196 WeakAliases.emplace_back(Sym, TagIndex);
197 } else {
198 Sym = createDefined(COFFSym, AuxP, IsFirst);
199 }
200 if (Sym) {
10
Assuming 'Sym' is null
11
Taking false branch
16
Assuming 'Sym' is null
17
Taking false branch
22
Assuming 'Sym' is null
23
Taking false branch
201 SymbolBodies.push_back(Sym);
202 SparseSymbolBodies[I] = Sym;
203 }
204 I += COFFSym.getNumberOfAuxSymbols();
205 LastSectionNumber = COFFSym.getSectionNumber();
206 }
207
208 for (auto &KV : WeakAliases) {
209 Symbol *Sym = KV.first;
210 uint32_t Idx = KV.second;
211 checkAndSetWeakAlias(Symtab, this, Sym, SparseSymbolBodies[Idx]);
212 }
213}
214
215Symbol *ObjFile::createUndefined(COFFSymbolRef Sym) {
216 StringRef Name;
217 COFFObj->getSymbolName(Sym, Name);
218 return Symtab->addUndefined(Name, this, Sym.isWeakExternal());
219}
220
221Symbol *ObjFile::createDefined(COFFSymbolRef Sym, const void *AuxP,
222 bool IsFirst) {
223 StringRef Name;
224 if (Sym.isCommon()) {
225 auto *C = make<CommonChunk>(Sym);
226 Chunks.push_back(C);
227 COFFObj->getSymbolName(Sym, Name);
228 Symbol *S =
229 Symtab->addCommon(this, Name, Sym.getValue(), Sym.getGeneric(), C);
230 return S;
231 }
232 if (Sym.isAbsolute()) {
233 COFFObj->getSymbolName(Sym, Name);
234 // Skip special symbols.
235 if (Name == "@comp.id")
236 return nullptr;
237 // COFF spec 5.10.1. The .sxdata section.
238 if (Name == "@feat.00") {
239 if (Sym.getValue() & 1)
240 SEHCompat = true;
241 return nullptr;
242 }
243 if (Sym.isExternal())
244 return Symtab->addAbsolute(Name, Sym);
245 else
246 return make<DefinedAbsolute>(Name, Sym);
247 }
248 int32_t SectionNumber = Sym.getSectionNumber();
249 if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
250 return nullptr;
251
252 // Reserved sections numbers don't have contents.
253 if (llvm::COFF::isReservedSectionNumber(SectionNumber))
254 fatal("broken object file: " + toString(this));
255
256 // This symbol references a section which is not present in the section
257 // header.
258 if ((uint32_t)SectionNumber >= SparseChunks.size())
259 fatal("broken object file: " + toString(this));
260
261 // Nothing else to do without a section chunk.
262 auto *SC = cast_or_null<SectionChunk>(SparseChunks[SectionNumber]);
263 if (!SC)
264 return nullptr;
265
266 // Handle section definitions
267 if (IsFirst && AuxP) {
268 auto *Aux = reinterpret_cast<const coff_aux_section_definition *>(AuxP);
269 if (Aux->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
270 if (auto *ParentSC = cast_or_null<SectionChunk>(
271 SparseChunks[Aux->getNumber(Sym.isBigObj())])) {
272 ParentSC->addAssociative(SC);
273 // If we already discarded the parent, discard the child.
274 if (ParentSC->isDiscarded())
275 SC->markDiscarded();
276 }
277 SC->Checksum = Aux->CheckSum;
278 }
279
280 DefinedRegular *B;
281 if (Sym.isExternal()) {
282 COFFObj->getSymbolName(Sym, Name);
283 Symbol *S =
284 Symtab->addRegular(this, Name, SC->isCOMDAT(), Sym.getGeneric(), SC);
285 B = cast<DefinedRegular>(S);
286 } else
287 B = make<DefinedRegular>(this, /*Name*/ "", SC->isCOMDAT(),
288 /*IsExternal*/ false, Sym.getGeneric(), SC);
289 if (SC->isCOMDAT() && Sym.getValue() == 0 && !AuxP)
290 SC->setSymbol(B);
291
292 return B;
293}
294
295void ObjFile::initializeSEH() {
296 if (!SEHCompat || !SXData)
297 return;
298 ArrayRef<uint8_t> A;
299 COFFObj->getSectionContents(SXData, A);
300 if (A.size() % 4 != 0)
301 fatal(".sxdata must be an array of symbol table indices");
302 auto *I = reinterpret_cast<const ulittle32_t *>(A.data());
303 auto *E = reinterpret_cast<const ulittle32_t *>(A.data() + A.size());
304 for (; I != E; ++I)
305 SEHandlers.insert(SparseSymbolBodies[*I]);
306}
307
308MachineTypes ObjFile::getMachineType() {
309 if (COFFObj)
310 return static_cast<MachineTypes>(COFFObj->getMachine());
311 return IMAGE_FILE_MACHINE_UNKNOWN;
312}
313
314StringRef ltrim1(StringRef S, const char *Chars) {
315 if (!S.empty() && strchr(Chars, S[0]))
316 return S.substr(1);
317 return S;
318}
319
320void ImportFile::parse() {
321 const char *Buf = MB.getBufferStart();
322 const char *End = MB.getBufferEnd();
323 const auto *Hdr = reinterpret_cast<const coff_import_header *>(Buf);
324
325 // Check if the total size is valid.
326 if ((size_t)(End - Buf) != (sizeof(*Hdr) + Hdr->SizeOfData))
327 fatal("broken import library");
328
329 // Read names and create an __imp_ symbol.
330 StringRef Name = Saver.save(StringRef(Buf + sizeof(*Hdr)));
331 StringRef ImpName = Saver.save("__imp_" + Name);
332 const char *NameStart = Buf + sizeof(coff_import_header) + Name.size() + 1;
333 DLLName = StringRef(NameStart);
334 StringRef ExtName;
335 switch (Hdr->getNameType()) {
336 case IMPORT_ORDINAL:
337 ExtName = "";
338 break;
339 case IMPORT_NAME:
340 ExtName = Name;
341 break;
342 case IMPORT_NAME_NOPREFIX:
343 ExtName = ltrim1(Name, "?@_");
344 break;
345 case IMPORT_NAME_UNDECORATE:
346 ExtName = ltrim1(Name, "?@_");
347 ExtName = ExtName.substr(0, ExtName.find('@'));
348 break;
349 }
350
351 this->Hdr = Hdr;
352 ExternalName = ExtName;
353
354 ImpSym = Symtab->addImportData(ImpName, this);
355
356 if (Hdr->getType() == llvm::COFF::IMPORT_CONST)
357 static_cast<void>(Symtab->addImportData(Name, this));
358
359 // If type is function, we need to create a thunk which jump to an
360 // address pointed by the __imp_ symbol. (This allows you to call
361 // DLL functions just like regular non-DLL functions.)
362 if (Hdr->getType() == llvm::COFF::IMPORT_CODE)
363 ThunkSym = Symtab->addImportThunk(Name, ImpSym, Hdr->Machine);
364}
365
366void BitcodeFile::parse() {
367 Obj = check(lto::InputFile::create(MemoryBufferRef(
368 MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier()))));
369 for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) {
370 StringRef SymName = Saver.save(ObjSym.getName());
371 Symbol *Sym;
372 if (ObjSym.isUndefined()) {
373 Sym = Symtab->addUndefined(SymName, this, false);
374 } else if (ObjSym.isCommon()) {
375 Sym = Symtab->addCommon(this, SymName, ObjSym.getCommonSize());
376 } else if (ObjSym.isWeak() && ObjSym.isIndirect()) {
377 // Weak external.
378 Sym = Symtab->addUndefined(SymName, this, true);
379 std::string Fallback = ObjSym.getCOFFWeakExternalFallback();
380 Symbol *Alias = Symtab->addUndefined(Saver.save(Fallback));
381 checkAndSetWeakAlias(Symtab, this, Sym, Alias);
382 } else {
383 bool IsCOMDAT = ObjSym.getComdatIndex() != -1;
384 Sym = Symtab->addRegular(this, SymName, IsCOMDAT);
385 }
386 SymbolBodies.push_back(Sym);
387 }
388 Directives = Obj->getCOFFLinkerOpts();
389}
390
391MachineTypes BitcodeFile::getMachineType() {
392 switch (Triple(Obj->getTargetTriple()).getArch()) {
393 case Triple::x86_64:
394 return AMD64;
395 case Triple::x86:
396 return I386;
397 case Triple::arm:
398 return ARMNT;
399 case Triple::aarch64:
400 return ARM64;
401 default:
402 return IMAGE_FILE_MACHINE_UNKNOWN;
403 }
404}
405} // namespace coff
406} // namespace lld
407
408// Returns the last element of a path, which is supposed to be a filename.
409static StringRef getBasename(StringRef Path) {
410 size_t Pos = Path.find_last_of("\\/");
411 if (Pos == StringRef::npos)
412 return Path;
413 return Path.substr(Pos + 1);
414}
415
416// Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".
417std::string lld::toString(coff::InputFile *File) {
418 if (!File)
419 return "(internal)";
420 if (File->ParentName.empty())
421 return File->getName().lower();
422
423 std::string Res =
424 (getBasename(File->ParentName) + "(" + getBasename(File->getName()) + ")")
425 .str();
426 return StringRef(Res).lower();
427}