blob: b02c25ad153dc686324affe5a2beaf13893b3a1c [file] [log] [blame]
Simon Atanasyanae6bb332014-05-14 05:07:47 +00001//===------ utils/elf2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Simon Atanasyanae6bb332014-05-14 05:07:47 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "Error.h"
Rafael Espindola88ee57e2017-09-05 22:30:00 +000010#include "llvm/ADT/DenseSet.h"
Simon Atanasyanae6bb332014-05-14 05:07:47 +000011#include "llvm/ADT/STLExtras.h"
12#include "llvm/Object/ELFObjectFile.h"
Rafael Espindolaebd91932016-03-01 19:15:06 +000013#include "llvm/ObjectYAML/ELFYAML.h"
Simon Atanasyanae6bb332014-05-14 05:07:47 +000014#include "llvm/Support/ErrorHandling.h"
15#include "llvm/Support/YAMLTraits.h"
16
17using namespace llvm;
18
19namespace {
20
21template <class ELFT>
22class ELFDumper {
Shankar Easwaran6fbbe202015-02-21 04:28:26 +000023 typedef object::Elf_Sym_Impl<ELFT> Elf_Sym;
George Rimar0e7ed912019-02-09 11:34:28 +000024 typedef typename ELFT::Dyn Elf_Dyn;
Rui Ueyama478d6352018-01-12 02:28:31 +000025 typedef typename ELFT::Shdr Elf_Shdr;
26 typedef typename ELFT::Word Elf_Word;
27 typedef typename ELFT::Rel Elf_Rel;
28 typedef typename ELFT::Rela Elf_Rela;
Simon Atanasyanae6bb332014-05-14 05:07:47 +000029
Rafael Espindola88ee57e2017-09-05 22:30:00 +000030 ArrayRef<Elf_Shdr> Sections;
31
32 // If the file has multiple sections with the same name, we add a
33 // suffix to make them unique.
34 unsigned Suffix = 0;
35 DenseSet<StringRef> UsedSectionNames;
36 std::vector<std::string> SectionNames;
37 Expected<StringRef> getUniquedSectionName(const Elf_Shdr *Sec);
Rafael Espindoladc8b7a92017-09-06 00:57:53 +000038 Expected<StringRef> getSymbolName(const Elf_Sym *Sym, StringRef StrTable,
39 const Elf_Shdr *SymTab);
Rafael Espindola88ee57e2017-09-05 22:30:00 +000040
Simon Atanasyanae6bb332014-05-14 05:07:47 +000041 const object::ELFFile<ELFT> &Obj;
Rafael Espindolaaae55412015-08-10 21:29:35 +000042 ArrayRef<Elf_Word> ShndxTable;
Simon Atanasyanae6bb332014-05-14 05:07:47 +000043
Dave Lee67b49662017-11-16 18:10:15 +000044 std::error_code dumpSymbols(const Elf_Shdr *Symtab,
45 ELFYAML::LocalGlobalWeakSymbols &Symbols);
Rafael Espindolaaae55412015-08-10 21:29:35 +000046 std::error_code dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
47 StringRef StrTable, ELFYAML::Symbol &S);
Rafael Espindola4453e42942014-06-13 03:07:50 +000048 std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
49 std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr,
50 ELFYAML::RelocationSection &S);
Simon Atanasyanae6bb332014-05-14 05:07:47 +000051 template <class RelT>
Rafael Espindola7d250f72015-09-02 15:07:39 +000052 std::error_code dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
Rafael Espindola4453e42942014-06-13 03:07:50 +000053 ELFYAML::Relocation &R);
George Rimar0e7ed912019-02-09 11:34:28 +000054
55 ErrorOr<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr);
George Rimarafe8a042019-02-01 07:50:08 +000056 ErrorOr<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
Simon Atanasyanae6bb332014-05-14 05:07:47 +000057 ErrorOr<ELFYAML::RawContentSection *>
58 dumpContentSection(const Elf_Shdr *Shdr);
Simon Atanasyan5db02762015-07-03 23:00:54 +000059 ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
George Rimar623ae722019-02-21 12:21:43 +000060 ErrorOr<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr);
George Rimar646af082019-02-19 15:29:07 +000061 ErrorOr<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
George Rimar0621b792019-02-19 14:53:48 +000062 ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
Shankar Easwaran6fbbe202015-02-21 04:28:26 +000063 ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
Simon Atanasyan04d9e652015-05-07 15:40:48 +000064 ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
Simon Atanasyanae6bb332014-05-14 05:07:47 +000065
66public:
67 ELFDumper(const object::ELFFile<ELFT> &O);
68 ErrorOr<ELFYAML::Object *> dump();
69};
70
71}
72
73template <class ELFT>
74ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O)
75 : Obj(O) {}
76
77template <class ELFT>
Rafael Espindola88ee57e2017-09-05 22:30:00 +000078Expected<StringRef>
79ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr *Sec) {
80 unsigned SecIndex = Sec - &Sections[0];
81 assert(&Sections[SecIndex] == Sec);
82 if (!SectionNames[SecIndex].empty())
83 return SectionNames[SecIndex];
84
85 auto NameOrErr = Obj.getSectionName(Sec);
86 if (!NameOrErr)
87 return NameOrErr;
88 StringRef Name = *NameOrErr;
Rafael Espindola8db11a42017-09-05 23:00:51 +000089 std::string &Ret = SectionNames[SecIndex];
90 Ret = Name;
Rafael Espindola88ee57e2017-09-05 22:30:00 +000091 while (!UsedSectionNames.insert(Ret).second)
92 Ret = (Name + to_string(++Suffix)).str();
Rafael Espindola8db11a42017-09-05 23:00:51 +000093 return Ret;
Rafael Espindola88ee57e2017-09-05 22:30:00 +000094}
95
Rafael Espindoladc8b7a92017-09-06 00:57:53 +000096template <class ELFT>
97Expected<StringRef> ELFDumper<ELFT>::getSymbolName(const Elf_Sym *Sym,
98 StringRef StrTable,
99 const Elf_Shdr *SymTab) {
100 Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
101 if (!SymbolNameOrErr)
102 return SymbolNameOrErr;
103 StringRef Name = *SymbolNameOrErr;
104 if (Name.empty() && Sym->getType() == ELF::STT_SECTION) {
105 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
106 if (!ShdrOrErr)
107 return ShdrOrErr.takeError();
108 return getUniquedSectionName(*ShdrOrErr);
109 }
110 return Name;
111}
112
Rafael Espindola88ee57e2017-09-05 22:30:00 +0000113template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000114 auto Y = make_unique<ELFYAML::Object>();
115
116 // Dump header
117 Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass());
118 Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding());
119 Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI];
George Rimar6367d7a2018-12-20 10:43:49 +0000120 Y->Header.ABIVersion = Obj.getHeader()->e_ident[ELF::EI_ABIVERSION];
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000121 Y->Header.Type = Obj.getHeader()->e_type;
122 Y->Header.Machine = Obj.getHeader()->e_machine;
123 Y->Header.Flags = Obj.getHeader()->e_flags;
124 Y->Header.Entry = Obj.getHeader()->e_entry;
125
Rafael Espindola94515ab2015-08-10 14:27:50 +0000126 const Elf_Shdr *Symtab = nullptr;
Dave Lee67b49662017-11-16 18:10:15 +0000127 const Elf_Shdr *DynSymtab = nullptr;
Rafael Espindola94515ab2015-08-10 14:27:50 +0000128
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000129 // Dump sections
Rafael Espindola25be8c82016-11-02 14:10:57 +0000130 auto SectionsOrErr = Obj.sections();
Davide Italiano6cf09262016-11-16 05:10:28 +0000131 if (!SectionsOrErr)
132 return errorToErrorCode(SectionsOrErr.takeError());
Rafael Espindola88ee57e2017-09-05 22:30:00 +0000133 Sections = *SectionsOrErr;
134 SectionNames.resize(Sections.size());
135 for (const Elf_Shdr &Sec : Sections) {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000136 switch (Sec.sh_type) {
George Rimar0e7ed912019-02-09 11:34:28 +0000137 case ELF::SHT_DYNAMIC: {
138 ErrorOr<ELFYAML::DynamicSection *> S = dumpDynamicSection(&Sec);
139 if (std::error_code EC = S.getError())
140 return EC;
141 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
142 break;
143 }
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000144 case ELF::SHT_NULL:
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000145 case ELF::SHT_STRTAB:
146 // Do not dump these sections.
147 break;
Rafael Espindola94515ab2015-08-10 14:27:50 +0000148 case ELF::SHT_SYMTAB:
149 Symtab = &Sec;
150 break;
Dave Lee67b49662017-11-16 18:10:15 +0000151 case ELF::SHT_DYNSYM:
152 DynSymtab = &Sec;
153 break;
Rafael Espindolaaae55412015-08-10 21:29:35 +0000154 case ELF::SHT_SYMTAB_SHNDX: {
Davide Italiano6cf09262016-11-16 05:10:28 +0000155 auto TableOrErr = Obj.getSHNDXTable(Sec);
156 if (!TableOrErr)
157 return errorToErrorCode(TableOrErr.takeError());
Rafael Espindolaaae55412015-08-10 21:29:35 +0000158 ShndxTable = *TableOrErr;
159 break;
160 }
George Rimarafe8a042019-02-01 07:50:08 +0000161 case ELF::SHT_REL:
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000162 case ELF::SHT_RELA: {
George Rimarafe8a042019-02-01 07:50:08 +0000163 ErrorOr<ELFYAML::RelocationSection *> S = dumpRelocSection(&Sec);
Rafael Espindola4453e42942014-06-13 03:07:50 +0000164 if (std::error_code EC = S.getError())
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000165 return EC;
166 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
167 break;
168 }
Shankar Easwaran6fbbe202015-02-21 04:28:26 +0000169 case ELF::SHT_GROUP: {
170 ErrorOr<ELFYAML::Group *> G = dumpGroup(&Sec);
171 if (std::error_code EC = G.getError())
172 return EC;
173 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get()));
174 break;
175 }
Simon Atanasyan04d9e652015-05-07 15:40:48 +0000176 case ELF::SHT_MIPS_ABIFLAGS: {
177 ErrorOr<ELFYAML::MipsABIFlags *> G = dumpMipsABIFlags(&Sec);
178 if (std::error_code EC = G.getError())
179 return EC;
180 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get()));
181 break;
182 }
Simon Atanasyan5db02762015-07-03 23:00:54 +0000183 case ELF::SHT_NOBITS: {
184 ErrorOr<ELFYAML::NoBitsSection *> S = dumpNoBitsSection(&Sec);
185 if (std::error_code EC = S.getError())
186 return EC;
187 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
188 break;
189 }
George Rimar623ae722019-02-21 12:21:43 +0000190 case ELF::SHT_GNU_verdef: {
191 ErrorOr<ELFYAML::VerdefSection *> S = dumpVerdefSection(&Sec);
192 if (std::error_code EC = S.getError())
193 return EC;
194 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
195 break;
196 }
George Rimar646af082019-02-19 15:29:07 +0000197 case ELF::SHT_GNU_versym: {
198 ErrorOr<ELFYAML::SymverSection *> S = dumpSymverSection(&Sec);
199 if (std::error_code EC = S.getError())
200 return EC;
201 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
202 break;
203 }
George Rimar0621b792019-02-19 14:53:48 +0000204 case ELF::SHT_GNU_verneed: {
205 ErrorOr<ELFYAML::VerneedSection *> S = dumpVerneedSection(&Sec);
206 if (std::error_code EC = S.getError())
207 return EC;
208 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
209 break;
210 }
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000211 default: {
212 ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec);
Rafael Espindola4453e42942014-06-13 03:07:50 +0000213 if (std::error_code EC = S.getError())
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000214 return EC;
215 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
216 }
217 }
218 }
219
Dave Lee67b49662017-11-16 18:10:15 +0000220 if (auto EC = dumpSymbols(Symtab, Y->Symbols))
221 return EC;
222 if (auto EC = dumpSymbols(DynSymtab, Y->DynamicSymbols))
223 return EC;
224
225 return Y.release();
226}
227
228template <class ELFT>
229std::error_code
230ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
231 ELFYAML::LocalGlobalWeakSymbols &Symbols) {
Alexander Richardsonc46750e2017-09-22 09:30:40 +0000232 if (!Symtab)
Dave Lee67b49662017-11-16 18:10:15 +0000233 return std::error_code();
234
Davide Italiano6cf09262016-11-16 05:10:28 +0000235 auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
236 if (!StrTableOrErr)
237 return errorToErrorCode(StrTableOrErr.takeError());
Rafael Espindolabd051012015-07-21 18:04:29 +0000238 StringRef StrTable = *StrTableOrErr;
239
Rafael Espindola9ea68342016-11-03 13:43:30 +0000240 auto SymtabOrErr = Obj.symbols(Symtab);
Davide Italiano6cf09262016-11-16 05:10:28 +0000241 if (!SymtabOrErr)
242 return errorToErrorCode(SymtabOrErr.takeError());
Dave Lee67b49662017-11-16 18:10:15 +0000243
244 bool IsFirstSym = true;
245 for (const auto &Sym : *SymtabOrErr) {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000246 if (IsFirstSym) {
247 IsFirstSym = false;
248 continue;
249 }
250
251 ELFYAML::Symbol S;
Dave Lee67b49662017-11-16 18:10:15 +0000252 if (auto EC = dumpSymbol(&Sym, Symtab, StrTable, S))
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000253 return EC;
254
Dave Lee67b49662017-11-16 18:10:15 +0000255 switch (Sym.getBinding()) {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000256 case ELF::STB_LOCAL:
Dave Lee67b49662017-11-16 18:10:15 +0000257 Symbols.Local.push_back(S);
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000258 break;
259 case ELF::STB_GLOBAL:
Dave Lee67b49662017-11-16 18:10:15 +0000260 Symbols.Global.push_back(S);
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000261 break;
262 case ELF::STB_WEAK:
Dave Lee67b49662017-11-16 18:10:15 +0000263 Symbols.Weak.push_back(S);
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000264 break;
265 default:
266 llvm_unreachable("Unknown ELF symbol binding");
267 }
268 }
269
Dave Lee67b49662017-11-16 18:10:15 +0000270 return std::error_code();
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000271}
272
273template <class ELFT>
Rafael Espindolaaae55412015-08-10 21:29:35 +0000274std::error_code
275ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
276 StringRef StrTable, ELFYAML::Symbol &S) {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000277 S.Type = Sym->getType();
278 S.Value = Sym->st_value;
279 S.Size = Sym->st_size;
Simon Atanasyan60e1a792014-11-06 22:46:24 +0000280 S.Other = Sym->st_other;
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000281
Rafael Espindoladc8b7a92017-09-06 00:57:53 +0000282 Expected<StringRef> SymbolNameOrErr = getSymbolName(Sym, StrTable, SymTab);
Kevin Enderby81e8b7d2016-04-20 21:24:34 +0000283 if (!SymbolNameOrErr)
284 return errorToErrorCode(SymbolNameOrErr.takeError());
285 S.Name = SymbolNameOrErr.get();
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000286
Davide Italiano6cf09262016-11-16 05:10:28 +0000287 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
288 if (!ShdrOrErr)
289 return errorToErrorCode(ShdrOrErr.takeError());
Rafael Espindola6def3042015-07-01 12:56:27 +0000290 const Elf_Shdr *Shdr = *ShdrOrErr;
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000291 if (!Shdr)
292 return obj2yaml_error::success;
293
Rafael Espindola88ee57e2017-09-05 22:30:00 +0000294 auto NameOrErr = getUniquedSectionName(Shdr);
Davide Italiano6cf09262016-11-16 05:10:28 +0000295 if (!NameOrErr)
296 return errorToErrorCode(NameOrErr.takeError());
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000297 S.Section = NameOrErr.get();
298
299 return obj2yaml_error::success;
300}
301
302template <class ELFT>
303template <class RelT>
Rafael Espindola7d250f72015-09-02 15:07:39 +0000304std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
305 const Elf_Shdr *SymTab,
Rafael Espindola4453e42942014-06-13 03:07:50 +0000306 ELFYAML::Relocation &R) {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000307 R.Type = Rel->getType(Obj.isMips64EL());
308 R.Offset = Rel->r_offset;
309 R.Addend = 0;
310
Rafael Espindolaed1395a2016-11-03 18:05:33 +0000311 auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
Davide Italiano6cf09262016-11-16 05:10:28 +0000312 if (!SymOrErr)
313 return errorToErrorCode(SymOrErr.takeError());
Rafael Espindolaed1395a2016-11-03 18:05:33 +0000314 const Elf_Sym *Sym = *SymOrErr;
Davide Italiano6cf09262016-11-16 05:10:28 +0000315 auto StrTabSec = Obj.getSection(SymTab->sh_link);
316 if (!StrTabSec)
317 return errorToErrorCode(StrTabSec.takeError());
318 auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
319 if (!StrTabOrErr)
320 return errorToErrorCode(StrTabOrErr.takeError());
Rafael Espindola6a1bfb22015-06-29 14:39:25 +0000321 StringRef StrTab = *StrTabOrErr;
Rafael Espindola719dc7c2015-06-29 12:38:31 +0000322
Davide Italiano44f12812017-01-26 23:12:53 +0000323 if (Sym) {
Rafael Espindoladc8b7a92017-09-06 00:57:53 +0000324 Expected<StringRef> NameOrErr = getSymbolName(Sym, StrTab, SymTab);
Davide Italiano44f12812017-01-26 23:12:53 +0000325 if (!NameOrErr)
326 return errorToErrorCode(NameOrErr.takeError());
327 R.Symbol = NameOrErr.get();
328 } else {
329 // We have some edge cases of relocations without a symbol associated,
330 // e.g. an object containing the invalid (according to the System V
331 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
332 // of crashing.
333 R.Symbol = "";
334 }
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000335
336 return obj2yaml_error::success;
337}
338
339template <class ELFT>
Rafael Espindola4453e42942014-06-13 03:07:50 +0000340std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
341 ELFYAML::Section &S) {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000342 S.Type = Shdr->sh_type;
343 S.Flags = Shdr->sh_flags;
344 S.Address = Shdr->sh_addr;
345 S.AddressAlign = Shdr->sh_addralign;
George Rimar31684962019-01-28 15:05:10 +0000346 if (Shdr->sh_entsize)
347 S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000348
Rafael Espindola88ee57e2017-09-05 22:30:00 +0000349 auto NameOrErr = getUniquedSectionName(Shdr);
Davide Italiano6cf09262016-11-16 05:10:28 +0000350 if (!NameOrErr)
351 return errorToErrorCode(NameOrErr.takeError());
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000352 S.Name = NameOrErr.get();
353
354 if (Shdr->sh_link != ELF::SHN_UNDEF) {
Davide Italiano6cf09262016-11-16 05:10:28 +0000355 auto LinkSection = Obj.getSection(Shdr->sh_link);
356 if (LinkSection.takeError())
357 return errorToErrorCode(LinkSection.takeError());
Rafael Espindola88ee57e2017-09-05 22:30:00 +0000358 NameOrErr = getUniquedSectionName(*LinkSection);
Davide Italiano6cf09262016-11-16 05:10:28 +0000359 if (!NameOrErr)
360 return errorToErrorCode(NameOrErr.takeError());
Rafael Espindola6def3042015-07-01 12:56:27 +0000361 S.Link = NameOrErr.get();
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000362 }
Simon Atanasyan87459932014-05-29 11:05:31 +0000363
364 return obj2yaml_error::success;
365}
366
367template <class ELFT>
Rafael Espindola4453e42942014-06-13 03:07:50 +0000368std::error_code
Simon Atanasyan87459932014-05-29 11:05:31 +0000369ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr,
370 ELFYAML::RelocationSection &S) {
Rafael Espindola4453e42942014-06-13 03:07:50 +0000371 if (std::error_code EC = dumpCommonSection(Shdr, S))
Simon Atanasyan87459932014-05-29 11:05:31 +0000372 return EC;
373
Davide Italiano6cf09262016-11-16 05:10:28 +0000374 auto InfoSection = Obj.getSection(Shdr->sh_info);
375 if (!InfoSection)
376 return errorToErrorCode(InfoSection.takeError());
Rafael Espindola6def3042015-07-01 12:56:27 +0000377
Rafael Espindola88ee57e2017-09-05 22:30:00 +0000378 auto NameOrErr = getUniquedSectionName(*InfoSection);
Davide Italiano6cf09262016-11-16 05:10:28 +0000379 if (!NameOrErr)
380 return errorToErrorCode(NameOrErr.takeError());
George Rimarb87ea732019-02-12 09:08:59 +0000381 S.RelocatableSec = NameOrErr.get();
Simon Atanasyan87459932014-05-29 11:05:31 +0000382
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000383 return obj2yaml_error::success;
384}
385
386template <class ELFT>
George Rimar0e7ed912019-02-09 11:34:28 +0000387ErrorOr<ELFYAML::DynamicSection *>
388ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
389 auto S = make_unique<ELFYAML::DynamicSection>();
390 if (std::error_code EC = dumpCommonSection(Shdr, *S))
391 return EC;
392
393 auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(Shdr);
394 if (!DynTagsOrErr)
395 return errorToErrorCode(DynTagsOrErr.takeError());
396
397 for (const Elf_Dyn &Dyn : *DynTagsOrErr)
398 S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
399
400 return S.release();
401}
402
403template <class ELFT>
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000404ErrorOr<ELFYAML::RelocationSection *>
George Rimarafe8a042019-02-01 07:50:08 +0000405ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000406 auto S = make_unique<ELFYAML::RelocationSection>();
Rafael Espindola4453e42942014-06-13 03:07:50 +0000407 if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S))
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000408 return EC;
409
Davide Italiano6cf09262016-11-16 05:10:28 +0000410 auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
411 if (!SymTabOrErr)
412 return errorToErrorCode(SymTabOrErr.takeError());
Rafael Espindola7d250f72015-09-02 15:07:39 +0000413 const Elf_Shdr *SymTab = *SymTabOrErr;
414
George Rimarafe8a042019-02-01 07:50:08 +0000415 if (Shdr->sh_type == ELF::SHT_REL) {
416 auto Rels = Obj.rels(Shdr);
417 if (!Rels)
418 return errorToErrorCode(Rels.takeError());
419 for (const Elf_Rel &Rel : *Rels) {
420 ELFYAML::Relocation R;
421 if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
422 return EC;
423 S->Relocations.push_back(R);
424 }
425 } else {
426 auto Rels = Obj.relas(Shdr);
427 if (!Rels)
428 return errorToErrorCode(Rels.takeError());
429 for (const Elf_Rela &Rel : *Rels) {
430 ELFYAML::Relocation R;
431 if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
432 return EC;
433 R.Addend = Rel.r_addend;
434 S->Relocations.push_back(R);
435 }
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000436 }
437
438 return S.release();
439}
440
441template <class ELFT>
442ErrorOr<ELFYAML::RawContentSection *>
443ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
444 auto S = make_unique<ELFYAML::RawContentSection>();
445
Rafael Espindola4453e42942014-06-13 03:07:50 +0000446 if (std::error_code EC = dumpCommonSection(Shdr, *S))
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000447 return EC;
448
Davide Italiano6cf09262016-11-16 05:10:28 +0000449 auto ContentOrErr = Obj.getSectionContents(Shdr);
450 if (!ContentOrErr)
451 return errorToErrorCode(ContentOrErr.takeError());
Rafael Espindola97de4742014-07-03 02:01:39 +0000452 S->Content = yaml::BinaryRef(ContentOrErr.get());
Simon Atanasyanb83f3802014-05-16 16:01:00 +0000453 S->Size = S->Content.binary_size();
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000454
455 return S.release();
456}
457
458template <class ELFT>
Simon Atanasyan5db02762015-07-03 23:00:54 +0000459ErrorOr<ELFYAML::NoBitsSection *>
460ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
461 auto S = make_unique<ELFYAML::NoBitsSection>();
462
463 if (std::error_code EC = dumpCommonSection(Shdr, *S))
464 return EC;
465 S->Size = Shdr->sh_size;
466
467 return S.release();
468}
469
470template <class ELFT>
George Rimar623ae722019-02-21 12:21:43 +0000471ErrorOr<ELFYAML::VerdefSection *>
472ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
473 typedef typename ELFT::Verdef Elf_Verdef;
474 typedef typename ELFT::Verdaux Elf_Verdaux;
475
476 auto S = make_unique<ELFYAML::VerdefSection>();
477 if (std::error_code EC = dumpCommonSection(Shdr, *S))
478 return EC;
479
480 S->Info = Shdr->sh_info;
481
482 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
483 if (!StringTableShdrOrErr)
484 return errorToErrorCode(StringTableShdrOrErr.takeError());
485
486 auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
487 if (!StringTableOrErr)
488 return errorToErrorCode(StringTableOrErr.takeError());
489
490 auto Contents = Obj.getSectionContents(Shdr);
491 if (!Contents)
492 return errorToErrorCode(Contents.takeError());
493
494 llvm::ArrayRef<uint8_t> Data = *Contents;
495 const uint8_t *Buf = Data.data();
496 while (Buf) {
497 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
498 ELFYAML::VerdefEntry Entry;
499 Entry.Version = Verdef->vd_version;
500 Entry.Flags = Verdef->vd_flags;
501 Entry.VersionNdx = Verdef->vd_ndx;
502 Entry.Hash = Verdef->vd_hash;
503
504 const uint8_t *BufAux = Buf + Verdef->vd_aux;
505 while (BufAux) {
506 const Elf_Verdaux *Verdaux =
507 reinterpret_cast<const Elf_Verdaux *>(BufAux);
508 Entry.VerNames.push_back(
509 StringTableOrErr->drop_front(Verdaux->vda_name).data());
510 BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
511 }
512
513 S->Entries.push_back(Entry);
514 Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
515 }
516
517 return S.release();
518}
519
520template <class ELFT>
George Rimar646af082019-02-19 15:29:07 +0000521ErrorOr<ELFYAML::SymverSection *>
522ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
523 typedef typename ELFT::Half Elf_Half;
524
525 auto S = make_unique<ELFYAML::SymverSection>();
526 if (std::error_code EC = dumpCommonSection(Shdr, *S))
527 return EC;
528
529 auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(Shdr);
530 if (!VersionsOrErr)
531 return errorToErrorCode(VersionsOrErr.takeError());
532 for (const Elf_Half &E : *VersionsOrErr)
533 S->Entries.push_back(E);
534
535 return S.release();
536}
537
538template <class ELFT>
George Rimar0621b792019-02-19 14:53:48 +0000539ErrorOr<ELFYAML::VerneedSection *>
540ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
541 typedef typename ELFT::Verneed Elf_Verneed;
542 typedef typename ELFT::Vernaux Elf_Vernaux;
543
544 auto S = make_unique<ELFYAML::VerneedSection>();
545 if (std::error_code EC = dumpCommonSection(Shdr, *S))
546 return EC;
547
548 S->Info = Shdr->sh_info;
549
550 auto Contents = Obj.getSectionContents(Shdr);
551 if (!Contents)
552 return errorToErrorCode(Contents.takeError());
553
554 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
555 if (!StringTableShdrOrErr)
556 return errorToErrorCode(StringTableShdrOrErr.takeError());
557
558 auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
559 if (!StringTableOrErr)
560 return errorToErrorCode(StringTableOrErr.takeError());
561
562 llvm::ArrayRef<uint8_t> Data = *Contents;
563 const uint8_t *Buf = Data.data();
564 while (Buf) {
565 const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
566
567 ELFYAML::VerneedEntry Entry;
568 Entry.Version = Verneed->vn_version;
569 Entry.File =
570 StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data());
571
572 const uint8_t *BufAux = Buf + Verneed->vn_aux;
573 while (BufAux) {
574 const Elf_Vernaux *Vernaux =
575 reinterpret_cast<const Elf_Vernaux *>(BufAux);
576
577 ELFYAML::VernauxEntry Aux;
578 Aux.Hash = Vernaux->vna_hash;
579 Aux.Flags = Vernaux->vna_flags;
580 Aux.Other = Vernaux->vna_other;
581 Aux.Name =
582 StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data());
583
584 Entry.AuxV.push_back(Aux);
585 BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
586 }
587
588 S->VerneedV.push_back(Entry);
589 Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
590 }
591
592 return S.release();
593}
594
595template <class ELFT>
Shankar Easwaran6fbbe202015-02-21 04:28:26 +0000596ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
597 auto S = make_unique<ELFYAML::Group>();
598
599 if (std::error_code EC = dumpCommonSection(Shdr, *S))
600 return EC;
601 // Get sh_info which is the signature.
Davide Italiano6cf09262016-11-16 05:10:28 +0000602 auto SymtabOrErr = Obj.getSection(Shdr->sh_link);
603 if (!SymtabOrErr)
604 return errorToErrorCode(SymtabOrErr.takeError());
Rafael Espindola651ed6c2015-07-23 12:49:40 +0000605 const Elf_Shdr *Symtab = *SymtabOrErr;
Davide Italiano6cf09262016-11-16 05:10:28 +0000606 auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
607 if (!SymOrErr)
608 return errorToErrorCode(SymOrErr.takeError());
George Rimar02334f62016-11-03 08:41:46 +0000609 const Elf_Sym *symbol = *SymOrErr;
Davide Italiano6cf09262016-11-16 05:10:28 +0000610 auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
611 if (!StrTabOrErr)
612 return errorToErrorCode(StrTabOrErr.takeError());
Rafael Espindola6a1bfb22015-06-29 14:39:25 +0000613 StringRef StrTab = *StrTabOrErr;
Shankar Easwaran6fbbe202015-02-21 04:28:26 +0000614 auto sectionContents = Obj.getSectionContents(Shdr);
Davide Italiano6cf09262016-11-16 05:10:28 +0000615 if (!sectionContents)
616 return errorToErrorCode(sectionContents.takeError());
Rafael Espindoladc8b7a92017-09-06 00:57:53 +0000617 Expected<StringRef> symbolName = getSymbolName(symbol, StrTab, Symtab);
Kevin Enderby81e8b7d2016-04-20 21:24:34 +0000618 if (!symbolName)
619 return errorToErrorCode(symbolName.takeError());
George Rimarb87ea732019-02-12 09:08:59 +0000620 S->Signature = *symbolName;
Shankar Easwaran6fbbe202015-02-21 04:28:26 +0000621 const Elf_Word *groupMembers =
622 reinterpret_cast<const Elf_Word *>(sectionContents->data());
623 const long count = (Shdr->sh_size) / sizeof(Elf_Word);
624 ELFYAML::SectionOrType s;
625 for (int i = 0; i < count; i++) {
626 if (groupMembers[i] == llvm::ELF::GRP_COMDAT) {
627 s.sectionNameOrType = "GRP_COMDAT";
628 } else {
Davide Italiano6cf09262016-11-16 05:10:28 +0000629 auto sHdr = Obj.getSection(groupMembers[i]);
630 if (!sHdr)
631 return errorToErrorCode(sHdr.takeError());
Rafael Espindola88ee57e2017-09-05 22:30:00 +0000632 auto sectionName = getUniquedSectionName(*sHdr);
Davide Italiano6cf09262016-11-16 05:10:28 +0000633 if (!sectionName)
634 return errorToErrorCode(sectionName.takeError());
Shankar Easwaran6fbbe202015-02-21 04:28:26 +0000635 s.sectionNameOrType = *sectionName;
636 }
637 S->Members.push_back(s);
638 }
639 return S.release();
640}
641
642template <class ELFT>
Simon Atanasyan04d9e652015-05-07 15:40:48 +0000643ErrorOr<ELFYAML::MipsABIFlags *>
644ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
645 assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&
646 "Section type is not SHT_MIPS_ABIFLAGS");
647 auto S = make_unique<ELFYAML::MipsABIFlags>();
648 if (std::error_code EC = dumpCommonSection(Shdr, *S))
649 return EC;
650
Davide Italiano6cf09262016-11-16 05:10:28 +0000651 auto ContentOrErr = Obj.getSectionContents(Shdr);
652 if (!ContentOrErr)
653 return errorToErrorCode(ContentOrErr.takeError());
Simon Atanasyan04d9e652015-05-07 15:40:48 +0000654
655 auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
656 ContentOrErr.get().data());
657 S->Version = Flags->version;
658 S->ISALevel = Flags->isa_level;
659 S->ISARevision = Flags->isa_rev;
660 S->GPRSize = Flags->gpr_size;
661 S->CPR1Size = Flags->cpr1_size;
662 S->CPR2Size = Flags->cpr2_size;
663 S->FpABI = Flags->fp_abi;
664 S->ISAExtension = Flags->isa_ext;
665 S->ASEs = Flags->ases;
666 S->Flags1 = Flags->flags1;
667 S->Flags2 = Flags->flags2;
668 return S.release();
669}
670
671template <class ELFT>
Rafael Espindola4453e42942014-06-13 03:07:50 +0000672static std::error_code elf2yaml(raw_ostream &Out,
673 const object::ELFFile<ELFT> &Obj) {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000674 ELFDumper<ELFT> Dumper(Obj);
675 ErrorOr<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
Rafael Espindola4453e42942014-06-13 03:07:50 +0000676 if (std::error_code EC = YAMLOrErr.getError())
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000677 return EC;
678
679 std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
680 yaml::Output Yout(Out);
681 Yout << *YAML;
682
Rui Ueyama7d099192015-06-09 15:20:42 +0000683 return std::error_code();
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000684}
685
Rafael Espindola4453e42942014-06-13 03:07:50 +0000686std::error_code elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
Simon Atanasyanae6bb332014-05-14 05:07:47 +0000687 if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
688 return elf2yaml(Out, *ELFObj->getELFFile());
689
690 if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
691 return elf2yaml(Out, *ELFObj->getELFFile());
692
693 if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
694 return elf2yaml(Out, *ELFObj->getELFFile());
695
696 if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
697 return elf2yaml(Out, *ELFObj->getELFFile());
698
699 return obj2yaml_error::unsupported_obj_file_format;
700}