Bug Summary

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