Bug Summary

File:tools/obj2yaml/elf2yaml.cpp
Warning:line 142, column 24
Forming reference to null pointer

Annotated Source Code

1//===------ utils/elf2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
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 "Error.h"
11#include "obj2yaml.h"
12#include "llvm/ADT/STLExtras.h"
13#include "llvm/Object/ELFObjectFile.h"
14#include "llvm/ObjectYAML/ELFYAML.h"
15#include "llvm/Support/ErrorHandling.h"
16#include "llvm/Support/YAMLTraits.h"
17
18using namespace llvm;
19
20namespace {
21
22template <class ELFT>
23class ELFDumper {
24 typedef object::Elf_Sym_Impl<ELFT> Elf_Sym;
25 typedef typename object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
26 typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word;
27 typedef typename object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
28 typedef typename object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
29
30 const object::ELFFile<ELFT> &Obj;
31 ArrayRef<Elf_Word> ShndxTable;
32
33 std::error_code dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
34 StringRef StrTable, ELFYAML::Symbol &S);
35 std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
36 std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr,
37 ELFYAML::RelocationSection &S);
38 template <class RelT>
39 std::error_code dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
40 ELFYAML::Relocation &R);
41
42 ErrorOr<ELFYAML::RelocationSection *> dumpRelSection(const Elf_Shdr *Shdr);
43 ErrorOr<ELFYAML::RelocationSection *> dumpRelaSection(const Elf_Shdr *Shdr);
44 ErrorOr<ELFYAML::RawContentSection *>
45 dumpContentSection(const Elf_Shdr *Shdr);
46 ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
47 ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
48 ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
49
50public:
51 ELFDumper(const object::ELFFile<ELFT> &O);
52 ErrorOr<ELFYAML::Object *> dump();
53};
54
55}
56
57template <class ELFT>
58ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O)
59 : Obj(O) {}
60
61template <class ELFT>
62ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
63 auto Y = make_unique<ELFYAML::Object>();
64
65 // Dump header
66 Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass());
67 Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding());
68 Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI];
69 Y->Header.Type = Obj.getHeader()->e_type;
70 Y->Header.Machine = Obj.getHeader()->e_machine;
71 Y->Header.Flags = Obj.getHeader()->e_flags;
72 Y->Header.Entry = Obj.getHeader()->e_entry;
73
74 const Elf_Shdr *Symtab = nullptr;
2
'Symtab' initialized to a null pointer value
75
76 // Dump sections
77 auto SectionsOrErr = Obj.sections();
78 if (!SectionsOrErr)
3
Taking false branch
79 return errorToErrorCode(SectionsOrErr.takeError());
80 for (const Elf_Shdr &Sec : *SectionsOrErr) {
4
Assuming '__begin' is equal to '__end'
81 switch (Sec.sh_type) {
82 case ELF::SHT_NULL:
83 case ELF::SHT_DYNSYM:
84 case ELF::SHT_STRTAB:
85 // Do not dump these sections.
86 break;
87 case ELF::SHT_SYMTAB:
88 Symtab = &Sec;
89 break;
90 case ELF::SHT_SYMTAB_SHNDX: {
91 auto TableOrErr = Obj.getSHNDXTable(Sec);
92 if (!TableOrErr)
93 return errorToErrorCode(TableOrErr.takeError());
94 ShndxTable = *TableOrErr;
95 break;
96 }
97 case ELF::SHT_RELA: {
98 ErrorOr<ELFYAML::RelocationSection *> S = dumpRelaSection(&Sec);
99 if (std::error_code EC = S.getError())
100 return EC;
101 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
102 break;
103 }
104 case ELF::SHT_REL: {
105 ErrorOr<ELFYAML::RelocationSection *> S = dumpRelSection(&Sec);
106 if (std::error_code EC = S.getError())
107 return EC;
108 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
109 break;
110 }
111 case ELF::SHT_GROUP: {
112 ErrorOr<ELFYAML::Group *> G = dumpGroup(&Sec);
113 if (std::error_code EC = G.getError())
114 return EC;
115 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get()));
116 break;
117 }
118 case ELF::SHT_MIPS_ABIFLAGS: {
119 ErrorOr<ELFYAML::MipsABIFlags *> G = dumpMipsABIFlags(&Sec);
120 if (std::error_code EC = G.getError())
121 return EC;
122 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get()));
123 break;
124 }
125 case ELF::SHT_NOBITS: {
126 ErrorOr<ELFYAML::NoBitsSection *> S = dumpNoBitsSection(&Sec);
127 if (std::error_code EC = S.getError())
128 return EC;
129 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
130 break;
131 }
132 default: {
133 ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec);
134 if (std::error_code EC = S.getError())
135 return EC;
136 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
137 }
138 }
139 }
140
141 // Dump symbols
142 auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
5
Forming reference to null pointer
143 if (!StrTableOrErr)
144 return errorToErrorCode(StrTableOrErr.takeError());
145 StringRef StrTable = *StrTableOrErr;
146
147 bool IsFirstSym = true;
148 auto SymtabOrErr = Obj.symbols(Symtab);
149 if (!SymtabOrErr)
150 return errorToErrorCode(SymtabOrErr.takeError());
151 for (const Elf_Sym &Sym : *SymtabOrErr) {
152 if (IsFirstSym) {
153 IsFirstSym = false;
154 continue;
155 }
156
157 ELFYAML::Symbol S;
158 if (std::error_code EC =
159 ELFDumper<ELFT>::dumpSymbol(&Sym, Symtab, StrTable, S))
160 return EC;
161
162 switch (Sym.getBinding())
163 {
164 case ELF::STB_LOCAL:
165 Y->Symbols.Local.push_back(S);
166 break;
167 case ELF::STB_GLOBAL:
168 Y->Symbols.Global.push_back(S);
169 break;
170 case ELF::STB_WEAK:
171 Y->Symbols.Weak.push_back(S);
172 break;
173 default:
174 llvm_unreachable("Unknown ELF symbol binding")::llvm::llvm_unreachable_internal("Unknown ELF symbol binding"
, "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/tools/obj2yaml/elf2yaml.cpp"
, 174)
;
175 }
176 }
177
178 return Y.release();
179}
180
181template <class ELFT>
182std::error_code
183ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
184 StringRef StrTable, ELFYAML::Symbol &S) {
185 S.Type = Sym->getType();
186 S.Value = Sym->st_value;
187 S.Size = Sym->st_size;
188 S.Other = Sym->st_other;
189
190 Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
191 if (!SymbolNameOrErr)
192 return errorToErrorCode(SymbolNameOrErr.takeError());
193 S.Name = SymbolNameOrErr.get();
194
195 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
196 if (!ShdrOrErr)
197 return errorToErrorCode(ShdrOrErr.takeError());
198 const Elf_Shdr *Shdr = *ShdrOrErr;
199 if (!Shdr)
200 return obj2yaml_error::success;
201
202 auto NameOrErr = Obj.getSectionName(Shdr);
203 if (!NameOrErr)
204 return errorToErrorCode(NameOrErr.takeError());
205 S.Section = NameOrErr.get();
206
207 return obj2yaml_error::success;
208}
209
210template <class ELFT>
211template <class RelT>
212std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
213 const Elf_Shdr *SymTab,
214 ELFYAML::Relocation &R) {
215 R.Type = Rel->getType(Obj.isMips64EL());
216 R.Offset = Rel->r_offset;
217 R.Addend = 0;
218
219 auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
220 if (!SymOrErr)
221 return errorToErrorCode(SymOrErr.takeError());
222 const Elf_Sym *Sym = *SymOrErr;
223 auto StrTabSec = Obj.getSection(SymTab->sh_link);
224 if (!StrTabSec)
225 return errorToErrorCode(StrTabSec.takeError());
226 auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
227 if (!StrTabOrErr)
228 return errorToErrorCode(StrTabOrErr.takeError());
229 StringRef StrTab = *StrTabOrErr;
230
231 if (Sym) {
232 Expected<StringRef> NameOrErr = Sym->getName(StrTab);
233 if (!NameOrErr)
234 return errorToErrorCode(NameOrErr.takeError());
235 R.Symbol = NameOrErr.get();
236 } else {
237 // We have some edge cases of relocations without a symbol associated,
238 // e.g. an object containing the invalid (according to the System V
239 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
240 // of crashing.
241 R.Symbol = "";
242 }
243
244 return obj2yaml_error::success;
245}
246
247template <class ELFT>
248std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
249 ELFYAML::Section &S) {
250 S.Type = Shdr->sh_type;
251 S.Flags = Shdr->sh_flags;
252 S.Address = Shdr->sh_addr;
253 S.AddressAlign = Shdr->sh_addralign;
254
255 auto NameOrErr = Obj.getSectionName(Shdr);
256 if (!NameOrErr)
257 return errorToErrorCode(NameOrErr.takeError());
258 S.Name = NameOrErr.get();
259
260 if (Shdr->sh_link != ELF::SHN_UNDEF) {
261 auto LinkSection = Obj.getSection(Shdr->sh_link);
262 if (LinkSection.takeError())
263 return errorToErrorCode(LinkSection.takeError());
264 NameOrErr = Obj.getSectionName(*LinkSection);
265 if (!NameOrErr)
266 return errorToErrorCode(NameOrErr.takeError());
267 S.Link = NameOrErr.get();
268 }
269
270 return obj2yaml_error::success;
271}
272
273template <class ELFT>
274std::error_code
275ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr,
276 ELFYAML::RelocationSection &S) {
277 if (std::error_code EC = dumpCommonSection(Shdr, S))
278 return EC;
279
280 auto InfoSection = Obj.getSection(Shdr->sh_info);
281 if (!InfoSection)
282 return errorToErrorCode(InfoSection.takeError());
283
284 auto NameOrErr = Obj.getSectionName(*InfoSection);
285 if (!NameOrErr)
286 return errorToErrorCode(NameOrErr.takeError());
287 S.Info = NameOrErr.get();
288
289 return obj2yaml_error::success;
290}
291
292template <class ELFT>
293ErrorOr<ELFYAML::RelocationSection *>
294ELFDumper<ELFT>::dumpRelSection(const Elf_Shdr *Shdr) {
295 assert(Shdr->sh_type == ELF::SHT_REL && "Section type is not SHT_REL")((Shdr->sh_type == ELF::SHT_REL && "Section type is not SHT_REL"
) ? static_cast<void> (0) : __assert_fail ("Shdr->sh_type == ELF::SHT_REL && \"Section type is not SHT_REL\""
, "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/tools/obj2yaml/elf2yaml.cpp"
, 295, __PRETTY_FUNCTION__))
;
296 auto S = make_unique<ELFYAML::RelocationSection>();
297
298 if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S))
299 return EC;
300
301 auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
302 if (!SymTabOrErr)
303 return errorToErrorCode(SymTabOrErr.takeError());
304 const Elf_Shdr *SymTab = *SymTabOrErr;
305
306 auto Rels = Obj.rels(Shdr);
307 if (!Rels)
308 return errorToErrorCode(Rels.takeError());
309 for (const Elf_Rel &Rel : *Rels) {
310 ELFYAML::Relocation R;
311 if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
312 return EC;
313 S->Relocations.push_back(R);
314 }
315
316 return S.release();
317}
318
319template <class ELFT>
320ErrorOr<ELFYAML::RelocationSection *>
321ELFDumper<ELFT>::dumpRelaSection(const Elf_Shdr *Shdr) {
322 assert(Shdr->sh_type == ELF::SHT_RELA && "Section type is not SHT_RELA")((Shdr->sh_type == ELF::SHT_RELA && "Section type is not SHT_RELA"
) ? static_cast<void> (0) : __assert_fail ("Shdr->sh_type == ELF::SHT_RELA && \"Section type is not SHT_RELA\""
, "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/tools/obj2yaml/elf2yaml.cpp"
, 322, __PRETTY_FUNCTION__))
;
323 auto S = make_unique<ELFYAML::RelocationSection>();
324
325 if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S))
326 return EC;
327
328 auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
329 if (!SymTabOrErr)
330 return errorToErrorCode(SymTabOrErr.takeError());
331 const Elf_Shdr *SymTab = *SymTabOrErr;
332
333 auto Rels = Obj.relas(Shdr);
334 if (!Rels)
335 return errorToErrorCode(Rels.takeError());
336 for (const Elf_Rela &Rel : *Rels) {
337 ELFYAML::Relocation R;
338 if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
339 return EC;
340 R.Addend = Rel.r_addend;
341 S->Relocations.push_back(R);
342 }
343
344 return S.release();
345}
346
347template <class ELFT>
348ErrorOr<ELFYAML::RawContentSection *>
349ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
350 auto S = make_unique<ELFYAML::RawContentSection>();
351
352 if (std::error_code EC = dumpCommonSection(Shdr, *S))
353 return EC;
354
355 auto ContentOrErr = Obj.getSectionContents(Shdr);
356 if (!ContentOrErr)
357 return errorToErrorCode(ContentOrErr.takeError());
358 S->Content = yaml::BinaryRef(ContentOrErr.get());
359 S->Size = S->Content.binary_size();
360
361 return S.release();
362}
363
364template <class ELFT>
365ErrorOr<ELFYAML::NoBitsSection *>
366ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
367 auto S = make_unique<ELFYAML::NoBitsSection>();
368
369 if (std::error_code EC = dumpCommonSection(Shdr, *S))
370 return EC;
371 S->Size = Shdr->sh_size;
372
373 return S.release();
374}
375
376template <class ELFT>
377ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
378 auto S = make_unique<ELFYAML::Group>();
379
380 if (std::error_code EC = dumpCommonSection(Shdr, *S))
381 return EC;
382 // Get sh_info which is the signature.
383 auto SymtabOrErr = Obj.getSection(Shdr->sh_link);
384 if (!SymtabOrErr)
385 return errorToErrorCode(SymtabOrErr.takeError());
386 const Elf_Shdr *Symtab = *SymtabOrErr;
387 auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
388 if (!SymOrErr)
389 return errorToErrorCode(SymOrErr.takeError());
390 const Elf_Sym *symbol = *SymOrErr;
391 auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
392 if (!StrTabOrErr)
393 return errorToErrorCode(StrTabOrErr.takeError());
394 StringRef StrTab = *StrTabOrErr;
395 auto sectionContents = Obj.getSectionContents(Shdr);
396 if (!sectionContents)
397 return errorToErrorCode(sectionContents.takeError());
398 Expected<StringRef> symbolName = symbol->getName(StrTab);
399 if (!symbolName)
400 return errorToErrorCode(symbolName.takeError());
401 S->Info = *symbolName;
402 const Elf_Word *groupMembers =
403 reinterpret_cast<const Elf_Word *>(sectionContents->data());
404 const long count = (Shdr->sh_size) / sizeof(Elf_Word);
405 ELFYAML::SectionOrType s;
406 for (int i = 0; i < count; i++) {
407 if (groupMembers[i] == llvm::ELF::GRP_COMDAT) {
408 s.sectionNameOrType = "GRP_COMDAT";
409 } else {
410 auto sHdr = Obj.getSection(groupMembers[i]);
411 if (!sHdr)
412 return errorToErrorCode(sHdr.takeError());
413 auto sectionName = Obj.getSectionName(*sHdr);
414 if (!sectionName)
415 return errorToErrorCode(sectionName.takeError());
416 s.sectionNameOrType = *sectionName;
417 }
418 S->Members.push_back(s);
419 }
420 return S.release();
421}
422
423template <class ELFT>
424ErrorOr<ELFYAML::MipsABIFlags *>
425ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
426 assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&((Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && "Section type is not SHT_MIPS_ABIFLAGS"
) ? static_cast<void> (0) : __assert_fail ("Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && \"Section type is not SHT_MIPS_ABIFLAGS\""
, "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/tools/obj2yaml/elf2yaml.cpp"
, 427, __PRETTY_FUNCTION__))
427 "Section type is not SHT_MIPS_ABIFLAGS")((Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && "Section type is not SHT_MIPS_ABIFLAGS"
) ? static_cast<void> (0) : __assert_fail ("Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && \"Section type is not SHT_MIPS_ABIFLAGS\""
, "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/tools/obj2yaml/elf2yaml.cpp"
, 427, __PRETTY_FUNCTION__))
;
428 auto S = make_unique<ELFYAML::MipsABIFlags>();
429 if (std::error_code EC = dumpCommonSection(Shdr, *S))
430 return EC;
431
432 auto ContentOrErr = Obj.getSectionContents(Shdr);
433 if (!ContentOrErr)
434 return errorToErrorCode(ContentOrErr.takeError());
435
436 auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
437 ContentOrErr.get().data());
438 S->Version = Flags->version;
439 S->ISALevel = Flags->isa_level;
440 S->ISARevision = Flags->isa_rev;
441 S->GPRSize = Flags->gpr_size;
442 S->CPR1Size = Flags->cpr1_size;
443 S->CPR2Size = Flags->cpr2_size;
444 S->FpABI = Flags->fp_abi;
445 S->ISAExtension = Flags->isa_ext;
446 S->ASEs = Flags->ases;
447 S->Flags1 = Flags->flags1;
448 S->Flags2 = Flags->flags2;
449 return S.release();
450}
451
452template <class ELFT>
453static std::error_code elf2yaml(raw_ostream &Out,
454 const object::ELFFile<ELFT> &Obj) {
455 ELFDumper<ELFT> Dumper(Obj);
456 ErrorOr<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
1
Calling 'ELFDumper::dump'
457 if (std::error_code EC = YAMLOrErr.getError())
458 return EC;
459
460 std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
461 yaml::Output Yout(Out);
462 Yout << *YAML;
463
464 return std::error_code();
465}
466
467std::error_code elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
468 if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
469 return elf2yaml(Out, *ELFObj->getELFFile());
470
471 if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
472 return elf2yaml(Out, *ELFObj->getELFFile());
473
474 if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
475 return elf2yaml(Out, *ELFObj->getELFFile());
476
477 if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
478 return elf2yaml(Out, *ELFObj->getELFFile());
479
480 return obj2yaml_error::unsupported_obj_file_format;
481}