blob: 159e300de305851b59bd0d96ae51b4f795e15776 [file] [log] [blame]
Eugene Zelenko416e0592017-06-09 21:41:54 +00001//===- ELFDumper.cpp - ELF-specific dumper --------------------------------===//
George Rimar47936762016-01-16 00:49:19 +00002//
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
George Rimar47936762016-01-16 00:49:19 +00006//
7//===----------------------------------------------------------------------===//
8///
9/// \file
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000010/// This file implements the ELF-specific dumper for llvm-readobj.
George Rimar47936762016-01-16 00:49:19 +000011///
12//===----------------------------------------------------------------------===//
13
George Rimar47936762016-01-16 00:49:19 +000014#include "ARMEHABIPrinter.h"
Rafael Auler86fb7bf2018-03-08 00:46:53 +000015#include "DwarfCFIEHPrinter.h"
George Rimar47936762016-01-16 00:49:19 +000016#include "Error.h"
17#include "ObjDumper.h"
18#include "StackMapPrinter.h"
Zachary Turner88bb1632016-05-03 00:28:04 +000019#include "llvm-readobj.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000020#include "llvm/ADT/ArrayRef.h"
George Rimar762abff62017-09-16 14:29:51 +000021#include "llvm/ADT/DenseMap.h"
Matt Davis0d0e9c02019-02-05 21:01:01 +000022#include "llvm/ADT/DenseSet.h"
George Rimar47936762016-01-16 00:49:19 +000023#include "llvm/ADT/Optional.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000024#include "llvm/ADT/PointerIntPair.h"
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +000025#include "llvm/ADT/STLExtras.h"
George Rimar47936762016-01-16 00:49:19 +000026#include "llvm/ADT/SmallString.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000027#include "llvm/ADT/SmallVector.h"
George Rimar47936762016-01-16 00:49:19 +000028#include "llvm/ADT/StringExtras.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000029#include "llvm/ADT/StringRef.h"
30#include "llvm/ADT/Twine.h"
Scott Linderf5b36e52018-12-12 19:39:27 +000031#include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000032#include "llvm/BinaryFormat/ELF.h"
James Hendersone50d9cb2019-01-17 15:34:12 +000033#include "llvm/Demangle/Demangle.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000034#include "llvm/Object/ELF.h"
George Rimar47936762016-01-16 00:49:19 +000035#include "llvm/Object/ELFObjectFile.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000036#include "llvm/Object/ELFTypes.h"
37#include "llvm/Object/Error.h"
38#include "llvm/Object/ObjectFile.h"
39#include "llvm/Object/StackMapParser.h"
Konstantin Zhuravlyovb3c605d2017-10-14 18:21:42 +000040#include "llvm/Support/AMDGPUMetadata.h"
Sam Parker34315ee2017-01-13 10:50:01 +000041#include "llvm/Support/ARMAttributeParser.h"
George Rimar47936762016-01-16 00:49:19 +000042#include "llvm/Support/ARMBuildAttributes.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000043#include "llvm/Support/Casting.h"
George Rimar47936762016-01-16 00:49:19 +000044#include "llvm/Support/Compiler.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000045#include "llvm/Support/Endian.h"
46#include "llvm/Support/ErrorHandling.h"
George Rimar47936762016-01-16 00:49:19 +000047#include "llvm/Support/Format.h"
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +000048#include "llvm/Support/FormatVariadic.h"
Zachary Turner88bb1632016-05-03 00:28:04 +000049#include "llvm/Support/FormattedStream.h"
Peter Collingbourne3e227332018-07-17 22:17:18 +000050#include "llvm/Support/LEB128.h"
George Rimar47936762016-01-16 00:49:19 +000051#include "llvm/Support/MathExtras.h"
52#include "llvm/Support/MipsABIFlags.h"
Zachary Turner88bb1632016-05-03 00:28:04 +000053#include "llvm/Support/ScopedPrinter.h"
George Rimar47936762016-01-16 00:49:19 +000054#include "llvm/Support/raw_ostream.h"
Eugene Zelenko416e0592017-06-09 21:41:54 +000055#include <algorithm>
56#include <cinttypes>
57#include <cstddef>
58#include <cstdint>
59#include <cstdlib>
60#include <iterator>
61#include <memory>
62#include <string>
63#include <system_error>
64#include <vector>
George Rimar47936762016-01-16 00:49:19 +000065
66using namespace llvm;
67using namespace llvm::object;
68using namespace ELF;
69
George Rimar9e88a262019-05-14 14:22:44 +000070#define LLVM_READOBJ_ENUM_CASE(ns, enum) \
71 case ns::enum: \
72 return #enum;
George Rimar47936762016-01-16 00:49:19 +000073
George Rimar9e88a262019-05-14 14:22:44 +000074#define ENUM_ENT(enum, altName) \
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +000075 { #enum, altName, ELF::enum }
76
George Rimar9e88a262019-05-14 14:22:44 +000077#define ENUM_ENT_1(enum) \
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +000078 { #enum, #enum, ELF::enum }
79
Hemant Kulkarni7d564ba2016-03-28 17:20:23 +000080#define LLVM_READOBJ_PHDR_ENUM(ns, enum) \
81 case ns::enum: \
82 return std::string(#enum).substr(3);
83
Hemant Kulkarni206ba842016-03-09 19:16:13 +000084#define TYPEDEF_ELF_TYPES(ELFT) \
Eugene Zelenko416e0592017-06-09 21:41:54 +000085 using ELFO = ELFFile<ELFT>; \
Rui Ueyama478d6352018-01-12 02:28:31 +000086 using Elf_Addr = typename ELFT::Addr; \
87 using Elf_Shdr = typename ELFT::Shdr; \
88 using Elf_Sym = typename ELFT::Sym; \
89 using Elf_Dyn = typename ELFT::Dyn; \
90 using Elf_Dyn_Range = typename ELFT::DynRange; \
91 using Elf_Rel = typename ELFT::Rel; \
92 using Elf_Rela = typename ELFT::Rela; \
Jake Ehrlich0f440d82018-06-28 21:07:34 +000093 using Elf_Relr = typename ELFT::Relr; \
Rui Ueyama478d6352018-01-12 02:28:31 +000094 using Elf_Rel_Range = typename ELFT::RelRange; \
95 using Elf_Rela_Range = typename ELFT::RelaRange; \
Jake Ehrlich0f440d82018-06-28 21:07:34 +000096 using Elf_Relr_Range = typename ELFT::RelrRange; \
Rui Ueyama478d6352018-01-12 02:28:31 +000097 using Elf_Phdr = typename ELFT::Phdr; \
98 using Elf_Half = typename ELFT::Half; \
99 using Elf_Ehdr = typename ELFT::Ehdr; \
100 using Elf_Word = typename ELFT::Word; \
101 using Elf_Hash = typename ELFT::Hash; \
102 using Elf_GnuHash = typename ELFT::GnuHash; \
George Rimarec895f12019-05-16 06:22:51 +0000103 using Elf_Note = typename ELFT::Note; \
Rui Ueyama478d6352018-01-12 02:28:31 +0000104 using Elf_Sym_Range = typename ELFT::SymRange; \
105 using Elf_Versym = typename ELFT::Versym; \
106 using Elf_Verneed = typename ELFT::Verneed; \
107 using Elf_Vernaux = typename ELFT::Vernaux; \
108 using Elf_Verdef = typename ELFT::Verdef; \
109 using Elf_Verdaux = typename ELFT::Verdaux; \
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000110 using Elf_CGProfile = typename ELFT::CGProfile; \
Rui Ueyama478d6352018-01-12 02:28:31 +0000111 using uintX_t = typename ELFT::uint;
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000112
George Rimar47936762016-01-16 00:49:19 +0000113namespace {
114
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000115template <class ELFT> class DumpStyle;
116
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000117/// Represents a contiguous uniform range in the file. We cannot just create a
118/// range directly because when creating one of these from the .dynamic table
119/// the size, entity size and virtual address are different entries in arbitrary
120/// order (DT_REL, DT_RELSZ, DT_RELENT for example).
Rafael Espindola65a6fd82016-02-16 14:27:33 +0000121struct DynRegionInfo {
Eugene Zelenko416e0592017-06-09 21:41:54 +0000122 DynRegionInfo() = default;
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000123 DynRegionInfo(const void *A, uint64_t S, uint64_t ES)
124 : Addr(A), Size(S), EntSize(ES) {}
Eugene Zelenko416e0592017-06-09 21:41:54 +0000125
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000126 /// Address in current address space.
Eugene Zelenko416e0592017-06-09 21:41:54 +0000127 const void *Addr = nullptr;
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000128 /// Size in bytes of the region.
Eugene Zelenko416e0592017-06-09 21:41:54 +0000129 uint64_t Size = 0;
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000130 /// Size of each entity in the region.
Eugene Zelenko416e0592017-06-09 21:41:54 +0000131 uint64_t EntSize = 0;
Rafael Espindolac70aeda2016-02-16 14:50:39 +0000132
Rafael Espindolaaafcf752016-04-05 14:47:22 +0000133 template <typename Type> ArrayRef<Type> getAsArrayRef() const {
Rafael Espindolac70aeda2016-02-16 14:50:39 +0000134 const Type *Start = reinterpret_cast<const Type *>(Addr);
Rafael Espindola944f6552016-02-16 15:16:00 +0000135 if (!Start)
136 return {Start, Start};
Rafael Espindolac70aeda2016-02-16 14:50:39 +0000137 if (EntSize != sizeof(Type) || Size % EntSize)
138 reportError("Invalid entity size");
139 return {Start, Start + (Size / EntSize)};
140 }
Rafael Espindola65a6fd82016-02-16 14:27:33 +0000141};
142
George Rimar9e88a262019-05-14 14:22:44 +0000143template <typename ELFT> class ELFDumper : public ObjDumper {
George Rimar47936762016-01-16 00:49:19 +0000144public:
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000145 ELFDumper(const object::ELFObjectFile<ELFT> *ObjF, ScopedPrinter &Writer);
George Rimar47936762016-01-16 00:49:19 +0000146
147 void printFileHeaders() override;
Jordan Rupprechtdbf552c2018-11-12 18:02:38 +0000148 void printSectionHeaders() override;
George Rimar47936762016-01-16 00:49:19 +0000149 void printRelocations() override;
150 void printDynamicRelocations() override;
James Henderson21ed8682019-01-23 16:15:39 +0000151 void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override;
James Henderson5fc812f2019-01-22 09:35:35 +0000152 void printHashSymbols() override;
George Rimar47936762016-01-16 00:49:19 +0000153 void printUnwindInfo() override;
154
155 void printDynamicTable() override;
156 void printNeededLibraries() override;
Matt Davis50ca8ed2019-02-01 18:51:10 +0000157 void printProgramHeaders(bool PrintProgramHeaders,
158 cl::boolOrDefault PrintSectionMapping) override;
George Rimar47936762016-01-16 00:49:19 +0000159 void printHashTable() override;
160 void printGnuHashTable() override;
161 void printLoadName() override;
162 void printVersionInfo() override;
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +0000163 void printGroupSections() override;
George Rimar47936762016-01-16 00:49:19 +0000164
165 void printAttributes() override;
166 void printMipsPLTGOT() override;
167 void printMipsABIFlags() override;
168 void printMipsReginfo() override;
Simon Atanasyan8a71b532016-05-04 05:58:57 +0000169 void printMipsOptions() override;
George Rimar47936762016-01-16 00:49:19 +0000170
171 void printStackMap() const override;
172
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +0000173 void printHashHistogram() override;
174
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000175 void printCGProfile() override;
Peter Collingbourne3e227332018-07-17 22:17:18 +0000176 void printAddrsig() override;
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000177
Saleem Abdulrasool6a405442016-08-30 18:52:02 +0000178 void printNotes() override;
179
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +0000180 void printELFLinkerOptions() override;
181
George Rimar47936762016-01-16 00:49:19 +0000182private:
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000183 std::unique_ptr<DumpStyle<ELFT>> ELFDumperStyle;
Eugene Zelenko416e0592017-06-09 21:41:54 +0000184
Rafael Espindola6bc29902016-10-06 14:07:26 +0000185 TYPEDEF_ELF_TYPES(ELFT)
George Rimar47936762016-01-16 00:49:19 +0000186
Rafael Espindolae17c3f32016-02-17 16:48:00 +0000187 DynRegionInfo checkDRI(DynRegionInfo DRI) {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000188 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
Rafael Espindolae17c3f32016-02-17 16:48:00 +0000189 if (DRI.Addr < Obj->base() ||
Xing GUO0df95d22019-04-08 11:48:36 +0000190 reinterpret_cast<const uint8_t *>(DRI.Addr) + DRI.Size >
191 Obj->base() + Obj->getBufSize())
Rafael Espindolae17c3f32016-02-17 16:48:00 +0000192 error(llvm::object::object_error::parse_failed);
193 return DRI;
194 }
195
196 DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
George Rimar9e88a262019-05-14 14:22:44 +0000197 return checkDRI(
198 {ObjF->getELFFile()->base() + P->p_offset, P->p_filesz, EntSize});
Rafael Espindolae17c3f32016-02-17 16:48:00 +0000199 }
200
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000201 DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
George Rimar9e88a262019-05-14 14:22:44 +0000202 return checkDRI(
203 {ObjF->getELFFile()->base() + S->sh_offset, S->sh_size, S->sh_entsize});
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000204 }
205
George Rimar72f821d2019-05-20 15:41:48 +0000206 void loadDynamicTable(const ELFFile<ELFT> *Obj);
207 void parseDynamicTable();
Michael J. Spencer60d82b22016-02-11 04:59:37 +0000208
George Rimar47936762016-01-16 00:49:19 +0000209 void printValue(uint64_t Type, uint64_t Value);
210
George Rimar47936762016-01-16 00:49:19 +0000211 StringRef getDynamicString(uint64_t Offset) const;
George Rimar47936762016-01-16 00:49:19 +0000212 StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000213 bool &IsDefault) const;
214 void LoadVersionMap() const;
George Rimar47936762016-01-16 00:49:19 +0000215 void LoadVersionNeeds(const Elf_Shdr *ec) const;
216 void LoadVersionDefs(const Elf_Shdr *sec) const;
217
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000218 const object::ELFObjectFile<ELFT> *ObjF;
Simon Atanasyan72155c32016-01-16 22:40:09 +0000219 DynRegionInfo DynRelRegion;
George Rimar47936762016-01-16 00:49:19 +0000220 DynRegionInfo DynRelaRegion;
Jake Ehrlich0f440d82018-06-28 21:07:34 +0000221 DynRegionInfo DynRelrRegion;
Rafael Espindola944f6552016-02-16 15:16:00 +0000222 DynRegionInfo DynPLTRelRegion;
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000223 DynRegionInfo DynSymRegion;
Rafael Espindolae17c3f32016-02-17 16:48:00 +0000224 DynRegionInfo DynamicTable;
George Rimar47936762016-01-16 00:49:19 +0000225 StringRef DynamicStringTable;
George Rimar47936762016-01-16 00:49:19 +0000226 StringRef SOName;
227 const Elf_Hash *HashTable = nullptr;
228 const Elf_GnuHash *GnuHashTable = nullptr;
George Rimar47936762016-01-16 00:49:19 +0000229 const Elf_Shdr *DotSymtabSec = nullptr;
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000230 const Elf_Shdr *DotCGProfileSec = nullptr;
Peter Collingbourne3e227332018-07-17 22:17:18 +0000231 const Elf_Shdr *DotAddrsigSec = nullptr;
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000232 StringRef DynSymtabName;
George Rimar47936762016-01-16 00:49:19 +0000233 ArrayRef<Elf_Word> ShndxTable;
234
George Rimarec895f12019-05-16 06:22:51 +0000235 const Elf_Shdr *SymbolVersionSection = nullptr; // .gnu.version
Xing GUO09a77fe2019-03-29 01:26:36 +0000236 const Elf_Shdr *SymbolVersionNeedSection = nullptr; // .gnu.version_r
George Rimarec895f12019-05-16 06:22:51 +0000237 const Elf_Shdr *SymbolVersionDefSection = nullptr; // .gnu.version_d
George Rimar47936762016-01-16 00:49:19 +0000238
239 // Records for each version index the corresponding Verdef or Vernaux entry.
240 // This is filled the first time LoadVersionMap() is called.
241 class VersionMapEntry : public PointerIntPair<const void *, 1> {
242 public:
243 // If the integer is 0, this is an Elf_Verdef*.
244 // If the integer is 1, this is an Elf_Vernaux*.
245 VersionMapEntry() : PointerIntPair<const void *, 1>(nullptr, 0) {}
246 VersionMapEntry(const Elf_Verdef *verdef)
247 : PointerIntPair<const void *, 1>(verdef, 0) {}
248 VersionMapEntry(const Elf_Vernaux *vernaux)
249 : PointerIntPair<const void *, 1>(vernaux, 1) {}
Eugene Zelenko416e0592017-06-09 21:41:54 +0000250
George Rimar47936762016-01-16 00:49:19 +0000251 bool isNull() const { return getPointer() == nullptr; }
252 bool isVerdef() const { return !isNull() && getInt() == 0; }
253 bool isVernaux() const { return !isNull() && getInt() == 1; }
254 const Elf_Verdef *getVerdef() const {
255 return isVerdef() ? (const Elf_Verdef *)getPointer() : nullptr;
256 }
257 const Elf_Vernaux *getVernaux() const {
258 return isVernaux() ? (const Elf_Vernaux *)getPointer() : nullptr;
259 }
260 };
261 mutable SmallVector<VersionMapEntry, 16> VersionMap;
262
263public:
264 Elf_Dyn_Range dynamic_table() const {
Rafael Espindolaaafcf752016-04-05 14:47:22 +0000265 return DynamicTable.getAsArrayRef<Elf_Dyn>();
George Rimar47936762016-01-16 00:49:19 +0000266 }
267
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000268 Elf_Sym_Range dynamic_symbols() const {
Rafael Espindolaaafcf752016-04-05 14:47:22 +0000269 return DynSymRegion.getAsArrayRef<Elf_Sym>();
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000270 }
271
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000272 Elf_Rel_Range dyn_rels() const;
273 Elf_Rela_Range dyn_relas() const;
Jake Ehrlich0f440d82018-06-28 21:07:34 +0000274 Elf_Relr_Range dyn_relrs() const;
George Rimar47936762016-01-16 00:49:19 +0000275 std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000276 bool IsDynamic) const;
Simon Atanasyan62d32592017-12-21 10:26:02 +0000277 void getSectionNameIndex(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
278 StringRef &SectionName,
279 unsigned &SectionIndex) const;
James Hendersone50d9cb2019-01-17 15:34:12 +0000280 std::string getStaticSymbolName(uint32_t Index) const;
Liang Zou9f4a4d32019-03-31 14:49:00 +0000281 StringRef getSymbolVersionByIndex(StringRef StrTab,
282 uint32_t VersionSymbolIndex,
Xing GUO7ffd9112019-03-28 12:51:46 +0000283 bool &IsDefault) const;
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000284
285 void printSymbolsHelper(bool IsDynamic) const;
George Rimar47936762016-01-16 00:49:19 +0000286 const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000287 const Elf_Shdr *getDotCGProfileSec() const { return DotCGProfileSec; }
Peter Collingbourne3e227332018-07-17 22:17:18 +0000288 const Elf_Shdr *getDotAddrsigSec() const { return DotAddrsigSec; }
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000289 ArrayRef<Elf_Word> getShndxTable() const { return ShndxTable; }
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000290 StringRef getDynamicStringTable() const { return DynamicStringTable; }
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000291 const DynRegionInfo &getDynRelRegion() const { return DynRelRegion; }
292 const DynRegionInfo &getDynRelaRegion() const { return DynRelaRegion; }
Jake Ehrlich0f440d82018-06-28 21:07:34 +0000293 const DynRegionInfo &getDynRelrRegion() const { return DynRelrRegion; }
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000294 const DynRegionInfo &getDynPLTRelRegion() const { return DynPLTRelRegion; }
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +0000295 const Elf_Hash *getHashTable() const { return HashTable; }
296 const Elf_GnuHash *getGnuHashTable() const { return GnuHashTable; }
George Rimar47936762016-01-16 00:49:19 +0000297};
298
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000299template <class ELFT>
300void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {
301 StringRef StrTable, SymtabName;
302 size_t Entries = 0;
303 Elf_Sym_Range Syms(nullptr, nullptr);
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000304 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000305 if (IsDynamic) {
306 StrTable = DynamicStringTable;
307 Syms = dynamic_symbols();
308 SymtabName = DynSymtabName;
309 if (DynSymRegion.Addr)
310 Entries = DynSymRegion.Size / DynSymRegion.EntSize;
311 } else {
312 if (!DotSymtabSec)
313 return;
314 StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
Rafael Espindola9ea68342016-11-03 13:43:30 +0000315 Syms = unwrapOrError(Obj->symbols(DotSymtabSec));
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000316 SymtabName = unwrapOrError(Obj->getSectionName(DotSymtabSec));
317 Entries = DotSymtabSec->getEntityCount();
318 }
319 if (Syms.begin() == Syms.end())
320 return;
321 ELFDumperStyle->printSymtabMessage(Obj, SymtabName, Entries);
322 for (const auto &Sym : Syms)
323 ELFDumperStyle->printSymbol(Obj, &Sym, Syms.begin(), StrTable, IsDynamic);
324}
325
Simon Atanasyan62d32592017-12-21 10:26:02 +0000326template <class ELFT> class MipsGOTParser;
327
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000328template <typename ELFT> class DumpStyle {
329public:
Rui Ueyama478d6352018-01-12 02:28:31 +0000330 using Elf_Shdr = typename ELFT::Shdr;
331 using Elf_Sym = typename ELFT::Sym;
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000332
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000333 DumpStyle(ELFDumper<ELFT> *Dumper) : Dumper(Dumper) {}
Eugene Zelenko416e0592017-06-09 21:41:54 +0000334 virtual ~DumpStyle() = default;
335
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000336 virtual void printFileHeaders(const ELFFile<ELFT> *Obj) = 0;
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000337 virtual void printGroupSections(const ELFFile<ELFT> *Obj) = 0;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000338 virtual void printRelocations(const ELFFile<ELFT> *Obj) = 0;
Jordan Rupprechtdbf552c2018-11-12 18:02:38 +0000339 virtual void printSectionHeaders(const ELFFile<ELFT> *Obj) = 0;
James Henderson21ed8682019-01-23 16:15:39 +0000340 virtual void printSymbols(const ELFFile<ELFT> *Obj, bool PrintSymbols,
341 bool PrintDynamicSymbols) = 0;
James Henderson5fc812f2019-01-22 09:35:35 +0000342 virtual void printHashSymbols(const ELFFile<ELFT> *Obj) {}
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000343 virtual void printDynamicRelocations(const ELFFile<ELFT> *Obj) = 0;
James Henderson5fc812f2019-01-22 09:35:35 +0000344 virtual void printSymtabMessage(const ELFFile<ELFT> *Obj, StringRef Name,
Eugene Zelenko416e0592017-06-09 21:41:54 +0000345 size_t Offset) {}
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000346 virtual void printSymbol(const ELFFile<ELFT> *Obj, const Elf_Sym *Symbol,
347 const Elf_Sym *FirstSym, StringRef StrTable,
348 bool IsDynamic) = 0;
Matt Davis50ca8ed2019-02-01 18:51:10 +0000349 virtual void printProgramHeaders(const ELFFile<ELFT> *Obj,
350 bool PrintProgramHeaders,
351 cl::boolOrDefault PrintSectionMapping) = 0;
Xing GUOea16be12019-03-25 11:02:49 +0000352 virtual void printVersionSymbolSection(const ELFFile<ELFT> *Obj,
353 const Elf_Shdr *Sec) = 0;
354 virtual void printVersionDefinitionSection(const ELFFile<ELFT> *Obj,
355 const Elf_Shdr *Sec) = 0;
356 virtual void printVersionDependencySection(const ELFFile<ELFT> *Obj,
357 const Elf_Shdr *Sec) = 0;
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +0000358 virtual void printHashHistogram(const ELFFile<ELFT> *Obj) = 0;
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000359 virtual void printCGProfile(const ELFFile<ELFT> *Obj) = 0;
Peter Collingbourne3e227332018-07-17 22:17:18 +0000360 virtual void printAddrsig(const ELFFile<ELFT> *Obj) = 0;
Saleem Abdulrasool6a405442016-08-30 18:52:02 +0000361 virtual void printNotes(const ELFFile<ELFT> *Obj) = 0;
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +0000362 virtual void printELFLinkerOptions(const ELFFile<ELFT> *Obj) = 0;
Simon Atanasyan62d32592017-12-21 10:26:02 +0000363 virtual void printMipsGOT(const MipsGOTParser<ELFT> &Parser) = 0;
364 virtual void printMipsPLT(const MipsGOTParser<ELFT> &Parser) = 0;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000365 const ELFDumper<ELFT> *dumper() const { return Dumper; }
Eugene Zelenko416e0592017-06-09 21:41:54 +0000366
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000367private:
368 const ELFDumper<ELFT> *Dumper;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000369};
370
371template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
372 formatted_raw_ostream OS;
Eugene Zelenko416e0592017-06-09 21:41:54 +0000373
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000374public:
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000375 TYPEDEF_ELF_TYPES(ELFT)
Eugene Zelenko416e0592017-06-09 21:41:54 +0000376
Zachary Turner88bb1632016-05-03 00:28:04 +0000377 GNUStyle(ScopedPrinter &W, ELFDumper<ELFT> *Dumper)
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000378 : DumpStyle<ELFT>(Dumper), OS(W.getOStream()) {}
Eugene Zelenko416e0592017-06-09 21:41:54 +0000379
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000380 void printFileHeaders(const ELFO *Obj) override;
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000381 void printGroupSections(const ELFFile<ELFT> *Obj) override;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000382 void printRelocations(const ELFO *Obj) override;
Jordan Rupprechtdbf552c2018-11-12 18:02:38 +0000383 void printSectionHeaders(const ELFO *Obj) override;
James Henderson21ed8682019-01-23 16:15:39 +0000384 void printSymbols(const ELFO *Obj, bool PrintSymbols,
385 bool PrintDynamicSymbols) override;
James Henderson5fc812f2019-01-22 09:35:35 +0000386 void printHashSymbols(const ELFO *Obj) override;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000387 void printDynamicRelocations(const ELFO *Obj) override;
Eugene Zelenko416e0592017-06-09 21:41:54 +0000388 void printSymtabMessage(const ELFO *Obj, StringRef Name,
389 size_t Offset) override;
Matt Davis50ca8ed2019-02-01 18:51:10 +0000390 void printProgramHeaders(const ELFO *Obj, bool PrintProgramHeaders,
391 cl::boolOrDefault PrintSectionMapping) override;
Xing GUOea16be12019-03-25 11:02:49 +0000392 void printVersionSymbolSection(const ELFFile<ELFT> *Obj,
393 const Elf_Shdr *Sec) override;
394 void printVersionDefinitionSection(const ELFFile<ELFT> *Obj,
395 const Elf_Shdr *Sec) override;
396 void printVersionDependencySection(const ELFFile<ELFT> *Obj,
397 const Elf_Shdr *Sec) override;
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +0000398 void printHashHistogram(const ELFFile<ELFT> *Obj) override;
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000399 void printCGProfile(const ELFFile<ELFT> *Obj) override;
Peter Collingbourne3e227332018-07-17 22:17:18 +0000400 void printAddrsig(const ELFFile<ELFT> *Obj) override;
Saleem Abdulrasool6a405442016-08-30 18:52:02 +0000401 void printNotes(const ELFFile<ELFT> *Obj) override;
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +0000402 void printELFLinkerOptions(const ELFFile<ELFT> *Obj) override;
Simon Atanasyan62d32592017-12-21 10:26:02 +0000403 void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
404 void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000405
406private:
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000407 struct Field {
George Rimar4b4899b2019-01-30 14:08:55 +0000408 std::string Str;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000409 unsigned Column;
Eugene Zelenko416e0592017-06-09 21:41:54 +0000410
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000411 Field(StringRef S, unsigned Col) : Str(S), Column(Col) {}
George Rimar4b4899b2019-01-30 14:08:55 +0000412 Field(unsigned Col) : Column(Col) {}
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000413 };
414
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000415 template <typename T, typename TEnum>
416 std::string printEnum(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) {
417 for (const auto &EnumItem : EnumValues)
418 if (EnumItem.Value == Value)
419 return EnumItem.AltName;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000420 return to_hexString(Value, false);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000421 }
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000422
Simon Atanasyan19932542018-10-25 05:39:27 +0000423 template <typename T, typename TEnum>
424 std::string printFlags(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues,
425 TEnum EnumMask1 = {}, TEnum EnumMask2 = {},
426 TEnum EnumMask3 = {}) {
427 std::string Str;
428 for (const auto &Flag : EnumValues) {
429 if (Flag.Value == 0)
430 continue;
431
432 TEnum EnumMask{};
433 if (Flag.Value & EnumMask1)
434 EnumMask = EnumMask1;
435 else if (Flag.Value & EnumMask2)
436 EnumMask = EnumMask2;
437 else if (Flag.Value & EnumMask3)
438 EnumMask = EnumMask3;
439 bool IsEnum = (Flag.Value & EnumMask) != 0;
440 if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
441 (IsEnum && (Value & EnumMask) == Flag.Value)) {
442 if (!Str.empty())
443 Str += ", ";
444 Str += Flag.AltName;
445 }
446 }
447 return Str;
448 }
449
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000450 formatted_raw_ostream &printField(struct Field F) {
451 if (F.Column != 0)
452 OS.PadToColumn(F.Column);
453 OS << F.Str;
454 OS.flush();
455 return OS;
456 }
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +0000457 void printHashedSymbol(const ELFO *Obj, const Elf_Sym *FirstSym, uint32_t Sym,
458 StringRef StrTable, uint32_t Bucket);
Jake Ehrlich0f440d82018-06-28 21:07:34 +0000459 void printRelocHeader(unsigned SType);
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000460 void printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
461 const Elf_Rela &R, bool IsRela);
James Henderson814ab372019-03-29 11:47:19 +0000462 void printRelocation(const ELFO *Obj, const Elf_Sym *Sym,
463 StringRef SymbolName, const Elf_Rela &R, bool IsRela);
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000464 void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
465 StringRef StrTable, bool IsDynamic) override;
466 std::string getSymbolSectionNdx(const ELFO *Obj, const Elf_Sym *Symbol,
467 const Elf_Sym *FirstSym);
Hemant Kulkarnia79c7982016-03-29 02:41:49 +0000468 void printDynamicRelocation(const ELFO *Obj, Elf_Rela R, bool IsRela);
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +0000469 bool checkTLSSections(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
470 bool checkoffsets(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
471 bool checkVMA(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
472 bool checkPTDynamic(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
Matt Davis50ca8ed2019-02-01 18:51:10 +0000473 void printProgramHeaders(const ELFO *Obj);
474 void printSectionMapping(const ELFO *Obj);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000475};
476
477template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
478public:
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000479 TYPEDEF_ELF_TYPES(ELFT)
Eugene Zelenko416e0592017-06-09 21:41:54 +0000480
Zachary Turner88bb1632016-05-03 00:28:04 +0000481 LLVMStyle(ScopedPrinter &W, ELFDumper<ELFT> *Dumper)
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000482 : DumpStyle<ELFT>(Dumper), W(W) {}
483
484 void printFileHeaders(const ELFO *Obj) override;
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000485 void printGroupSections(const ELFFile<ELFT> *Obj) override;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000486 void printRelocations(const ELFO *Obj) override;
487 void printRelocations(const Elf_Shdr *Sec, const ELFO *Obj);
Jordan Rupprechtdbf552c2018-11-12 18:02:38 +0000488 void printSectionHeaders(const ELFO *Obj) override;
James Henderson21ed8682019-01-23 16:15:39 +0000489 void printSymbols(const ELFO *Obj, bool PrintSymbols,
490 bool PrintDynamicSymbols) override;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000491 void printDynamicRelocations(const ELFO *Obj) override;
Matt Davis50ca8ed2019-02-01 18:51:10 +0000492 void printProgramHeaders(const ELFO *Obj, bool PrintProgramHeaders,
493 cl::boolOrDefault PrintSectionMapping) override;
Xing GUOea16be12019-03-25 11:02:49 +0000494 void printVersionSymbolSection(const ELFFile<ELFT> *Obj,
495 const Elf_Shdr *Sec) override;
496 void printVersionDefinitionSection(const ELFFile<ELFT> *Obj,
497 const Elf_Shdr *Sec) override;
498 void printVersionDependencySection(const ELFFile<ELFT> *Obj,
499 const Elf_Shdr *Sec) override;
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +0000500 void printHashHistogram(const ELFFile<ELFT> *Obj) override;
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000501 void printCGProfile(const ELFFile<ELFT> *Obj) override;
Peter Collingbourne3e227332018-07-17 22:17:18 +0000502 void printAddrsig(const ELFFile<ELFT> *Obj) override;
Saleem Abdulrasool6a405442016-08-30 18:52:02 +0000503 void printNotes(const ELFFile<ELFT> *Obj) override;
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +0000504 void printELFLinkerOptions(const ELFFile<ELFT> *Obj) override;
Simon Atanasyan62d32592017-12-21 10:26:02 +0000505 void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
506 void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000507
508private:
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000509 void printRelocation(const ELFO *Obj, Elf_Rela Rel, const Elf_Shdr *SymTab);
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000510 void printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel);
James Henderson21ed8682019-01-23 16:15:39 +0000511 void printSymbols(const ELFO *Obj);
512 void printDynamicSymbols(const ELFO *Obj);
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +0000513 void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
514 StringRef StrTable, bool IsDynamic) override;
Matt Davis50ca8ed2019-02-01 18:51:10 +0000515 void printProgramHeaders(const ELFO *Obj);
516 void printSectionMapping(const ELFO *Obj) {}
Eugene Zelenko416e0592017-06-09 21:41:54 +0000517
Zachary Turner88bb1632016-05-03 00:28:04 +0000518 ScopedPrinter &W;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000519};
520
Eugene Zelenko416e0592017-06-09 21:41:54 +0000521} // end anonymous namespace
George Rimar47936762016-01-16 00:49:19 +0000522
523namespace llvm {
524
525template <class ELFT>
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000526static std::error_code createELFDumper(const ELFObjectFile<ELFT> *Obj,
Zachary Turner88bb1632016-05-03 00:28:04 +0000527 ScopedPrinter &Writer,
George Rimar47936762016-01-16 00:49:19 +0000528 std::unique_ptr<ObjDumper> &Result) {
529 Result.reset(new ELFDumper<ELFT>(Obj, Writer));
530 return readobj_error::success;
531}
532
533std::error_code createELFDumper(const object::ObjectFile *Obj,
Zachary Turner88bb1632016-05-03 00:28:04 +0000534 ScopedPrinter &Writer,
George Rimar47936762016-01-16 00:49:19 +0000535 std::unique_ptr<ObjDumper> &Result) {
536 // Little-endian 32-bit
537 if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000538 return createELFDumper(ELFObj, Writer, Result);
George Rimar47936762016-01-16 00:49:19 +0000539
540 // Big-endian 32-bit
541 if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000542 return createELFDumper(ELFObj, Writer, Result);
George Rimar47936762016-01-16 00:49:19 +0000543
544 // Little-endian 64-bit
545 if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000546 return createELFDumper(ELFObj, Writer, Result);
George Rimar47936762016-01-16 00:49:19 +0000547
548 // Big-endian 64-bit
549 if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000550 return createELFDumper(ELFObj, Writer, Result);
George Rimar47936762016-01-16 00:49:19 +0000551
552 return readobj_error::unsupported_obj_file_format;
553}
554
Eugene Zelenko416e0592017-06-09 21:41:54 +0000555} // end namespace llvm
George Rimar47936762016-01-16 00:49:19 +0000556
557// Iterate through the versions needed section, and place each Elf_Vernaux
558// in the VersionMap according to its index.
559template <class ELFT>
Xing GUOe855e2e2019-04-12 07:09:41 +0000560void ELFDumper<ELFT>::LoadVersionNeeds(const Elf_Shdr *Sec) const {
561 unsigned VerneedSize = Sec->sh_size; // Size of section in bytes
562 unsigned VerneedEntries = Sec->sh_info; // Number of Verneed entries
563 const uint8_t *VerneedStart = reinterpret_cast<const uint8_t *>(
564 ObjF->getELFFile()->base() + Sec->sh_offset);
565 const uint8_t *VerneedEnd = VerneedStart + VerneedSize;
George Rimar47936762016-01-16 00:49:19 +0000566 // The first Verneed entry is at the start of the section.
Xing GUOe855e2e2019-04-12 07:09:41 +0000567 const uint8_t *VerneedBuf = VerneedStart;
568 for (unsigned VerneedIndex = 0; VerneedIndex < VerneedEntries;
569 ++VerneedIndex) {
570 if (VerneedBuf + sizeof(Elf_Verneed) > VerneedEnd)
George Rimar47936762016-01-16 00:49:19 +0000571 report_fatal_error("Section ended unexpectedly while scanning "
572 "version needed records.");
Xing GUOe855e2e2019-04-12 07:09:41 +0000573 const Elf_Verneed *Verneed =
574 reinterpret_cast<const Elf_Verneed *>(VerneedBuf);
575 if (Verneed->vn_version != ELF::VER_NEED_CURRENT)
George Rimar47936762016-01-16 00:49:19 +0000576 report_fatal_error("Unexpected verneed version");
577 // Iterate through the Vernaux entries
Xing GUOe855e2e2019-04-12 07:09:41 +0000578 const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;
579 for (unsigned VernauxIndex = 0; VernauxIndex < Verneed->vn_cnt;
580 ++VernauxIndex) {
581 if (VernauxBuf + sizeof(Elf_Vernaux) > VerneedEnd)
George Rimar47936762016-01-16 00:49:19 +0000582 report_fatal_error("Section ended unexpected while scanning auxiliary "
583 "version needed records.");
Xing GUOe855e2e2019-04-12 07:09:41 +0000584 const Elf_Vernaux *Vernaux =
585 reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);
586 size_t Index = Vernaux->vna_other & ELF::VERSYM_VERSION;
587 if (Index >= VersionMap.size())
588 VersionMap.resize(Index + 1);
589 VersionMap[Index] = VersionMapEntry(Vernaux);
590 VernauxBuf += Vernaux->vna_next;
George Rimar47936762016-01-16 00:49:19 +0000591 }
Xing GUOe855e2e2019-04-12 07:09:41 +0000592 VerneedBuf += Verneed->vn_next;
George Rimar47936762016-01-16 00:49:19 +0000593 }
594}
595
596// Iterate through the version definitions, and place each Elf_Verdef
597// in the VersionMap according to its index.
598template <class ELFT>
Xing GUOe855e2e2019-04-12 07:09:41 +0000599void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *Sec) const {
600 unsigned VerdefSize = Sec->sh_size; // Size of section in bytes
601 unsigned VerdefEntries = Sec->sh_info; // Number of Verdef entries
602 const uint8_t *VerdefStart = reinterpret_cast<const uint8_t *>(
603 ObjF->getELFFile()->base() + Sec->sh_offset);
604 const uint8_t *VerdefEnd = VerdefStart + VerdefSize;
George Rimar47936762016-01-16 00:49:19 +0000605 // The first Verdef entry is at the start of the section.
Xing GUOe855e2e2019-04-12 07:09:41 +0000606 const uint8_t *VerdefBuf = VerdefStart;
607 for (unsigned VerdefIndex = 0; VerdefIndex < VerdefEntries; ++VerdefIndex) {
608 if (VerdefBuf + sizeof(Elf_Verdef) > VerdefEnd)
George Rimar47936762016-01-16 00:49:19 +0000609 report_fatal_error("Section ended unexpectedly while scanning "
610 "version definitions.");
Xing GUOe855e2e2019-04-12 07:09:41 +0000611 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);
612 if (Verdef->vd_version != ELF::VER_DEF_CURRENT)
George Rimar47936762016-01-16 00:49:19 +0000613 report_fatal_error("Unexpected verdef version");
Xing GUOe855e2e2019-04-12 07:09:41 +0000614 size_t Index = Verdef->vd_ndx & ELF::VERSYM_VERSION;
615 if (Index >= VersionMap.size())
616 VersionMap.resize(Index + 1);
617 VersionMap[Index] = VersionMapEntry(Verdef);
618 VerdefBuf += Verdef->vd_next;
George Rimar47936762016-01-16 00:49:19 +0000619 }
620}
621
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000622template <class ELFT> void ELFDumper<ELFT>::LoadVersionMap() const {
George Rimar47936762016-01-16 00:49:19 +0000623 // If there is no dynamic symtab or version table, there is nothing to do.
Xing GUO09a77fe2019-03-29 01:26:36 +0000624 if (!DynSymRegion.Addr || !SymbolVersionSection)
George Rimar47936762016-01-16 00:49:19 +0000625 return;
626
627 // Has the VersionMap already been loaded?
Jordan Rupprecht16a0de22018-12-20 00:57:06 +0000628 if (!VersionMap.empty())
George Rimar47936762016-01-16 00:49:19 +0000629 return;
630
631 // The first two version indexes are reserved.
632 // Index 0 is LOCAL, index 1 is GLOBAL.
633 VersionMap.push_back(VersionMapEntry());
634 VersionMap.push_back(VersionMapEntry());
635
Xing GUO09a77fe2019-03-29 01:26:36 +0000636 if (SymbolVersionDefSection)
637 LoadVersionDefs(SymbolVersionDefSection);
George Rimar47936762016-01-16 00:49:19 +0000638
Xing GUO09a77fe2019-03-29 01:26:36 +0000639 if (SymbolVersionNeedSection)
640 LoadVersionNeeds(SymbolVersionNeedSection);
George Rimar47936762016-01-16 00:49:19 +0000641}
642
George Rimar47936762016-01-16 00:49:19 +0000643template <typename ELFT>
644StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
Xing GUO137315e2019-03-28 12:51:35 +0000645 const Elf_Sym *Sym,
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000646 bool &IsDefault) const {
George Rimar47936762016-01-16 00:49:19 +0000647 // This is a dynamic symbol. Look in the GNU symbol version table.
Xing GUO09a77fe2019-03-29 01:26:36 +0000648 if (!SymbolVersionSection) {
George Rimar47936762016-01-16 00:49:19 +0000649 // No version table.
650 IsDefault = false;
Xing GUO12632c72019-03-28 12:51:56 +0000651 return "";
George Rimar47936762016-01-16 00:49:19 +0000652 }
653
654 // Determine the position in the symbol table of this entry.
Xing GUO137315e2019-03-28 12:51:35 +0000655 size_t EntryIndex = (reinterpret_cast<uintptr_t>(Sym) -
George Rimarec895f12019-05-16 06:22:51 +0000656 reinterpret_cast<uintptr_t>(DynSymRegion.Addr)) /
657 sizeof(Elf_Sym);
George Rimar47936762016-01-16 00:49:19 +0000658
Xing GUO7ffd9112019-03-28 12:51:46 +0000659 // Get the corresponding version index entry.
Xing GUO137315e2019-03-28 12:51:35 +0000660 const Elf_Versym *Versym =
661 unwrapOrError(ObjF->getELFFile()->template getEntry<Elf_Versym>(
Xing GUO09a77fe2019-03-29 01:26:36 +0000662 SymbolVersionSection, EntryIndex));
Xing GUO7ffd9112019-03-28 12:51:46 +0000663 return this->getSymbolVersionByIndex(StrTab, Versym->vs_index, IsDefault);
George Rimar47936762016-01-16 00:49:19 +0000664}
665
James Hendersone50d9cb2019-01-17 15:34:12 +0000666static std::string maybeDemangle(StringRef Name) {
667 return opts::Demangle ? demangle(Name) : Name.str();
668}
669
George Rimar47936762016-01-16 00:49:19 +0000670template <typename ELFT>
James Hendersone50d9cb2019-01-17 15:34:12 +0000671std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000672 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
George Rimar9e88a262019-05-14 14:22:44 +0000673 StringRef StrTable =
674 unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000675 Elf_Sym_Range Syms = unwrapOrError(Obj->symbols(DotSymtabSec));
676 if (Index >= Syms.size())
677 reportError("Invalid symbol index");
678 const Elf_Sym *Sym = &Syms[Index];
James Hendersone50d9cb2019-01-17 15:34:12 +0000679 return maybeDemangle(unwrapOrError(Sym->getName(StrTable)));
Michael J. Spencerae6eeae2018-06-02 16:33:01 +0000680}
681
682template <typename ELFT>
George Rimar9e88a262019-05-14 14:22:44 +0000683StringRef ELFDumper<ELFT>::getSymbolVersionByIndex(StringRef StrTab,
684 uint32_t SymbolVersionIndex,
685 bool &IsDefault) const {
Xing GUO137315e2019-03-28 12:51:35 +0000686 size_t VersionIndex = SymbolVersionIndex & VERSYM_VERSION;
687
688 // Special markers for unversioned symbols.
George Rimar9e88a262019-05-14 14:22:44 +0000689 if (VersionIndex == VER_NDX_LOCAL || VersionIndex == VER_NDX_GLOBAL) {
Xing GUO137315e2019-03-28 12:51:35 +0000690 IsDefault = false;
Xing GUO12632c72019-03-28 12:51:56 +0000691 return "";
Xing GUO137315e2019-03-28 12:51:35 +0000692 }
693
Xing GUO7ffd9112019-03-28 12:51:46 +0000694 // Lookup this symbol in the version table.
Xing GUO137315e2019-03-28 12:51:35 +0000695 LoadVersionMap();
696 if (VersionIndex >= VersionMap.size() || VersionMap[VersionIndex].isNull())
697 reportError("Invalid version entry");
698 const VersionMapEntry &Entry = VersionMap[VersionIndex];
699
Xing GUO7ffd9112019-03-28 12:51:46 +0000700 // Get the version name string.
Xing GUO137315e2019-03-28 12:51:35 +0000701 size_t NameOffset;
702 if (Entry.isVerdef()) {
703 // The first Verdaux entry holds the name.
704 NameOffset = Entry.getVerdef()->getAux()->vda_name;
705 IsDefault = !(SymbolVersionIndex & VERSYM_HIDDEN);
706 } else {
707 NameOffset = Entry.getVernaux()->vna_name;
708 IsDefault = false;
709 }
710 if (NameOffset >= StrTab.size())
711 reportError("Invalid string offset");
Xing GUO12632c72019-03-28 12:51:56 +0000712 return StrTab.data() + NameOffset;
Xing GUO137315e2019-03-28 12:51:35 +0000713}
714
715template <typename ELFT>
George Rimar47936762016-01-16 00:49:19 +0000716std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol,
717 StringRef StrTable,
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000718 bool IsDynamic) const {
James Hendersone50d9cb2019-01-17 15:34:12 +0000719 std::string SymbolName =
720 maybeDemangle(unwrapOrError(Symbol->getName(StrTable)));
Matt Davis8a6f11f2019-03-01 17:31:32 +0000721
722 if (SymbolName.empty() && Symbol->getType() == ELF::STT_SECTION) {
723 unsigned SectionIndex;
724 StringRef SectionName;
725 Elf_Sym_Range Syms =
726 unwrapOrError(ObjF->getELFFile()->symbols(DotSymtabSec));
727 getSectionNameIndex(Symbol, Syms.begin(), SectionName, SectionIndex);
728 return SectionName;
729 }
730
George Rimar47936762016-01-16 00:49:19 +0000731 if (!IsDynamic)
732 return SymbolName;
733
George Rimar47936762016-01-16 00:49:19 +0000734 bool IsDefault;
735 StringRef Version = getSymbolVersion(StrTable, &*Symbol, IsDefault);
James Henderson6135b0f82019-01-08 10:58:05 +0000736 if (!Version.empty()) {
James Hendersone50d9cb2019-01-17 15:34:12 +0000737 SymbolName += (IsDefault ? "@@" : "@");
738 SymbolName += Version;
James Henderson6135b0f82019-01-08 10:58:05 +0000739 }
James Hendersone50d9cb2019-01-17 15:34:12 +0000740 return SymbolName;
George Rimar47936762016-01-16 00:49:19 +0000741}
742
Rafael Espindola714c2952016-11-03 14:41:17 +0000743template <typename ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +0000744void ELFDumper<ELFT>::getSectionNameIndex(const Elf_Sym *Symbol,
745 const Elf_Sym *FirstSym,
746 StringRef &SectionName,
747 unsigned &SectionIndex) const {
George Rimar47936762016-01-16 00:49:19 +0000748 SectionIndex = Symbol->st_shndx;
749 if (Symbol->isUndefined())
750 SectionName = "Undefined";
751 else if (Symbol->isProcessorSpecific())
752 SectionName = "Processor Specific";
753 else if (Symbol->isOSSpecific())
754 SectionName = "Operating System Specific";
755 else if (Symbol->isAbsolute())
756 SectionName = "Absolute";
757 else if (Symbol->isCommon())
758 SectionName = "Common";
759 else if (Symbol->isReserved() && SectionIndex != SHN_XINDEX)
760 SectionName = "Reserved";
761 else {
762 if (SectionIndex == SHN_XINDEX)
Rafael Espindola714c2952016-11-03 14:41:17 +0000763 SectionIndex = unwrapOrError(object::getExtendedSymbolTableIndex<ELFT>(
764 Symbol, FirstSym, ShndxTable));
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000765 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
Rafael Espindola714c2952016-11-03 14:41:17 +0000766 const typename ELFT::Shdr *Sec =
Simon Atanasyan62d32592017-12-21 10:26:02 +0000767 unwrapOrError(Obj->getSection(SectionIndex));
768 SectionName = unwrapOrError(Obj->getSectionName(Sec));
George Rimar47936762016-01-16 00:49:19 +0000769 }
770}
771
772template <class ELFO>
Simon Atanasyancb1175c2016-02-09 18:45:35 +0000773static const typename ELFO::Elf_Shdr *
774findNotEmptySectionByAddress(const ELFO *Obj, uint64_t Addr) {
Rafael Espindola25be8c82016-11-02 14:10:57 +0000775 for (const auto &Shdr : unwrapOrError(Obj->sections()))
Simon Atanasyancb1175c2016-02-09 18:45:35 +0000776 if (Shdr.sh_addr == Addr && Shdr.sh_size > 0)
George Rimar47936762016-01-16 00:49:19 +0000777 return &Shdr;
778 return nullptr;
779}
780
781template <class ELFO>
782static const typename ELFO::Elf_Shdr *findSectionByName(const ELFO &Obj,
783 StringRef Name) {
Rafael Espindola25be8c82016-11-02 14:10:57 +0000784 for (const auto &Shdr : unwrapOrError(Obj.sections())) {
Rafael Espindolaf04f1842016-02-17 16:21:49 +0000785 if (Name == unwrapOrError(Obj.getSectionName(&Shdr)))
George Rimar47936762016-01-16 00:49:19 +0000786 return &Shdr;
787 }
788 return nullptr;
789}
790
791static const EnumEntry<unsigned> ElfClass[] = {
George Rimarec895f12019-05-16 06:22:51 +0000792 {"None", "none", ELF::ELFCLASSNONE},
793 {"32-bit", "ELF32", ELF::ELFCLASS32},
794 {"64-bit", "ELF64", ELF::ELFCLASS64},
George Rimar47936762016-01-16 00:49:19 +0000795};
796
797static const EnumEntry<unsigned> ElfDataEncoding[] = {
George Rimarec895f12019-05-16 06:22:51 +0000798 {"None", "none", ELF::ELFDATANONE},
799 {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB},
800 {"BigEndian", "2's complement, big endian", ELF::ELFDATA2MSB},
George Rimar47936762016-01-16 00:49:19 +0000801};
802
803static const EnumEntry<unsigned> ElfObjectFileType[] = {
George Rimarec895f12019-05-16 06:22:51 +0000804 {"None", "NONE (none)", ELF::ET_NONE},
805 {"Relocatable", "REL (Relocatable file)", ELF::ET_REL},
806 {"Executable", "EXEC (Executable file)", ELF::ET_EXEC},
807 {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN},
808 {"Core", "CORE (Core file)", ELF::ET_CORE},
George Rimar47936762016-01-16 00:49:19 +0000809};
810
811static const EnumEntry<unsigned> ElfOSABI[] = {
George Rimarec895f12019-05-16 06:22:51 +0000812 {"SystemV", "UNIX - System V", ELF::ELFOSABI_NONE},
813 {"HPUX", "UNIX - HP-UX", ELF::ELFOSABI_HPUX},
814 {"NetBSD", "UNIX - NetBSD", ELF::ELFOSABI_NETBSD},
815 {"GNU/Linux", "UNIX - GNU", ELF::ELFOSABI_LINUX},
816 {"GNU/Hurd", "GNU/Hurd", ELF::ELFOSABI_HURD},
817 {"Solaris", "UNIX - Solaris", ELF::ELFOSABI_SOLARIS},
818 {"AIX", "UNIX - AIX", ELF::ELFOSABI_AIX},
819 {"IRIX", "UNIX - IRIX", ELF::ELFOSABI_IRIX},
820 {"FreeBSD", "UNIX - FreeBSD", ELF::ELFOSABI_FREEBSD},
821 {"TRU64", "UNIX - TRU64", ELF::ELFOSABI_TRU64},
822 {"Modesto", "Novell - Modesto", ELF::ELFOSABI_MODESTO},
823 {"OpenBSD", "UNIX - OpenBSD", ELF::ELFOSABI_OPENBSD},
824 {"OpenVMS", "VMS - OpenVMS", ELF::ELFOSABI_OPENVMS},
825 {"NSK", "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK},
826 {"AROS", "AROS", ELF::ELFOSABI_AROS},
827 {"FenixOS", "FenixOS", ELF::ELFOSABI_FENIXOS},
828 {"CloudABI", "CloudABI", ELF::ELFOSABI_CLOUDABI},
829 {"Standalone", "Standalone App", ELF::ELFOSABI_STANDALONE}
830};
George Rimar47936762016-01-16 00:49:19 +0000831
Xing GUOea16be12019-03-25 11:02:49 +0000832static const EnumEntry<unsigned> SymVersionFlags[] = {
833 {"Base", "BASE", VER_FLG_BASE},
834 {"Weak", "WEAK", VER_FLG_WEAK},
835 {"Info", "INFO", VER_FLG_INFO}};
836
Konstantin Zhuravlyov121125f2017-10-02 20:49:58 +0000837static const EnumEntry<unsigned> AMDGPUElfOSABI[] = {
George Rimarec895f12019-05-16 06:22:51 +0000838 {"AMDGPU_HSA", "AMDGPU - HSA", ELF::ELFOSABI_AMDGPU_HSA},
839 {"AMDGPU_PAL", "AMDGPU - PAL", ELF::ELFOSABI_AMDGPU_PAL},
840 {"AMDGPU_MESA3D", "AMDGPU - MESA3D", ELF::ELFOSABI_AMDGPU_MESA3D}
841};
Konstantin Zhuravlyov121125f2017-10-02 20:49:58 +0000842
843static const EnumEntry<unsigned> ARMElfOSABI[] = {
George Rimarec895f12019-05-16 06:22:51 +0000844 {"ARM", "ARM", ELF::ELFOSABI_ARM}
845};
Konstantin Zhuravlyov121125f2017-10-02 20:49:58 +0000846
847static const EnumEntry<unsigned> C6000ElfOSABI[] = {
George Rimarec895f12019-05-16 06:22:51 +0000848 {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI},
849 {"C6000_LINUX", "Linux C6000", ELF::ELFOSABI_C6000_LINUX}
850};
Konstantin Zhuravlyov121125f2017-10-02 20:49:58 +0000851
George Rimar47936762016-01-16 00:49:19 +0000852static const EnumEntry<unsigned> ElfMachineType[] = {
George Rimarec895f12019-05-16 06:22:51 +0000853 ENUM_ENT(EM_NONE, "None"),
854 ENUM_ENT(EM_M32, "WE32100"),
855 ENUM_ENT(EM_SPARC, "Sparc"),
856 ENUM_ENT(EM_386, "Intel 80386"),
857 ENUM_ENT(EM_68K, "MC68000"),
858 ENUM_ENT(EM_88K, "MC88000"),
859 ENUM_ENT(EM_IAMCU, "EM_IAMCU"),
860 ENUM_ENT(EM_860, "Intel 80860"),
861 ENUM_ENT(EM_MIPS, "MIPS R3000"),
862 ENUM_ENT(EM_S370, "IBM System/370"),
863 ENUM_ENT(EM_MIPS_RS3_LE, "MIPS R3000 little-endian"),
864 ENUM_ENT(EM_PARISC, "HPPA"),
865 ENUM_ENT(EM_VPP500, "Fujitsu VPP500"),
866 ENUM_ENT(EM_SPARC32PLUS, "Sparc v8+"),
867 ENUM_ENT(EM_960, "Intel 80960"),
868 ENUM_ENT(EM_PPC, "PowerPC"),
869 ENUM_ENT(EM_PPC64, "PowerPC64"),
870 ENUM_ENT(EM_S390, "IBM S/390"),
871 ENUM_ENT(EM_SPU, "SPU"),
872 ENUM_ENT(EM_V800, "NEC V800 series"),
873 ENUM_ENT(EM_FR20, "Fujistsu FR20"),
874 ENUM_ENT(EM_RH32, "TRW RH-32"),
875 ENUM_ENT(EM_RCE, "Motorola RCE"),
876 ENUM_ENT(EM_ARM, "ARM"),
877 ENUM_ENT(EM_ALPHA, "EM_ALPHA"),
878 ENUM_ENT(EM_SH, "Hitachi SH"),
879 ENUM_ENT(EM_SPARCV9, "Sparc v9"),
880 ENUM_ENT(EM_TRICORE, "Siemens Tricore"),
881 ENUM_ENT(EM_ARC, "ARC"),
882 ENUM_ENT(EM_H8_300, "Hitachi H8/300"),
883 ENUM_ENT(EM_H8_300H, "Hitachi H8/300H"),
884 ENUM_ENT(EM_H8S, "Hitachi H8S"),
885 ENUM_ENT(EM_H8_500, "Hitachi H8/500"),
886 ENUM_ENT(EM_IA_64, "Intel IA-64"),
887 ENUM_ENT(EM_MIPS_X, "Stanford MIPS-X"),
888 ENUM_ENT(EM_COLDFIRE, "Motorola Coldfire"),
889 ENUM_ENT(EM_68HC12, "Motorola MC68HC12 Microcontroller"),
890 ENUM_ENT(EM_MMA, "Fujitsu Multimedia Accelerator"),
891 ENUM_ENT(EM_PCP, "Siemens PCP"),
892 ENUM_ENT(EM_NCPU, "Sony nCPU embedded RISC processor"),
893 ENUM_ENT(EM_NDR1, "Denso NDR1 microprocesspr"),
894 ENUM_ENT(EM_STARCORE, "Motorola Star*Core processor"),
895 ENUM_ENT(EM_ME16, "Toyota ME16 processor"),
896 ENUM_ENT(EM_ST100, "STMicroelectronics ST100 processor"),
897 ENUM_ENT(EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor"),
898 ENUM_ENT(EM_X86_64, "Advanced Micro Devices X86-64"),
899 ENUM_ENT(EM_PDSP, "Sony DSP processor"),
900 ENUM_ENT(EM_PDP10, "Digital Equipment Corp. PDP-10"),
901 ENUM_ENT(EM_PDP11, "Digital Equipment Corp. PDP-11"),
902 ENUM_ENT(EM_FX66, "Siemens FX66 microcontroller"),
903 ENUM_ENT(EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller"),
904 ENUM_ENT(EM_ST7, "STMicroelectronics ST7 8-bit microcontroller"),
905 ENUM_ENT(EM_68HC16, "Motorola MC68HC16 Microcontroller"),
906 ENUM_ENT(EM_68HC11, "Motorola MC68HC11 Microcontroller"),
907 ENUM_ENT(EM_68HC08, "Motorola MC68HC08 Microcontroller"),
908 ENUM_ENT(EM_68HC05, "Motorola MC68HC05 Microcontroller"),
909 ENUM_ENT(EM_SVX, "Silicon Graphics SVx"),
910 ENUM_ENT(EM_ST19, "STMicroelectronics ST19 8-bit microcontroller"),
911 ENUM_ENT(EM_VAX, "Digital VAX"),
912 ENUM_ENT(EM_CRIS, "Axis Communications 32-bit embedded processor"),
913 ENUM_ENT(EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu"),
914 ENUM_ENT(EM_FIREPATH, "Element 14 64-bit DSP processor"),
915 ENUM_ENT(EM_ZSP, "LSI Logic's 16-bit DSP processor"),
916 ENUM_ENT(EM_MMIX, "Donald Knuth's educational 64-bit processor"),
917 ENUM_ENT(EM_HUANY, "Harvard Universitys's machine-independent object format"),
918 ENUM_ENT(EM_PRISM, "Vitesse Prism"),
919 ENUM_ENT(EM_AVR, "Atmel AVR 8-bit microcontroller"),
920 ENUM_ENT(EM_FR30, "Fujitsu FR30"),
921 ENUM_ENT(EM_D10V, "Mitsubishi D10V"),
922 ENUM_ENT(EM_D30V, "Mitsubishi D30V"),
923 ENUM_ENT(EM_V850, "NEC v850"),
924 ENUM_ENT(EM_M32R, "Renesas M32R (formerly Mitsubishi M32r)"),
925 ENUM_ENT(EM_MN10300, "Matsushita MN10300"),
926 ENUM_ENT(EM_MN10200, "Matsushita MN10200"),
927 ENUM_ENT(EM_PJ, "picoJava"),
928 ENUM_ENT(EM_OPENRISC, "OpenRISC 32-bit embedded processor"),
929 ENUM_ENT(EM_ARC_COMPACT, "EM_ARC_COMPACT"),
930 ENUM_ENT(EM_XTENSA, "Tensilica Xtensa Processor"),
931 ENUM_ENT(EM_VIDEOCORE, "Alphamosaic VideoCore processor"),
932 ENUM_ENT(EM_TMM_GPP, "Thompson Multimedia General Purpose Processor"),
933 ENUM_ENT(EM_NS32K, "National Semiconductor 32000 series"),
934 ENUM_ENT(EM_TPC, "Tenor Network TPC processor"),
935 ENUM_ENT(EM_SNP1K, "EM_SNP1K"),
936 ENUM_ENT(EM_ST200, "STMicroelectronics ST200 microcontroller"),
937 ENUM_ENT(EM_IP2K, "Ubicom IP2xxx 8-bit microcontrollers"),
938 ENUM_ENT(EM_MAX, "MAX Processor"),
939 ENUM_ENT(EM_CR, "National Semiconductor CompactRISC"),
940 ENUM_ENT(EM_F2MC16, "Fujitsu F2MC16"),
941 ENUM_ENT(EM_MSP430, "Texas Instruments msp430 microcontroller"),
942 ENUM_ENT(EM_BLACKFIN, "Analog Devices Blackfin"),
943 ENUM_ENT(EM_SE_C33, "S1C33 Family of Seiko Epson processors"),
944 ENUM_ENT(EM_SEP, "Sharp embedded microprocessor"),
945 ENUM_ENT(EM_ARCA, "Arca RISC microprocessor"),
946 ENUM_ENT(EM_UNICORE, "Unicore"),
947 ENUM_ENT(EM_EXCESS, "eXcess 16/32/64-bit configurable embedded CPU"),
948 ENUM_ENT(EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor"),
949 ENUM_ENT(EM_ALTERA_NIOS2, "Altera Nios"),
950 ENUM_ENT(EM_CRX, "National Semiconductor CRX microprocessor"),
951 ENUM_ENT(EM_XGATE, "Motorola XGATE embedded processor"),
952 ENUM_ENT(EM_C166, "Infineon Technologies xc16x"),
953 ENUM_ENT(EM_M16C, "Renesas M16C"),
954 ENUM_ENT(EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller"),
955 ENUM_ENT(EM_CE, "Freescale Communication Engine RISC core"),
956 ENUM_ENT(EM_M32C, "Renesas M32C"),
957 ENUM_ENT(EM_TSK3000, "Altium TSK3000 core"),
958 ENUM_ENT(EM_RS08, "Freescale RS08 embedded processor"),
959 ENUM_ENT(EM_SHARC, "EM_SHARC"),
960 ENUM_ENT(EM_ECOG2, "Cyan Technology eCOG2 microprocessor"),
961 ENUM_ENT(EM_SCORE7, "SUNPLUS S+Core"),
962 ENUM_ENT(EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor"),
963 ENUM_ENT(EM_VIDEOCORE3, "Broadcom VideoCore III processor"),
964 ENUM_ENT(EM_LATTICEMICO32, "Lattice Mico32"),
965 ENUM_ENT(EM_SE_C17, "Seiko Epson C17 family"),
966 ENUM_ENT(EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family"),
967 ENUM_ENT(EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family"),
968 ENUM_ENT(EM_TI_C5500, "Texas Instruments TMS320C55x DSP family"),
969 ENUM_ENT(EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor"),
970 ENUM_ENT(EM_CYPRESS_M8C, "Cypress M8C microprocessor"),
971 ENUM_ENT(EM_R32C, "Renesas R32C series microprocessors"),
972 ENUM_ENT(EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family"),
973 ENUM_ENT(EM_HEXAGON, "Qualcomm Hexagon"),
974 ENUM_ENT(EM_8051, "Intel 8051 and variants"),
975 ENUM_ENT(EM_STXP7X, "STMicroelectronics STxP7x family"),
976 ENUM_ENT(EM_NDS32, "Andes Technology compact code size embedded RISC processor family"),
977 ENUM_ENT(EM_ECOG1, "Cyan Technology eCOG1 microprocessor"),
978 ENUM_ENT(EM_ECOG1X, "Cyan Technology eCOG1X family"),
979 ENUM_ENT(EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core microcontrollers"),
980 ENUM_ENT(EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor"),
981 ENUM_ENT(EM_MANIK, "M2000 Reconfigurable RISC Microprocessor"),
982 ENUM_ENT(EM_CRAYNV2, "Cray Inc. NV2 vector architecture"),
983 ENUM_ENT(EM_RX, "Renesas RX"),
984 ENUM_ENT(EM_METAG, "Imagination Technologies Meta processor architecture"),
985 ENUM_ENT(EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture"),
986 ENUM_ENT(EM_ECOG16, "Cyan Technology eCOG16 family"),
987 ENUM_ENT(EM_CR16, "Xilinx MicroBlaze"),
988 ENUM_ENT(EM_ETPU, "Freescale Extended Time Processing Unit"),
989 ENUM_ENT(EM_SLE9X, "Infineon Technologies SLE9X core"),
990 ENUM_ENT(EM_L10M, "EM_L10M"),
991 ENUM_ENT(EM_K10M, "EM_K10M"),
992 ENUM_ENT(EM_AARCH64, "AArch64"),
993 ENUM_ENT(EM_AVR32, "Atmel Corporation 32-bit microprocessor family"),
994 ENUM_ENT(EM_STM8, "STMicroeletronics STM8 8-bit microcontroller"),
995 ENUM_ENT(EM_TILE64, "Tilera TILE64 multicore architecture family"),
996 ENUM_ENT(EM_TILEPRO, "Tilera TILEPro multicore architecture family"),
997 ENUM_ENT(EM_CUDA, "NVIDIA CUDA architecture"),
998 ENUM_ENT(EM_TILEGX, "Tilera TILE-Gx multicore architecture family"),
999 ENUM_ENT(EM_CLOUDSHIELD, "EM_CLOUDSHIELD"),
1000 ENUM_ENT(EM_COREA_1ST, "EM_COREA_1ST"),
1001 ENUM_ENT(EM_COREA_2ND, "EM_COREA_2ND"),
1002 ENUM_ENT(EM_ARC_COMPACT2, "EM_ARC_COMPACT2"),
1003 ENUM_ENT(EM_OPEN8, "EM_OPEN8"),
1004 ENUM_ENT(EM_RL78, "Renesas RL78"),
1005 ENUM_ENT(EM_VIDEOCORE5, "Broadcom VideoCore V processor"),
1006 ENUM_ENT(EM_78KOR, "EM_78KOR"),
1007 ENUM_ENT(EM_56800EX, "EM_56800EX"),
1008 ENUM_ENT(EM_AMDGPU, "EM_AMDGPU"),
1009 ENUM_ENT(EM_RISCV, "RISC-V"),
1010 ENUM_ENT(EM_LANAI, "EM_LANAI"),
1011 ENUM_ENT(EM_BPF, "EM_BPF"),
George Rimar47936762016-01-16 00:49:19 +00001012};
1013
1014static const EnumEntry<unsigned> ElfSymbolBindings[] = {
George Rimarec895f12019-05-16 06:22:51 +00001015 {"Local", "LOCAL", ELF::STB_LOCAL},
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00001016 {"Global", "GLOBAL", ELF::STB_GLOBAL},
George Rimarec895f12019-05-16 06:22:51 +00001017 {"Weak", "WEAK", ELF::STB_WEAK},
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00001018 {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE}};
George Rimar47936762016-01-16 00:49:19 +00001019
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00001020static const EnumEntry<unsigned> ElfSymbolVisibilities[] = {
George Rimarec895f12019-05-16 06:22:51 +00001021 {"DEFAULT", "DEFAULT", ELF::STV_DEFAULT},
1022 {"INTERNAL", "INTERNAL", ELF::STV_INTERNAL},
1023 {"HIDDEN", "HIDDEN", ELF::STV_HIDDEN},
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00001024 {"PROTECTED", "PROTECTED", ELF::STV_PROTECTED}};
1025
George Rimar47936762016-01-16 00:49:19 +00001026static const EnumEntry<unsigned> AMDGPUSymbolTypes[] = {
George Rimarec895f12019-05-16 06:22:51 +00001027 { "AMDGPU_HSA_KERNEL", ELF::STT_AMDGPU_HSA_KERNEL }
1028};
George Rimar47936762016-01-16 00:49:19 +00001029
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +00001030static const char *getGroupType(uint32_t Flag) {
1031 if (Flag & ELF::GRP_COMDAT)
1032 return "COMDAT";
1033 else
1034 return "(unknown)";
1035}
1036
George Rimar47936762016-01-16 00:49:19 +00001037static const EnumEntry<unsigned> ElfSectionFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001038 ENUM_ENT(SHF_WRITE, "W"),
1039 ENUM_ENT(SHF_ALLOC, "A"),
1040 ENUM_ENT(SHF_EXCLUDE, "E"),
1041 ENUM_ENT(SHF_EXECINSTR, "X"),
1042 ENUM_ENT(SHF_MERGE, "M"),
1043 ENUM_ENT(SHF_STRINGS, "S"),
1044 ENUM_ENT(SHF_INFO_LINK, "I"),
1045 ENUM_ENT(SHF_LINK_ORDER, "L"),
1046 ENUM_ENT(SHF_OS_NONCONFORMING, "o"),
1047 ENUM_ENT(SHF_GROUP, "G"),
1048 ENUM_ENT(SHF_TLS, "T"),
1049 ENUM_ENT(SHF_MASKOS, "o"),
1050 ENUM_ENT(SHF_MASKPROC, "p"),
1051 ENUM_ENT_1(SHF_COMPRESSED),
George Rimarc13c59a2016-05-21 10:16:58 +00001052};
1053
1054static const EnumEntry<unsigned> ElfXCoreSectionFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001055 LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION),
1056 LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION)
1057};
Simon Atanasyan2d0d8532016-01-20 19:15:18 +00001058
Prakhar Bahuguna52a7dd72016-12-15 07:59:08 +00001059static const EnumEntry<unsigned> ElfARMSectionFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001060 LLVM_READOBJ_ENUM_ENT(ELF, SHF_ARM_PURECODE)
1061};
Prakhar Bahuguna52a7dd72016-12-15 07:59:08 +00001062
Simon Atanasyan2d0d8532016-01-20 19:15:18 +00001063static const EnumEntry<unsigned> ElfHexagonSectionFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001064 LLVM_READOBJ_ENUM_ENT(ELF, SHF_HEX_GPREL)
1065};
Simon Atanasyan2d0d8532016-01-20 19:15:18 +00001066
1067static const EnumEntry<unsigned> ElfMipsSectionFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001068 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NODUPES),
1069 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NAMES ),
1070 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_LOCAL ),
1071 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP),
1072 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_GPREL ),
1073 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_MERGE ),
1074 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_ADDR ),
1075 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_STRING )
1076};
Simon Atanasyan2d0d8532016-01-20 19:15:18 +00001077
1078static const EnumEntry<unsigned> ElfX86_64SectionFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001079 LLVM_READOBJ_ENUM_ENT(ELF, SHF_X86_64_LARGE)
1080};
Simon Atanasyan2d0d8532016-01-20 19:15:18 +00001081
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001082static std::string getGNUFlags(uint64_t Flags) {
1083 std::string Str;
1084 for (auto Entry : ElfSectionFlags) {
1085 uint64_t Flag = Entry.Value & Flags;
1086 Flags &= ~Entry.Value;
1087 switch (Flag) {
1088 case ELF::SHF_WRITE:
1089 case ELF::SHF_ALLOC:
1090 case ELF::SHF_EXECINSTR:
1091 case ELF::SHF_MERGE:
1092 case ELF::SHF_STRINGS:
1093 case ELF::SHF_INFO_LINK:
1094 case ELF::SHF_LINK_ORDER:
1095 case ELF::SHF_OS_NONCONFORMING:
1096 case ELF::SHF_GROUP:
1097 case ELF::SHF_TLS:
1098 case ELF::SHF_EXCLUDE:
1099 Str += Entry.AltName;
1100 break;
1101 default:
Hemant Kulkarni04ac3d72016-05-12 19:58:52 +00001102 if (Flag & ELF::SHF_MASKOS)
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001103 Str += "o";
Hemant Kulkarni04ac3d72016-05-12 19:58:52 +00001104 else if (Flag & ELF::SHF_MASKPROC)
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001105 Str += "p";
1106 else if (Flag)
1107 Str += "x";
1108 }
1109 }
1110 return Str;
1111}
1112
George Rimar47936762016-01-16 00:49:19 +00001113static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
1114 // Check potentially overlapped processor-specific
1115 // program header type.
1116 switch (Arch) {
George Rimar47936762016-01-16 00:49:19 +00001117 case ELF::EM_ARM:
George Rimar9e88a262019-05-14 14:22:44 +00001118 switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); }
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00001119 break;
George Rimar47936762016-01-16 00:49:19 +00001120 case ELF::EM_MIPS:
1121 case ELF::EM_MIPS_RS3_LE:
1122 switch (Type) {
George Rimar9e88a262019-05-14 14:22:44 +00001123 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
George Rimarec895f12019-05-16 06:22:51 +00001124 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
1125 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
1126 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);
George Rimar47936762016-01-16 00:49:19 +00001127 }
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00001128 break;
George Rimar47936762016-01-16 00:49:19 +00001129 }
1130
1131 switch (Type) {
George Rimarec895f12019-05-16 06:22:51 +00001132 LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL );
1133 LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD );
1134 LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
1135 LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP );
1136 LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE );
1137 LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB );
1138 LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR );
1139 LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS );
George Rimar47936762016-01-16 00:49:19 +00001140
George Rimarec895f12019-05-16 06:22:51 +00001141 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
1142 LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
George Rimar47936762016-01-16 00:49:19 +00001143
George Rimar9e88a262019-05-14 14:22:44 +00001144 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
1145 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
George Rimarbcfcb9e2016-10-18 10:54:56 +00001146
George Rimar9e88a262019-05-14 14:22:44 +00001147 LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE);
1148 LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED);
1149 LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA);
George Rimarbcfcb9e2016-10-18 10:54:56 +00001150
George Rimar9e88a262019-05-14 14:22:44 +00001151 default:
1152 return "";
George Rimar47936762016-01-16 00:49:19 +00001153 }
1154}
1155
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00001156static std::string getElfPtType(unsigned Arch, unsigned Type) {
1157 switch (Type) {
Hemant Kulkarni7d564ba2016-03-28 17:20:23 +00001158 LLVM_READOBJ_PHDR_ENUM(ELF, PT_NULL)
1159 LLVM_READOBJ_PHDR_ENUM(ELF, PT_LOAD)
1160 LLVM_READOBJ_PHDR_ENUM(ELF, PT_DYNAMIC)
1161 LLVM_READOBJ_PHDR_ENUM(ELF, PT_INTERP)
1162 LLVM_READOBJ_PHDR_ENUM(ELF, PT_NOTE)
1163 LLVM_READOBJ_PHDR_ENUM(ELF, PT_SHLIB)
1164 LLVM_READOBJ_PHDR_ENUM(ELF, PT_PHDR)
1165 LLVM_READOBJ_PHDR_ENUM(ELF, PT_TLS)
1166 LLVM_READOBJ_PHDR_ENUM(ELF, PT_GNU_EH_FRAME)
1167 LLVM_READOBJ_PHDR_ENUM(ELF, PT_SUNW_UNWIND)
1168 LLVM_READOBJ_PHDR_ENUM(ELF, PT_GNU_STACK)
1169 LLVM_READOBJ_PHDR_ENUM(ELF, PT_GNU_RELRO)
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00001170 default:
1171 // All machine specific PT_* types
1172 switch (Arch) {
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00001173 case ELF::EM_ARM:
1174 if (Type == ELF::PT_ARM_EXIDX)
1175 return "EXIDX";
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00001176 break;
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00001177 case ELF::EM_MIPS:
1178 case ELF::EM_MIPS_RS3_LE:
1179 switch (Type) {
1180 case PT_MIPS_REGINFO:
1181 return "REGINFO";
1182 case PT_MIPS_RTPROC:
1183 return "RTPROC";
1184 case PT_MIPS_OPTIONS:
1185 return "OPTIONS";
1186 case PT_MIPS_ABIFLAGS:
1187 return "ABIFLAGS";
1188 }
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00001189 break;
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00001190 }
1191 }
1192 return std::string("<unknown>: ") + to_string(format_hex(Type, 1));
1193}
1194
George Rimar47936762016-01-16 00:49:19 +00001195static const EnumEntry<unsigned> ElfSegmentFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001196 LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
1197 LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
1198 LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
1199};
George Rimar47936762016-01-16 00:49:19 +00001200
1201static const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001202 ENUM_ENT(EF_MIPS_NOREORDER, "noreorder"),
1203 ENUM_ENT(EF_MIPS_PIC, "pic"),
1204 ENUM_ENT(EF_MIPS_CPIC, "cpic"),
1205 ENUM_ENT(EF_MIPS_ABI2, "abi2"),
1206 ENUM_ENT(EF_MIPS_32BITMODE, "32bitmode"),
1207 ENUM_ENT(EF_MIPS_FP64, "fp64"),
1208 ENUM_ENT(EF_MIPS_NAN2008, "nan2008"),
1209 ENUM_ENT(EF_MIPS_ABI_O32, "o32"),
1210 ENUM_ENT(EF_MIPS_ABI_O64, "o64"),
1211 ENUM_ENT(EF_MIPS_ABI_EABI32, "eabi32"),
1212 ENUM_ENT(EF_MIPS_ABI_EABI64, "eabi64"),
1213 ENUM_ENT(EF_MIPS_MACH_3900, "3900"),
1214 ENUM_ENT(EF_MIPS_MACH_4010, "4010"),
1215 ENUM_ENT(EF_MIPS_MACH_4100, "4100"),
1216 ENUM_ENT(EF_MIPS_MACH_4650, "4650"),
1217 ENUM_ENT(EF_MIPS_MACH_4120, "4120"),
1218 ENUM_ENT(EF_MIPS_MACH_4111, "4111"),
1219 ENUM_ENT(EF_MIPS_MACH_SB1, "sb1"),
1220 ENUM_ENT(EF_MIPS_MACH_OCTEON, "octeon"),
1221 ENUM_ENT(EF_MIPS_MACH_XLR, "xlr"),
1222 ENUM_ENT(EF_MIPS_MACH_OCTEON2, "octeon2"),
1223 ENUM_ENT(EF_MIPS_MACH_OCTEON3, "octeon3"),
1224 ENUM_ENT(EF_MIPS_MACH_5400, "5400"),
1225 ENUM_ENT(EF_MIPS_MACH_5900, "5900"),
1226 ENUM_ENT(EF_MIPS_MACH_5500, "5500"),
1227 ENUM_ENT(EF_MIPS_MACH_9000, "9000"),
1228 ENUM_ENT(EF_MIPS_MACH_LS2E, "loongson-2e"),
1229 ENUM_ENT(EF_MIPS_MACH_LS2F, "loongson-2f"),
1230 ENUM_ENT(EF_MIPS_MACH_LS3A, "loongson-3a"),
1231 ENUM_ENT(EF_MIPS_MICROMIPS, "micromips"),
1232 ENUM_ENT(EF_MIPS_ARCH_ASE_M16, "mips16"),
1233 ENUM_ENT(EF_MIPS_ARCH_ASE_MDMX, "mdmx"),
1234 ENUM_ENT(EF_MIPS_ARCH_1, "mips1"),
1235 ENUM_ENT(EF_MIPS_ARCH_2, "mips2"),
1236 ENUM_ENT(EF_MIPS_ARCH_3, "mips3"),
1237 ENUM_ENT(EF_MIPS_ARCH_4, "mips4"),
1238 ENUM_ENT(EF_MIPS_ARCH_5, "mips5"),
1239 ENUM_ENT(EF_MIPS_ARCH_32, "mips32"),
1240 ENUM_ENT(EF_MIPS_ARCH_64, "mips64"),
1241 ENUM_ENT(EF_MIPS_ARCH_32R2, "mips32r2"),
1242 ENUM_ENT(EF_MIPS_ARCH_64R2, "mips64r2"),
1243 ENUM_ENT(EF_MIPS_ARCH_32R6, "mips32r6"),
1244 ENUM_ENT(EF_MIPS_ARCH_64R6, "mips64r6")
1245};
George Rimar47936762016-01-16 00:49:19 +00001246
Konstantin Zhuravlyovaa0835a2017-10-05 16:19:18 +00001247static const EnumEntry<unsigned> ElfHeaderAMDGPUFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001248 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_NONE),
1249 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R600),
1250 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R630),
1251 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RS880),
1252 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV670),
1253 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV710),
1254 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV730),
1255 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV770),
1256 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CEDAR),
1257 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CYPRESS),
1258 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_JUNIPER),
1259 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_REDWOOD),
1260 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_SUMO),
1261 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_BARTS),
1262 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAICOS),
1263 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAYMAN),
1264 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_TURKS),
1265 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX600),
1266 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX601),
1267 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX700),
1268 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX701),
1269 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX702),
1270 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX703),
1271 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX704),
1272 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX801),
1273 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX802),
1274 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX803),
1275 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX810),
1276 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX900),
1277 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX902),
1278 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX904),
1279 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX906),
1280 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX909),
1281 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1010),
1282 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_XNACK),
1283 LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_SRAM_ECC)
1284};
Konstantin Zhuravlyovaa0835a2017-10-05 16:19:18 +00001285
Alex Bradburybb89b2b2017-10-03 08:41:59 +00001286static const EnumEntry<unsigned> ElfHeaderRISCVFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001287 ENUM_ENT(EF_RISCV_RVC, "RVC"),
1288 ENUM_ENT(EF_RISCV_FLOAT_ABI_SINGLE, "single-float ABI"),
1289 ENUM_ENT(EF_RISCV_FLOAT_ABI_DOUBLE, "double-float ABI"),
1290 ENUM_ENT(EF_RISCV_FLOAT_ABI_QUAD, "quad-float ABI"),
1291 ENUM_ENT(EF_RISCV_RVE, "RVE")
1292};
Alex Bradburybb89b2b2017-10-03 08:41:59 +00001293
Simon Atanasyanb7807a02016-03-24 16:10:37 +00001294static const EnumEntry<unsigned> ElfSymOtherFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001295 LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL),
1296 LLVM_READOBJ_ENUM_ENT(ELF, STV_HIDDEN),
1297 LLVM_READOBJ_ENUM_ENT(ELF, STV_PROTECTED)
1298};
Simon Atanasyanb7807a02016-03-24 16:10:37 +00001299
1300static const EnumEntry<unsigned> ElfMipsSymOtherFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001301 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
1302 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
1303 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PIC),
1304 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MICROMIPS)
1305};
Simon Atanasyanb7807a02016-03-24 16:10:37 +00001306
1307static const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001308 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
1309 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
1310 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16)
1311};
Simon Atanasyanb7807a02016-03-24 16:10:37 +00001312
Simon Atanasyan8a71b532016-05-04 05:58:57 +00001313static const char *getElfMipsOptionsOdkType(unsigned Odk) {
1314 switch (Odk) {
George Rimarec895f12019-05-16 06:22:51 +00001315 LLVM_READOBJ_ENUM_CASE(ELF, ODK_NULL);
1316 LLVM_READOBJ_ENUM_CASE(ELF, ODK_REGINFO);
1317 LLVM_READOBJ_ENUM_CASE(ELF, ODK_EXCEPTIONS);
1318 LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAD);
1319 LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWPATCH);
1320 LLVM_READOBJ_ENUM_CASE(ELF, ODK_FILL);
1321 LLVM_READOBJ_ENUM_CASE(ELF, ODK_TAGS);
1322 LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWAND);
1323 LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWOR);
1324 LLVM_READOBJ_ENUM_CASE(ELF, ODK_GP_GROUP);
1325 LLVM_READOBJ_ENUM_CASE(ELF, ODK_IDENT);
1326 LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAGESIZE);
Simon Atanasyan8a71b532016-05-04 05:58:57 +00001327 default:
1328 return "Unknown";
1329 }
1330}
1331
George Rimar47936762016-01-16 00:49:19 +00001332template <typename ELFT>
George Rimar72f821d2019-05-20 15:41:48 +00001333void ELFDumper<ELFT>::loadDynamicTable(const ELFFile<ELFT> *Obj) {
1334 const Elf_Phdr *DynamicPhdr = nullptr;
1335 for (const Elf_Phdr &Phdr : unwrapOrError(Obj->program_headers())) {
1336 if (Phdr.p_type != ELF::PT_DYNAMIC)
1337 continue;
1338 DynamicPhdr = &Phdr;
1339 break;
1340 }
1341
1342 // We do not want to dump dynamic section if we have no PT_DYNAMIC header.
1343 // This matches GNU's behavior.
1344 if (!DynamicPhdr)
1345 return;
1346
1347 // Try to locate the .dynamic section in the sections header table.
1348 const Elf_Shdr *DynamicSec = nullptr;
1349 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
1350 if (Sec.sh_type != ELF::SHT_DYNAMIC)
1351 continue;
1352 DynamicSec = &Sec;
1353 break;
1354 }
1355
1356 // Information in the section header has priority over the information
1357 // in a PT_DYNAMIC header.
1358 // Ignore sh_entsize and use the expected value for entry size explicitly.
1359 // This allows us to dump the dynamic sections with a broken sh_entsize
1360 // field.
1361 if (DynamicSec)
1362 DynamicTable = checkDRI({ObjF->getELFFile()->base() + DynamicSec->sh_offset,
1363 DynamicSec->sh_size, sizeof(Elf_Dyn)});
1364
1365 if (DynamicPhdr->p_offset + DynamicPhdr->p_filesz >
1366 ObjF->getMemoryBufferRef().getBufferSize())
1367 reportError(
1368 "PT_DYNAMIC segment offset + size exceeds the size of the file");
1369
1370 if (!DynamicSec) {
1371 DynamicTable = createDRIFrom(DynamicPhdr, sizeof(Elf_Dyn));
1372 parseDynamicTable();
1373 return;
1374 }
1375
1376 StringRef Name = unwrapOrError(Obj->getSectionName(DynamicSec));
1377
1378 if (DynamicSec->sh_addr + DynamicSec->sh_size >
1379 DynamicPhdr->p_vaddr + DynamicPhdr->p_memsz ||
1380 DynamicSec->sh_addr < DynamicPhdr->p_vaddr)
1381 reportWarning("The SHT_DYNAMIC section '" + Name +
1382 "' is not contained within the "
1383 "PT_DYNAMIC segment");
1384
1385 if (DynamicSec->sh_addr != DynamicPhdr->p_vaddr)
1386 reportWarning("The SHT_DYNAMIC section '" + Name +
1387 "' is not at the start of "
1388 "PT_DYNAMIC segment");
1389
1390 parseDynamicTable();
1391}
1392
1393template <typename ELFT>
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001394ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
George Rimarec895f12019-05-16 06:22:51 +00001395 ScopedPrinter &Writer)
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001396 : ObjDumper(Writer), ObjF(ObjF) {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001397 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
George Rimar47936762016-01-16 00:49:19 +00001398
Rafael Espindola25be8c82016-11-02 14:10:57 +00001399 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
Michael J. Spencer37304f12016-02-11 04:59:26 +00001400 switch (Sec.sh_type) {
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001401 case ELF::SHT_SYMTAB:
1402 if (DotSymtabSec != nullptr)
Saleem Abdulrasool46ee7332017-09-29 02:45:44 +00001403 reportError("Multiple SHT_SYMTAB");
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001404 DotSymtabSec = &Sec;
1405 break;
1406 case ELF::SHT_DYNSYM:
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001407 if (DynSymRegion.Size)
Saleem Abdulrasool46ee7332017-09-29 02:45:44 +00001408 reportError("Multiple SHT_DYNSYM");
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001409 DynSymRegion = createDRIFrom(&Sec);
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00001410 // This is only used (if Elf_Shdr present)for naming section in GNU style
1411 DynSymtabName = unwrapOrError(Obj->getSectionName(&Sec));
Dave Lee67b49662017-11-16 18:10:15 +00001412 DynamicStringTable = unwrapOrError(Obj->getStringTableForSymtab(Sec));
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001413 break;
Michael J. Spencer1c793ef2016-02-17 22:30:41 +00001414 case ELF::SHT_SYMTAB_SHNDX:
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001415 ShndxTable = unwrapOrError(Obj->getSHNDXTable(Sec));
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001416 break;
Michael J. Spencer37304f12016-02-11 04:59:26 +00001417 case ELF::SHT_GNU_versym:
Xing GUO09a77fe2019-03-29 01:26:36 +00001418 if (SymbolVersionSection != nullptr)
Michael J. Spencer37304f12016-02-11 04:59:26 +00001419 reportError("Multiple SHT_GNU_versym");
Xing GUO09a77fe2019-03-29 01:26:36 +00001420 SymbolVersionSection = &Sec;
Michael J. Spencer37304f12016-02-11 04:59:26 +00001421 break;
1422 case ELF::SHT_GNU_verdef:
Xing GUO09a77fe2019-03-29 01:26:36 +00001423 if (SymbolVersionDefSection != nullptr)
Michael J. Spencer37304f12016-02-11 04:59:26 +00001424 reportError("Multiple SHT_GNU_verdef");
Xing GUO09a77fe2019-03-29 01:26:36 +00001425 SymbolVersionDefSection = &Sec;
Michael J. Spencer37304f12016-02-11 04:59:26 +00001426 break;
1427 case ELF::SHT_GNU_verneed:
Xing GUO09a77fe2019-03-29 01:26:36 +00001428 if (SymbolVersionNeedSection != nullptr)
Saleem Abdulrasool46ee7332017-09-29 02:45:44 +00001429 reportError("Multiple SHT_GNU_verneed");
Xing GUO09a77fe2019-03-29 01:26:36 +00001430 SymbolVersionNeedSection = &Sec;
Michael J. Spencer37304f12016-02-11 04:59:26 +00001431 break;
Michael J. Spencerae6eeae2018-06-02 16:33:01 +00001432 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
1433 if (DotCGProfileSec != nullptr)
Fangrui Song49c9ba12018-10-12 22:57:57 +00001434 reportError("Multiple .llvm.call-graph-profile");
Michael J. Spencerae6eeae2018-06-02 16:33:01 +00001435 DotCGProfileSec = &Sec;
Peter Collingbourne3e227332018-07-17 22:17:18 +00001436 break;
1437 case ELF::SHT_LLVM_ADDRSIG:
1438 if (DotAddrsigSec != nullptr)
1439 reportError("Multiple .llvm_addrsig");
1440 DotAddrsigSec = &Sec;
1441 break;
Michael J. Spencer37304f12016-02-11 04:59:26 +00001442 }
1443 }
1444
George Rimar72f821d2019-05-20 15:41:48 +00001445 loadDynamicTable(Obj);
Michael J. Spencer60d82b22016-02-11 04:59:37 +00001446
1447 if (opts::Output == opts::GNU)
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001448 ELFDumperStyle.reset(new GNUStyle<ELFT>(Writer, this));
Michael J. Spencer60d82b22016-02-11 04:59:37 +00001449 else
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001450 ELFDumperStyle.reset(new LLVMStyle<ELFT>(Writer, this));
Michael J. Spencer60d82b22016-02-11 04:59:37 +00001451}
1452
George Rimar72f821d2019-05-20 15:41:48 +00001453template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() {
George Rimar47936762016-01-16 00:49:19 +00001454 auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001455 auto MappedAddrOrError = ObjF->getELFFile()->toMappedAddr(VAddr);
Xing GUOfe5a6c32018-12-08 05:32:28 +00001456 if (!MappedAddrOrError)
1457 report_fatal_error(MappedAddrOrError.takeError());
1458 return MappedAddrOrError.get();
George Rimar47936762016-01-16 00:49:19 +00001459 };
1460
1461 uint64_t SONameOffset = 0;
1462 const char *StringTableBegin = nullptr;
1463 uint64_t StringTableSize = 0;
1464 for (const Elf_Dyn &Dyn : dynamic_table()) {
1465 switch (Dyn.d_tag) {
1466 case ELF::DT_HASH:
1467 HashTable =
1468 reinterpret_cast<const Elf_Hash *>(toMappedAddr(Dyn.getPtr()));
1469 break;
1470 case ELF::DT_GNU_HASH:
1471 GnuHashTable =
1472 reinterpret_cast<const Elf_GnuHash *>(toMappedAddr(Dyn.getPtr()));
1473 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001474 case ELF::DT_STRTAB:
Xing GUO0df95d22019-04-08 11:48:36 +00001475 StringTableBegin =
1476 reinterpret_cast<const char *>(toMappedAddr(Dyn.getPtr()));
Simon Atanasyan72155c32016-01-16 22:40:09 +00001477 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001478 case ELF::DT_STRSZ:
1479 StringTableSize = Dyn.getVal();
Simon Atanasyan72155c32016-01-16 22:40:09 +00001480 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001481 case ELF::DT_SYMTAB:
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001482 DynSymRegion.Addr = toMappedAddr(Dyn.getPtr());
1483 DynSymRegion.EntSize = sizeof(Elf_Sym);
Simon Atanasyan72155c32016-01-16 22:40:09 +00001484 break;
George Rimar47936762016-01-16 00:49:19 +00001485 case ELF::DT_RELA:
1486 DynRelaRegion.Addr = toMappedAddr(Dyn.getPtr());
1487 break;
1488 case ELF::DT_RELASZ:
1489 DynRelaRegion.Size = Dyn.getVal();
1490 break;
1491 case ELF::DT_RELAENT:
1492 DynRelaRegion.EntSize = Dyn.getVal();
1493 break;
1494 case ELF::DT_SONAME:
1495 SONameOffset = Dyn.getVal();
1496 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001497 case ELF::DT_REL:
1498 DynRelRegion.Addr = toMappedAddr(Dyn.getPtr());
George Rimar47936762016-01-16 00:49:19 +00001499 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001500 case ELF::DT_RELSZ:
1501 DynRelRegion.Size = Dyn.getVal();
George Rimar47936762016-01-16 00:49:19 +00001502 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001503 case ELF::DT_RELENT:
1504 DynRelRegion.EntSize = Dyn.getVal();
George Rimar47936762016-01-16 00:49:19 +00001505 break;
Jake Ehrlich0f440d82018-06-28 21:07:34 +00001506 case ELF::DT_RELR:
1507 case ELF::DT_ANDROID_RELR:
1508 DynRelrRegion.Addr = toMappedAddr(Dyn.getPtr());
1509 break;
1510 case ELF::DT_RELRSZ:
1511 case ELF::DT_ANDROID_RELRSZ:
1512 DynRelrRegion.Size = Dyn.getVal();
1513 break;
1514 case ELF::DT_RELRENT:
1515 case ELF::DT_ANDROID_RELRENT:
1516 DynRelrRegion.EntSize = Dyn.getVal();
1517 break;
Rafael Espindola944f6552016-02-16 15:16:00 +00001518 case ELF::DT_PLTREL:
1519 if (Dyn.getVal() == DT_REL)
1520 DynPLTRelRegion.EntSize = sizeof(Elf_Rel);
1521 else if (Dyn.getVal() == DT_RELA)
1522 DynPLTRelRegion.EntSize = sizeof(Elf_Rela);
1523 else
1524 reportError(Twine("unknown DT_PLTREL value of ") +
1525 Twine((uint64_t)Dyn.getVal()));
1526 break;
1527 case ELF::DT_JMPREL:
1528 DynPLTRelRegion.Addr = toMappedAddr(Dyn.getPtr());
1529 break;
1530 case ELF::DT_PLTRELSZ:
1531 DynPLTRelRegion.Size = Dyn.getVal();
1532 break;
George Rimar47936762016-01-16 00:49:19 +00001533 }
1534 }
1535 if (StringTableBegin)
1536 DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
1537 if (SONameOffset)
1538 SOName = getDynamicString(SONameOffset);
Rafael Espindola6009db62016-02-16 14:17:48 +00001539}
George Rimar47936762016-01-16 00:49:19 +00001540
Rafael Espindola6009db62016-02-16 14:17:48 +00001541template <typename ELFT>
Simon Atanasyan72155c32016-01-16 22:40:09 +00001542typename ELFDumper<ELFT>::Elf_Rel_Range ELFDumper<ELFT>::dyn_rels() const {
Rafael Espindolaaafcf752016-04-05 14:47:22 +00001543 return DynRelRegion.getAsArrayRef<Elf_Rel>();
George Rimar47936762016-01-16 00:49:19 +00001544}
1545
1546template <typename ELFT>
1547typename ELFDumper<ELFT>::Elf_Rela_Range ELFDumper<ELFT>::dyn_relas() const {
Rafael Espindolaaafcf752016-04-05 14:47:22 +00001548 return DynRelaRegion.getAsArrayRef<Elf_Rela>();
George Rimar47936762016-01-16 00:49:19 +00001549}
1550
Jake Ehrlich0f440d82018-06-28 21:07:34 +00001551template <typename ELFT>
1552typename ELFDumper<ELFT>::Elf_Relr_Range ELFDumper<ELFT>::dyn_relrs() const {
1553 return DynRelrRegion.getAsArrayRef<Elf_Relr>();
1554}
1555
George Rimar9e88a262019-05-14 14:22:44 +00001556template <class ELFT> void ELFDumper<ELFT>::printFileHeaders() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001557 ELFDumperStyle->printFileHeaders(ObjF->getELFFile());
George Rimar47936762016-01-16 00:49:19 +00001558}
1559
George Rimar9e88a262019-05-14 14:22:44 +00001560template <class ELFT> void ELFDumper<ELFT>::printSectionHeaders() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001561 ELFDumperStyle->printSectionHeaders(ObjF->getELFFile());
George Rimar47936762016-01-16 00:49:19 +00001562}
1563
George Rimar9e88a262019-05-14 14:22:44 +00001564template <class ELFT> void ELFDumper<ELFT>::printRelocations() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001565 ELFDumperStyle->printRelocations(ObjF->getELFFile());
George Rimar47936762016-01-16 00:49:19 +00001566}
1567
Matt Davis50ca8ed2019-02-01 18:51:10 +00001568template <class ELFT>
1569void ELFDumper<ELFT>::printProgramHeaders(
1570 bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {
1571 ELFDumperStyle->printProgramHeaders(ObjF->getELFFile(), PrintProgramHeaders,
1572 PrintSectionMapping);
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00001573}
1574
Xing GUOea16be12019-03-25 11:02:49 +00001575template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
1576 // Dump version symbol section.
1577 ELFDumperStyle->printVersionSymbolSection(ObjF->getELFFile(),
Xing GUO09a77fe2019-03-29 01:26:36 +00001578 SymbolVersionSection);
Xing GUOea16be12019-03-25 11:02:49 +00001579
1580 // Dump version definition section.
1581 ELFDumperStyle->printVersionDefinitionSection(ObjF->getELFFile(),
Xing GUO09a77fe2019-03-29 01:26:36 +00001582 SymbolVersionDefSection);
Xing GUOea16be12019-03-25 11:02:49 +00001583
1584 // Dump version dependency section.
1585 ELFDumperStyle->printVersionDependencySection(ObjF->getELFFile(),
Xing GUO09a77fe2019-03-29 01:26:36 +00001586 SymbolVersionNeedSection);
Xing GUOea16be12019-03-25 11:02:49 +00001587}
1588
Simon Atanasyan72155c32016-01-16 22:40:09 +00001589template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001590 ELFDumperStyle->printDynamicRelocations(ObjF->getELFFile());
George Rimar47936762016-01-16 00:49:19 +00001591}
1592
James Henderson21ed8682019-01-23 16:15:39 +00001593template <class ELFT>
1594void ELFDumper<ELFT>::printSymbols(bool PrintSymbols,
1595 bool PrintDynamicSymbols) {
1596 ELFDumperStyle->printSymbols(ObjF->getELFFile(), PrintSymbols,
1597 PrintDynamicSymbols);
George Rimar47936762016-01-16 00:49:19 +00001598}
1599
George Rimar9e88a262019-05-14 14:22:44 +00001600template <class ELFT> void ELFDumper<ELFT>::printHashSymbols() {
James Henderson5fc812f2019-01-22 09:35:35 +00001601 ELFDumperStyle->printHashSymbols(ObjF->getELFFile());
1602}
1603
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00001604template <class ELFT> void ELFDumper<ELFT>::printHashHistogram() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001605 ELFDumperStyle->printHashHistogram(ObjF->getELFFile());
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00001606}
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00001607
Michael J. Spencerae6eeae2018-06-02 16:33:01 +00001608template <class ELFT> void ELFDumper<ELFT>::printCGProfile() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001609 ELFDumperStyle->printCGProfile(ObjF->getELFFile());
Michael J. Spencerae6eeae2018-06-02 16:33:01 +00001610}
1611
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00001612template <class ELFT> void ELFDumper<ELFT>::printNotes() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001613 ELFDumperStyle->printNotes(ObjF->getELFFile());
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00001614}
1615
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +00001616template <class ELFT> void ELFDumper<ELFT>::printELFLinkerOptions() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001617 ELFDumperStyle->printELFLinkerOptions(ObjF->getELFFile());
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +00001618}
1619
Hemant Kulkarnie60b2942016-12-27 19:59:29 +00001620static const char *getTypeString(unsigned Arch, uint64_t Type) {
Alexander Richardson3056a842018-03-21 14:17:50 +00001621#define DYNAMIC_TAG(n, v)
Hemant Kulkarnie60b2942016-12-27 19:59:29 +00001622 switch (Arch) {
1623 case EM_HEXAGON:
1624 switch (Type) {
Alexander Richardson3056a842018-03-21 14:17:50 +00001625#define HEXAGON_DYNAMIC_TAG(name, value) \
George Rimarec895f12019-05-16 06:22:51 +00001626 case DT_##name: \
1627 return #name;
Alexander Richardson3056a842018-03-21 14:17:50 +00001628#include "llvm/BinaryFormat/DynamicTags.def"
1629#undef HEXAGON_DYNAMIC_TAG
Hemant Kulkarnie60b2942016-12-27 19:59:29 +00001630 }
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00001631 break;
Sean Fertileeaa16072018-04-13 16:42:48 +00001632
Hemant Kulkarnie60b2942016-12-27 19:59:29 +00001633 case EM_MIPS:
1634 switch (Type) {
Alexander Richardson3056a842018-03-21 14:17:50 +00001635#define MIPS_DYNAMIC_TAG(name, value) \
George Rimarec895f12019-05-16 06:22:51 +00001636 case DT_##name: \
1637 return #name;
Alexander Richardson3056a842018-03-21 14:17:50 +00001638#include "llvm/BinaryFormat/DynamicTags.def"
1639#undef MIPS_DYNAMIC_TAG
Hemant Kulkarnie60b2942016-12-27 19:59:29 +00001640 }
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00001641 break;
Sean Fertileeaa16072018-04-13 16:42:48 +00001642
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00001643 case EM_PPC64:
George Rimarec895f12019-05-16 06:22:51 +00001644 switch(Type) {
Sean Fertileeaa16072018-04-13 16:42:48 +00001645#define PPC64_DYNAMIC_TAG(name, value) \
George Rimarec895f12019-05-16 06:22:51 +00001646 case DT_##name: \
1647 return #name;
Sean Fertileeaa16072018-04-13 16:42:48 +00001648#include "llvm/BinaryFormat/DynamicTags.def"
1649#undef PPC64_DYNAMIC_TAG
1650 }
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00001651 break;
Hemant Kulkarnie60b2942016-12-27 19:59:29 +00001652 }
Alexander Richardson3056a842018-03-21 14:17:50 +00001653#undef DYNAMIC_TAG
George Rimar47936762016-01-16 00:49:19 +00001654 switch (Type) {
Alexander Richardson3056a842018-03-21 14:17:50 +00001655// Now handle all dynamic tags except the architecture specific ones
1656#define MIPS_DYNAMIC_TAG(name, value)
1657#define HEXAGON_DYNAMIC_TAG(name, value)
Sean Fertileeaa16072018-04-13 16:42:48 +00001658#define PPC64_DYNAMIC_TAG(name, value)
Alexander Richardson3056a842018-03-21 14:17:50 +00001659// Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
1660#define DYNAMIC_TAG_MARKER(name, value)
1661#define DYNAMIC_TAG(name, value) \
1662 case DT_##name: \
1663 return #name;
1664#include "llvm/BinaryFormat/DynamicTags.def"
1665#undef DYNAMIC_TAG
1666#undef MIPS_DYNAMIC_TAG
1667#undef HEXAGON_DYNAMIC_TAG
Sean Fertileeaa16072018-04-13 16:42:48 +00001668#undef PPC64_DYNAMIC_TAG
Alexander Richardson3056a842018-03-21 14:17:50 +00001669#undef DYNAMIC_TAG_MARKER
George Rimar9e88a262019-05-14 14:22:44 +00001670 default:
1671 return "unknown";
George Rimar47936762016-01-16 00:49:19 +00001672 }
1673}
1674
George Rimar9e88a262019-05-14 14:22:44 +00001675#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \
George Rimar47936762016-01-16 00:49:19 +00001676 { #enum, prefix##_##enum }
1677
1678static const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001679 LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
1680 LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
1681 LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
1682 LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
1683 LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
1684};
George Rimar47936762016-01-16 00:49:19 +00001685
1686static const EnumEntry<unsigned> ElfDynamicDTFlags1[] = {
George Rimarec895f12019-05-16 06:22:51 +00001687 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW),
1688 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL),
1689 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP),
1690 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE),
1691 LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR),
1692 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST),
1693 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN),
1694 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN),
1695 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT),
1696 LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS),
1697 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE),
1698 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB),
1699 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP),
1700 LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT),
1701 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE),
1702 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE),
1703 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELPND),
1704 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT),
1705 LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF),
1706 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS),
1707 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR),
1708 LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED),
1709 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC),
1710 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE),
1711 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT),
1712 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON)
1713};
George Rimar47936762016-01-16 00:49:19 +00001714
1715static const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00001716 LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
1717 LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
1718 LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
1719 LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
1720 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
1721 LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
1722 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
1723 LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
1724 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
1725 LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
1726 LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
1727 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
1728 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
1729 LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
1730 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
1731 LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
1732};
George Rimar47936762016-01-16 00:49:19 +00001733
1734#undef LLVM_READOBJ_DT_FLAG_ENT
1735
1736template <typename T, typename TFlag>
1737void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
Eugene Zelenko416e0592017-06-09 21:41:54 +00001738 using FlagEntry = EnumEntry<TFlag>;
1739 using FlagVector = SmallVector<FlagEntry, 10>;
George Rimar47936762016-01-16 00:49:19 +00001740 FlagVector SetFlags;
1741
1742 for (const auto &Flag : Flags) {
1743 if (Flag.Value == 0)
1744 continue;
1745
1746 if ((Value & Flag.Value) == Flag.Value)
1747 SetFlags.push_back(Flag);
1748 }
1749
1750 for (const auto &Flag : SetFlags) {
1751 OS << Flag.Name << " ";
1752 }
1753}
1754
1755template <class ELFT>
1756StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
1757 if (Value >= DynamicStringTable.size())
1758 reportError("Invalid dynamic string table reference");
1759 return StringRef(DynamicStringTable.data() + Value);
1760}
1761
George Rimarefd3ffb2017-07-14 16:00:16 +00001762static void printLibrary(raw_ostream &OS, const Twine &Tag, const Twine &Name) {
1763 OS << Tag << ": [" << Name << "]";
1764}
1765
George Rimar47936762016-01-16 00:49:19 +00001766template <class ELFT>
1767void ELFDumper<ELFT>::printValue(uint64_t Type, uint64_t Value) {
1768 raw_ostream &OS = W.getOStream();
George Rimar9e88a262019-05-14 14:22:44 +00001769 const char *ConvChar =
1770 (opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64;
George Rimar47936762016-01-16 00:49:19 +00001771 switch (Type) {
1772 case DT_PLTREL:
1773 if (Value == DT_REL) {
1774 OS << "REL";
1775 break;
1776 } else if (Value == DT_RELA) {
1777 OS << "RELA";
1778 break;
1779 }
Justin Bognerb03fd122016-08-17 05:10:15 +00001780 LLVM_FALLTHROUGH;
George Rimar47936762016-01-16 00:49:19 +00001781 case DT_PLTGOT:
1782 case DT_HASH:
1783 case DT_STRTAB:
1784 case DT_SYMTAB:
1785 case DT_RELA:
1786 case DT_INIT:
1787 case DT_FINI:
1788 case DT_REL:
1789 case DT_JMPREL:
1790 case DT_INIT_ARRAY:
1791 case DT_FINI_ARRAY:
1792 case DT_PREINIT_ARRAY:
1793 case DT_DEBUG:
1794 case DT_VERDEF:
1795 case DT_VERNEED:
1796 case DT_VERSYM:
1797 case DT_GNU_HASH:
1798 case DT_NULL:
1799 case DT_MIPS_BASE_ADDRESS:
1800 case DT_MIPS_GOTSYM:
1801 case DT_MIPS_RLD_MAP:
1802 case DT_MIPS_RLD_MAP_REL:
1803 case DT_MIPS_PLTGOT:
1804 case DT_MIPS_OPTIONS:
Hemant Kulkarnicb21f3c2016-05-12 22:16:53 +00001805 OS << format(ConvChar, Value);
George Rimar47936762016-01-16 00:49:19 +00001806 break;
Davide Italiano8c503672016-01-16 06:06:36 +00001807 case DT_RELACOUNT:
George Rimar47936762016-01-16 00:49:19 +00001808 case DT_RELCOUNT:
1809 case DT_VERDEFNUM:
1810 case DT_VERNEEDNUM:
1811 case DT_MIPS_RLD_VERSION:
1812 case DT_MIPS_LOCAL_GOTNO:
1813 case DT_MIPS_SYMTABNO:
1814 case DT_MIPS_UNREFEXTNO:
1815 OS << Value;
1816 break;
1817 case DT_PLTRELSZ:
1818 case DT_RELASZ:
1819 case DT_RELAENT:
1820 case DT_STRSZ:
1821 case DT_SYMENT:
1822 case DT_RELSZ:
1823 case DT_RELENT:
1824 case DT_INIT_ARRAYSZ:
1825 case DT_FINI_ARRAYSZ:
1826 case DT_PREINIT_ARRAYSZ:
Peter Collingbourne5c54f152017-10-27 17:49:40 +00001827 case DT_ANDROID_RELSZ:
1828 case DT_ANDROID_RELASZ:
George Rimar47936762016-01-16 00:49:19 +00001829 OS << Value << " (bytes)";
1830 break;
1831 case DT_NEEDED:
George Rimarefd3ffb2017-07-14 16:00:16 +00001832 printLibrary(OS, "Shared library", getDynamicString(Value));
George Rimar47936762016-01-16 00:49:19 +00001833 break;
1834 case DT_SONAME:
George Rimarefd3ffb2017-07-14 16:00:16 +00001835 printLibrary(OS, "Library soname", getDynamicString(Value));
George Rimar47936762016-01-16 00:49:19 +00001836 break;
George Rimard8a4eca2016-09-02 07:35:19 +00001837 case DT_AUXILIARY:
George Rimarefd3ffb2017-07-14 16:00:16 +00001838 printLibrary(OS, "Auxiliary library", getDynamicString(Value));
1839 break;
Xing GUOeee62262019-03-07 14:53:10 +00001840 case DT_USED:
1841 printLibrary(OS, "Not needed object", getDynamicString(Value));
1842 break;
George Rimarefd3ffb2017-07-14 16:00:16 +00001843 case DT_FILTER:
1844 printLibrary(OS, "Filter library", getDynamicString(Value));
George Rimard8a4eca2016-09-02 07:35:19 +00001845 break;
George Rimar47936762016-01-16 00:49:19 +00001846 case DT_RPATH:
1847 case DT_RUNPATH:
1848 OS << getDynamicString(Value);
1849 break;
1850 case DT_MIPS_FLAGS:
1851 printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS);
1852 break;
1853 case DT_FLAGS:
1854 printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
1855 break;
1856 case DT_FLAGS_1:
1857 printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS);
1858 break;
1859 default:
Hemant Kulkarnicb21f3c2016-05-12 22:16:53 +00001860 OS << format(ConvChar, Value);
George Rimar47936762016-01-16 00:49:19 +00001861 break;
1862 }
1863}
1864
George Rimar9e88a262019-05-14 14:22:44 +00001865template <class ELFT> void ELFDumper<ELFT>::printUnwindInfo() {
Peter Collingbourneac136cd2019-02-28 22:42:55 +00001866 DwarfCFIEH::PrinterContext<ELFT> Ctx(W, ObjF);
1867 Ctx.printUnwindInformation();
George Rimar47936762016-01-16 00:49:19 +00001868}
1869
1870namespace {
Eugene Zelenko416e0592017-06-09 21:41:54 +00001871
Rui Ueyama1b31eb92018-01-12 01:40:32 +00001872template <> void ELFDumper<ELF32LE>::printUnwindInfo() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001873 const ELFFile<ELF32LE> *Obj = ObjF->getELFFile();
George Rimar47936762016-01-16 00:49:19 +00001874 const unsigned Machine = Obj->getHeader()->e_machine;
1875 if (Machine == EM_ARM) {
Rui Ueyama1b31eb92018-01-12 01:40:32 +00001876 ARM::EHABI::PrinterContext<ELF32LE> Ctx(W, Obj, DotSymtabSec);
Peter Collingbourneac136cd2019-02-28 22:42:55 +00001877 Ctx.PrintUnwindInformation();
George Rimar47936762016-01-16 00:49:19 +00001878 }
Peter Collingbourneac136cd2019-02-28 22:42:55 +00001879 DwarfCFIEH::PrinterContext<ELF32LE> Ctx(W, ObjF);
1880 Ctx.printUnwindInformation();
George Rimar47936762016-01-16 00:49:19 +00001881}
Eugene Zelenko416e0592017-06-09 21:41:54 +00001882
1883} // end anonymous namespace
George Rimar47936762016-01-16 00:49:19 +00001884
George Rimar9e88a262019-05-14 14:22:44 +00001885template <class ELFT> void ELFDumper<ELFT>::printDynamicTable() {
George Rimar7b4fce12019-02-28 08:15:59 +00001886 // A valid .dynamic section contains an array of entries terminated with
1887 // a DT_NULL entry. However, sometimes the section content may continue
1888 // past the DT_NULL entry, so to dump the section correctly, we first find
1889 // the end of the entries by iterating over them.
1890 size_t Size = 0;
1891 Elf_Dyn_Range DynTableEntries = dynamic_table();
1892 for (; Size < DynTableEntries.size();)
1893 if (DynTableEntries[Size++].getTag() == DT_NULL)
1894 break;
George Rimar47936762016-01-16 00:49:19 +00001895
George Rimar7b4fce12019-02-28 08:15:59 +00001896 if (!Size)
George Rimar47936762016-01-16 00:49:19 +00001897 return;
1898
1899 raw_ostream &OS = W.getOStream();
George Rimar7b4fce12019-02-28 08:15:59 +00001900 W.startLine() << "DynamicSection [ (" << Size << " entries)\n";
George Rimar47936762016-01-16 00:49:19 +00001901
1902 bool Is64 = ELFT::Is64Bits;
George Rimar9e88a262019-05-14 14:22:44 +00001903 W.startLine() << " Tag" << (Is64 ? " " : " ") << "Type"
1904 << " "
1905 << "Name/Value\n";
George Rimar7b4fce12019-02-28 08:15:59 +00001906 for (size_t I = 0; I < Size; ++I) {
1907 const Elf_Dyn &Entry = DynTableEntries[I];
George Rimar47936762016-01-16 00:49:19 +00001908 uintX_t Tag = Entry.getTag();
George Rimar9e88a262019-05-14 14:22:44 +00001909 W.startLine() << " "
1910 << format_hex(Tag, Is64 ? 18 : 10, opts::Output != opts::GNU)
1911 << " "
1912 << format(
1913 "%-21s",
1914 getTypeString(
1915 ObjF->getELFFile()->getHeader()->e_machine, Tag));
George Rimar47936762016-01-16 00:49:19 +00001916 printValue(Tag, Entry.getVal());
1917 OS << "\n";
1918 }
1919
1920 W.startLine() << "]\n";
1921}
1922
George Rimar9e88a262019-05-14 14:22:44 +00001923template <class ELFT> void ELFDumper<ELFT>::printNeededLibraries() {
George Rimar47936762016-01-16 00:49:19 +00001924 ListScope D(W, "NeededLibraries");
1925
Eugene Zelenko416e0592017-06-09 21:41:54 +00001926 using LibsTy = std::vector<StringRef>;
George Rimar47936762016-01-16 00:49:19 +00001927 LibsTy Libs;
1928
1929 for (const auto &Entry : dynamic_table())
1930 if (Entry.d_tag == ELF::DT_NEEDED)
1931 Libs.push_back(getDynamicString(Entry.d_un.d_val));
1932
Fangrui Songa5355a52019-04-22 15:53:43 +00001933 llvm::stable_sort(Libs);
George Rimar47936762016-01-16 00:49:19 +00001934
Sam Clegg88e9a152018-01-10 00:14:19 +00001935 for (const auto &L : Libs)
George Rimar9e88a262019-05-14 14:22:44 +00001936 W.startLine() << L << "\n";
George Rimar47936762016-01-16 00:49:19 +00001937}
1938
George Rimar9e88a262019-05-14 14:22:44 +00001939template <typename ELFT> void ELFDumper<ELFT>::printHashTable() {
George Rimar47936762016-01-16 00:49:19 +00001940 DictScope D(W, "HashTable");
1941 if (!HashTable)
1942 return;
1943 W.printNumber("Num Buckets", HashTable->nbucket);
1944 W.printNumber("Num Chains", HashTable->nchain);
1945 W.printList("Buckets", HashTable->buckets());
1946 W.printList("Chains", HashTable->chains());
1947}
1948
George Rimar9e88a262019-05-14 14:22:44 +00001949template <typename ELFT> void ELFDumper<ELFT>::printGnuHashTable() {
George Rimar47936762016-01-16 00:49:19 +00001950 DictScope D(W, "GnuHashTable");
1951 if (!GnuHashTable)
1952 return;
1953 W.printNumber("Num Buckets", GnuHashTable->nbuckets);
1954 W.printNumber("First Hashed Symbol Index", GnuHashTable->symndx);
1955 W.printNumber("Num Mask Words", GnuHashTable->maskwords);
1956 W.printNumber("Shift Count", GnuHashTable->shift2);
1957 W.printHexList("Bloom Filter", GnuHashTable->filter());
1958 W.printList("Buckets", GnuHashTable->buckets());
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001959 Elf_Sym_Range Syms = dynamic_symbols();
1960 unsigned NumSyms = std::distance(Syms.begin(), Syms.end());
1961 if (!NumSyms)
George Rimar47936762016-01-16 00:49:19 +00001962 reportError("No dynamic symbol section");
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001963 W.printHexList("Values", GnuHashTable->values(NumSyms));
George Rimar47936762016-01-16 00:49:19 +00001964}
1965
1966template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {
Sam Clegg88e9a152018-01-10 00:14:19 +00001967 W.printString("LoadName", SOName);
George Rimar47936762016-01-16 00:49:19 +00001968}
1969
George Rimar9e88a262019-05-14 14:22:44 +00001970template <class ELFT> void ELFDumper<ELFT>::printAttributes() {
George Rimar47936762016-01-16 00:49:19 +00001971 W.startLine() << "Attributes not implemented.\n";
1972}
1973
1974namespace {
Eugene Zelenko416e0592017-06-09 21:41:54 +00001975
Rui Ueyama1b31eb92018-01-12 01:40:32 +00001976template <> void ELFDumper<ELF32LE>::printAttributes() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00001977 const ELFFile<ELF32LE> *Obj = ObjF->getELFFile();
George Rimar47936762016-01-16 00:49:19 +00001978 if (Obj->getHeader()->e_machine != EM_ARM) {
1979 W.startLine() << "Attributes not implemented.\n";
1980 return;
1981 }
1982
1983 DictScope BA(W, "BuildAttributes");
Rafael Espindola25be8c82016-11-02 14:10:57 +00001984 for (const ELFO::Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
George Rimar47936762016-01-16 00:49:19 +00001985 if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES)
1986 continue;
1987
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001988 ArrayRef<uint8_t> Contents = unwrapOrError(Obj->getSectionContents(&Sec));
1989 if (Contents[0] != ARMBuildAttrs::Format_Version) {
Benjamin Kramer3a13ed62017-12-28 16:58:54 +00001990 errs() << "unrecognised FormatVersion: 0x"
1991 << Twine::utohexstr(Contents[0]) << '\n';
George Rimar47936762016-01-16 00:49:19 +00001992 continue;
1993 }
1994
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001995 W.printHex("FormatVersion", Contents[0]);
1996 if (Contents.size() == 1)
George Rimar47936762016-01-16 00:49:19 +00001997 continue;
1998
Sam Parkerdf7c6ef2017-01-18 13:52:12 +00001999 ARMAttributeParser(&W).Parse(Contents, true);
George Rimar47936762016-01-16 00:49:19 +00002000 }
2001}
George Rimar47936762016-01-16 00:49:19 +00002002
George Rimar47936762016-01-16 00:49:19 +00002003template <class ELFT> class MipsGOTParser {
2004public:
Rafael Espindola6bc29902016-10-06 14:07:26 +00002005 TYPEDEF_ELF_TYPES(ELFT)
Simon Atanasyan62d32592017-12-21 10:26:02 +00002006 using Entry = typename ELFO::Elf_Addr;
2007 using Entries = ArrayRef<Entry>;
Eugene Zelenko416e0592017-06-09 21:41:54 +00002008
Simon Atanasyan62d32592017-12-21 10:26:02 +00002009 const bool IsStatic;
George Rimarec895f12019-05-16 06:22:51 +00002010 const ELFO * const Obj;
George Rimar47936762016-01-16 00:49:19 +00002011
Simon Atanasyan62d32592017-12-21 10:26:02 +00002012 MipsGOTParser(const ELFO *Obj, Elf_Dyn_Range DynTable, Elf_Sym_Range DynSyms);
2013
2014 bool hasGot() const { return !GotEntries.empty(); }
2015 bool hasPlt() const { return !PltEntries.empty(); }
2016
2017 uint64_t getGp() const;
2018
2019 const Entry *getGotLazyResolver() const;
2020 const Entry *getGotModulePointer() const;
2021 const Entry *getPltLazyResolver() const;
2022 const Entry *getPltModulePointer() const;
2023
2024 Entries getLocalEntries() const;
2025 Entries getGlobalEntries() const;
2026 Entries getOtherEntries() const;
2027 Entries getPltEntries() const;
2028
George Rimarec895f12019-05-16 06:22:51 +00002029 uint64_t getGotAddress(const Entry * E) const;
2030 int64_t getGotOffset(const Entry * E) const;
Simon Atanasyan62d32592017-12-21 10:26:02 +00002031 const Elf_Sym *getGotSym(const Entry *E) const;
2032
George Rimarec895f12019-05-16 06:22:51 +00002033 uint64_t getPltAddress(const Entry * E) const;
Simon Atanasyan62d32592017-12-21 10:26:02 +00002034 const Elf_Sym *getPltSym(const Entry *E) const;
2035
2036 StringRef getPltStrTable() const { return PltStrTable; }
George Rimar47936762016-01-16 00:49:19 +00002037
2038private:
Simon Atanasyan62d32592017-12-21 10:26:02 +00002039 const Elf_Shdr *GotSec;
2040 size_t LocalNum;
2041 size_t GlobalNum;
George Rimar47936762016-01-16 00:49:19 +00002042
Simon Atanasyan62d32592017-12-21 10:26:02 +00002043 const Elf_Shdr *PltSec;
2044 const Elf_Shdr *PltRelSec;
2045 const Elf_Shdr *PltSymTable;
2046 Elf_Sym_Range GotDynSyms;
2047 StringRef PltStrTable;
George Rimar47936762016-01-16 00:49:19 +00002048
Simon Atanasyan62d32592017-12-21 10:26:02 +00002049 Entries GotEntries;
2050 Entries PltEntries;
George Rimar47936762016-01-16 00:49:19 +00002051};
Eugene Zelenko416e0592017-06-09 21:41:54 +00002052
2053} // end anonymous namespace
George Rimar47936762016-01-16 00:49:19 +00002054
2055template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00002056MipsGOTParser<ELFT>::MipsGOTParser(const ELFO *Obj, Elf_Dyn_Range DynTable,
2057 Elf_Sym_Range DynSyms)
2058 : IsStatic(DynTable.empty()), Obj(Obj), GotSec(nullptr), LocalNum(0),
2059 GlobalNum(0), PltSec(nullptr), PltRelSec(nullptr), PltSymTable(nullptr) {
2060 // See "Global Offset Table" in Chapter 5 in the following document
2061 // for detailed GOT description.
2062 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
2063
2064 // Find static GOT secton.
2065 if (IsStatic) {
2066 GotSec = findSectionByName(*Obj, ".got");
2067 if (!GotSec)
2068 reportError("Cannot find .got section");
2069
2070 ArrayRef<uint8_t> Content = unwrapOrError(Obj->getSectionContents(GotSec));
2071 GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),
2072 Content.size() / sizeof(Entry));
2073 LocalNum = GotEntries.size();
2074 return;
2075 }
2076
2077 // Lookup dynamic table tags which define GOT/PLT layouts.
2078 Optional<uint64_t> DtPltGot;
2079 Optional<uint64_t> DtLocalGotNum;
2080 Optional<uint64_t> DtGotSym;
2081 Optional<uint64_t> DtMipsPltGot;
2082 Optional<uint64_t> DtJmpRel;
George Rimar47936762016-01-16 00:49:19 +00002083 for (const auto &Entry : DynTable) {
2084 switch (Entry.getTag()) {
2085 case ELF::DT_PLTGOT:
2086 DtPltGot = Entry.getVal();
2087 break;
2088 case ELF::DT_MIPS_LOCAL_GOTNO:
2089 DtLocalGotNum = Entry.getVal();
2090 break;
2091 case ELF::DT_MIPS_GOTSYM:
2092 DtGotSym = Entry.getVal();
2093 break;
2094 case ELF::DT_MIPS_PLTGOT:
2095 DtMipsPltGot = Entry.getVal();
2096 break;
2097 case ELF::DT_JMPREL:
2098 DtJmpRel = Entry.getVal();
2099 break;
2100 }
2101 }
Simon Atanasyan62d32592017-12-21 10:26:02 +00002102
2103 // Find dynamic GOT section.
2104 if (DtPltGot || DtLocalGotNum || DtGotSym) {
2105 if (!DtPltGot)
2106 report_fatal_error("Cannot find PLTGOT dynamic table tag.");
2107 if (!DtLocalGotNum)
2108 report_fatal_error("Cannot find MIPS_LOCAL_GOTNO dynamic table tag.");
2109 if (!DtGotSym)
2110 report_fatal_error("Cannot find MIPS_GOTSYM dynamic table tag.");
2111
2112 size_t DynSymTotal = DynSyms.size();
2113 if (*DtGotSym > DynSymTotal)
2114 reportError("MIPS_GOTSYM exceeds a number of dynamic symbols");
2115
2116 GotSec = findNotEmptySectionByAddress(Obj, *DtPltGot);
2117 if (!GotSec)
2118 reportError("There is no not empty GOT section at 0x" +
2119 Twine::utohexstr(*DtPltGot));
2120
2121 LocalNum = *DtLocalGotNum;
2122 GlobalNum = DynSymTotal - *DtGotSym;
2123
2124 ArrayRef<uint8_t> Content = unwrapOrError(Obj->getSectionContents(GotSec));
2125 GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),
2126 Content.size() / sizeof(Entry));
2127 GotDynSyms = DynSyms.drop_front(*DtGotSym);
2128 }
2129
2130 // Find PLT section.
2131 if (DtMipsPltGot || DtJmpRel) {
2132 if (!DtMipsPltGot)
2133 report_fatal_error("Cannot find MIPS_PLTGOT dynamic table tag.");
2134 if (!DtJmpRel)
2135 report_fatal_error("Cannot find JMPREL dynamic table tag.");
2136
2137 PltSec = findNotEmptySectionByAddress(Obj, *DtMipsPltGot);
2138 if (!PltSec)
2139 report_fatal_error("There is no not empty PLTGOT section at 0x " +
2140 Twine::utohexstr(*DtMipsPltGot));
2141
2142 PltRelSec = findNotEmptySectionByAddress(Obj, *DtJmpRel);
2143 if (!PltRelSec)
2144 report_fatal_error("There is no not empty RELPLT section at 0x" +
2145 Twine::utohexstr(*DtJmpRel));
2146
2147 ArrayRef<uint8_t> PltContent =
2148 unwrapOrError(Obj->getSectionContents(PltSec));
2149 PltEntries = Entries(reinterpret_cast<const Entry *>(PltContent.data()),
2150 PltContent.size() / sizeof(Entry));
2151
2152 PltSymTable = unwrapOrError(Obj->getSection(PltRelSec->sh_link));
2153 PltStrTable = unwrapOrError(Obj->getStringTableForSymtab(*PltSymTable));
2154 }
2155}
2156
2157template <class ELFT> uint64_t MipsGOTParser<ELFT>::getGp() const {
2158 return GotSec->sh_addr + 0x7ff0;
George Rimar47936762016-01-16 00:49:19 +00002159}
2160
Simon Atanasyand4b693b2017-12-02 13:06:35 +00002161template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00002162const typename MipsGOTParser<ELFT>::Entry *
2163MipsGOTParser<ELFT>::getGotLazyResolver() const {
2164 return LocalNum > 0 ? &GotEntries[0] : nullptr;
George Rimar47936762016-01-16 00:49:19 +00002165}
2166
2167template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00002168const typename MipsGOTParser<ELFT>::Entry *
2169MipsGOTParser<ELFT>::getGotModulePointer() const {
2170 if (LocalNum < 2)
2171 return nullptr;
2172 const Entry &E = GotEntries[1];
2173 if ((E >> (sizeof(Entry) * 8 - 1)) == 0)
2174 return nullptr;
2175 return &E;
George Rimar47936762016-01-16 00:49:19 +00002176}
2177
2178template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00002179typename MipsGOTParser<ELFT>::Entries
2180MipsGOTParser<ELFT>::getLocalEntries() const {
2181 size_t Skip = getGotModulePointer() ? 2 : 1;
2182 if (LocalNum - Skip <= 0)
2183 return Entries();
2184 return GotEntries.slice(Skip, LocalNum - Skip);
George Rimar47936762016-01-16 00:49:19 +00002185}
2186
2187template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00002188typename MipsGOTParser<ELFT>::Entries
2189MipsGOTParser<ELFT>::getGlobalEntries() const {
2190 if (GlobalNum == 0)
2191 return Entries();
2192 return GotEntries.slice(LocalNum, GlobalNum);
George Rimar47936762016-01-16 00:49:19 +00002193}
2194
2195template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00002196typename MipsGOTParser<ELFT>::Entries
2197MipsGOTParser<ELFT>::getOtherEntries() const {
2198 size_t OtherNum = GotEntries.size() - LocalNum - GlobalNum;
2199 if (OtherNum == 0)
2200 return Entries();
2201 return GotEntries.slice(LocalNum + GlobalNum, OtherNum);
George Rimar47936762016-01-16 00:49:19 +00002202}
2203
2204template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00002205uint64_t MipsGOTParser<ELFT>::getGotAddress(const Entry *E) const {
2206 int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);
2207 return GotSec->sh_addr + Offset;
George Rimar47936762016-01-16 00:49:19 +00002208}
2209
2210template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00002211int64_t MipsGOTParser<ELFT>::getGotOffset(const Entry *E) const {
2212 int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);
2213 return Offset - 0x7ff0;
2214}
George Rimar47936762016-01-16 00:49:19 +00002215
Simon Atanasyan62d32592017-12-21 10:26:02 +00002216template <class ELFT>
2217const typename MipsGOTParser<ELFT>::Elf_Sym *
2218MipsGOTParser<ELFT>::getGotSym(const Entry *E) const {
2219 int64_t Offset = std::distance(GotEntries.data(), E);
2220 return &GotDynSyms[Offset - LocalNum];
2221}
George Rimar47936762016-01-16 00:49:19 +00002222
Simon Atanasyan62d32592017-12-21 10:26:02 +00002223template <class ELFT>
2224const typename MipsGOTParser<ELFT>::Entry *
2225MipsGOTParser<ELFT>::getPltLazyResolver() const {
2226 return PltEntries.empty() ? nullptr : &PltEntries[0];
2227}
2228
2229template <class ELFT>
2230const typename MipsGOTParser<ELFT>::Entry *
2231MipsGOTParser<ELFT>::getPltModulePointer() const {
2232 return PltEntries.size() < 2 ? nullptr : &PltEntries[1];
2233}
2234
2235template <class ELFT>
2236typename MipsGOTParser<ELFT>::Entries
2237MipsGOTParser<ELFT>::getPltEntries() const {
2238 if (PltEntries.size() <= 2)
2239 return Entries();
2240 return PltEntries.slice(2, PltEntries.size() - 2);
2241}
2242
2243template <class ELFT>
2244uint64_t MipsGOTParser<ELFT>::getPltAddress(const Entry *E) const {
2245 int64_t Offset = std::distance(PltEntries.data(), E) * sizeof(Entry);
2246 return PltSec->sh_addr + Offset;
2247}
2248
2249template <class ELFT>
2250const typename MipsGOTParser<ELFT>::Elf_Sym *
2251MipsGOTParser<ELFT>::getPltSym(const Entry *E) const {
2252 int64_t Offset = std::distance(getPltEntries().data(), E);
2253 if (PltRelSec->sh_type == ELF::SHT_REL) {
2254 Elf_Rel_Range Rels = unwrapOrError(Obj->rels(PltRelSec));
2255 return unwrapOrError(Obj->getRelocationSymbol(&Rels[Offset], PltSymTable));
2256 } else {
2257 Elf_Rela_Range Rels = unwrapOrError(Obj->relas(PltRelSec));
2258 return unwrapOrError(Obj->getRelocationSymbol(&Rels[Offset], PltSymTable));
2259 }
George Rimar47936762016-01-16 00:49:19 +00002260}
2261
2262template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00002263 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
Simon Atanasyan62d32592017-12-21 10:26:02 +00002264 if (Obj->getHeader()->e_machine != EM_MIPS)
2265 reportError("MIPS PLT GOT is available for MIPS targets only");
George Rimar47936762016-01-16 00:49:19 +00002266
Simon Atanasyan62d32592017-12-21 10:26:02 +00002267 MipsGOTParser<ELFT> Parser(Obj, dynamic_table(), dynamic_symbols());
2268 if (Parser.hasGot())
2269 ELFDumperStyle->printMipsGOT(Parser);
2270 if (Parser.hasPlt())
2271 ELFDumperStyle->printMipsPLT(Parser);
George Rimar47936762016-01-16 00:49:19 +00002272}
2273
2274static const EnumEntry<unsigned> ElfMipsISAExtType[] = {
George Rimarec895f12019-05-16 06:22:51 +00002275 {"None", Mips::AFL_EXT_NONE},
2276 {"Broadcom SB-1", Mips::AFL_EXT_SB1},
2277 {"Cavium Networks Octeon", Mips::AFL_EXT_OCTEON},
2278 {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2},
2279 {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP},
2280 {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3},
2281 {"LSI R4010", Mips::AFL_EXT_4010},
2282 {"Loongson 2E", Mips::AFL_EXT_LOONGSON_2E},
2283 {"Loongson 2F", Mips::AFL_EXT_LOONGSON_2F},
2284 {"Loongson 3A", Mips::AFL_EXT_LOONGSON_3A},
2285 {"MIPS R4650", Mips::AFL_EXT_4650},
2286 {"MIPS R5900", Mips::AFL_EXT_5900},
2287 {"MIPS R10000", Mips::AFL_EXT_10000},
2288 {"NEC VR4100", Mips::AFL_EXT_4100},
2289 {"NEC VR4111/VR4181", Mips::AFL_EXT_4111},
2290 {"NEC VR4120", Mips::AFL_EXT_4120},
2291 {"NEC VR5400", Mips::AFL_EXT_5400},
2292 {"NEC VR5500", Mips::AFL_EXT_5500},
2293 {"RMI Xlr", Mips::AFL_EXT_XLR},
2294 {"Toshiba R3900", Mips::AFL_EXT_3900}
2295};
George Rimar47936762016-01-16 00:49:19 +00002296
2297static const EnumEntry<unsigned> ElfMipsASEFlags[] = {
George Rimarec895f12019-05-16 06:22:51 +00002298 {"DSP", Mips::AFL_ASE_DSP},
2299 {"DSPR2", Mips::AFL_ASE_DSPR2},
2300 {"Enhanced VA Scheme", Mips::AFL_ASE_EVA},
2301 {"MCU", Mips::AFL_ASE_MCU},
2302 {"MDMX", Mips::AFL_ASE_MDMX},
2303 {"MIPS-3D", Mips::AFL_ASE_MIPS3D},
2304 {"MT", Mips::AFL_ASE_MT},
2305 {"SmartMIPS", Mips::AFL_ASE_SMARTMIPS},
2306 {"VZ", Mips::AFL_ASE_VIRT},
2307 {"MSA", Mips::AFL_ASE_MSA},
2308 {"MIPS16", Mips::AFL_ASE_MIPS16},
2309 {"microMIPS", Mips::AFL_ASE_MICROMIPS},
2310 {"XPA", Mips::AFL_ASE_XPA},
2311 {"CRC", Mips::AFL_ASE_CRC},
2312 {"GINV", Mips::AFL_ASE_GINV},
George Rimar47936762016-01-16 00:49:19 +00002313};
2314
2315static const EnumEntry<unsigned> ElfMipsFpABIType[] = {
George Rimarec895f12019-05-16 06:22:51 +00002316 {"Hard or soft float", Mips::Val_GNU_MIPS_ABI_FP_ANY},
2317 {"Hard float (double precision)", Mips::Val_GNU_MIPS_ABI_FP_DOUBLE},
2318 {"Hard float (single precision)", Mips::Val_GNU_MIPS_ABI_FP_SINGLE},
2319 {"Soft float", Mips::Val_GNU_MIPS_ABI_FP_SOFT},
2320 {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)",
2321 Mips::Val_GNU_MIPS_ABI_FP_OLD_64},
2322 {"Hard float (32-bit CPU, Any FPU)", Mips::Val_GNU_MIPS_ABI_FP_XX},
2323 {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64},
2324 {"Hard float compat (32-bit CPU, 64-bit FPU)",
2325 Mips::Val_GNU_MIPS_ABI_FP_64A}
2326};
George Rimar47936762016-01-16 00:49:19 +00002327
George Rimarec895f12019-05-16 06:22:51 +00002328static const EnumEntry<unsigned> ElfMipsFlags1[] {
2329 {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG},
George Rimar47936762016-01-16 00:49:19 +00002330};
2331
2332static int getMipsRegisterSize(uint8_t Flag) {
2333 switch (Flag) {
2334 case Mips::AFL_REG_NONE:
2335 return 0;
2336 case Mips::AFL_REG_32:
2337 return 32;
2338 case Mips::AFL_REG_64:
2339 return 64;
2340 case Mips::AFL_REG_128:
2341 return 128;
2342 default:
2343 return -1;
2344 }
2345}
2346
2347template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00002348 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
George Rimar47936762016-01-16 00:49:19 +00002349 const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.abiflags");
2350 if (!Shdr) {
2351 W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
2352 return;
2353 }
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002354 ArrayRef<uint8_t> Sec = unwrapOrError(Obj->getSectionContents(Shdr));
2355 if (Sec.size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) {
George Rimar47936762016-01-16 00:49:19 +00002356 W.startLine() << "The .MIPS.abiflags section has a wrong size.\n";
2357 return;
2358 }
2359
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002360 auto *Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(Sec.data());
George Rimar47936762016-01-16 00:49:19 +00002361
2362 raw_ostream &OS = W.getOStream();
2363 DictScope GS(W, "MIPS ABI Flags");
2364
2365 W.printNumber("Version", Flags->version);
2366 W.startLine() << "ISA: ";
2367 if (Flags->isa_rev <= 1)
2368 OS << format("MIPS%u", Flags->isa_level);
2369 else
2370 OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev);
2371 OS << "\n";
2372 W.printEnum("ISA Extension", Flags->isa_ext, makeArrayRef(ElfMipsISAExtType));
2373 W.printFlags("ASEs", Flags->ases, makeArrayRef(ElfMipsASEFlags));
2374 W.printEnum("FP ABI", Flags->fp_abi, makeArrayRef(ElfMipsFpABIType));
2375 W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size));
2376 W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size));
2377 W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size));
2378 W.printFlags("Flags 1", Flags->flags1, makeArrayRef(ElfMipsFlags1));
2379 W.printHex("Flags 2", Flags->flags2);
2380}
2381
Simon Atanasyan8a71b532016-05-04 05:58:57 +00002382template <class ELFT>
2383static void printMipsReginfoData(ScopedPrinter &W,
2384 const Elf_Mips_RegInfo<ELFT> &Reginfo) {
2385 W.printHex("GP", Reginfo.ri_gp_value);
2386 W.printHex("General Mask", Reginfo.ri_gprmask);
2387 W.printHex("Co-Proc Mask0", Reginfo.ri_cprmask[0]);
2388 W.printHex("Co-Proc Mask1", Reginfo.ri_cprmask[1]);
2389 W.printHex("Co-Proc Mask2", Reginfo.ri_cprmask[2]);
2390 W.printHex("Co-Proc Mask3", Reginfo.ri_cprmask[3]);
2391}
2392
George Rimar47936762016-01-16 00:49:19 +00002393template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00002394 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
George Rimar47936762016-01-16 00:49:19 +00002395 const Elf_Shdr *Shdr = findSectionByName(*Obj, ".reginfo");
2396 if (!Shdr) {
2397 W.startLine() << "There is no .reginfo section in the file.\n";
2398 return;
2399 }
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002400 ArrayRef<uint8_t> Sec = unwrapOrError(Obj->getSectionContents(Shdr));
2401 if (Sec.size() != sizeof(Elf_Mips_RegInfo<ELFT>)) {
George Rimar47936762016-01-16 00:49:19 +00002402 W.startLine() << "The .reginfo section has a wrong size.\n";
2403 return;
2404 }
2405
George Rimar47936762016-01-16 00:49:19 +00002406 DictScope GS(W, "MIPS RegInfo");
Simon Atanasyan8a71b532016-05-04 05:58:57 +00002407 auto *Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(Sec.data());
2408 printMipsReginfoData(W, *Reginfo);
2409}
2410
2411template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00002412 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
Simon Atanasyan8a71b532016-05-04 05:58:57 +00002413 const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.options");
2414 if (!Shdr) {
2415 W.startLine() << "There is no .MIPS.options section in the file.\n";
2416 return;
2417 }
2418
2419 DictScope GS(W, "MIPS Options");
2420
2421 ArrayRef<uint8_t> Sec = unwrapOrError(Obj->getSectionContents(Shdr));
2422 while (!Sec.empty()) {
2423 if (Sec.size() < sizeof(Elf_Mips_Options<ELFT>)) {
2424 W.startLine() << "The .MIPS.options section has a wrong size.\n";
2425 return;
2426 }
2427 auto *O = reinterpret_cast<const Elf_Mips_Options<ELFT> *>(Sec.data());
2428 DictScope GS(W, getElfMipsOptionsOdkType(O->kind));
2429 switch (O->kind) {
2430 case ODK_REGINFO:
2431 printMipsReginfoData(W, O->getRegInfo());
2432 break;
2433 default:
2434 W.startLine() << "Unsupported MIPS options tag.\n";
2435 break;
2436 }
2437 Sec = Sec.slice(O->size);
2438 }
George Rimar47936762016-01-16 00:49:19 +00002439}
2440
2441template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00002442 const ELFFile<ELFT> *Obj = ObjF->getELFFile();
George Rimar47936762016-01-16 00:49:19 +00002443 const Elf_Shdr *StackMapSection = nullptr;
Rafael Espindola25be8c82016-11-02 14:10:57 +00002444 for (const auto &Sec : unwrapOrError(Obj->sections())) {
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002445 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2446 if (Name == ".llvm_stackmaps") {
George Rimar47936762016-01-16 00:49:19 +00002447 StackMapSection = &Sec;
2448 break;
2449 }
2450 }
2451
2452 if (!StackMapSection)
2453 return;
2454
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002455 ArrayRef<uint8_t> StackMapContentsArray =
2456 unwrapOrError(Obj->getSectionContents(StackMapSection));
George Rimar47936762016-01-16 00:49:19 +00002457
Sam Clegg88e9a152018-01-10 00:14:19 +00002458 prettyPrintStackMap(
Philip Reames377f5072019-04-13 02:02:56 +00002459 W, StackMapParser<ELFT::TargetEndianness>(StackMapContentsArray));
George Rimar47936762016-01-16 00:49:19 +00002460}
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002461
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +00002462template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00002463 ELFDumperStyle->printGroupSections(ObjF->getELFFile());
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +00002464}
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002465
Peter Collingbourne3e227332018-07-17 22:17:18 +00002466template <class ELFT> void ELFDumper<ELFT>::printAddrsig() {
Luke Cheesemanf57d7d82018-12-18 10:37:42 +00002467 ELFDumperStyle->printAddrsig(ObjF->getELFFile());
Peter Collingbourne3e227332018-07-17 22:17:18 +00002468}
2469
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002470static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
2471 StringRef Str2) {
2472 OS.PadToColumn(2u);
2473 OS << Str1;
2474 OS.PadToColumn(37u);
2475 OS << Str2 << "\n";
2476 OS.flush();
2477}
2478
George Rimar6fdac3b2018-07-18 08:19:58 +00002479template <class ELFT>
2480static std::string getSectionHeadersNumString(const ELFFile<ELFT> *Obj) {
2481 const typename ELFT::Ehdr *ElfHeader = Obj->getHeader();
2482 if (ElfHeader->e_shnum != 0)
2483 return to_string(ElfHeader->e_shnum);
2484
2485 ArrayRef<typename ELFT::Shdr> Arr = unwrapOrError(Obj->sections());
2486 if (Arr.empty())
2487 return "0";
2488 return "0 (" + to_string(Arr[0].sh_size) + ")";
2489}
2490
2491template <class ELFT>
2492static std::string getSectionHeaderTableIndexString(const ELFFile<ELFT> *Obj) {
2493 const typename ELFT::Ehdr *ElfHeader = Obj->getHeader();
2494 if (ElfHeader->e_shstrndx != SHN_XINDEX)
2495 return to_string(ElfHeader->e_shstrndx);
2496
2497 ArrayRef<typename ELFT::Shdr> Arr = unwrapOrError(Obj->sections());
2498 if (Arr.empty())
2499 return "65535 (corrupt: out of range)";
George Rimar9e88a262019-05-14 14:22:44 +00002500 return to_string(ElfHeader->e_shstrndx) + " (" + to_string(Arr[0].sh_link) +
2501 ")";
George Rimar6fdac3b2018-07-18 08:19:58 +00002502}
2503
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002504template <class ELFT> void GNUStyle<ELFT>::printFileHeaders(const ELFO *Obj) {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002505 const Elf_Ehdr *e = Obj->getHeader();
2506 OS << "ELF Header:\n";
2507 OS << " Magic: ";
2508 std::string Str;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002509 for (int i = 0; i < ELF::EI_NIDENT; i++)
2510 OS << format(" %02x", static_cast<int>(e->e_ident[i]));
2511 OS << "\n";
2512 Str = printEnum(e->e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002513 printFields(OS, "Class:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002514 Str = printEnum(e->e_ident[ELF::EI_DATA], makeArrayRef(ElfDataEncoding));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002515 printFields(OS, "Data:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002516 OS.PadToColumn(2u);
2517 OS << "Version:";
2518 OS.PadToColumn(37u);
2519 OS << to_hexString(e->e_ident[ELF::EI_VERSION]);
2520 if (e->e_version == ELF::EV_CURRENT)
2521 OS << " (current)";
2522 OS << "\n";
2523 Str = printEnum(e->e_ident[ELF::EI_OSABI], makeArrayRef(ElfOSABI));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002524 printFields(OS, "OS/ABI:", Str);
Chandler Carruthe8fa5ae2016-11-03 17:11:11 +00002525 Str = "0x" + to_hexString(e->e_ident[ELF::EI_ABIVERSION]);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002526 printFields(OS, "ABI Version:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002527 Str = printEnum(e->e_type, makeArrayRef(ElfObjectFileType));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002528 printFields(OS, "Type:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002529 Str = printEnum(e->e_machine, makeArrayRef(ElfMachineType));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002530 printFields(OS, "Machine:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002531 Str = "0x" + to_hexString(e->e_version);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002532 printFields(OS, "Version:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002533 Str = "0x" + to_hexString(e->e_entry);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002534 printFields(OS, "Entry point address:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002535 Str = to_string(e->e_phoff) + " (bytes into file)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002536 printFields(OS, "Start of program headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002537 Str = to_string(e->e_shoff) + " (bytes into file)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002538 printFields(OS, "Start of section headers:", Str);
Simon Atanasyan19932542018-10-25 05:39:27 +00002539 std::string ElfFlags;
2540 if (e->e_machine == EM_MIPS)
2541 ElfFlags =
2542 printFlags(e->e_flags, makeArrayRef(ElfHeaderMipsFlags),
2543 unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
2544 unsigned(ELF::EF_MIPS_MACH));
2545 else if (e->e_machine == EM_RISCV)
2546 ElfFlags = printFlags(e->e_flags, makeArrayRef(ElfHeaderRISCVFlags));
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002547 Str = "0x" + to_hexString(e->e_flags);
Simon Atanasyan19932542018-10-25 05:39:27 +00002548 if (!ElfFlags.empty())
2549 Str = Str + ", " + ElfFlags;
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002550 printFields(OS, "Flags:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002551 Str = to_string(e->e_ehsize) + " (bytes)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002552 printFields(OS, "Size of this header:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002553 Str = to_string(e->e_phentsize) + " (bytes)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002554 printFields(OS, "Size of program headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002555 Str = to_string(e->e_phnum);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002556 printFields(OS, "Number of program headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002557 Str = to_string(e->e_shentsize) + " (bytes)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002558 printFields(OS, "Size of section headers:", Str);
George Rimar6fdac3b2018-07-18 08:19:58 +00002559 Str = getSectionHeadersNumString(Obj);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002560 printFields(OS, "Number of section headers:", Str);
George Rimar6fdac3b2018-07-18 08:19:58 +00002561 Str = getSectionHeaderTableIndexString(Obj);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002562 printFields(OS, "Section header string table index:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002563}
2564
George Rimarea39eed2017-09-14 07:32:52 +00002565namespace {
2566struct GroupMember {
2567 StringRef Name;
2568 uint64_t Index;
2569};
2570
2571struct GroupSection {
2572 StringRef Name;
James Hendersone50d9cb2019-01-17 15:34:12 +00002573 std::string Signature;
George Rimarea39eed2017-09-14 07:32:52 +00002574 uint64_t ShName;
2575 uint64_t Index;
Alexander Shaposhnikov8febe3d2018-03-12 22:40:09 +00002576 uint32_t Link;
2577 uint32_t Info;
George Rimarea39eed2017-09-14 07:32:52 +00002578 uint32_t Type;
2579 std::vector<GroupMember> Members;
2580};
2581
2582template <class ELFT>
2583std::vector<GroupSection> getGroups(const ELFFile<ELFT> *Obj) {
Rui Ueyama478d6352018-01-12 02:28:31 +00002584 using Elf_Shdr = typename ELFT::Shdr;
2585 using Elf_Sym = typename ELFT::Sym;
2586 using Elf_Word = typename ELFT::Word;
George Rimarea39eed2017-09-14 07:32:52 +00002587
2588 std::vector<GroupSection> Ret;
2589 uint64_t I = 0;
George Rimar3c0f3962017-09-14 07:26:14 +00002590 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
George Rimarea39eed2017-09-14 07:32:52 +00002591 ++I;
2592 if (Sec.sh_type != ELF::SHT_GROUP)
2593 continue;
2594
2595 const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link));
2596 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
2597 const Elf_Sym *Sym =
2598 unwrapOrError(Obj->template getEntry<Elf_Sym>(Symtab, Sec.sh_info));
2599 auto Data =
2600 unwrapOrError(Obj->template getSectionContentsAsArray<Elf_Word>(&Sec));
2601
2602 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2603 StringRef Signature = StrTable.data() + Sym->st_name;
James Hendersone50d9cb2019-01-17 15:34:12 +00002604 Ret.push_back({Name,
2605 maybeDemangle(Signature),
2606 Sec.sh_name,
Alexander Shaposhnikov8febe3d2018-03-12 22:40:09 +00002607 I - 1,
2608 Sec.sh_link,
2609 Sec.sh_info,
James Hendersone50d9cb2019-01-17 15:34:12 +00002610 Data[0],
Alexander Shaposhnikov8febe3d2018-03-12 22:40:09 +00002611 {}});
George Rimarea39eed2017-09-14 07:32:52 +00002612
2613 std::vector<GroupMember> &GM = Ret.back().Members;
2614 for (uint32_t Ndx : Data.slice(1)) {
2615 auto Sec = unwrapOrError(Obj->getSection(Ndx));
2616 const StringRef Name = unwrapOrError(Obj->getSectionName(Sec));
2617 GM.push_back({Name, Ndx});
George Rimar3c0f3962017-09-14 07:26:14 +00002618 }
George Rimarc2657cd2017-09-14 07:17:04 +00002619 }
George Rimarea39eed2017-09-14 07:32:52 +00002620 return Ret;
2621}
George Rimar762abff62017-09-16 14:29:51 +00002622
2623DenseMap<uint64_t, const GroupSection *>
2624mapSectionsToGroups(ArrayRef<GroupSection> Groups) {
2625 DenseMap<uint64_t, const GroupSection *> Ret;
2626 for (const GroupSection &G : Groups)
2627 for (const GroupMember &GM : G.Members)
2628 Ret.insert({GM.Index, &G});
2629 return Ret;
2630}
2631
George Rimarea39eed2017-09-14 07:32:52 +00002632} // namespace
2633
2634template <class ELFT> void GNUStyle<ELFT>::printGroupSections(const ELFO *Obj) {
2635 std::vector<GroupSection> V = getGroups<ELFT>(Obj);
George Rimar762abff62017-09-16 14:29:51 +00002636 DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
George Rimarea39eed2017-09-14 07:32:52 +00002637 for (const GroupSection &G : V) {
2638 OS << "\n"
2639 << getGroupType(G.Type) << " group section ["
2640 << format_decimal(G.Index, 5) << "] `" << G.Name << "' [" << G.Signature
2641 << "] contains " << G.Members.size() << " sections:\n"
2642 << " [Index] Name\n";
George Rimar762abff62017-09-16 14:29:51 +00002643 for (const GroupMember &GM : G.Members) {
2644 const GroupSection *MainGroup = Map[GM.Index];
2645 if (MainGroup != &G) {
2646 OS.flush();
2647 errs() << "Error: section [" << format_decimal(GM.Index, 5)
2648 << "] in group section [" << format_decimal(G.Index, 5)
2649 << "] already in group section ["
2650 << format_decimal(MainGroup->Index, 5) << "]";
2651 errs().flush();
2652 continue;
2653 }
George Rimarea39eed2017-09-14 07:32:52 +00002654 OS << " [" << format_decimal(GM.Index, 5) << "] " << GM.Name << "\n";
George Rimar762abff62017-09-16 14:29:51 +00002655 }
George Rimarea39eed2017-09-14 07:32:52 +00002656 }
2657
2658 if (V.empty())
Hemant Kulkarni206ba842016-03-09 19:16:13 +00002659 OS << "There are no section groups in this file.\n";
2660}
2661
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002662template <class ELFT>
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002663void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
2664 const Elf_Rela &R, bool IsRela) {
George Rimar1206f5a2019-01-30 15:39:05 +00002665 const Elf_Sym *Sym = unwrapOrError(Obj->getRelocationSymbol(&R, SymTab));
2666 std::string TargetName;
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002667 if (Sym && Sym->getType() == ELF::STT_SECTION) {
2668 const Elf_Shdr *Sec = unwrapOrError(
2669 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
2670 TargetName = unwrapOrError(Obj->getSectionName(Sec));
2671 } else if (Sym) {
Jake Ehrlich0f440d82018-06-28 21:07:34 +00002672 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
Xing GUOeec32062019-03-12 14:30:13 +00002673 TargetName = this->dumper()->getFullSymbolName(
2674 Sym, StrTable, SymTab->sh_type == SHT_DYNSYM /* IsDynamic */);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002675 }
James Henderson814ab372019-03-29 11:47:19 +00002676 printRelocation(Obj, Sym, TargetName, R, IsRela);
2677}
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002678
James Henderson814ab372019-03-29 11:47:19 +00002679template <class ELFT>
2680void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Sym *Sym,
2681 StringRef SymbolName, const Elf_Rela &R,
2682 bool IsRela) {
2683 // First two fields are bit width dependent. The rest of them are fixed width.
2684 unsigned Bias = ELFT::Is64Bits ? 8 : 0;
2685 Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
George Rimar4b4899b2019-01-30 14:08:55 +00002686 unsigned Width = ELFT::Is64Bits ? 16 : 8;
James Henderson814ab372019-03-29 11:47:19 +00002687
George Rimar4b4899b2019-01-30 14:08:55 +00002688 Fields[0].Str = to_string(format_hex_no_prefix(R.r_offset, Width));
2689 Fields[1].Str = to_string(format_hex_no_prefix(R.r_info, Width));
James Henderson814ab372019-03-29 11:47:19 +00002690
2691 SmallString<32> RelocName;
2692 Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
2693 Fields[2].Str = RelocName.c_str();
2694
2695 if (Sym && (!SymbolName.empty() || Sym->getValue() != 0))
George Rimar4b4899b2019-01-30 14:08:55 +00002696 Fields[3].Str = to_string(format_hex_no_prefix(Sym->getValue(), Width));
James Henderson814ab372019-03-29 11:47:19 +00002697
2698 Fields[4].Str = SymbolName;
2699 for (const Field &F : Fields)
George Rimar4b4899b2019-01-30 14:08:55 +00002700 printField(F);
2701
2702 std::string Addend;
James Hendersonb41130b2019-03-08 13:22:05 +00002703 if (IsRela) {
2704 int64_t RelAddend = R.r_addend;
James Henderson814ab372019-03-29 11:47:19 +00002705 if (!SymbolName.empty()) {
James Hendersonb41130b2019-03-08 13:22:05 +00002706 if (R.r_addend < 0) {
2707 Addend = " - ";
2708 RelAddend = std::abs(RelAddend);
2709 } else
2710 Addend = " + ";
2711 }
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002712
James Hendersonb41130b2019-03-08 13:22:05 +00002713 Addend += to_hexString(RelAddend, false);
2714 }
George Rimar1206f5a2019-01-30 15:39:05 +00002715 OS << Addend << "\n";
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00002716}
2717
Jake Ehrlich0f440d82018-06-28 21:07:34 +00002718template <class ELFT> void GNUStyle<ELFT>::printRelocHeader(unsigned SType) {
2719 bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA;
2720 bool IsRelr = SType == ELF::SHT_RELR || SType == ELF::SHT_ANDROID_RELR;
2721 if (ELFT::Is64Bits)
2722 OS << " ";
2723 else
2724 OS << " ";
2725 if (IsRelr && opts::RawRelr)
2726 OS << "Data ";
2727 else
2728 OS << "Offset";
2729 if (ELFT::Is64Bits)
2730 OS << " Info Type"
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00002731 << " Symbol's Value Symbol's Name";
2732 else
Jake Ehrlich0f440d82018-06-28 21:07:34 +00002733 OS << " Info Type Sym. Value Symbol's Name";
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002734 if (IsRela)
Jake Ehrlich0f440d82018-06-28 21:07:34 +00002735 OS << " + Addend";
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002736 OS << "\n";
2737}
2738
2739template <class ELFT> void GNUStyle<ELFT>::printRelocations(const ELFO *Obj) {
2740 bool HasRelocSections = false;
Rafael Espindola25be8c82016-11-02 14:10:57 +00002741 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
George Rimar9e88a262019-05-14 14:22:44 +00002742 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA &&
2743 Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_REL &&
Jake Ehrlich0f440d82018-06-28 21:07:34 +00002744 Sec.sh_type != ELF::SHT_ANDROID_RELA &&
2745 Sec.sh_type != ELF::SHT_ANDROID_RELR)
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002746 continue;
2747 HasRelocSections = true;
2748 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2749 unsigned Entries = Sec.getEntityCount();
Peter Collingbournecf017ad2018-06-07 00:02:07 +00002750 std::vector<Elf_Rela> AndroidRelas;
2751 if (Sec.sh_type == ELF::SHT_ANDROID_REL ||
2752 Sec.sh_type == ELF::SHT_ANDROID_RELA) {
2753 // Android's packed relocation section needs to be unpacked first
2754 // to get the actual number of entries.
2755 AndroidRelas = unwrapOrError(Obj->android_relas(&Sec));
2756 Entries = AndroidRelas.size();
2757 }
Jake Ehrlich0f440d82018-06-28 21:07:34 +00002758 std::vector<Elf_Rela> RelrRelas;
2759 if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR ||
2760 Sec.sh_type == ELF::SHT_ANDROID_RELR)) {
2761 // .relr.dyn relative relocation section needs to be unpacked first
2762 // to get the actual number of entries.
2763 Elf_Relr_Range Relrs = unwrapOrError(Obj->relrs(&Sec));
2764 RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
2765 Entries = RelrRelas.size();
2766 }
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002767 uintX_t Offset = Sec.sh_offset;
2768 OS << "\nRelocation section '" << Name << "' at offset 0x"
2769 << to_hexString(Offset, false) << " contains " << Entries
2770 << " entries:\n";
Jake Ehrlich0f440d82018-06-28 21:07:34 +00002771 printRelocHeader(Sec.sh_type);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002772 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec.sh_link));
Peter Collingbourne689e6c052017-10-25 03:37:12 +00002773 switch (Sec.sh_type) {
2774 case ELF::SHT_REL:
Rafael Espindola354680a2016-11-03 19:07:15 +00002775 for (const auto &R : unwrapOrError(Obj->rels(&Sec))) {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002776 Elf_Rela Rela;
2777 Rela.r_offset = R.r_offset;
2778 Rela.r_info = R.r_info;
2779 Rela.r_addend = 0;
2780 printRelocation(Obj, SymTab, Rela, false);
2781 }
Peter Collingbourne689e6c052017-10-25 03:37:12 +00002782 break;
2783 case ELF::SHT_RELA:
Rafael Espindola354680a2016-11-03 19:07:15 +00002784 for (const auto &R : unwrapOrError(Obj->relas(&Sec)))
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002785 printRelocation(Obj, SymTab, R, true);
Peter Collingbourne689e6c052017-10-25 03:37:12 +00002786 break;
Jake Ehrlich0f440d82018-06-28 21:07:34 +00002787 case ELF::SHT_RELR:
2788 case ELF::SHT_ANDROID_RELR:
2789 if (opts::RawRelr)
2790 for (const auto &R : unwrapOrError(Obj->relrs(&Sec)))
2791 OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8))
2792 << "\n";
2793 else
2794 for (const auto &R : RelrRelas)
2795 printRelocation(Obj, SymTab, R, false);
2796 break;
Peter Collingbourne689e6c052017-10-25 03:37:12 +00002797 case ELF::SHT_ANDROID_REL:
2798 case ELF::SHT_ANDROID_RELA:
Peter Collingbournecf017ad2018-06-07 00:02:07 +00002799 for (const auto &R : AndroidRelas)
Peter Collingbourne689e6c052017-10-25 03:37:12 +00002800 printRelocation(Obj, SymTab, R, Sec.sh_type == ELF::SHT_ANDROID_RELA);
2801 break;
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002802 }
2803 }
2804 if (!HasRelocSections)
2805 OS << "\nThere are no relocations in this file.\n";
2806}
2807
Matt Davis7a24dbd2019-02-27 18:39:17 +00002808// Print the offset of a particular section from anyone of the ranges:
2809// [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].
2810// If 'Type' does not fall within any of those ranges, then a string is
2811// returned as '<unknown>' followed by the type value.
2812static std::string getSectionTypeOffsetString(unsigned Type) {
2813 if (Type >= SHT_LOOS && Type <= SHT_HIOS)
2814 return "LOOS+0x" + to_hexString(Type - SHT_LOOS);
2815 else if (Type >= SHT_LOPROC && Type <= SHT_HIPROC)
2816 return "LOPROC+0x" + to_hexString(Type - SHT_LOPROC);
2817 else if (Type >= SHT_LOUSER && Type <= SHT_HIUSER)
2818 return "LOUSER+0x" + to_hexString(Type - SHT_LOUSER);
2819 return "0x" + to_hexString(Type) + ": <unknown>";
2820}
2821
2822static std::string getSectionTypeString(unsigned Arch, unsigned Type) {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002823 using namespace ELF;
Eugene Zelenko416e0592017-06-09 21:41:54 +00002824
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002825 switch (Arch) {
2826 case EM_ARM:
2827 switch (Type) {
2828 case SHT_ARM_EXIDX:
2829 return "ARM_EXIDX";
2830 case SHT_ARM_PREEMPTMAP:
2831 return "ARM_PREEMPTMAP";
2832 case SHT_ARM_ATTRIBUTES:
2833 return "ARM_ATTRIBUTES";
2834 case SHT_ARM_DEBUGOVERLAY:
2835 return "ARM_DEBUGOVERLAY";
2836 case SHT_ARM_OVERLAYSECTION:
2837 return "ARM_OVERLAYSECTION";
2838 }
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00002839 break;
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002840 case EM_X86_64:
2841 switch (Type) {
2842 case SHT_X86_64_UNWIND:
2843 return "X86_64_UNWIND";
2844 }
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00002845 break;
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002846 case EM_MIPS:
2847 case EM_MIPS_RS3_LE:
2848 switch (Type) {
2849 case SHT_MIPS_REGINFO:
2850 return "MIPS_REGINFO";
2851 case SHT_MIPS_OPTIONS:
2852 return "MIPS_OPTIONS";
Fangrui Song8443e882019-02-21 11:35:41 +00002853 case SHT_MIPS_DWARF:
2854 return "MIPS_DWARF";
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002855 case SHT_MIPS_ABIFLAGS:
2856 return "MIPS_ABIFLAGS";
2857 }
Ryan Prichard0c20b5b2018-10-26 23:01:54 +00002858 break;
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002859 }
2860 switch (Type) {
2861 case SHT_NULL:
2862 return "NULL";
2863 case SHT_PROGBITS:
2864 return "PROGBITS";
2865 case SHT_SYMTAB:
2866 return "SYMTAB";
2867 case SHT_STRTAB:
2868 return "STRTAB";
2869 case SHT_RELA:
2870 return "RELA";
2871 case SHT_HASH:
2872 return "HASH";
2873 case SHT_DYNAMIC:
2874 return "DYNAMIC";
2875 case SHT_NOTE:
2876 return "NOTE";
2877 case SHT_NOBITS:
2878 return "NOBITS";
2879 case SHT_REL:
2880 return "REL";
2881 case SHT_SHLIB:
2882 return "SHLIB";
2883 case SHT_DYNSYM:
2884 return "DYNSYM";
2885 case SHT_INIT_ARRAY:
2886 return "INIT_ARRAY";
2887 case SHT_FINI_ARRAY:
2888 return "FINI_ARRAY";
2889 case SHT_PREINIT_ARRAY:
2890 return "PREINIT_ARRAY";
2891 case SHT_GROUP:
2892 return "GROUP";
2893 case SHT_SYMTAB_SHNDX:
2894 return "SYMTAB SECTION INDICES";
Matt Davis7a24dbd2019-02-27 18:39:17 +00002895 case SHT_ANDROID_REL:
2896 return "ANDROID_REL";
2897 case SHT_ANDROID_RELA:
2898 return "ANDROID_RELA";
Jake Ehrlich0f440d82018-06-28 21:07:34 +00002899 case SHT_RELR:
2900 case SHT_ANDROID_RELR:
2901 return "RELR";
Peter Collingbournef0e26e72017-06-14 18:52:12 +00002902 case SHT_LLVM_ODRTAB:
2903 return "LLVM_ODRTAB";
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +00002904 case SHT_LLVM_LINKER_OPTIONS:
2905 return "LLVM_LINKER_OPTIONS";
Michael J. Spencerae6eeae2018-06-02 16:33:01 +00002906 case SHT_LLVM_CALL_GRAPH_PROFILE:
2907 return "LLVM_CALL_GRAPH_PROFILE";
Peter Collingbourne3e227332018-07-17 22:17:18 +00002908 case SHT_LLVM_ADDRSIG:
2909 return "LLVM_ADDRSIG";
Ben Dunbobbin1d165152019-05-17 03:44:15 +00002910 case SHT_LLVM_DEPENDENT_LIBRARIES:
2911 return "LLVM_DEPENDENT_LIBRARIES";
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002912 // FIXME: Parse processor specific GNU attributes
2913 case SHT_GNU_ATTRIBUTES:
2914 return "ATTRIBUTES";
2915 case SHT_GNU_HASH:
2916 return "GNU_HASH";
2917 case SHT_GNU_verdef:
2918 return "VERDEF";
2919 case SHT_GNU_verneed:
2920 return "VERNEED";
2921 case SHT_GNU_versym:
2922 return "VERSYM";
2923 default:
Matt Davis7a24dbd2019-02-27 18:39:17 +00002924 return getSectionTypeOffsetString(Type);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002925 }
2926 return "";
2927}
2928
Jordan Rupprechtdbf552c2018-11-12 18:02:38 +00002929template <class ELFT>
2930void GNUStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
George Rimar4b4899b2019-01-30 14:08:55 +00002931 unsigned Bias = ELFT::Is64Bits ? 0 : 8;
George Rimara2b553b2018-07-19 14:52:57 +00002932 ArrayRef<Elf_Shdr> Sections = unwrapOrError(Obj->sections());
2933 OS << "There are " << to_string(Sections.size())
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002934 << " section headers, starting at offset "
2935 << "0x" << to_hexString(Obj->getHeader()->e_shoff, false) << ":\n\n";
2936 OS << "Section Headers:\n";
George Rimar4b4899b2019-01-30 14:08:55 +00002937 Field Fields[11] = {
2938 {"[Nr]", 2}, {"Name", 7}, {"Type", 25},
2939 {"Address", 41}, {"Off", 58 - Bias}, {"Size", 65 - Bias},
2940 {"ES", 72 - Bias}, {"Flg", 75 - Bias}, {"Lk", 79 - Bias},
2941 {"Inf", 82 - Bias}, {"Al", 86 - Bias}};
2942 for (auto &F : Fields)
2943 printField(F);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002944 OS << "\n";
2945
George Rimar4b4899b2019-01-30 14:08:55 +00002946 size_t SectionIndex = 0;
George Rimara2b553b2018-07-19 14:52:57 +00002947 for (const Elf_Shdr &Sec : Sections) {
George Rimar4b4899b2019-01-30 14:08:55 +00002948 Fields[0].Str = to_string(SectionIndex);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002949 Fields[1].Str = unwrapOrError(Obj->getSectionName(&Sec));
George Rimar4b4899b2019-01-30 14:08:55 +00002950 Fields[2].Str =
2951 getSectionTypeString(Obj->getHeader()->e_machine, Sec.sh_type);
2952 Fields[3].Str =
2953 to_string(format_hex_no_prefix(Sec.sh_addr, ELFT::Is64Bits ? 16 : 8));
2954 Fields[4].Str = to_string(format_hex_no_prefix(Sec.sh_offset, 6));
2955 Fields[5].Str = to_string(format_hex_no_prefix(Sec.sh_size, 6));
2956 Fields[6].Str = to_string(format_hex_no_prefix(Sec.sh_entsize, 2));
2957 Fields[7].Str = getGNUFlags(Sec.sh_flags);
2958 Fields[8].Str = to_string(Sec.sh_link);
2959 Fields[9].Str = to_string(Sec.sh_info);
2960 Fields[10].Str = to_string(Sec.sh_addralign);
2961
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002962 OS.PadToColumn(Fields[0].Column);
2963 OS << "[" << right_justify(Fields[0].Str, 2) << "]";
2964 for (int i = 1; i < 7; i++)
2965 printField(Fields[i]);
2966 OS.PadToColumn(Fields[7].Column);
2967 OS << right_justify(Fields[7].Str, 3);
2968 OS.PadToColumn(Fields[8].Column);
2969 OS << right_justify(Fields[8].Str, 2);
2970 OS.PadToColumn(Fields[9].Column);
2971 OS << right_justify(Fields[9].Str, 3);
2972 OS.PadToColumn(Fields[10].Column);
2973 OS << right_justify(Fields[10].Str, 2);
2974 OS << "\n";
2975 ++SectionIndex;
2976 }
2977 OS << "Key to Flags:\n"
2978 << " W (write), A (alloc), X (execute), M (merge), S (strings), l "
2979 "(large)\n"
2980 << " I (info), L (link order), G (group), T (TLS), E (exclude),\
2981 x (unknown)\n"
2982 << " O (extra OS processing required) o (OS specific),\
2983 p (processor specific)\n";
2984}
2985
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00002986template <class ELFT>
2987void GNUStyle<ELFT>::printSymtabMessage(const ELFO *Obj, StringRef Name,
2988 size_t Entries) {
Eugene Zelenko416e0592017-06-09 21:41:54 +00002989 if (!Name.empty())
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00002990 OS << "\nSymbol table '" << Name << "' contains " << Entries
2991 << " entries:\n";
2992 else
2993 OS << "\n Symbol table for image:\n";
2994
2995 if (ELFT::Is64Bits)
2996 OS << " Num: Value Size Type Bind Vis Ndx Name\n";
2997 else
2998 OS << " Num: Value Size Type Bind Vis Ndx Name\n";
2999}
3000
3001template <class ELFT>
3002std::string GNUStyle<ELFT>::getSymbolSectionNdx(const ELFO *Obj,
3003 const Elf_Sym *Symbol,
3004 const Elf_Sym *FirstSym) {
3005 unsigned SectionIndex = Symbol->st_shndx;
3006 switch (SectionIndex) {
3007 case ELF::SHN_UNDEF:
3008 return "UND";
3009 case ELF::SHN_ABS:
3010 return "ABS";
3011 case ELF::SHN_COMMON:
3012 return "COM";
3013 case ELF::SHN_XINDEX:
Eugene Leviant49187382019-04-15 11:21:47 +00003014 return to_string(
3015 format_decimal(unwrapOrError(object::getExtendedSymbolTableIndex<ELFT>(
3016 Symbol, FirstSym, this->dumper()->getShndxTable())),
3017 3));
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00003018 default:
3019 // Find if:
3020 // Processor specific
3021 if (SectionIndex >= ELF::SHN_LOPROC && SectionIndex <= ELF::SHN_HIPROC)
3022 return std::string("PRC[0x") +
3023 to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
3024 // OS specific
3025 if (SectionIndex >= ELF::SHN_LOOS && SectionIndex <= ELF::SHN_HIOS)
3026 return std::string("OS[0x") +
3027 to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
3028 // Architecture reserved:
3029 if (SectionIndex >= ELF::SHN_LORESERVE &&
3030 SectionIndex <= ELF::SHN_HIRESERVE)
3031 return std::string("RSV[0x") +
3032 to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
3033 // A normal section with an index
3034 return to_string(format_decimal(SectionIndex, 3));
3035 }
3036}
3037
3038template <class ELFT>
3039void GNUStyle<ELFT>::printSymbol(const ELFO *Obj, const Elf_Sym *Symbol,
3040 const Elf_Sym *FirstSym, StringRef StrTable,
3041 bool IsDynamic) {
3042 static int Idx = 0;
3043 static bool Dynamic = true;
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00003044
3045 // If this function was called with a different value from IsDynamic
3046 // from last call, happens when we move from dynamic to static symbol
3047 // table, "Num" field should be reset.
3048 if (!Dynamic != !IsDynamic) {
3049 Idx = 0;
3050 Dynamic = false;
3051 }
George Rimar4b4899b2019-01-30 14:08:55 +00003052
3053 unsigned Bias = ELFT::Is64Bits ? 8 : 0;
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00003054 Field Fields[8] = {0, 8, 17 + Bias, 23 + Bias,
3055 31 + Bias, 38 + Bias, 47 + Bias, 51 + Bias};
George Rimar4b4899b2019-01-30 14:08:55 +00003056 Fields[0].Str = to_string(format_decimal(Idx++, 6)) + ":";
3057 Fields[1].Str = to_string(
3058 format_hex_no_prefix(Symbol->st_value, ELFT::Is64Bits ? 16 : 8));
3059 Fields[2].Str = to_string(format_decimal(Symbol->st_size, 5));
3060
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00003061 unsigned char SymbolType = Symbol->getType();
3062 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU &&
3063 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
George Rimar4b4899b2019-01-30 14:08:55 +00003064 Fields[3].Str = printEnum(SymbolType, makeArrayRef(AMDGPUSymbolTypes));
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00003065 else
George Rimar4b4899b2019-01-30 14:08:55 +00003066 Fields[3].Str = printEnum(SymbolType, makeArrayRef(ElfSymbolTypes));
3067
3068 Fields[4].Str =
3069 printEnum(Symbol->getBinding(), makeArrayRef(ElfSymbolBindings));
3070 Fields[5].Str =
3071 printEnum(Symbol->getVisibility(), makeArrayRef(ElfSymbolVisibilities));
3072 Fields[6].Str = getSymbolSectionNdx(Obj, Symbol, FirstSym);
3073 Fields[7].Str =
3074 this->dumper()->getFullSymbolName(Symbol, StrTable, IsDynamic);
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00003075 for (auto &Entry : Fields)
3076 printField(Entry);
3077 OS << "\n";
3078}
George Rimar4b4899b2019-01-30 14:08:55 +00003079
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003080template <class ELFT>
3081void GNUStyle<ELFT>::printHashedSymbol(const ELFO *Obj, const Elf_Sym *FirstSym,
3082 uint32_t Sym, StringRef StrTable,
3083 uint32_t Bucket) {
George Rimar1206f5a2019-01-30 15:39:05 +00003084 unsigned Bias = ELFT::Is64Bits ? 8 : 0;
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003085 Field Fields[9] = {0, 6, 11, 20 + Bias, 25 + Bias,
3086 34 + Bias, 41 + Bias, 49 + Bias, 53 + Bias};
George Rimar4b4899b2019-01-30 14:08:55 +00003087 Fields[0].Str = to_string(format_decimal(Sym, 5));
3088 Fields[1].Str = to_string(format_decimal(Bucket, 3)) + ":";
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003089
3090 const auto Symbol = FirstSym + Sym;
George Rimar1206f5a2019-01-30 15:39:05 +00003091 Fields[2].Str = to_string(
3092 format_hex_no_prefix(Symbol->st_value, ELFT::Is64Bits ? 18 : 8));
George Rimar4b4899b2019-01-30 14:08:55 +00003093 Fields[3].Str = to_string(format_decimal(Symbol->st_size, 5));
3094
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003095 unsigned char SymbolType = Symbol->getType();
3096 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU &&
3097 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
George Rimar4b4899b2019-01-30 14:08:55 +00003098 Fields[4].Str = printEnum(SymbolType, makeArrayRef(AMDGPUSymbolTypes));
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003099 else
George Rimar4b4899b2019-01-30 14:08:55 +00003100 Fields[4].Str = printEnum(SymbolType, makeArrayRef(ElfSymbolTypes));
3101
3102 Fields[5].Str =
3103 printEnum(Symbol->getBinding(), makeArrayRef(ElfSymbolBindings));
3104 Fields[6].Str =
3105 printEnum(Symbol->getVisibility(), makeArrayRef(ElfSymbolVisibilities));
3106 Fields[7].Str = getSymbolSectionNdx(Obj, Symbol, FirstSym);
3107 Fields[8].Str = this->dumper()->getFullSymbolName(Symbol, StrTable, true);
3108
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003109 for (auto &Entry : Fields)
3110 printField(Entry);
3111 OS << "\n";
3112}
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00003113
Hemant Kulkarnic030f232016-03-15 17:25:31 +00003114template <class ELFT>
James Henderson21ed8682019-01-23 16:15:39 +00003115void GNUStyle<ELFT>::printSymbols(const ELFO *Obj, bool PrintSymbols,
3116 bool PrintDynamicSymbols) {
3117 if (!PrintSymbols && !PrintDynamicSymbols)
3118 return;
3119 // GNU readelf prints both the .dynsym and .symtab with --symbols.
James Henderson5fc812f2019-01-22 09:35:35 +00003120 this->dumper()->printSymbolsHelper(true);
James Henderson21ed8682019-01-23 16:15:39 +00003121 if (PrintSymbols)
3122 this->dumper()->printSymbolsHelper(false);
James Henderson5fc812f2019-01-22 09:35:35 +00003123}
3124
3125template <class ELFT> void GNUStyle<ELFT>::printHashSymbols(const ELFO *Obj) {
Eugene Zelenko416e0592017-06-09 21:41:54 +00003126 if (this->dumper()->getDynamicStringTable().empty())
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003127 return;
3128 auto StringTable = this->dumper()->getDynamicStringTable();
3129 auto DynSyms = this->dumper()->dynamic_symbols();
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003130
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003131 // Try printing .hash
George Rimar1206f5a2019-01-30 15:39:05 +00003132 if (auto SysVHash = this->dumper()->getHashTable()) {
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003133 OS << "\n Symbol table of .hash for image:\n";
3134 if (ELFT::Is64Bits)
3135 OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
3136 else
3137 OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
3138 OS << "\n";
3139
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003140 auto Buckets = SysVHash->buckets();
3141 auto Chains = SysVHash->chains();
George Rimar1206f5a2019-01-30 15:39:05 +00003142 for (uint32_t Buc = 0; Buc < SysVHash->nbucket; Buc++) {
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003143 if (Buckets[Buc] == ELF::STN_UNDEF)
3144 continue;
George Rimar1206f5a2019-01-30 15:39:05 +00003145 for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash->nchain; Ch = Chains[Ch]) {
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003146 if (Ch == ELF::STN_UNDEF)
3147 break;
3148 printHashedSymbol(Obj, &DynSyms[0], Ch, StringTable, Buc);
3149 }
3150 }
3151 }
3152
3153 // Try printing .gnu.hash
George Rimar1206f5a2019-01-30 15:39:05 +00003154 if (auto GnuHash = this->dumper()->getGnuHashTable()) {
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003155 OS << "\n Symbol table of .gnu.hash for image:\n";
3156 if (ELFT::Is64Bits)
3157 OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
3158 else
3159 OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
3160 OS << "\n";
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003161 auto Buckets = GnuHash->buckets();
George Rimar1206f5a2019-01-30 15:39:05 +00003162 for (uint32_t Buc = 0; Buc < GnuHash->nbuckets; Buc++) {
Hemant Kulkarnia6ee9fd2016-11-23 18:04:23 +00003163 if (Buckets[Buc] == ELF::STN_UNDEF)
3164 continue;
3165 uint32_t Index = Buckets[Buc];
3166 uint32_t GnuHashable = Index - GnuHash->symndx;
3167 // Print whole chain
3168 while (true) {
3169 printHashedSymbol(Obj, &DynSyms[0], Index++, StringTable, Buc);
3170 // Chain ends at symbol with stopper bit
3171 if ((GnuHash->values(DynSyms.size())[GnuHashable++] & 1) == 1)
3172 break;
3173 }
3174 }
3175 }
Hemant Kulkarnic030f232016-03-15 17:25:31 +00003176}
3177
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003178static inline std::string printPhdrFlags(unsigned Flag) {
3179 std::string Str;
3180 Str = (Flag & PF_R) ? "R" : " ";
3181 Str += (Flag & PF_W) ? "W" : " ";
3182 Str += (Flag & PF_X) ? "E" : " ";
3183 return Str;
3184}
3185
3186// SHF_TLS sections are only in PT_TLS, PT_LOAD or PT_GNU_RELRO
3187// PT_TLS must only have SHF_TLS sections
3188template <class ELFT>
3189bool GNUStyle<ELFT>::checkTLSSections(const Elf_Phdr &Phdr,
3190 const Elf_Shdr &Sec) {
3191 return (((Sec.sh_flags & ELF::SHF_TLS) &&
3192 ((Phdr.p_type == ELF::PT_TLS) || (Phdr.p_type == ELF::PT_LOAD) ||
3193 (Phdr.p_type == ELF::PT_GNU_RELRO))) ||
3194 (!(Sec.sh_flags & ELF::SHF_TLS) && Phdr.p_type != ELF::PT_TLS));
3195}
3196
3197// Non-SHT_NOBITS must have its offset inside the segment
3198// Only non-zero section can be at end of segment
3199template <class ELFT>
3200bool GNUStyle<ELFT>::checkoffsets(const Elf_Phdr &Phdr, const Elf_Shdr &Sec) {
3201 if (Sec.sh_type == ELF::SHT_NOBITS)
3202 return true;
3203 bool IsSpecial =
3204 (Sec.sh_type == ELF::SHT_NOBITS) && ((Sec.sh_flags & ELF::SHF_TLS) != 0);
3205 // .tbss is special, it only has memory in PT_TLS and has NOBITS properties
3206 auto SectionSize =
3207 (IsSpecial && Phdr.p_type != ELF::PT_TLS) ? 0 : Sec.sh_size;
3208 if (Sec.sh_offset >= Phdr.p_offset)
3209 return ((Sec.sh_offset + SectionSize <= Phdr.p_filesz + Phdr.p_offset)
George Rimar9e88a262019-05-14 14:22:44 +00003210 /*only non-zero sized sections at end*/
3211 && (Sec.sh_offset + 1 <= Phdr.p_offset + Phdr.p_filesz));
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003212 return false;
3213}
3214
3215// SHF_ALLOC must have VMA inside segment
3216// Only non-zero section can be at end of segment
3217template <class ELFT>
3218bool GNUStyle<ELFT>::checkVMA(const Elf_Phdr &Phdr, const Elf_Shdr &Sec) {
3219 if (!(Sec.sh_flags & ELF::SHF_ALLOC))
3220 return true;
3221 bool IsSpecial =
3222 (Sec.sh_type == ELF::SHT_NOBITS) && ((Sec.sh_flags & ELF::SHF_TLS) != 0);
3223 // .tbss is special, it only has memory in PT_TLS and has NOBITS properties
3224 auto SectionSize =
3225 (IsSpecial && Phdr.p_type != ELF::PT_TLS) ? 0 : Sec.sh_size;
3226 if (Sec.sh_addr >= Phdr.p_vaddr)
3227 return ((Sec.sh_addr + SectionSize <= Phdr.p_vaddr + Phdr.p_memsz) &&
3228 (Sec.sh_addr + 1 <= Phdr.p_vaddr + Phdr.p_memsz));
3229 return false;
3230}
3231
3232// No section with zero size must be at start or end of PT_DYNAMIC
3233template <class ELFT>
3234bool GNUStyle<ELFT>::checkPTDynamic(const Elf_Phdr &Phdr, const Elf_Shdr &Sec) {
3235 if (Phdr.p_type != ELF::PT_DYNAMIC || Sec.sh_size != 0 || Phdr.p_memsz == 0)
3236 return true;
3237 // Is section within the phdr both based on offset and VMA ?
3238 return ((Sec.sh_type == ELF::SHT_NOBITS) ||
3239 (Sec.sh_offset > Phdr.p_offset &&
3240 Sec.sh_offset < Phdr.p_offset + Phdr.p_filesz)) &&
3241 (!(Sec.sh_flags & ELF::SHF_ALLOC) ||
3242 (Sec.sh_addr > Phdr.p_vaddr && Sec.sh_addr < Phdr.p_memsz));
3243}
3244
3245template <class ELFT>
Matt Davis50ca8ed2019-02-01 18:51:10 +00003246void GNUStyle<ELFT>::printProgramHeaders(
3247 const ELFO *Obj, bool PrintProgramHeaders,
3248 cl::boolOrDefault PrintSectionMapping) {
3249 if (PrintProgramHeaders)
3250 printProgramHeaders(Obj);
3251
3252 // Display the section mapping along with the program headers, unless
3253 // -section-mapping is explicitly set to false.
3254 if (PrintSectionMapping != cl::BOU_FALSE)
3255 printSectionMapping(Obj);
3256}
3257
3258template <class ELFT>
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003259void GNUStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
Hemant Kulkarni2e3254e2016-03-29 14:20:20 +00003260 unsigned Bias = ELFT::Is64Bits ? 8 : 0;
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003261 const Elf_Ehdr *Header = Obj->getHeader();
3262 Field Fields[8] = {2, 17, 26, 37 + Bias,
3263 48 + Bias, 56 + Bias, 64 + Bias, 68 + Bias};
3264 OS << "\nElf file type is "
3265 << printEnum(Header->e_type, makeArrayRef(ElfObjectFileType)) << "\n"
Hemant Kulkarni787c2ed2016-05-12 22:51:26 +00003266 << "Entry point " << format_hex(Header->e_entry, 3) << "\n"
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003267 << "There are " << Header->e_phnum << " program headers,"
3268 << " starting at offset " << Header->e_phoff << "\n\n"
3269 << "Program Headers:\n";
3270 if (ELFT::Is64Bits)
3271 OS << " Type Offset VirtAddr PhysAddr "
3272 << " FileSiz MemSiz Flg Align\n";
3273 else
3274 OS << " Type Offset VirtAddr PhysAddr FileSiz "
3275 << "MemSiz Flg Align\n";
George Rimar1206f5a2019-01-30 15:39:05 +00003276
3277 unsigned Width = ELFT::Is64Bits ? 18 : 10;
3278 unsigned SizeWidth = ELFT::Is64Bits ? 8 : 7;
Rafael Espindola6a494972016-11-03 17:28:33 +00003279 for (const auto &Phdr : unwrapOrError(Obj->program_headers())) {
George Rimar4b4899b2019-01-30 14:08:55 +00003280 Fields[0].Str = getElfPtType(Header->e_machine, Phdr.p_type);
3281 Fields[1].Str = to_string(format_hex(Phdr.p_offset, 8));
3282 Fields[2].Str = to_string(format_hex(Phdr.p_vaddr, Width));
3283 Fields[3].Str = to_string(format_hex(Phdr.p_paddr, Width));
3284 Fields[4].Str = to_string(format_hex(Phdr.p_filesz, SizeWidth));
3285 Fields[5].Str = to_string(format_hex(Phdr.p_memsz, SizeWidth));
3286 Fields[6].Str = printPhdrFlags(Phdr.p_flags);
3287 Fields[7].Str = to_string(format_hex(Phdr.p_align, 1));
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003288 for (auto Field : Fields)
3289 printField(Field);
3290 if (Phdr.p_type == ELF::PT_INTERP) {
3291 OS << "\n [Requesting program interpreter: ";
3292 OS << reinterpret_cast<const char *>(Obj->base()) + Phdr.p_offset << "]";
3293 }
3294 OS << "\n";
3295 }
Matt Davis50ca8ed2019-02-01 18:51:10 +00003296}
3297
3298template <class ELFT>
3299void GNUStyle<ELFT>::printSectionMapping(const ELFO *Obj) {
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003300 OS << "\n Section to Segment mapping:\n Segment Sections...\n";
Matt Davis0d0e9c02019-02-05 21:01:01 +00003301 DenseSet<const Elf_Shdr *> BelongsToSegment;
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003302 int Phnum = 0;
Rafael Espindola6a494972016-11-03 17:28:33 +00003303 for (const Elf_Phdr &Phdr : unwrapOrError(Obj->program_headers())) {
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003304 std::string Sections;
3305 OS << format(" %2.2d ", Phnum++);
Rafael Espindola25be8c82016-11-02 14:10:57 +00003306 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003307 // Check if each section is in a segment and then print mapping.
3308 // readelf additionally makes sure it does not print zero sized sections
3309 // at end of segments and for PT_DYNAMIC both start and end of section
3310 // .tbss must only be shown in PT_TLS section.
3311 bool TbssInNonTLS = (Sec.sh_type == ELF::SHT_NOBITS) &&
3312 ((Sec.sh_flags & ELF::SHF_TLS) != 0) &&
3313 Phdr.p_type != ELF::PT_TLS;
3314 if (!TbssInNonTLS && checkTLSSections(Phdr, Sec) &&
3315 checkoffsets(Phdr, Sec) && checkVMA(Phdr, Sec) &&
Matt Davis0d0e9c02019-02-05 21:01:01 +00003316 checkPTDynamic(Phdr, Sec) && (Sec.sh_type != ELF::SHT_NULL)) {
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003317 Sections += unwrapOrError(Obj->getSectionName(&Sec)).str() + " ";
Matt Davis0d0e9c02019-02-05 21:01:01 +00003318 BelongsToSegment.insert(&Sec);
3319 }
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003320 }
3321 OS << Sections << "\n";
3322 OS.flush();
3323 }
Matt Davis0d0e9c02019-02-05 21:01:01 +00003324
3325 // Display sections that do not belong to a segment.
3326 std::string Sections;
3327 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
3328 if (BelongsToSegment.find(&Sec) == BelongsToSegment.end())
3329 Sections += unwrapOrError(Obj->getSectionName(&Sec)).str() + ' ';
3330 }
3331 if (!Sections.empty()) {
3332 OS << " None " << Sections << '\n';
3333 OS.flush();
3334 }
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00003335}
3336
Hemant Kulkarnic030f232016-03-15 17:25:31 +00003337template <class ELFT>
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003338void GNUStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela R,
3339 bool IsRela) {
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003340 uint32_t SymIndex = R.getSymbol(Obj->isMips64EL());
3341 const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex;
George Rimar4b4899b2019-01-30 14:08:55 +00003342 std::string SymbolName = maybeDemangle(
James Hendersone50d9cb2019-01-17 15:34:12 +00003343 unwrapOrError(Sym->getName(this->dumper()->getDynamicStringTable())));
James Henderson814ab372019-03-29 11:47:19 +00003344 printRelocation(Obj, Sym, SymbolName, R, IsRela);
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003345}
3346
3347template <class ELFT>
Hemant Kulkarnic030f232016-03-15 17:25:31 +00003348void GNUStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003349 const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
3350 const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
Jake Ehrlich0f440d82018-06-28 21:07:34 +00003351 const DynRegionInfo &DynRelrRegion = this->dumper()->getDynRelrRegion();
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003352 const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
3353 if (DynRelaRegion.Size > 0) {
3354 OS << "\n'RELA' relocation section at offset "
3355 << format_hex(reinterpret_cast<const uint8_t *>(DynRelaRegion.Addr) -
3356 Obj->base(),
George Rimar9e88a262019-05-14 14:22:44 +00003357 1)
3358 << " contains " << DynRelaRegion.Size << " bytes:\n";
Jake Ehrlich0f440d82018-06-28 21:07:34 +00003359 printRelocHeader(ELF::SHT_RELA);
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003360 for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
3361 printDynamicRelocation(Obj, Rela, true);
3362 }
3363 if (DynRelRegion.Size > 0) {
3364 OS << "\n'REL' relocation section at offset "
3365 << format_hex(reinterpret_cast<const uint8_t *>(DynRelRegion.Addr) -
3366 Obj->base(),
George Rimar9e88a262019-05-14 14:22:44 +00003367 1)
3368 << " contains " << DynRelRegion.Size << " bytes:\n";
Jake Ehrlich0f440d82018-06-28 21:07:34 +00003369 printRelocHeader(ELF::SHT_REL);
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003370 for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
3371 Elf_Rela Rela;
3372 Rela.r_offset = Rel.r_offset;
3373 Rela.r_info = Rel.r_info;
3374 Rela.r_addend = 0;
3375 printDynamicRelocation(Obj, Rela, false);
3376 }
3377 }
Jake Ehrlich0f440d82018-06-28 21:07:34 +00003378 if (DynRelrRegion.Size > 0) {
3379 OS << "\n'RELR' relocation section at offset "
3380 << format_hex(reinterpret_cast<const uint8_t *>(DynRelrRegion.Addr) -
3381 Obj->base(),
George Rimar9e88a262019-05-14 14:22:44 +00003382 1)
3383 << " contains " << DynRelrRegion.Size << " bytes:\n";
Jake Ehrlich0f440d82018-06-28 21:07:34 +00003384 printRelocHeader(ELF::SHT_REL);
3385 Elf_Relr_Range Relrs = this->dumper()->dyn_relrs();
3386 std::vector<Elf_Rela> RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
3387 for (const Elf_Rela &Rela : RelrRelas) {
3388 printDynamicRelocation(Obj, Rela, false);
3389 }
3390 }
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003391 if (DynPLTRelRegion.Size) {
3392 OS << "\n'PLT' relocation section at offset "
3393 << format_hex(reinterpret_cast<const uint8_t *>(DynPLTRelRegion.Addr) -
3394 Obj->base(),
George Rimar9e88a262019-05-14 14:22:44 +00003395 1)
3396 << " contains " << DynPLTRelRegion.Size << " bytes:\n";
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003397 }
3398 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) {
Jake Ehrlich0f440d82018-06-28 21:07:34 +00003399 printRelocHeader(ELF::SHT_RELA);
Rafael Espindolaaafcf752016-04-05 14:47:22 +00003400 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef<Elf_Rela>())
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003401 printDynamicRelocation(Obj, Rela, true);
3402 } else {
Jake Ehrlich0f440d82018-06-28 21:07:34 +00003403 printRelocHeader(ELF::SHT_REL);
Rafael Espindolaaafcf752016-04-05 14:47:22 +00003404 for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef<Elf_Rel>()) {
Hemant Kulkarnia79c7982016-03-29 02:41:49 +00003405 Elf_Rela Rela;
3406 Rela.r_offset = Rel.r_offset;
3407 Rela.r_info = Rel.r_info;
3408 Rela.r_addend = 0;
3409 printDynamicRelocation(Obj, Rela, false);
3410 }
3411 }
Hemant Kulkarnic030f232016-03-15 17:25:31 +00003412}
3413
Xing GUOea16be12019-03-25 11:02:49 +00003414template <class ELFT>
3415void GNUStyle<ELFT>::printVersionSymbolSection(const ELFFile<ELFT> *Obj,
3416 const Elf_Shdr *Sec) {
3417 if (!Sec)
3418 return;
3419
3420 StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
Xing GUO8f6166a2019-04-03 13:32:49 +00003421 uint64_t Entries = Sec->sh_size / sizeof(Elf_Versym);
3422
3423 OS << "Version symbols section '" << SecName << "' "
3424 << "contains " << Entries << " entries:\n";
3425
3426 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link));
3427 StringRef SymTabName = unwrapOrError(Obj->getSectionName(SymTab));
3428 OS << " Addr: " << format_hex_no_prefix(Sec->sh_addr, 16)
3429 << " Offset: " << format_hex(Sec->sh_offset, 8)
3430 << " Link: " << Sec->sh_link << " (" << SymTabName << ")\n";
3431
3432 const uint8_t *VersymBuf =
3433 reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset);
3434 const ELFDumper<ELFT> *Dumper = this->dumper();
3435 StringRef StrTable = Dumper->getDynamicStringTable();
3436
3437 // readelf prints 4 entries per line.
3438 for (uint64_t VersymRow = 0; VersymRow < Entries; VersymRow += 4) {
3439 OS << " " << format_hex_no_prefix(VersymRow, 3) << ":";
3440
3441 for (uint64_t VersymIndex = 0;
3442 (VersymIndex < 4) && (VersymIndex + VersymRow) < Entries;
3443 ++VersymIndex) {
3444 const Elf_Versym *Versym =
3445 reinterpret_cast<const Elf_Versym *>(VersymBuf);
3446 switch (Versym->vs_index) {
3447 case 0:
3448 OS << " 0 (*local*) ";
3449 break;
3450 case 1:
3451 OS << " 1 (*global*) ";
3452 break;
3453 default:
3454 OS << format("%4x%c", Versym->vs_index & VERSYM_VERSION,
3455 Versym->vs_index & VERSYM_HIDDEN ? 'h' : ' ');
3456
3457 bool IsDefault = true;
3458 std::string VersionName = Dumper->getSymbolVersionByIndex(
3459 StrTable, Versym->vs_index, IsDefault);
3460
3461 if (!VersionName.empty())
3462 VersionName = "(" + VersionName + ")";
3463 else
3464 VersionName = "(*invalid*)";
3465 OS << left_justify(VersionName, 13);
3466 }
3467 VersymBuf += sizeof(Elf_Versym);
3468 }
3469 OS << '\n';
3470 }
3471 OS << '\n';
Xing GUOea16be12019-03-25 11:02:49 +00003472}
3473
3474template <class ELFT>
3475void GNUStyle<ELFT>::printVersionDefinitionSection(const ELFFile<ELFT> *Obj,
3476 const Elf_Shdr *Sec) {
3477 if (!Sec)
3478 return;
3479
3480 StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
3481 OS << "Dumper for " << SecName << " is not implemented\n";
3482}
3483
3484template <class ELFT>
3485void GNUStyle<ELFT>::printVersionDependencySection(const ELFFile<ELFT> *Obj,
3486 const Elf_Shdr *Sec) {
3487 if (!Sec)
3488 return;
3489
3490 StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
3491 OS << "Dumper for " << SecName << " is not implemented\n";
3492}
3493
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00003494// Hash histogram shows statistics of how efficient the hash was for the
3495// dynamic symbol table. The table shows number of hash buckets for different
3496// lengths of chains as absolute number and percentage of the total buckets.
3497// Additionally cumulative coverage of symbols for each set of buckets.
3498template <class ELFT>
3499void GNUStyle<ELFT>::printHashHistogram(const ELFFile<ELFT> *Obj) {
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00003500 // Print histogram for .hash section
George Rimar1206f5a2019-01-30 15:39:05 +00003501 if (const Elf_Hash *HashTable = this->dumper()->getHashTable()) {
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00003502 size_t NBucket = HashTable->nbucket;
3503 size_t NChain = HashTable->nchain;
3504 ArrayRef<Elf_Word> Buckets = HashTable->buckets();
3505 ArrayRef<Elf_Word> Chains = HashTable->chains();
3506 size_t TotalSyms = 0;
3507 // If hash table is correct, we have at least chains with 0 length
3508 size_t MaxChain = 1;
3509 size_t CumulativeNonZero = 0;
3510
3511 if (NChain == 0 || NBucket == 0)
3512 return;
3513
3514 std::vector<size_t> ChainLen(NBucket, 0);
3515 // Go over all buckets and and note chain lengths of each bucket (total
3516 // unique chain lengths).
3517 for (size_t B = 0; B < NBucket; B++) {
3518 for (size_t C = Buckets[B]; C > 0 && C < NChain; C = Chains[C])
3519 if (MaxChain <= ++ChainLen[B])
3520 MaxChain++;
3521 TotalSyms += ChainLen[B];
3522 }
3523
3524 if (!TotalSyms)
3525 return;
3526
George Rimarec895f12019-05-16 06:22:51 +00003527 std::vector<size_t> Count(MaxChain, 0) ;
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00003528 // Count how long is the chain for each bucket
3529 for (size_t B = 0; B < NBucket; B++)
3530 ++Count[ChainLen[B]];
3531 // Print Number of buckets with each chain lengths and their cumulative
3532 // coverage of the symbols
3533 OS << "Histogram for bucket list length (total of " << NBucket
3534 << " buckets)\n"
3535 << " Length Number % of total Coverage\n";
3536 for (size_t I = 0; I < MaxChain; I++) {
3537 CumulativeNonZero += Count[I] * I;
3538 OS << format("%7lu %-10lu (%5.1f%%) %5.1f%%\n", I, Count[I],
3539 (Count[I] * 100.0) / NBucket,
3540 (CumulativeNonZero * 100.0) / TotalSyms);
3541 }
3542 }
3543
3544 // Print histogram for .gnu.hash section
George Rimar1206f5a2019-01-30 15:39:05 +00003545 if (const Elf_GnuHash *GnuHashTable = this->dumper()->getGnuHashTable()) {
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00003546 size_t NBucket = GnuHashTable->nbuckets;
3547 ArrayRef<Elf_Word> Buckets = GnuHashTable->buckets();
3548 unsigned NumSyms = this->dumper()->dynamic_symbols().size();
3549 if (!NumSyms)
3550 return;
3551 ArrayRef<Elf_Word> Chains = GnuHashTable->values(NumSyms);
3552 size_t Symndx = GnuHashTable->symndx;
3553 size_t TotalSyms = 0;
3554 size_t MaxChain = 1;
3555 size_t CumulativeNonZero = 0;
3556
Eugene Zelenko416e0592017-06-09 21:41:54 +00003557 if (Chains.empty() || NBucket == 0)
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00003558 return;
3559
3560 std::vector<size_t> ChainLen(NBucket, 0);
3561
3562 for (size_t B = 0; B < NBucket; B++) {
3563 if (!Buckets[B])
3564 continue;
3565 size_t Len = 1;
3566 for (size_t C = Buckets[B] - Symndx;
3567 C < Chains.size() && (Chains[C] & 1) == 0; C++)
3568 if (MaxChain < ++Len)
3569 MaxChain++;
3570 ChainLen[B] = Len;
3571 TotalSyms += Len;
3572 }
3573 MaxChain++;
3574
3575 if (!TotalSyms)
3576 return;
3577
George Rimarec895f12019-05-16 06:22:51 +00003578 std::vector<size_t> Count(MaxChain, 0) ;
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00003579 for (size_t B = 0; B < NBucket; B++)
3580 ++Count[ChainLen[B]];
3581 // Print Number of buckets with each chain lengths and their cumulative
3582 // coverage of the symbols
3583 OS << "Histogram for `.gnu.hash' bucket list length (total of " << NBucket
3584 << " buckets)\n"
3585 << " Length Number % of total Coverage\n";
George Rimarec895f12019-05-16 06:22:51 +00003586 for (size_t I = 0; I <MaxChain; I++) {
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00003587 CumulativeNonZero += Count[I] * I;
3588 OS << format("%7lu %-10lu (%5.1f%%) %5.1f%%\n", I, Count[I],
3589 (Count[I] * 100.0) / NBucket,
3590 (CumulativeNonZero * 100.0) / TotalSyms);
3591 }
3592 }
3593}
3594
Michael J. Spencerae6eeae2018-06-02 16:33:01 +00003595template <class ELFT>
3596void GNUStyle<ELFT>::printCGProfile(const ELFFile<ELFT> *Obj) {
3597 OS << "GNUStyle::printCGProfile not implemented\n";
3598}
3599
Peter Collingbourne3e227332018-07-17 22:17:18 +00003600template <class ELFT>
3601void GNUStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
George Rimarec895f12019-05-16 06:22:51 +00003602 OS << "GNUStyle::printAddrsig not implemented\n";
Peter Collingbourne3e227332018-07-17 22:17:18 +00003603}
3604
Jordan Rupprecht871baa22019-03-29 16:48:19 +00003605static StringRef getGenericNoteTypeName(const uint32_t NT) {
3606 static const struct {
3607 uint32_t ID;
3608 const char *Name;
3609 } Notes[] = {
3610 {ELF::NT_VERSION, "NT_VERSION (version)"},
3611 {ELF::NT_ARCH, "NT_ARCH (architecture)"},
3612 {ELF::NT_GNU_BUILD_ATTRIBUTE_OPEN, "OPEN"},
3613 {ELF::NT_GNU_BUILD_ATTRIBUTE_FUNC, "func"},
3614 };
3615
3616 for (const auto &Note : Notes)
3617 if (Note.ID == NT)
3618 return Note.Name;
3619
3620 return "";
3621}
3622
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003623static std::string getGNUNoteTypeName(const uint32_t NT) {
3624 static const struct {
3625 uint32_t ID;
3626 const char *Name;
3627 } Notes[] = {
3628 {ELF::NT_GNU_ABI_TAG, "NT_GNU_ABI_TAG (ABI version tag)"},
3629 {ELF::NT_GNU_HWCAP, "NT_GNU_HWCAP (DSO-supplied software HWCAP info)"},
3630 {ELF::NT_GNU_BUILD_ID, "NT_GNU_BUILD_ID (unique build ID bitstring)"},
3631 {ELF::NT_GNU_GOLD_VERSION, "NT_GNU_GOLD_VERSION (gold version)"},
George Rimar6a14c022018-03-21 08:34:55 +00003632 {ELF::NT_GNU_PROPERTY_TYPE_0, "NT_GNU_PROPERTY_TYPE_0 (property note)"},
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003633 };
3634
3635 for (const auto &Note : Notes)
3636 if (Note.ID == NT)
3637 return std::string(Note.Name);
3638
3639 std::string string;
3640 raw_string_ostream OS(string);
3641 OS << format("Unknown note type (0x%08x)", NT);
Konstantin Zhuravlyov716af742017-10-14 16:43:46 +00003642 return OS.str();
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003643}
3644
Saleem Abdulrasool4b089132017-02-12 18:55:33 +00003645static std::string getFreeBSDNoteTypeName(const uint32_t NT) {
3646 static const struct {
3647 uint32_t ID;
3648 const char *Name;
3649 } Notes[] = {
3650 {ELF::NT_FREEBSD_THRMISC, "NT_THRMISC (thrmisc structure)"},
3651 {ELF::NT_FREEBSD_PROCSTAT_PROC, "NT_PROCSTAT_PROC (proc data)"},
3652 {ELF::NT_FREEBSD_PROCSTAT_FILES, "NT_PROCSTAT_FILES (files data)"},
3653 {ELF::NT_FREEBSD_PROCSTAT_VMMAP, "NT_PROCSTAT_VMMAP (vmmap data)"},
3654 {ELF::NT_FREEBSD_PROCSTAT_GROUPS, "NT_PROCSTAT_GROUPS (groups data)"},
3655 {ELF::NT_FREEBSD_PROCSTAT_UMASK, "NT_PROCSTAT_UMASK (umask data)"},
3656 {ELF::NT_FREEBSD_PROCSTAT_RLIMIT, "NT_PROCSTAT_RLIMIT (rlimit data)"},
3657 {ELF::NT_FREEBSD_PROCSTAT_OSREL, "NT_PROCSTAT_OSREL (osreldate data)"},
3658 {ELF::NT_FREEBSD_PROCSTAT_PSSTRINGS,
3659 "NT_PROCSTAT_PSSTRINGS (ps_strings data)"},
3660 {ELF::NT_FREEBSD_PROCSTAT_AUXV, "NT_PROCSTAT_AUXV (auxv data)"},
3661 };
3662
3663 for (const auto &Note : Notes)
3664 if (Note.ID == NT)
3665 return std::string(Note.Name);
3666
3667 std::string string;
3668 raw_string_ostream OS(string);
3669 OS << format("Unknown note type (0x%08x)", NT);
Konstantin Zhuravlyov716af742017-10-14 16:43:46 +00003670 return OS.str();
3671}
3672
Scott Linderf5b36e52018-12-12 19:39:27 +00003673static std::string getAMDNoteTypeName(const uint32_t NT) {
Konstantin Zhuravlyov716af742017-10-14 16:43:46 +00003674 static const struct {
3675 uint32_t ID;
3676 const char *Name;
George Rimar9e88a262019-05-14 14:22:44 +00003677 } Notes[] = {{ELF::NT_AMD_AMDGPU_HSA_METADATA,
3678 "NT_AMD_AMDGPU_HSA_METADATA (HSA Metadata)"},
3679 {ELF::NT_AMD_AMDGPU_ISA, "NT_AMD_AMDGPU_ISA (ISA Version)"},
3680 {ELF::NT_AMD_AMDGPU_PAL_METADATA,
3681 "NT_AMD_AMDGPU_PAL_METADATA (PAL Metadata)"}};
Konstantin Zhuravlyov716af742017-10-14 16:43:46 +00003682
3683 for (const auto &Note : Notes)
3684 if (Note.ID == NT)
3685 return std::string(Note.Name);
3686
3687 std::string string;
3688 raw_string_ostream OS(string);
3689 OS << format("Unknown note type (0x%08x)", NT);
3690 return OS.str();
Saleem Abdulrasool4b089132017-02-12 18:55:33 +00003691}
3692
Scott Linderf5b36e52018-12-12 19:39:27 +00003693static std::string getAMDGPUNoteTypeName(const uint32_t NT) {
3694 if (NT == ELF::NT_AMDGPU_METADATA)
3695 return std::string("NT_AMDGPU_METADATA (AMDGPU Metadata)");
3696
3697 std::string string;
3698 raw_string_ostream OS(string);
3699 OS << format("Unknown note type (0x%08x)", NT);
3700 return OS.str();
3701}
3702
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003703template <typename ELFT>
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003704static std::string getGNUProperty(uint32_t Type, uint32_t DataSize,
3705 ArrayRef<uint8_t> Data) {
3706 std::string str;
3707 raw_string_ostream OS(str);
Fangrui Song6a03b932019-02-13 15:58:23 +00003708 uint32_t PrData;
Fangrui Song12d55992019-02-13 01:51:45 +00003709 auto DumpBit = [&](uint32_t Flag, StringRef Name) {
Fangrui Song6a03b932019-02-13 15:58:23 +00003710 if (PrData & Flag) {
3711 PrData &= ~Flag;
Fangrui Song12d55992019-02-13 01:51:45 +00003712 OS << Name;
Fangrui Song6a03b932019-02-13 15:58:23 +00003713 if (PrData)
Fangrui Song12d55992019-02-13 01:51:45 +00003714 OS << ", ";
3715 }
3716 };
3717
George Rimar6a14c022018-03-21 08:34:55 +00003718 switch (Type) {
3719 default:
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003720 OS << format("<application-specific type 0x%x>", Type);
3721 return OS.str();
George Rimar6a14c022018-03-21 08:34:55 +00003722 case GNU_PROPERTY_STACK_SIZE: {
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003723 OS << "stack size: ";
George Rimar6a14c022018-03-21 08:34:55 +00003724 if (DataSize == sizeof(typename ELFT::uint))
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003725 OS << formatv("{0:x}",
3726 (uint64_t)(*(const typename ELFT::Addr *)Data.data()));
George Rimar6a14c022018-03-21 08:34:55 +00003727 else
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003728 OS << format("<corrupt length: 0x%x>", DataSize);
3729 return OS.str();
George Rimar6a14c022018-03-21 08:34:55 +00003730 }
3731 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003732 OS << "no copy on protected";
George Rimar6a14c022018-03-21 08:34:55 +00003733 if (DataSize)
3734 OS << format(" <corrupt length: 0x%x>", DataSize);
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003735 return OS.str();
Alexander Ivchenkoab60a282018-06-04 15:14:18 +00003736 case GNU_PROPERTY_X86_FEATURE_1_AND:
Fangrui Song12d55992019-02-13 01:51:45 +00003737 OS << "x86 feature: ";
Fangrui Song8e0d5ac2019-02-12 09:56:01 +00003738 if (DataSize != 4) {
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003739 OS << format("<corrupt length: 0x%x>", DataSize);
3740 return OS.str();
Alexander Ivchenkoab60a282018-06-04 15:14:18 +00003741 }
Fangrui Song6a03b932019-02-13 15:58:23 +00003742 PrData = support::endian::read32<ELFT::TargetEndianness>(Data.data());
3743 if (PrData == 0) {
Fangrui Song12d55992019-02-13 01:51:45 +00003744 OS << "<None>";
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003745 return OS.str();
Alexander Ivchenkoab60a282018-06-04 15:14:18 +00003746 }
Fangrui Song12d55992019-02-13 01:51:45 +00003747 DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT");
3748 DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK");
Fangrui Song6a03b932019-02-13 15:58:23 +00003749 if (PrData)
3750 OS << format("<unknown flags: 0x%x>", PrData);
Fangrui Song12d55992019-02-13 01:51:45 +00003751 return OS.str();
Fangrui Song91ab9bf2019-02-13 23:18:05 +00003752 case GNU_PROPERTY_X86_ISA_1_NEEDED:
3753 case GNU_PROPERTY_X86_ISA_1_USED:
3754 OS << "x86 ISA "
3755 << (Type == GNU_PROPERTY_X86_ISA_1_NEEDED ? "needed: " : "used: ");
3756 if (DataSize != 4) {
3757 OS << format("<corrupt length: 0x%x>", DataSize);
3758 return OS.str();
3759 }
3760 PrData = support::endian::read32<ELFT::TargetEndianness>(Data.data());
3761 if (PrData == 0) {
3762 OS << "<None>";
3763 return OS.str();
3764 }
3765 DumpBit(GNU_PROPERTY_X86_ISA_1_CMOV, "CMOV");
3766 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE, "SSE");
3767 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE2, "SSE2");
3768 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE3, "SSE3");
3769 DumpBit(GNU_PROPERTY_X86_ISA_1_SSSE3, "SSSE3");
3770 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE4_1, "SSE4_1");
3771 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE4_2, "SSE4_2");
3772 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX, "AVX");
3773 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX2, "AVX2");
3774 DumpBit(GNU_PROPERTY_X86_ISA_1_FMA, "FMA");
3775 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512F, "AVX512F");
3776 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512CD, "AVX512CD");
3777 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512ER, "AVX512ER");
3778 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512PF, "AVX512PF");
3779 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512VL, "AVX512VL");
3780 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512DQ, "AVX512DQ");
3781 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512BW, "AVX512BW");
3782 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS, "AVX512_4FMAPS");
3783 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW, "AVX512_4VNNIW");
3784 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_BITALG, "AVX512_BITALG");
3785 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_IFMA, "AVX512_IFMA");
3786 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_VBMI, "AVX512_VBMI");
3787 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2, "AVX512_VBMI2");
3788 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_VNNI, "AVX512_VNNI");
3789 if (PrData)
3790 OS << format("<unknown flags: 0x%x>", PrData);
3791 return OS.str();
3792 break;
Fangrui Song12d55992019-02-13 01:51:45 +00003793 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
3794 case GNU_PROPERTY_X86_FEATURE_2_USED:
3795 OS << "x86 feature "
3796 << (Type == GNU_PROPERTY_X86_FEATURE_2_NEEDED ? "needed: " : "used: ");
3797 if (DataSize != 4) {
3798 OS << format("<corrupt length: 0x%x>", DataSize);
3799 return OS.str();
Alexander Ivchenkoab60a282018-06-04 15:14:18 +00003800 }
Fangrui Song6a03b932019-02-13 15:58:23 +00003801 PrData = support::endian::read32<ELFT::TargetEndianness>(Data.data());
3802 if (PrData == 0) {
Fangrui Song12d55992019-02-13 01:51:45 +00003803 OS << "<None>";
3804 return OS.str();
Alexander Ivchenkoab60a282018-06-04 15:14:18 +00003805 }
Fangrui Song12d55992019-02-13 01:51:45 +00003806 DumpBit(GNU_PROPERTY_X86_FEATURE_2_X86, "x86");
3807 DumpBit(GNU_PROPERTY_X86_FEATURE_2_X87, "x87");
3808 DumpBit(GNU_PROPERTY_X86_FEATURE_2_MMX, "MMX");
3809 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XMM, "XMM");
3810 DumpBit(GNU_PROPERTY_X86_FEATURE_2_YMM, "YMM");
3811 DumpBit(GNU_PROPERTY_X86_FEATURE_2_ZMM, "ZMM");
3812 DumpBit(GNU_PROPERTY_X86_FEATURE_2_FXSR, "FXSR");
3813 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVE, "XSAVE");
3814 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT, "XSAVEOPT");
3815 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEC, "XSAVEC");
Fangrui Song6a03b932019-02-13 15:58:23 +00003816 if (PrData)
3817 OS << format("<unknown flags: 0x%x>", PrData);
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003818 return OS.str();
George Rimar6a14c022018-03-21 08:34:55 +00003819 }
3820}
3821
3822template <typename ELFT>
George Rimar9e88a262019-05-14 14:22:44 +00003823static SmallVector<std::string, 4> getGNUPropertyList(ArrayRef<uint8_t> Arr) {
George Rimar6a14c022018-03-21 08:34:55 +00003824 using Elf_Word = typename ELFT::Word;
3825
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003826 SmallVector<std::string, 4> Properties;
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003827 while (Arr.size() >= 8) {
3828 uint32_t Type = *reinterpret_cast<const Elf_Word *>(Arr.data());
3829 uint32_t DataSize = *reinterpret_cast<const Elf_Word *>(Arr.data() + 4);
3830 Arr = Arr.drop_front(8);
3831
3832 // Take padding size into account if present.
3833 uint64_t PaddedSize = alignTo(DataSize, sizeof(typename ELFT::uint));
3834 std::string str;
3835 raw_string_ostream OS(str);
3836 if (Arr.size() < PaddedSize) {
3837 OS << format("<corrupt type (0x%x) datasz: 0x%x>", Type, DataSize);
3838 Properties.push_back(OS.str());
3839 break;
3840 }
3841 Properties.push_back(
3842 getGNUProperty<ELFT>(Type, DataSize, Arr.take_front(PaddedSize)));
3843 Arr = Arr.drop_front(PaddedSize);
3844 }
3845
3846 if (!Arr.empty())
3847 Properties.push_back("<corrupted GNU_PROPERTY_TYPE_0>");
3848
3849 return Properties;
3850}
3851
3852struct GNUAbiTag {
3853 std::string OSName;
3854 std::string ABI;
3855 bool IsValid;
3856};
3857
George Rimar9e88a262019-05-14 14:22:44 +00003858template <typename ELFT> static GNUAbiTag getGNUAbiTag(ArrayRef<uint8_t> Desc) {
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003859 typedef typename ELFT::Word Elf_Word;
3860
George Rimar9e88a262019-05-14 14:22:44 +00003861 ArrayRef<Elf_Word> Words(reinterpret_cast<const Elf_Word *>(Desc.begin()),
3862 reinterpret_cast<const Elf_Word *>(Desc.end()));
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003863
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003864 if (Words.size() < 4)
3865 return {"", "", /*IsValid=*/false};
3866
3867 static const char *OSNames[] = {
3868 "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable", "NaCl",
3869 };
3870 StringRef OSName = "Unknown";
3871 if (Words[0] < array_lengthof(OSNames))
3872 OSName = OSNames[Words[0]];
3873 uint32_t Major = Words[1], Minor = Words[2], Patch = Words[3];
3874 std::string str;
3875 raw_string_ostream ABI(str);
3876 ABI << Major << "." << Minor << "." << Patch;
3877 return {OSName, ABI.str(), /*IsValid=*/true};
3878}
3879
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003880static std::string getGNUBuildId(ArrayRef<uint8_t> Desc) {
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003881 std::string str;
3882 raw_string_ostream OS(str);
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003883 for (const auto &B : Desc)
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003884 OS << format_hex_no_prefix(B, 2);
3885 return OS.str();
3886}
3887
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003888static StringRef getGNUGoldVersion(ArrayRef<uint8_t> Desc) {
3889 return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003890}
3891
3892template <typename ELFT>
3893static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003894 ArrayRef<uint8_t> Desc) {
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003895 switch (NoteType) {
3896 default:
3897 return;
3898 case ELF::NT_GNU_ABI_TAG: {
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003899 const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003900 if (!AbiTag.IsValid)
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003901 OS << " <corrupt GNU_ABI_TAG>";
3902 else
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003903 OS << " OS: " << AbiTag.OSName << ", ABI: " << AbiTag.ABI;
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003904 break;
3905 }
3906 case ELF::NT_GNU_BUILD_ID: {
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003907 OS << " Build ID: " << getGNUBuildId(Desc);
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003908 break;
3909 }
3910 case ELF::NT_GNU_GOLD_VERSION:
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003911 OS << " Version: " << getGNUGoldVersion(Desc);
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003912 break;
George Rimar6a14c022018-03-21 08:34:55 +00003913 case ELF::NT_GNU_PROPERTY_TYPE_0:
3914 OS << " Properties:";
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003915 for (const auto &Property : getGNUPropertyList<ELFT>(Desc))
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003916 OS << " " << Property << "\n";
George Rimar6a14c022018-03-21 08:34:55 +00003917 break;
3918 }
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003919 OS << '\n';
3920}
3921
Scott Linderf5b36e52018-12-12 19:39:27 +00003922struct AMDNote {
3923 std::string Type;
3924 std::string Value;
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003925};
3926
Konstantin Zhuravlyovb3c605d2017-10-14 18:21:42 +00003927template <typename ELFT>
Scott Linderf5b36e52018-12-12 19:39:27 +00003928static AMDNote getAMDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
Konstantin Zhuravlyovb3c605d2017-10-14 18:21:42 +00003929 switch (NoteType) {
3930 default:
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003931 return {"", ""};
3932 case ELF::NT_AMD_AMDGPU_HSA_METADATA:
George Rimar9e88a262019-05-14 14:22:44 +00003933 return {
3934 "HSA Metadata",
3935 std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size())};
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003936 case ELF::NT_AMD_AMDGPU_ISA:
George Rimar9e88a262019-05-14 14:22:44 +00003937 return {
3938 "ISA Version",
3939 std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size())};
Konstantin Zhuravlyovb3c605d2017-10-14 18:21:42 +00003940 }
Konstantin Zhuravlyovb3c605d2017-10-14 18:21:42 +00003941}
3942
Scott Linderf5b36e52018-12-12 19:39:27 +00003943struct AMDGPUNote {
3944 std::string Type;
3945 std::string Value;
3946};
3947
3948template <typename ELFT>
3949static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
3950 switch (NoteType) {
3951 default:
3952 return {"", ""};
Tim Renoufed0b9af2019-03-13 18:55:50 +00003953 case ELF::NT_AMDGPU_METADATA: {
Scott Linderf5b36e52018-12-12 19:39:27 +00003954 auto MsgPackString =
3955 StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
Tim Renoufed0b9af2019-03-13 18:55:50 +00003956 msgpack::Document MsgPackDoc;
3957 if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false))
Scott Linderf5b36e52018-12-12 19:39:27 +00003958 return {"AMDGPU Metadata", "Invalid AMDGPU Metadata"};
Scott Linderf5b36e52018-12-12 19:39:27 +00003959
3960 AMDGPU::HSAMD::V3::MetadataVerifier Verifier(true);
Tim Renoufed0b9af2019-03-13 18:55:50 +00003961 if (!Verifier.verify(MsgPackDoc.getRoot()))
Scott Linderf5b36e52018-12-12 19:39:27 +00003962 return {"AMDGPU Metadata", "Invalid AMDGPU Metadata"};
3963
3964 std::string HSAMetadataString;
3965 raw_string_ostream StrOS(HSAMetadataString);
Tim Renoufed0b9af2019-03-13 18:55:50 +00003966 MsgPackDoc.toYAML(StrOS);
Scott Linderf5b36e52018-12-12 19:39:27 +00003967
3968 return {"AMDGPU Metadata", StrOS.str()};
3969 }
Tim Renoufed0b9af2019-03-13 18:55:50 +00003970 }
Scott Linderf5b36e52018-12-12 19:39:27 +00003971}
3972
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003973template <class ELFT>
3974void GNUStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
Scott Linder77a5f212018-03-12 19:28:50 +00003975 auto PrintHeader = [&](const typename ELFT::Off Offset,
3976 const typename ELFT::Addr Size) {
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003977 OS << "Displaying notes found at file offset " << format_hex(Offset, 10)
3978 << " with length " << format_hex(Size, 10) << ":\n"
3979 << " Owner Data size\tDescription\n";
Scott Linder77a5f212018-03-12 19:28:50 +00003980 };
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003981
Scott Linder77a5f212018-03-12 19:28:50 +00003982 auto ProcessNote = [&](const Elf_Note &Note) {
3983 StringRef Name = Note.getName();
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00003984 ArrayRef<uint8_t> Descriptor = Note.getDesc();
Scott Linder77a5f212018-03-12 19:28:50 +00003985 Elf_Word Type = Note.getType();
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003986
Scott Linder77a5f212018-03-12 19:28:50 +00003987 OS << " " << Name << std::string(22 - Name.size(), ' ')
3988 << format_hex(Descriptor.size(), 10) << '\t';
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00003989
Scott Linder77a5f212018-03-12 19:28:50 +00003990 if (Name == "GNU") {
3991 OS << getGNUNoteTypeName(Type) << '\n';
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00003992 printGNUNote<ELFT>(OS, Type, Descriptor);
Scott Linder77a5f212018-03-12 19:28:50 +00003993 } else if (Name == "FreeBSD") {
3994 OS << getFreeBSDNoteTypeName(Type) << '\n';
3995 } else if (Name == "AMD") {
Scott Linderf5b36e52018-12-12 19:39:27 +00003996 OS << getAMDNoteTypeName(Type) << '\n';
3997 const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
3998 if (!N.Type.empty())
3999 OS << " " << N.Type << ":\n " << N.Value << '\n';
4000 } else if (Name == "AMDGPU") {
Scott Linder77a5f212018-03-12 19:28:50 +00004001 OS << getAMDGPUNoteTypeName(Type) << '\n';
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004002 const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
Scott Linderf5b36e52018-12-12 19:39:27 +00004003 if (!N.Type.empty())
4004 OS << " " << N.Type << ":\n " << N.Value << '\n';
Scott Linder77a5f212018-03-12 19:28:50 +00004005 } else {
Jordan Rupprecht871baa22019-03-29 16:48:19 +00004006 StringRef NoteType = getGenericNoteTypeName(Type);
4007 if (!NoteType.empty())
4008 OS << NoteType;
4009 else
4010 OS << "Unknown note type: (" << format_hex(Type, 10) << ')';
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00004011 }
Scott Linder77a5f212018-03-12 19:28:50 +00004012 OS << '\n';
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00004013 };
4014
George Rimar1206f5a2019-01-30 15:39:05 +00004015 if (Obj->getHeader()->e_type == ELF::ET_CORE) {
Scott Linder77a5f212018-03-12 19:28:50 +00004016 for (const auto &P : unwrapOrError(Obj->program_headers())) {
4017 if (P.p_type != PT_NOTE)
4018 continue;
4019 PrintHeader(P.p_offset, P.p_filesz);
4020 Error Err = Error::success();
4021 for (const auto &Note : Obj->notes(P, Err))
4022 ProcessNote(Note);
4023 if (Err)
4024 error(std::move(Err));
4025 }
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00004026 } else {
Scott Linder77a5f212018-03-12 19:28:50 +00004027 for (const auto &S : unwrapOrError(Obj->sections())) {
4028 if (S.sh_type != SHT_NOTE)
4029 continue;
4030 PrintHeader(S.sh_offset, S.sh_size);
4031 Error Err = Error::success();
4032 for (const auto &Note : Obj->notes(S, Err))
4033 ProcessNote(Note);
4034 if (Err)
4035 error(std::move(Err));
4036 }
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00004037 }
4038}
4039
Simon Atanasyan62d32592017-12-21 10:26:02 +00004040template <class ELFT>
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +00004041void GNUStyle<ELFT>::printELFLinkerOptions(const ELFFile<ELFT> *Obj) {
4042 OS << "printELFLinkerOptions not implemented!\n";
4043}
4044
4045template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00004046void GNUStyle<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
4047 size_t Bias = ELFT::Is64Bits ? 8 : 0;
4048 auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {
4049 OS.PadToColumn(2);
4050 OS << format_hex_no_prefix(Parser.getGotAddress(E), 8 + Bias);
4051 OS.PadToColumn(11 + Bias);
4052 OS << format_decimal(Parser.getGotOffset(E), 6) << "(gp)";
4053 OS.PadToColumn(22 + Bias);
4054 OS << format_hex_no_prefix(*E, 8 + Bias);
4055 OS.PadToColumn(31 + 2 * Bias);
4056 OS << Purpose << "\n";
4057 };
4058
4059 OS << (Parser.IsStatic ? "Static GOT:\n" : "Primary GOT:\n");
4060 OS << " Canonical gp value: "
4061 << format_hex_no_prefix(Parser.getGp(), 8 + Bias) << "\n\n";
4062
4063 OS << " Reserved entries:\n";
Simon Atanasyane4f01ec2019-05-24 10:26:48 +00004064 if (ELFT::Is64Bits)
4065 OS << " Address Access Initial Purpose\n";
4066 else
4067 OS << " Address Access Initial Purpose\n";
Simon Atanasyan62d32592017-12-21 10:26:02 +00004068 PrintEntry(Parser.getGotLazyResolver(), "Lazy resolver");
4069 if (Parser.getGotModulePointer())
4070 PrintEntry(Parser.getGotModulePointer(), "Module pointer (GNU extension)");
4071
4072 if (!Parser.getLocalEntries().empty()) {
4073 OS << "\n";
4074 OS << " Local entries:\n";
Simon Atanasyane4f01ec2019-05-24 10:26:48 +00004075 if (ELFT::Is64Bits)
4076 OS << " Address Access Initial\n";
4077 else
4078 OS << " Address Access Initial\n";
Simon Atanasyan62d32592017-12-21 10:26:02 +00004079 for (auto &E : Parser.getLocalEntries())
4080 PrintEntry(&E, "");
4081 }
4082
4083 if (Parser.IsStatic)
4084 return;
4085
4086 if (!Parser.getGlobalEntries().empty()) {
4087 OS << "\n";
4088 OS << " Global entries:\n";
Simon Atanasyane4f01ec2019-05-24 10:26:48 +00004089 if (ELFT::Is64Bits)
4090 OS << " Address Access Initial Sym.Val."
4091 << " Type Ndx Name\n";
4092 else
4093 OS << " Address Access Initial Sym.Val. Type Ndx Name\n";
Simon Atanasyan62d32592017-12-21 10:26:02 +00004094 for (auto &E : Parser.getGlobalEntries()) {
4095 const Elf_Sym *Sym = Parser.getGotSym(&E);
4096 std::string SymName = this->dumper()->getFullSymbolName(
4097 Sym, this->dumper()->getDynamicStringTable(), false);
4098
4099 OS.PadToColumn(2);
4100 OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias));
4101 OS.PadToColumn(11 + Bias);
4102 OS << to_string(format_decimal(Parser.getGotOffset(&E), 6)) + "(gp)";
4103 OS.PadToColumn(22 + Bias);
4104 OS << to_string(format_hex_no_prefix(E, 8 + Bias));
4105 OS.PadToColumn(31 + 2 * Bias);
4106 OS << to_string(format_hex_no_prefix(Sym->st_value, 8 + Bias));
4107 OS.PadToColumn(40 + 3 * Bias);
4108 OS << printEnum(Sym->getType(), makeArrayRef(ElfSymbolTypes));
4109 OS.PadToColumn(48 + 3 * Bias);
4110 OS << getSymbolSectionNdx(Parser.Obj, Sym,
4111 this->dumper()->dynamic_symbols().begin());
4112 OS.PadToColumn(52 + 3 * Bias);
4113 OS << SymName << "\n";
4114 }
4115 }
4116
4117 if (!Parser.getOtherEntries().empty())
4118 OS << "\n Number of TLS and multi-GOT entries "
4119 << Parser.getOtherEntries().size() << "\n";
4120}
4121
4122template <class ELFT>
4123void GNUStyle<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
4124 size_t Bias = ELFT::Is64Bits ? 8 : 0;
4125 auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {
4126 OS.PadToColumn(2);
4127 OS << format_hex_no_prefix(Parser.getGotAddress(E), 8 + Bias);
4128 OS.PadToColumn(11 + Bias);
4129 OS << format_hex_no_prefix(*E, 8 + Bias);
4130 OS.PadToColumn(20 + 2 * Bias);
4131 OS << Purpose << "\n";
4132 };
4133
4134 OS << "PLT GOT:\n\n";
4135
4136 OS << " Reserved entries:\n";
4137 OS << " Address Initial Purpose\n";
4138 PrintEntry(Parser.getPltLazyResolver(), "PLT lazy resolver");
4139 if (Parser.getPltModulePointer())
4140 PrintEntry(Parser.getGotModulePointer(), "Module pointer");
4141
4142 if (!Parser.getPltEntries().empty()) {
4143 OS << "\n";
4144 OS << " Entries:\n";
4145 OS << " Address Initial Sym.Val. Type Ndx Name\n";
4146 for (auto &E : Parser.getPltEntries()) {
4147 const Elf_Sym *Sym = Parser.getPltSym(&E);
4148 std::string SymName = this->dumper()->getFullSymbolName(
4149 Sym, this->dumper()->getDynamicStringTable(), false);
4150
4151 OS.PadToColumn(2);
4152 OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias));
4153 OS.PadToColumn(11 + Bias);
4154 OS << to_string(format_hex_no_prefix(E, 8 + Bias));
4155 OS.PadToColumn(20 + 2 * Bias);
4156 OS << to_string(format_hex_no_prefix(Sym->st_value, 8 + Bias));
4157 OS.PadToColumn(29 + 3 * Bias);
4158 OS << printEnum(Sym->getType(), makeArrayRef(ElfSymbolTypes));
4159 OS.PadToColumn(37 + 3 * Bias);
4160 OS << getSymbolSectionNdx(Parser.Obj, Sym,
4161 this->dumper()->dynamic_symbols().begin());
4162 OS.PadToColumn(41 + 3 * Bias);
4163 OS << SymName << "\n";
4164 }
4165 }
4166}
4167
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004168template <class ELFT> void LLVMStyle<ELFT>::printFileHeaders(const ELFO *Obj) {
George Rimar1206f5a2019-01-30 15:39:05 +00004169 const Elf_Ehdr *E = Obj->getHeader();
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00004170 {
4171 DictScope D(W, "ElfHeader");
4172 {
4173 DictScope D(W, "Ident");
George Rimar1206f5a2019-01-30 15:39:05 +00004174 W.printBinary("Magic", makeArrayRef(E->e_ident).slice(ELF::EI_MAG0, 4));
4175 W.printEnum("Class", E->e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
4176 W.printEnum("DataEncoding", E->e_ident[ELF::EI_DATA],
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00004177 makeArrayRef(ElfDataEncoding));
George Rimar1206f5a2019-01-30 15:39:05 +00004178 W.printNumber("FileVersion", E->e_ident[ELF::EI_VERSION]);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00004179
Konstantin Zhuravlyov121125f2017-10-02 20:49:58 +00004180 auto OSABI = makeArrayRef(ElfOSABI);
George Rimar1206f5a2019-01-30 15:39:05 +00004181 if (E->e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH &&
4182 E->e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) {
4183 switch (E->e_machine) {
Konstantin Zhuravlyov121125f2017-10-02 20:49:58 +00004184 case ELF::EM_AMDGPU:
4185 OSABI = makeArrayRef(AMDGPUElfOSABI);
4186 break;
4187 case ELF::EM_ARM:
4188 OSABI = makeArrayRef(ARMElfOSABI);
4189 break;
4190 case ELF::EM_TI_C6000:
4191 OSABI = makeArrayRef(C6000ElfOSABI);
4192 break;
4193 }
4194 }
George Rimar1206f5a2019-01-30 15:39:05 +00004195 W.printEnum("OS/ABI", E->e_ident[ELF::EI_OSABI], OSABI);
4196 W.printNumber("ABIVersion", E->e_ident[ELF::EI_ABIVERSION]);
4197 W.printBinary("Unused", makeArrayRef(E->e_ident).slice(ELF::EI_PAD));
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00004198 }
4199
George Rimar1206f5a2019-01-30 15:39:05 +00004200 W.printEnum("Type", E->e_type, makeArrayRef(ElfObjectFileType));
4201 W.printEnum("Machine", E->e_machine, makeArrayRef(ElfMachineType));
4202 W.printNumber("Version", E->e_version);
4203 W.printHex("Entry", E->e_entry);
4204 W.printHex("ProgramHeaderOffset", E->e_phoff);
4205 W.printHex("SectionHeaderOffset", E->e_shoff);
4206 if (E->e_machine == EM_MIPS)
4207 W.printFlags("Flags", E->e_flags, makeArrayRef(ElfHeaderMipsFlags),
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00004208 unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
4209 unsigned(ELF::EF_MIPS_MACH));
George Rimar1206f5a2019-01-30 15:39:05 +00004210 else if (E->e_machine == EM_AMDGPU)
4211 W.printFlags("Flags", E->e_flags, makeArrayRef(ElfHeaderAMDGPUFlags),
Konstantin Zhuravlyov9122a632018-02-16 22:33:59 +00004212 unsigned(ELF::EF_AMDGPU_MACH));
George Rimar1206f5a2019-01-30 15:39:05 +00004213 else if (E->e_machine == EM_RISCV)
4214 W.printFlags("Flags", E->e_flags, makeArrayRef(ElfHeaderRISCVFlags));
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00004215 else
George Rimar1206f5a2019-01-30 15:39:05 +00004216 W.printFlags("Flags", E->e_flags);
4217 W.printNumber("HeaderSize", E->e_ehsize);
4218 W.printNumber("ProgramHeaderEntrySize", E->e_phentsize);
4219 W.printNumber("ProgramHeaderCount", E->e_phnum);
4220 W.printNumber("SectionHeaderEntrySize", E->e_shentsize);
George Rimar6fdac3b2018-07-18 08:19:58 +00004221 W.printString("SectionHeaderCount", getSectionHeadersNumString(Obj));
George Rimar9e88a262019-05-14 14:22:44 +00004222 W.printString("StringTableSectionIndex",
4223 getSectionHeaderTableIndexString(Obj));
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00004224 }
4225}
Hemant Kulkarni206ba842016-03-09 19:16:13 +00004226
4227template <class ELFT>
4228void LLVMStyle<ELFT>::printGroupSections(const ELFO *Obj) {
4229 DictScope Lists(W, "Groups");
George Rimarea39eed2017-09-14 07:32:52 +00004230 std::vector<GroupSection> V = getGroups<ELFT>(Obj);
George Rimar762abff62017-09-16 14:29:51 +00004231 DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
George Rimarea39eed2017-09-14 07:32:52 +00004232 for (const GroupSection &G : V) {
4233 DictScope D(W, "Group");
4234 W.printNumber("Name", G.Name, G.ShName);
4235 W.printNumber("Index", G.Index);
Alexander Shaposhnikov8febe3d2018-03-12 22:40:09 +00004236 W.printNumber("Link", G.Link);
4237 W.printNumber("Info", G.Info);
George Rimarea39eed2017-09-14 07:32:52 +00004238 W.printHex("Type", getGroupType(G.Type), G.Type);
4239 W.startLine() << "Signature: " << G.Signature << "\n";
4240
4241 ListScope L(W, "Section(s) in group");
George Rimar762abff62017-09-16 14:29:51 +00004242 for (const GroupMember &GM : G.Members) {
4243 const GroupSection *MainGroup = Map[GM.Index];
4244 if (MainGroup != &G) {
4245 W.flush();
4246 errs() << "Error: " << GM.Name << " (" << GM.Index
4247 << ") in a group " + G.Name + " (" << G.Index
4248 << ") is already in a group " + MainGroup->Name + " ("
4249 << MainGroup->Index << ")\n";
4250 errs().flush();
4251 continue;
4252 }
George Rimarea39eed2017-09-14 07:32:52 +00004253 W.startLine() << GM.Name << " (" << GM.Index << ")\n";
George Rimar762abff62017-09-16 14:29:51 +00004254 }
Hemant Kulkarni206ba842016-03-09 19:16:13 +00004255 }
George Rimarea39eed2017-09-14 07:32:52 +00004256
4257 if (V.empty())
Hemant Kulkarni206ba842016-03-09 19:16:13 +00004258 W.startLine() << "There are no group sections in the file.\n";
4259}
George Rimar762abff62017-09-16 14:29:51 +00004260
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004261template <class ELFT> void LLVMStyle<ELFT>::printRelocations(const ELFO *Obj) {
4262 ListScope D(W, "Relocations");
4263
4264 int SectionNumber = -1;
Rafael Espindola25be8c82016-11-02 14:10:57 +00004265 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004266 ++SectionNumber;
4267
George Rimar9e88a262019-05-14 14:22:44 +00004268 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA &&
4269 Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_REL &&
Jake Ehrlich0f440d82018-06-28 21:07:34 +00004270 Sec.sh_type != ELF::SHT_ANDROID_RELA &&
4271 Sec.sh_type != ELF::SHT_ANDROID_RELR)
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004272 continue;
4273
4274 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
4275
4276 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
4277 W.indent();
4278
4279 printRelocations(&Sec, Obj);
4280
4281 W.unindent();
4282 W.startLine() << "}\n";
4283 }
4284}
4285
4286template <class ELFT>
4287void LLVMStyle<ELFT>::printRelocations(const Elf_Shdr *Sec, const ELFO *Obj) {
4288 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link));
4289
4290 switch (Sec->sh_type) {
4291 case ELF::SHT_REL:
Rafael Espindola354680a2016-11-03 19:07:15 +00004292 for (const Elf_Rel &R : unwrapOrError(Obj->rels(Sec))) {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004293 Elf_Rela Rela;
4294 Rela.r_offset = R.r_offset;
4295 Rela.r_info = R.r_info;
4296 Rela.r_addend = 0;
4297 printRelocation(Obj, Rela, SymTab);
4298 }
4299 break;
4300 case ELF::SHT_RELA:
Rafael Espindola354680a2016-11-03 19:07:15 +00004301 for (const Elf_Rela &R : unwrapOrError(Obj->relas(Sec)))
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004302 printRelocation(Obj, R, SymTab);
4303 break;
Jake Ehrlich0f440d82018-06-28 21:07:34 +00004304 case ELF::SHT_RELR:
4305 case ELF::SHT_ANDROID_RELR: {
4306 Elf_Relr_Range Relrs = unwrapOrError(Obj->relrs(Sec));
4307 if (opts::RawRelr) {
4308 for (const Elf_Relr &R : Relrs)
4309 W.startLine() << W.hex(R) << "\n";
4310 } else {
4311 std::vector<Elf_Rela> RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
4312 for (const Elf_Rela &R : RelrRelas)
4313 printRelocation(Obj, R, SymTab);
4314 }
4315 break;
4316 }
Peter Collingbourne689e6c052017-10-25 03:37:12 +00004317 case ELF::SHT_ANDROID_REL:
4318 case ELF::SHT_ANDROID_RELA:
4319 for (const Elf_Rela &R : unwrapOrError(Obj->android_relas(Sec)))
4320 printRelocation(Obj, R, SymTab);
4321 break;
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004322 }
4323}
4324
4325template <class ELFT>
4326void LLVMStyle<ELFT>::printRelocation(const ELFO *Obj, Elf_Rela Rel,
4327 const Elf_Shdr *SymTab) {
4328 SmallString<32> RelocName;
4329 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
James Hendersone50d9cb2019-01-17 15:34:12 +00004330 std::string TargetName;
Rafael Espindolaed1395a2016-11-03 18:05:33 +00004331 const Elf_Sym *Sym = unwrapOrError(Obj->getRelocationSymbol(&Rel, SymTab));
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004332 if (Sym && Sym->getType() == ELF::STT_SECTION) {
4333 const Elf_Shdr *Sec = unwrapOrError(
4334 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
4335 TargetName = unwrapOrError(Obj->getSectionName(Sec));
4336 } else if (Sym) {
4337 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
Xing GUOeec32062019-03-12 14:30:13 +00004338 TargetName = this->dumper()->getFullSymbolName(
4339 Sym, StrTable, SymTab->sh_type == SHT_DYNSYM /* IsDynamic */);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004340 }
4341
4342 if (opts::ExpandRelocs) {
4343 DictScope Group(W, "Relocation");
4344 W.printHex("Offset", Rel.r_offset);
4345 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
Eugene Zelenko416e0592017-06-09 21:41:54 +00004346 W.printNumber("Symbol", !TargetName.empty() ? TargetName : "-",
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004347 Rel.getSymbol(Obj->isMips64EL()));
4348 W.printHex("Addend", Rel.r_addend);
4349 } else {
4350 raw_ostream &OS = W.startLine();
4351 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
George Rimar9e88a262019-05-14 14:22:44 +00004352 << (!TargetName.empty() ? TargetName : "-") << " " << W.hex(Rel.r_addend)
4353 << "\n";
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004354 }
4355}
4356
Jordan Rupprechtdbf552c2018-11-12 18:02:38 +00004357template <class ELFT>
4358void LLVMStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004359 ListScope SectionsD(W, "Sections");
4360
4361 int SectionIndex = -1;
Rafael Espindola25be8c82016-11-02 14:10:57 +00004362 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004363 ++SectionIndex;
4364
4365 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
4366
4367 DictScope SectionD(W, "Section");
4368 W.printNumber("Index", SectionIndex);
4369 W.printNumber("Name", Name, Sec.sh_name);
Rafael Espindola3ba25732017-05-02 14:04:52 +00004370 W.printHex(
4371 "Type",
4372 object::getELFSectionTypeName(Obj->getHeader()->e_machine, Sec.sh_type),
4373 Sec.sh_type);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004374 std::vector<EnumEntry<unsigned>> SectionFlags(std::begin(ElfSectionFlags),
4375 std::end(ElfSectionFlags));
4376 switch (Obj->getHeader()->e_machine) {
Prakhar Bahuguna52a7dd72016-12-15 07:59:08 +00004377 case EM_ARM:
4378 SectionFlags.insert(SectionFlags.end(), std::begin(ElfARMSectionFlags),
4379 std::end(ElfARMSectionFlags));
4380 break;
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004381 case EM_HEXAGON:
4382 SectionFlags.insert(SectionFlags.end(),
4383 std::begin(ElfHexagonSectionFlags),
4384 std::end(ElfHexagonSectionFlags));
4385 break;
4386 case EM_MIPS:
4387 SectionFlags.insert(SectionFlags.end(), std::begin(ElfMipsSectionFlags),
4388 std::end(ElfMipsSectionFlags));
4389 break;
4390 case EM_X86_64:
4391 SectionFlags.insert(SectionFlags.end(), std::begin(ElfX86_64SectionFlags),
4392 std::end(ElfX86_64SectionFlags));
4393 break;
George Rimarc13c59a2016-05-21 10:16:58 +00004394 case EM_XCORE:
4395 SectionFlags.insert(SectionFlags.end(), std::begin(ElfXCoreSectionFlags),
4396 std::end(ElfXCoreSectionFlags));
4397 break;
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004398 default:
4399 // Nothing to do.
4400 break;
4401 }
4402 W.printFlags("Flags", Sec.sh_flags, makeArrayRef(SectionFlags));
4403 W.printHex("Address", Sec.sh_addr);
4404 W.printHex("Offset", Sec.sh_offset);
4405 W.printNumber("Size", Sec.sh_size);
4406 W.printNumber("Link", Sec.sh_link);
4407 W.printNumber("Info", Sec.sh_info);
4408 W.printNumber("AddressAlignment", Sec.sh_addralign);
4409 W.printNumber("EntrySize", Sec.sh_entsize);
4410
4411 if (opts::SectionRelocations) {
4412 ListScope D(W, "Relocations");
4413 printRelocations(&Sec, Obj);
4414 }
4415
4416 if (opts::SectionSymbols) {
4417 ListScope D(W, "Symbols");
4418 const Elf_Shdr *Symtab = this->dumper()->getDotSymtabSec();
4419 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
4420
Rafael Espindola9ea68342016-11-03 13:43:30 +00004421 for (const Elf_Sym &Sym : unwrapOrError(Obj->symbols(Symtab))) {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004422 const Elf_Shdr *SymSec = unwrapOrError(
4423 Obj->getSection(&Sym, Symtab, this->dumper()->getShndxTable()));
4424 if (SymSec == &Sec)
Rafael Espindola9ea68342016-11-03 13:43:30 +00004425 printSymbol(Obj, &Sym, unwrapOrError(Obj->symbols(Symtab)).begin(),
4426 StrTable, false);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004427 }
4428 }
4429
4430 if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
4431 ArrayRef<uint8_t> Data = unwrapOrError(Obj->getSectionContents(&Sec));
Xing GUO0df95d22019-04-08 11:48:36 +00004432 W.printBinaryBlock(
4433 "SectionData",
4434 StringRef(reinterpret_cast<const char *>(Data.data()), Data.size()));
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004435 }
4436 }
4437}
4438
4439template <class ELFT>
4440void LLVMStyle<ELFT>::printSymbol(const ELFO *Obj, const Elf_Sym *Symbol,
4441 const Elf_Sym *First, StringRef StrTable,
4442 bool IsDynamic) {
4443 unsigned SectionIndex = 0;
4444 StringRef SectionName;
Simon Atanasyan62d32592017-12-21 10:26:02 +00004445 this->dumper()->getSectionNameIndex(Symbol, First, SectionName, SectionIndex);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004446 std::string FullSymbolName =
4447 this->dumper()->getFullSymbolName(Symbol, StrTable, IsDynamic);
4448 unsigned char SymbolType = Symbol->getType();
4449
4450 DictScope D(W, "Symbol");
4451 W.printNumber("Name", FullSymbolName, Symbol->st_name);
4452 W.printHex("Value", Symbol->st_value);
4453 W.printNumber("Size", Symbol->st_size);
4454 W.printEnum("Binding", Symbol->getBinding(), makeArrayRef(ElfSymbolBindings));
4455 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU &&
4456 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
4457 W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
4458 else
4459 W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
Simon Atanasyanb7807a02016-03-24 16:10:37 +00004460 if (Symbol->st_other == 0)
4461 // Usually st_other flag is zero. Do not pollute the output
4462 // by flags enumeration in that case.
4463 W.printNumber("Other", 0);
4464 else {
4465 std::vector<EnumEntry<unsigned>> SymOtherFlags(std::begin(ElfSymOtherFlags),
4466 std::end(ElfSymOtherFlags));
4467 if (Obj->getHeader()->e_machine == EM_MIPS) {
4468 // Someones in their infinite wisdom decided to make STO_MIPS_MIPS16
4469 // flag overlapped with other ST_MIPS_xxx flags. So consider both
4470 // cases separately.
4471 if ((Symbol->st_other & STO_MIPS_MIPS16) == STO_MIPS_MIPS16)
4472 SymOtherFlags.insert(SymOtherFlags.end(),
4473 std::begin(ElfMips16SymOtherFlags),
4474 std::end(ElfMips16SymOtherFlags));
4475 else
4476 SymOtherFlags.insert(SymOtherFlags.end(),
4477 std::begin(ElfMipsSymOtherFlags),
4478 std::end(ElfMipsSymOtherFlags));
4479 }
4480 W.printFlags("Other", Symbol->st_other, makeArrayRef(SymOtherFlags), 0x3u);
4481 }
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004482 W.printHex("Section", SectionName, SectionIndex);
4483}
4484
James Henderson21ed8682019-01-23 16:15:39 +00004485template <class ELFT>
4486void LLVMStyle<ELFT>::printSymbols(const ELFO *Obj, bool PrintSymbols,
4487 bool PrintDynamicSymbols) {
4488 if (PrintSymbols)
4489 printSymbols(Obj);
4490 if (PrintDynamicSymbols)
4491 printDynamicSymbols(Obj);
4492}
4493
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004494template <class ELFT> void LLVMStyle<ELFT>::printSymbols(const ELFO *Obj) {
4495 ListScope Group(W, "Symbols");
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00004496 this->dumper()->printSymbolsHelper(false);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004497}
4498
4499template <class ELFT>
4500void LLVMStyle<ELFT>::printDynamicSymbols(const ELFO *Obj) {
4501 ListScope Group(W, "DynamicSymbols");
Hemant Kulkarnia11fbe12016-03-21 17:18:23 +00004502 this->dumper()->printSymbolsHelper(true);
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004503}
4504
4505template <class ELFT>
4506void LLVMStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
4507 const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
4508 const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
Jake Ehrlich0f440d82018-06-28 21:07:34 +00004509 const DynRegionInfo &DynRelrRegion = this->dumper()->getDynRelrRegion();
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004510 const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
4511 if (DynRelRegion.Size && DynRelaRegion.Size)
4512 report_fatal_error("There are both REL and RELA dynamic relocations");
4513 W.startLine() << "Dynamic Relocations {\n";
4514 W.indent();
4515 if (DynRelaRegion.Size > 0)
4516 for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
4517 printDynamicRelocation(Obj, Rela);
4518 else
4519 for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
4520 Elf_Rela Rela;
4521 Rela.r_offset = Rel.r_offset;
4522 Rela.r_info = Rel.r_info;
4523 Rela.r_addend = 0;
4524 printDynamicRelocation(Obj, Rela);
4525 }
Jake Ehrlich0f440d82018-06-28 21:07:34 +00004526 if (DynRelrRegion.Size > 0) {
4527 Elf_Relr_Range Relrs = this->dumper()->dyn_relrs();
4528 std::vector<Elf_Rela> RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
4529 for (const Elf_Rela &Rela : RelrRelas)
4530 printDynamicRelocation(Obj, Rela);
4531 }
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004532 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
Rafael Espindolaaafcf752016-04-05 14:47:22 +00004533 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef<Elf_Rela>())
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004534 printDynamicRelocation(Obj, Rela);
4535 else
Rafael Espindolaaafcf752016-04-05 14:47:22 +00004536 for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef<Elf_Rel>()) {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004537 Elf_Rela Rela;
4538 Rela.r_offset = Rel.r_offset;
4539 Rela.r_info = Rel.r_info;
4540 Rela.r_addend = 0;
4541 printDynamicRelocation(Obj, Rela);
4542 }
4543 W.unindent();
4544 W.startLine() << "}\n";
4545}
4546
4547template <class ELFT>
4548void LLVMStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel) {
4549 SmallString<32> RelocName;
4550 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
James Hendersone50d9cb2019-01-17 15:34:12 +00004551 std::string SymbolName;
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004552 uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
4553 const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex;
James Hendersone50d9cb2019-01-17 15:34:12 +00004554 SymbolName = maybeDemangle(
4555 unwrapOrError(Sym->getName(this->dumper()->getDynamicStringTable())));
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004556 if (opts::ExpandRelocs) {
4557 DictScope Group(W, "Relocation");
4558 W.printHex("Offset", Rel.r_offset);
4559 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
Eugene Zelenko416e0592017-06-09 21:41:54 +00004560 W.printString("Symbol", !SymbolName.empty() ? SymbolName : "-");
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004561 W.printHex("Addend", Rel.r_addend);
4562 } else {
4563 raw_ostream &OS = W.startLine();
4564 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
George Rimar9e88a262019-05-14 14:22:44 +00004565 << (!SymbolName.empty() ? SymbolName : "-") << " " << W.hex(Rel.r_addend)
4566 << "\n";
Hemant Kulkarnic030f232016-03-15 17:25:31 +00004567 }
4568}
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00004569
4570template <class ELFT>
Matt Davis50ca8ed2019-02-01 18:51:10 +00004571void LLVMStyle<ELFT>::printProgramHeaders(
4572 const ELFO *Obj, bool PrintProgramHeaders,
4573 cl::boolOrDefault PrintSectionMapping) {
4574 if (PrintProgramHeaders)
4575 printProgramHeaders(Obj);
4576 if (PrintSectionMapping == cl::BOU_TRUE)
4577 printSectionMapping(Obj);
4578}
4579
4580template <class ELFT>
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00004581void LLVMStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
4582 ListScope L(W, "ProgramHeaders");
4583
Rafael Espindola6a494972016-11-03 17:28:33 +00004584 for (const Elf_Phdr &Phdr : unwrapOrError(Obj->program_headers())) {
Hemant Kulkarni966b3ac2016-03-25 16:04:48 +00004585 DictScope P(W, "ProgramHeader");
4586 W.printHex("Type",
4587 getElfSegmentType(Obj->getHeader()->e_machine, Phdr.p_type),
4588 Phdr.p_type);
4589 W.printHex("Offset", Phdr.p_offset);
4590 W.printHex("VirtualAddress", Phdr.p_vaddr);
4591 W.printHex("PhysicalAddress", Phdr.p_paddr);
4592 W.printNumber("FileSize", Phdr.p_filesz);
4593 W.printNumber("MemSize", Phdr.p_memsz);
4594 W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags));
4595 W.printNumber("Alignment", Phdr.p_align);
4596 }
4597}
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00004598
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00004599template <class ELFT>
Xing GUOea16be12019-03-25 11:02:49 +00004600void LLVMStyle<ELFT>::printVersionSymbolSection(const ELFFile<ELFT> *Obj,
4601 const Elf_Shdr *Sec) {
4602 DictScope SS(W, "Version symbols");
4603 if (!Sec)
4604 return;
4605
4606 StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
4607 W.printNumber("Section Name", SecName, Sec->sh_name);
4608 W.printHex("Address", Sec->sh_addr);
4609 W.printHex("Offset", Sec->sh_offset);
4610 W.printNumber("Link", Sec->sh_link);
4611
Xing GUO0df95d22019-04-08 11:48:36 +00004612 const uint8_t *VersymBuf =
4613 reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset);
Xing GUOea16be12019-03-25 11:02:49 +00004614 const ELFDumper<ELFT> *Dumper = this->dumper();
4615 StringRef StrTable = Dumper->getDynamicStringTable();
4616
4617 // Same number of entries in the dynamic symbol table (DT_SYMTAB).
4618 ListScope Syms(W, "Symbols");
4619 for (const Elf_Sym &Sym : Dumper->dynamic_symbols()) {
4620 DictScope S(W, "Symbol");
4621 const Elf_Versym *Versym = reinterpret_cast<const Elf_Versym *>(VersymBuf);
4622 std::string FullSymbolName =
4623 Dumper->getFullSymbolName(&Sym, StrTable, true /* IsDynamic */);
4624 W.printNumber("Version", Versym->vs_index & VERSYM_VERSION);
4625 W.printString("Name", FullSymbolName);
4626 VersymBuf += sizeof(Elf_Versym);
4627 }
4628}
4629
4630template <class ELFT>
4631void LLVMStyle<ELFT>::printVersionDefinitionSection(const ELFFile<ELFT> *Obj,
4632 const Elf_Shdr *Sec) {
4633 DictScope SD(W, "SHT_GNU_verdef");
4634 if (!Sec)
4635 return;
4636
4637 const uint8_t *SecStartAddress =
Xing GUO0df95d22019-04-08 11:48:36 +00004638 reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset);
Xing GUOea16be12019-03-25 11:02:49 +00004639 const uint8_t *SecEndAddress = SecStartAddress + Sec->sh_size;
4640 const uint8_t *VerdefBuf = SecStartAddress;
4641 const Elf_Shdr *StrTab = unwrapOrError(Obj->getSection(Sec->sh_link));
4642
4643 unsigned VerDefsNum = Sec->sh_info;
4644 while (VerDefsNum--) {
4645 if (VerdefBuf + sizeof(Elf_Verdef) > SecEndAddress)
4646 // FIXME: report_fatal_error is not a good way to report error. We should
4647 // emit a parsing error here and below.
4648 report_fatal_error("invalid offset in the section");
4649
4650 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);
4651 DictScope Def(W, "Definition");
4652 W.printNumber("Version", Verdef->vd_version);
4653 W.printEnum("Flags", Verdef->vd_flags, makeArrayRef(SymVersionFlags));
4654 W.printNumber("Index", Verdef->vd_ndx);
4655 W.printNumber("Hash", Verdef->vd_hash);
Xing GUO0df95d22019-04-08 11:48:36 +00004656 W.printString("Name", StringRef(reinterpret_cast<const char *>(
4657 Obj->base() + StrTab->sh_offset +
4658 Verdef->getAux()->vda_name)));
Xing GUOea16be12019-03-25 11:02:49 +00004659 if (!Verdef->vd_cnt)
4660 report_fatal_error("at least one definition string must exist");
4661 if (Verdef->vd_cnt > 2)
4662 report_fatal_error("more than one predecessor is not expected");
4663
4664 if (Verdef->vd_cnt == 2) {
4665 const uint8_t *VerdauxBuf =
4666 VerdefBuf + Verdef->vd_aux + Verdef->getAux()->vda_next;
4667 const Elf_Verdaux *Verdaux =
4668 reinterpret_cast<const Elf_Verdaux *>(VerdauxBuf);
4669 W.printString("Predecessor",
Xing GUO0df95d22019-04-08 11:48:36 +00004670 StringRef(reinterpret_cast<const char *>(
4671 Obj->base() + StrTab->sh_offset + Verdaux->vda_name)));
Xing GUOea16be12019-03-25 11:02:49 +00004672 }
4673 VerdefBuf += Verdef->vd_next;
4674 }
4675}
4676
4677template <class ELFT>
4678void LLVMStyle<ELFT>::printVersionDependencySection(const ELFFile<ELFT> *Obj,
4679 const Elf_Shdr *Sec) {
4680 DictScope SD(W, "SHT_GNU_verneed");
4681 if (!Sec)
4682 return;
4683
Xing GUO0df95d22019-04-08 11:48:36 +00004684 const uint8_t *SecData =
4685 reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset);
Xing GUOea16be12019-03-25 11:02:49 +00004686 const Elf_Shdr *StrTab = unwrapOrError(Obj->getSection(Sec->sh_link));
4687
4688 const uint8_t *VerneedBuf = SecData;
4689 unsigned VerneedNum = Sec->sh_info;
4690 for (unsigned I = 0; I < VerneedNum; ++I) {
4691 const Elf_Verneed *Verneed =
4692 reinterpret_cast<const Elf_Verneed *>(VerneedBuf);
4693 DictScope Entry(W, "Dependency");
4694 W.printNumber("Version", Verneed->vn_version);
4695 W.printNumber("Count", Verneed->vn_cnt);
4696 W.printString("FileName",
Xing GUO0df95d22019-04-08 11:48:36 +00004697 StringRef(reinterpret_cast<const char *>(
4698 Obj->base() + StrTab->sh_offset + Verneed->vn_file)));
Xing GUOea16be12019-03-25 11:02:49 +00004699
4700 const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;
Xing GUO8ab74142019-04-10 12:47:21 +00004701 ListScope L(W, "Entries");
Xing GUOea16be12019-03-25 11:02:49 +00004702 for (unsigned J = 0; J < Verneed->vn_cnt; ++J) {
4703 const Elf_Vernaux *Vernaux =
4704 reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);
4705 DictScope Entry(W, "Entry");
4706 W.printNumber("Hash", Vernaux->vna_hash);
4707 W.printEnum("Flags", Vernaux->vna_flags, makeArrayRef(SymVersionFlags));
4708 W.printNumber("Index", Vernaux->vna_other);
4709 W.printString("Name",
Xing GUO0df95d22019-04-08 11:48:36 +00004710 StringRef(reinterpret_cast<const char *>(
4711 Obj->base() + StrTab->sh_offset + Vernaux->vna_name)));
Xing GUOea16be12019-03-25 11:02:49 +00004712 VernauxBuf += Vernaux->vna_next;
4713 }
4714 VerneedBuf += Verneed->vn_next;
4715 }
4716}
4717
4718template <class ELFT>
Hemant Kulkarni9b1b7f02016-04-11 17:15:30 +00004719void LLVMStyle<ELFT>::printHashHistogram(const ELFFile<ELFT> *Obj) {
4720 W.startLine() << "Hash Histogram not implemented!\n";
4721}
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00004722
4723template <class ELFT>
Michael J. Spencerae6eeae2018-06-02 16:33:01 +00004724void LLVMStyle<ELFT>::printCGProfile(const ELFFile<ELFT> *Obj) {
4725 ListScope L(W, "CGProfile");
4726 if (!this->dumper()->getDotCGProfileSec())
4727 return;
4728 auto CGProfile =
4729 unwrapOrError(Obj->template getSectionContentsAsArray<Elf_CGProfile>(
4730 this->dumper()->getDotCGProfileSec()));
4731 for (const Elf_CGProfile &CGPE : CGProfile) {
4732 DictScope D(W, "CGProfileEntry");
4733 W.printNumber("From", this->dumper()->getStaticSymbolName(CGPE.cgp_from),
4734 CGPE.cgp_from);
4735 W.printNumber("To", this->dumper()->getStaticSymbolName(CGPE.cgp_to),
4736 CGPE.cgp_to);
4737 W.printNumber("Weight", CGPE.cgp_weight);
4738 }
4739}
4740
4741template <class ELFT>
Peter Collingbourne3e227332018-07-17 22:17:18 +00004742void LLVMStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
4743 ListScope L(W, "Addrsig");
4744 if (!this->dumper()->getDotAddrsigSec())
4745 return;
4746 ArrayRef<uint8_t> Contents = unwrapOrError(
4747 Obj->getSectionContents(this->dumper()->getDotAddrsigSec()));
4748 const uint8_t *Cur = Contents.begin();
4749 const uint8_t *End = Contents.end();
4750 while (Cur != End) {
4751 unsigned Size;
4752 const char *Err;
Peter Collingbourne7d179082018-08-21 17:18:18 +00004753 uint64_t SymIndex = decodeULEB128(Cur, &Size, End, &Err);
Peter Collingbourne3e227332018-07-17 22:17:18 +00004754 if (Err)
4755 reportError(Err);
4756 W.printNumber("Sym", this->dumper()->getStaticSymbolName(SymIndex),
4757 SymIndex);
4758 Cur += Size;
4759 }
4760}
4761
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004762template <typename ELFT>
George Rimar9e88a262019-05-14 14:22:44 +00004763static void printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004764 ScopedPrinter &W) {
4765 switch (NoteType) {
4766 default:
4767 return;
4768 case ELF::NT_GNU_ABI_TAG: {
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00004769 const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004770 if (!AbiTag.IsValid) {
4771 W.printString("ABI", "<corrupt GNU_ABI_TAG>");
4772 } else {
4773 W.printString("OS", AbiTag.OSName);
4774 W.printString("ABI", AbiTag.ABI);
4775 }
4776 break;
4777 }
4778 case ELF::NT_GNU_BUILD_ID: {
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00004779 W.printString("Build ID", getGNUBuildId(Desc));
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004780 break;
4781 }
4782 case ELF::NT_GNU_GOLD_VERSION:
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00004783 W.printString("Version", getGNUGoldVersion(Desc));
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004784 break;
4785 case ELF::NT_GNU_PROPERTY_TYPE_0:
4786 ListScope D(W, "Property");
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00004787 for (const auto &Property : getGNUPropertyList<ELFT>(Desc))
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004788 W.printString(Property);
4789 break;
4790 }
4791}
4792
Peter Collingbourne3e227332018-07-17 22:17:18 +00004793template <class ELFT>
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00004794void LLVMStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004795 ListScope L(W, "Notes");
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004796
4797 auto PrintHeader = [&](const typename ELFT::Off Offset,
4798 const typename ELFT::Addr Size) {
4799 W.printHex("Offset", Offset);
4800 W.printHex("Size", Size);
4801 };
4802
4803 auto ProcessNote = [&](const Elf_Note &Note) {
4804 DictScope D2(W, "Note");
4805 StringRef Name = Note.getName();
Jake Ehrlichee7ec6c2018-11-13 01:10:35 +00004806 ArrayRef<uint8_t> Descriptor = Note.getDesc();
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004807 Elf_Word Type = Note.getType();
4808
4809 W.printString("Owner", Name);
4810 W.printHex("Data size", Descriptor.size());
4811 if (Name == "GNU") {
4812 W.printString("Type", getGNUNoteTypeName(Type));
4813 printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W);
4814 } else if (Name == "FreeBSD") {
4815 W.printString("Type", getFreeBSDNoteTypeName(Type));
4816 } else if (Name == "AMD") {
Scott Linderf5b36e52018-12-12 19:39:27 +00004817 W.printString("Type", getAMDNoteTypeName(Type));
4818 const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
4819 if (!N.Type.empty())
4820 W.printString(N.Type, N.Value);
4821 } else if (Name == "AMDGPU") {
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004822 W.printString("Type", getAMDGPUNoteTypeName(Type));
4823 const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
Scott Linderf5b36e52018-12-12 19:39:27 +00004824 if (!N.Type.empty())
4825 W.printString(N.Type, N.Value);
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004826 } else {
Jordan Rupprecht871baa22019-03-29 16:48:19 +00004827 StringRef NoteType = getGenericNoteTypeName(Type);
4828 if (!NoteType.empty())
4829 W.printString("Type", NoteType);
4830 else
4831 W.printString("Type",
4832 "Unknown (" + to_string(format_hex(Type, 10)) + ")");
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004833 }
4834 };
4835
George Rimar1206f5a2019-01-30 15:39:05 +00004836 if (Obj->getHeader()->e_type == ELF::ET_CORE) {
Jordan Rupprecht4f36c7a2018-11-07 23:53:50 +00004837 for (const auto &P : unwrapOrError(Obj->program_headers())) {
4838 if (P.p_type != PT_NOTE)
4839 continue;
4840 DictScope D(W, "NoteSection");
4841 PrintHeader(P.p_offset, P.p_filesz);
4842 Error Err = Error::success();
4843 for (const auto &Note : Obj->notes(P, Err))
4844 ProcessNote(Note);
4845 if (Err)
4846 error(std::move(Err));
4847 }
4848 } else {
4849 for (const auto &S : unwrapOrError(Obj->sections())) {
4850 if (S.sh_type != SHT_NOTE)
4851 continue;
4852 DictScope D(W, "NoteSection");
4853 PrintHeader(S.sh_offset, S.sh_size);
4854 Error Err = Error::success();
4855 for (const auto &Note : Obj->notes(S, Err))
4856 ProcessNote(Note);
4857 if (Err)
4858 error(std::move(Err));
4859 }
4860 }
Saleem Abdulrasool6a405442016-08-30 18:52:02 +00004861}
Simon Atanasyan62d32592017-12-21 10:26:02 +00004862
4863template <class ELFT>
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +00004864void LLVMStyle<ELFT>::printELFLinkerOptions(const ELFFile<ELFT> *Obj) {
4865 ListScope L(W, "LinkerOptions");
4866
4867 for (const Elf_Shdr &Shdr : unwrapOrError(Obj->sections())) {
4868 if (Shdr.sh_type != ELF::SHT_LLVM_LINKER_OPTIONS)
4869 continue;
4870
4871 ArrayRef<uint8_t> Contents = unwrapOrError(Obj->getSectionContents(&Shdr));
George Rimarec895f12019-05-16 06:22:51 +00004872 for (const uint8_t *P = Contents.begin(), *E = Contents.end(); P < E; ) {
Saleem Abdulrasoolb36fbbc2018-01-30 16:29:29 +00004873 StringRef Key = StringRef(reinterpret_cast<const char *>(P));
4874 StringRef Value =
4875 StringRef(reinterpret_cast<const char *>(P) + Key.size() + 1);
4876
4877 W.printString(Key, Value);
4878
4879 P = P + Key.size() + Value.size() + 2;
4880 }
4881 }
4882}
4883
4884template <class ELFT>
Simon Atanasyan62d32592017-12-21 10:26:02 +00004885void LLVMStyle<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
4886 auto PrintEntry = [&](const Elf_Addr *E) {
4887 W.printHex("Address", Parser.getGotAddress(E));
4888 W.printNumber("Access", Parser.getGotOffset(E));
4889 W.printHex("Initial", *E);
4890 };
4891
4892 DictScope GS(W, Parser.IsStatic ? "Static GOT" : "Primary GOT");
4893
4894 W.printHex("Canonical gp value", Parser.getGp());
4895 {
4896 ListScope RS(W, "Reserved entries");
4897 {
4898 DictScope D(W, "Entry");
4899 PrintEntry(Parser.getGotLazyResolver());
4900 W.printString("Purpose", StringRef("Lazy resolver"));
4901 }
4902
4903 if (Parser.getGotModulePointer()) {
4904 DictScope D(W, "Entry");
4905 PrintEntry(Parser.getGotModulePointer());
4906 W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
4907 }
4908 }
4909 {
4910 ListScope LS(W, "Local entries");
4911 for (auto &E : Parser.getLocalEntries()) {
4912 DictScope D(W, "Entry");
4913 PrintEntry(&E);
4914 }
4915 }
4916
4917 if (Parser.IsStatic)
4918 return;
4919
4920 {
4921 ListScope GS(W, "Global entries");
4922 for (auto &E : Parser.getGlobalEntries()) {
4923 DictScope D(W, "Entry");
4924
4925 PrintEntry(&E);
4926
4927 const Elf_Sym *Sym = Parser.getGotSym(&E);
4928 W.printHex("Value", Sym->st_value);
4929 W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes));
4930
4931 unsigned SectionIndex = 0;
4932 StringRef SectionName;
4933 this->dumper()->getSectionNameIndex(
4934 Sym, this->dumper()->dynamic_symbols().begin(), SectionName,
4935 SectionIndex);
4936 W.printHex("Section", SectionName, SectionIndex);
4937
4938 std::string SymName = this->dumper()->getFullSymbolName(
4939 Sym, this->dumper()->getDynamicStringTable(), true);
4940 W.printNumber("Name", SymName, Sym->st_name);
4941 }
4942 }
4943
4944 W.printNumber("Number of TLS and multi-GOT entries",
Simon Atanasyan4e945b62017-12-21 10:46:20 +00004945 uint64_t(Parser.getOtherEntries().size()));
Simon Atanasyan62d32592017-12-21 10:26:02 +00004946}
4947
4948template <class ELFT>
4949void LLVMStyle<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
4950 auto PrintEntry = [&](const Elf_Addr *E) {
4951 W.printHex("Address", Parser.getPltAddress(E));
4952 W.printHex("Initial", *E);
4953 };
4954
4955 DictScope GS(W, "PLT GOT");
4956
4957 {
4958 ListScope RS(W, "Reserved entries");
4959 {
4960 DictScope D(W, "Entry");
4961 PrintEntry(Parser.getPltLazyResolver());
4962 W.printString("Purpose", StringRef("PLT lazy resolver"));
4963 }
4964
4965 if (auto E = Parser.getPltModulePointer()) {
4966 DictScope D(W, "Entry");
4967 PrintEntry(E);
4968 W.printString("Purpose", StringRef("Module pointer"));
4969 }
4970 }
4971 {
4972 ListScope LS(W, "Entries");
4973 for (auto &E : Parser.getPltEntries()) {
4974 DictScope D(W, "Entry");
4975 PrintEntry(&E);
4976
4977 const Elf_Sym *Sym = Parser.getPltSym(&E);
4978 W.printHex("Value", Sym->st_value);
4979 W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes));
4980
4981 unsigned SectionIndex = 0;
4982 StringRef SectionName;
4983 this->dumper()->getSectionNameIndex(
4984 Sym, this->dumper()->dynamic_symbols().begin(), SectionName,
4985 SectionIndex);
4986 W.printHex("Section", SectionName, SectionIndex);
4987
4988 std::string SymName =
4989 this->dumper()->getFullSymbolName(Sym, Parser.getPltStrTable(), true);
4990 W.printNumber("Name", SymName, Sym->st_name);
4991 }
4992 }
4993}