File: | tools/obj2yaml/elf2yaml.cpp |
Warning: | line 142, column 24 Forming reference to null pointer |
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 | ||||
18 | using namespace llvm; | |||
19 | ||||
20 | namespace { | |||
21 | ||||
22 | template <class ELFT> | |||
23 | class 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 | ||||
50 | public: | |||
51 | ELFDumper(const object::ELFFile<ELFT> &O); | |||
52 | ErrorOr<ELFYAML::Object *> dump(); | |||
53 | }; | |||
54 | ||||
55 | } | |||
56 | ||||
57 | template <class ELFT> | |||
58 | ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O) | |||
59 | : Obj(O) {} | |||
60 | ||||
61 | template <class ELFT> | |||
62 | ErrorOr<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; | |||
75 | ||||
76 | // Dump sections | |||
77 | auto SectionsOrErr = Obj.sections(); | |||
78 | if (!SectionsOrErr) | |||
79 | return errorToErrorCode(SectionsOrErr.takeError()); | |||
80 | for (const Elf_Shdr &Sec : *SectionsOrErr) { | |||
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); | |||
| ||||
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 | ||||
181 | template <class ELFT> | |||
182 | std::error_code | |||
183 | ELFDumper<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 | ||||
210 | template <class ELFT> | |||
211 | template <class RelT> | |||
212 | std::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 | ||||
247 | template <class ELFT> | |||
248 | std::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 | ||||
273 | template <class ELFT> | |||
274 | std::error_code | |||
275 | ELFDumper<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 | ||||
292 | template <class ELFT> | |||
293 | ErrorOr<ELFYAML::RelocationSection *> | |||
294 | ELFDumper<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 | ||||
319 | template <class ELFT> | |||
320 | ErrorOr<ELFYAML::RelocationSection *> | |||
321 | ELFDumper<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 | ||||
347 | template <class ELFT> | |||
348 | ErrorOr<ELFYAML::RawContentSection *> | |||
349 | ELFDumper<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 | ||||
364 | template <class ELFT> | |||
365 | ErrorOr<ELFYAML::NoBitsSection *> | |||
366 | ELFDumper<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 | ||||
376 | template <class ELFT> | |||
377 | ErrorOr<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 | ||||
423 | template <class ELFT> | |||
424 | ErrorOr<ELFYAML::MipsABIFlags *> | |||
425 | ELFDumper<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 | ||||
452 | template <class ELFT> | |||
453 | static 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(); | |||
| ||||
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 | ||||
467 | std::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 | } |