ELFDump.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. //===-- ELFDump.cpp - ELF-specific dumper -----------------------*- C++ -*-===//
  2. //
  3. // 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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. /// This file implements the ELF-specific dumper for llvm-objdump.
  11. ///
  12. //===----------------------------------------------------------------------===//
  13. #include "ELFDump.h"
  14. #include "llvm-objdump.h"
  15. #include "llvm/Demangle/Demangle.h"
  16. #include "llvm/Object/ELFObjectFile.h"
  17. #include "llvm/Support/Format.h"
  18. #include "llvm/Support/MathExtras.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. using namespace llvm;
  21. using namespace llvm::object;
  22. using namespace llvm::objdump;
  23. template <class ELFT>
  24. static Expected<StringRef> getDynamicStrTab(const ELFFile<ELFT> &Elf) {
  25. auto DynamicEntriesOrError = Elf.dynamicEntries();
  26. if (!DynamicEntriesOrError)
  27. return DynamicEntriesOrError.takeError();
  28. for (const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
  29. if (Dyn.d_tag == ELF::DT_STRTAB) {
  30. auto MappedAddrOrError = Elf.toMappedAddr(Dyn.getPtr());
  31. if (!MappedAddrOrError)
  32. consumeError(MappedAddrOrError.takeError());
  33. return StringRef(reinterpret_cast<const char *>(*MappedAddrOrError));
  34. }
  35. }
  36. // If the dynamic segment is not present, we fall back on the sections.
  37. auto SectionsOrError = Elf.sections();
  38. if (!SectionsOrError)
  39. return SectionsOrError.takeError();
  40. for (const typename ELFT::Shdr &Sec : *SectionsOrError) {
  41. if (Sec.sh_type == ELF::SHT_DYNSYM)
  42. return Elf.getStringTableForSymtab(Sec);
  43. }
  44. return createError("dynamic string table not found");
  45. }
  46. template <class ELFT>
  47. static Error getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
  48. const RelocationRef &RelRef,
  49. SmallVectorImpl<char> &Result) {
  50. const ELFFile<ELFT> &EF = Obj->getELFFile();
  51. DataRefImpl Rel = RelRef.getRawDataRefImpl();
  52. auto SecOrErr = EF.getSection(Rel.d.a);
  53. if (!SecOrErr)
  54. return SecOrErr.takeError();
  55. int64_t Addend = 0;
  56. // If there is no Symbol associated with the relocation, we set the undef
  57. // boolean value to 'true'. This will prevent us from calling functions that
  58. // requires the relocation to be associated with a symbol.
  59. //
  60. // In SHT_REL case we would need to read the addend from section data.
  61. // GNU objdump does not do that and we just follow for simplicity atm.
  62. bool Undef = false;
  63. if ((*SecOrErr)->sh_type == ELF::SHT_RELA) {
  64. const typename ELFT::Rela *ERela = Obj->getRela(Rel);
  65. Addend = ERela->r_addend;
  66. Undef = ERela->getSymbol(false) == 0;
  67. } else if ((*SecOrErr)->sh_type != ELF::SHT_REL) {
  68. return make_error<BinaryError>();
  69. }
  70. // Default scheme is to print Target, as well as "+ <addend>" for nonzero
  71. // addend. Should be acceptable for all normal purposes.
  72. std::string FmtBuf;
  73. raw_string_ostream Fmt(FmtBuf);
  74. if (!Undef) {
  75. symbol_iterator SI = RelRef.getSymbol();
  76. Expected<const typename ELFT::Sym *> SymOrErr =
  77. Obj->getSymbol(SI->getRawDataRefImpl());
  78. // TODO: test this error.
  79. if (!SymOrErr)
  80. return SymOrErr.takeError();
  81. if ((*SymOrErr)->getType() == ELF::STT_SECTION) {
  82. Expected<section_iterator> SymSI = SI->getSection();
  83. if (!SymSI)
  84. return SymSI.takeError();
  85. const typename ELFT::Shdr *SymSec =
  86. Obj->getSection((*SymSI)->getRawDataRefImpl());
  87. auto SecName = EF.getSectionName(*SymSec);
  88. if (!SecName)
  89. return SecName.takeError();
  90. Fmt << *SecName;
  91. } else {
  92. Expected<StringRef> SymName = SI->getName();
  93. if (!SymName)
  94. return SymName.takeError();
  95. if (Demangle)
  96. Fmt << demangle(std::string(*SymName));
  97. else
  98. Fmt << *SymName;
  99. }
  100. } else {
  101. Fmt << "*ABS*";
  102. }
  103. if (Addend != 0) {
  104. Fmt << (Addend < 0
  105. ? "-"
  106. : "+") << format("0x%" PRIx64,
  107. (Addend < 0 ? -(uint64_t)Addend : (uint64_t)Addend));
  108. }
  109. Fmt.flush();
  110. Result.append(FmtBuf.begin(), FmtBuf.end());
  111. return Error::success();
  112. }
  113. Error objdump::getELFRelocationValueString(const ELFObjectFileBase *Obj,
  114. const RelocationRef &Rel,
  115. SmallVectorImpl<char> &Result) {
  116. if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
  117. return getRelocationValueString(ELF32LE, Rel, Result);
  118. if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
  119. return getRelocationValueString(ELF64LE, Rel, Result);
  120. if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
  121. return getRelocationValueString(ELF32BE, Rel, Result);
  122. auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
  123. return getRelocationValueString(ELF64BE, Rel, Result);
  124. }
  125. template <class ELFT>
  126. static uint64_t getSectionLMA(const ELFFile<ELFT> &Obj,
  127. const object::ELFSectionRef &Sec) {
  128. auto PhdrRangeOrErr = Obj.program_headers();
  129. if (!PhdrRangeOrErr)
  130. report_fatal_error(toString(PhdrRangeOrErr.takeError()));
  131. // Search for a PT_LOAD segment containing the requested section. Use this
  132. // segment's p_addr to calculate the section's LMA.
  133. for (const typename ELFT::Phdr &Phdr : *PhdrRangeOrErr)
  134. if ((Phdr.p_type == ELF::PT_LOAD) && (Phdr.p_vaddr <= Sec.getAddress()) &&
  135. (Phdr.p_vaddr + Phdr.p_memsz > Sec.getAddress()))
  136. return Sec.getAddress() - Phdr.p_vaddr + Phdr.p_paddr;
  137. // Return section's VMA if it isn't in a PT_LOAD segment.
  138. return Sec.getAddress();
  139. }
  140. uint64_t objdump::getELFSectionLMA(const object::ELFSectionRef &Sec) {
  141. if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Sec.getObject()))
  142. return getSectionLMA(ELFObj->getELFFile(), Sec);
  143. else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Sec.getObject()))
  144. return getSectionLMA(ELFObj->getELFFile(), Sec);
  145. else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Sec.getObject()))
  146. return getSectionLMA(ELFObj->getELFFile(), Sec);
  147. const auto *ELFObj = cast<ELF64BEObjectFile>(Sec.getObject());
  148. return getSectionLMA(ELFObj->getELFFile(), Sec);
  149. }
  150. template <class ELFT>
  151. static void printDynamicSection(const ELFFile<ELFT> &Elf, StringRef Filename) {
  152. ArrayRef<typename ELFT::Dyn> DynamicEntries =
  153. unwrapOrError(Elf.dynamicEntries(), Filename);
  154. // Find the maximum tag name length to format the value column properly.
  155. size_t MaxLen = 0;
  156. for (const typename ELFT::Dyn &Dyn : DynamicEntries)
  157. MaxLen = std::max(MaxLen, Elf.getDynamicTagAsString(Dyn.d_tag).size());
  158. std::string TagFmt = " %-" + std::to_string(MaxLen) + "s ";
  159. outs() << "Dynamic Section:\n";
  160. for (const typename ELFT::Dyn &Dyn : DynamicEntries) {
  161. if (Dyn.d_tag == ELF::DT_NULL)
  162. continue;
  163. std::string Str = Elf.getDynamicTagAsString(Dyn.d_tag);
  164. outs() << format(TagFmt.c_str(), Str.c_str());
  165. const char *Fmt =
  166. ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n";
  167. if (Dyn.d_tag == ELF::DT_NEEDED || Dyn.d_tag == ELF::DT_RPATH ||
  168. Dyn.d_tag == ELF::DT_RUNPATH || Dyn.d_tag == ELF::DT_SONAME ||
  169. Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER) {
  170. Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
  171. if (StrTabOrErr) {
  172. const char *Data = StrTabOrErr.get().data();
  173. outs() << (Data + Dyn.d_un.d_val) << "\n";
  174. continue;
  175. }
  176. reportWarning(toString(StrTabOrErr.takeError()), Filename);
  177. consumeError(StrTabOrErr.takeError());
  178. }
  179. outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val);
  180. }
  181. }
  182. template <class ELFT>
  183. static void printProgramHeaders(const ELFFile<ELFT> &Obj, StringRef FileName) {
  184. outs() << "Program Header:\n";
  185. auto ProgramHeaderOrError = Obj.program_headers();
  186. if (!ProgramHeaderOrError) {
  187. reportWarning("unable to read program headers: " +
  188. toString(ProgramHeaderOrError.takeError()),
  189. FileName);
  190. return;
  191. }
  192. for (const typename ELFT::Phdr &Phdr : *ProgramHeaderOrError) {
  193. switch (Phdr.p_type) {
  194. case ELF::PT_DYNAMIC:
  195. outs() << " DYNAMIC ";
  196. break;
  197. case ELF::PT_GNU_EH_FRAME:
  198. outs() << "EH_FRAME ";
  199. break;
  200. case ELF::PT_GNU_RELRO:
  201. outs() << " RELRO ";
  202. break;
  203. case ELF::PT_GNU_PROPERTY:
  204. outs() << " PROPERTY ";
  205. break;
  206. case ELF::PT_GNU_STACK:
  207. outs() << " STACK ";
  208. break;
  209. case ELF::PT_INTERP:
  210. outs() << " INTERP ";
  211. break;
  212. case ELF::PT_LOAD:
  213. outs() << " LOAD ";
  214. break;
  215. case ELF::PT_NOTE:
  216. outs() << " NOTE ";
  217. break;
  218. case ELF::PT_OPENBSD_BOOTDATA:
  219. outs() << " OPENBSD_BOOTDATA ";
  220. break;
  221. case ELF::PT_OPENBSD_RANDOMIZE:
  222. outs() << " OPENBSD_RANDOMIZE ";
  223. break;
  224. case ELF::PT_OPENBSD_WXNEEDED:
  225. outs() << " OPENBSD_WXNEEDED ";
  226. break;
  227. case ELF::PT_PHDR:
  228. outs() << " PHDR ";
  229. break;
  230. case ELF::PT_TLS:
  231. outs() << " TLS ";
  232. break;
  233. default:
  234. outs() << " UNKNOWN ";
  235. }
  236. const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " ";
  237. outs() << "off " << format(Fmt, (uint64_t)Phdr.p_offset) << "vaddr "
  238. << format(Fmt, (uint64_t)Phdr.p_vaddr) << "paddr "
  239. << format(Fmt, (uint64_t)Phdr.p_paddr)
  240. << format("align 2**%u\n",
  241. countTrailingZeros<uint64_t>(Phdr.p_align))
  242. << " filesz " << format(Fmt, (uint64_t)Phdr.p_filesz)
  243. << "memsz " << format(Fmt, (uint64_t)Phdr.p_memsz) << "flags "
  244. << ((Phdr.p_flags & ELF::PF_R) ? "r" : "-")
  245. << ((Phdr.p_flags & ELF::PF_W) ? "w" : "-")
  246. << ((Phdr.p_flags & ELF::PF_X) ? "x" : "-") << "\n";
  247. }
  248. outs() << "\n";
  249. }
  250. template <class ELFT>
  251. static void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
  252. StringRef StrTab) {
  253. outs() << "Version References:\n";
  254. const uint8_t *Buf = Contents.data();
  255. while (Buf) {
  256. auto *Verneed = reinterpret_cast<const typename ELFT::Verneed *>(Buf);
  257. outs() << " required from "
  258. << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n";
  259. const uint8_t *BufAux = Buf + Verneed->vn_aux;
  260. while (BufAux) {
  261. auto *Vernaux = reinterpret_cast<const typename ELFT::Vernaux *>(BufAux);
  262. outs() << " "
  263. << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash)
  264. << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags)
  265. << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other)
  266. << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n';
  267. BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
  268. }
  269. Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
  270. }
  271. }
  272. template <class ELFT>
  273. static void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
  274. ArrayRef<uint8_t> Contents,
  275. StringRef StrTab) {
  276. outs() << "Version definitions:\n";
  277. const uint8_t *Buf = Contents.data();
  278. uint32_t VerdefIndex = 1;
  279. // sh_info contains the number of entries in the SHT_GNU_verdef section. To
  280. // make the index column have consistent width, we should insert blank spaces
  281. // according to sh_info.
  282. uint16_t VerdefIndexWidth = std::to_string(Shdr.sh_info).size();
  283. while (Buf) {
  284. auto *Verdef = reinterpret_cast<const typename ELFT::Verdef *>(Buf);
  285. outs() << format_decimal(VerdefIndex++, VerdefIndexWidth) << " "
  286. << format("0x%02" PRIx16 " ", (uint16_t)Verdef->vd_flags)
  287. << format("0x%08" PRIx32 " ", (uint32_t)Verdef->vd_hash);
  288. const uint8_t *BufAux = Buf + Verdef->vd_aux;
  289. uint16_t VerdauxIndex = 0;
  290. while (BufAux) {
  291. auto *Verdaux = reinterpret_cast<const typename ELFT::Verdaux *>(BufAux);
  292. if (VerdauxIndex)
  293. outs() << std::string(VerdefIndexWidth + 17, ' ');
  294. outs() << StringRef(StrTab.drop_front(Verdaux->vda_name).data()) << '\n';
  295. BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
  296. ++VerdauxIndex;
  297. }
  298. Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
  299. }
  300. }
  301. template <class ELFT>
  302. static void printSymbolVersionInfo(const ELFFile<ELFT> &Elf,
  303. StringRef FileName) {
  304. ArrayRef<typename ELFT::Shdr> Sections =
  305. unwrapOrError(Elf.sections(), FileName);
  306. for (const typename ELFT::Shdr &Shdr : Sections) {
  307. if (Shdr.sh_type != ELF::SHT_GNU_verneed &&
  308. Shdr.sh_type != ELF::SHT_GNU_verdef)
  309. continue;
  310. ArrayRef<uint8_t> Contents =
  311. unwrapOrError(Elf.getSectionContents(Shdr), FileName);
  312. const typename ELFT::Shdr *StrTabSec =
  313. unwrapOrError(Elf.getSection(Shdr.sh_link), FileName);
  314. StringRef StrTab = unwrapOrError(Elf.getStringTable(*StrTabSec), FileName);
  315. if (Shdr.sh_type == ELF::SHT_GNU_verneed)
  316. printSymbolVersionDependency<ELFT>(Contents, StrTab);
  317. else
  318. printSymbolVersionDefinition<ELFT>(Shdr, Contents, StrTab);
  319. }
  320. }
  321. void objdump::printELFFileHeader(const object::ObjectFile *Obj) {
  322. if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
  323. printProgramHeaders(ELFObj->getELFFile(), Obj->getFileName());
  324. else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
  325. printProgramHeaders(ELFObj->getELFFile(), Obj->getFileName());
  326. else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
  327. printProgramHeaders(ELFObj->getELFFile(), Obj->getFileName());
  328. else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
  329. printProgramHeaders(ELFObj->getELFFile(), Obj->getFileName());
  330. }
  331. void objdump::printELFDynamicSection(const object::ObjectFile *Obj) {
  332. if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
  333. printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
  334. else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
  335. printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
  336. else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
  337. printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
  338. else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
  339. printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
  340. }
  341. void objdump::printELFSymbolVersionInfo(const object::ObjectFile *Obj) {
  342. if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
  343. printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
  344. else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
  345. printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
  346. else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
  347. printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
  348. else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
  349. printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
  350. }