Bug Summary

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