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