1 //===- ELFDumper.cpp - ELF-specific dumper --------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file implements the ELF-specific dumper for llvm-readobj.
12 //===----------------------------------------------------------------------===//
14 #include "ARMEHABIPrinter.h"
15 #include "DwarfCFIEHPrinter.h"
17 #include "ObjDumper.h"
18 #include "StackMapPrinter.h"
19 #include "llvm-readobj.h"
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/DenseSet.h"
23 #include "llvm/ADT/MapVector.h"
24 #include "llvm/ADT/Optional.h"
25 #include "llvm/ADT/PointerIntPair.h"
26 #include "llvm/ADT/STLExtras.h"
27 #include "llvm/ADT/SmallString.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/ADT/StringExtras.h"
30 #include "llvm/ADT/StringRef.h"
31 #include "llvm/ADT/Twine.h"
32 #include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h"
33 #include "llvm/BinaryFormat/ELF.h"
34 #include "llvm/Demangle/Demangle.h"
35 #include "llvm/Object/ELF.h"
36 #include "llvm/Object/ELFObjectFile.h"
37 #include "llvm/Object/ELFTypes.h"
38 #include "llvm/Object/Error.h"
39 #include "llvm/Object/ObjectFile.h"
40 #include "llvm/Object/RelocationResolver.h"
41 #include "llvm/Object/StackMapParser.h"
42 #include "llvm/Support/AMDGPUMetadata.h"
43 #include "llvm/Support/ARMAttributeParser.h"
44 #include "llvm/Support/ARMBuildAttributes.h"
45 #include "llvm/Support/Casting.h"
46 #include "llvm/Support/Compiler.h"
47 #include "llvm/Support/Endian.h"
48 #include "llvm/Support/ErrorHandling.h"
49 #include "llvm/Support/Format.h"
50 #include "llvm/Support/FormatVariadic.h"
51 #include "llvm/Support/FormattedStream.h"
52 #include "llvm/Support/LEB128.h"
53 #include "llvm/Support/MathExtras.h"
54 #include "llvm/Support/MipsABIFlags.h"
55 #include "llvm/Support/ScopedPrinter.h"
56 #include "llvm/Support/raw_ostream.h"
65 #include <system_error>
66 #include <unordered_set>
70 using namespace llvm::object
;
73 #define LLVM_READOBJ_ENUM_CASE(ns, enum) \
77 #define ENUM_ENT(enum, altName) \
78 { #enum, altName, ELF::enum }
80 #define ENUM_ENT_1(enum) \
81 { #enum, #enum, ELF::enum }
83 #define LLVM_READOBJ_PHDR_ENUM(ns, enum) \
85 return std::string(#enum).substr(3);
87 #define TYPEDEF_ELF_TYPES(ELFT) \
88 using ELFO = ELFFile<ELFT>; \
89 using Elf_Addr = typename ELFT::Addr; \
90 using Elf_Shdr = typename ELFT::Shdr; \
91 using Elf_Sym = typename ELFT::Sym; \
92 using Elf_Dyn = typename ELFT::Dyn; \
93 using Elf_Dyn_Range = typename ELFT::DynRange; \
94 using Elf_Rel = typename ELFT::Rel; \
95 using Elf_Rela = typename ELFT::Rela; \
96 using Elf_Relr = typename ELFT::Relr; \
97 using Elf_Rel_Range = typename ELFT::RelRange; \
98 using Elf_Rela_Range = typename ELFT::RelaRange; \
99 using Elf_Relr_Range = typename ELFT::RelrRange; \
100 using Elf_Phdr = typename ELFT::Phdr; \
101 using Elf_Half = typename ELFT::Half; \
102 using Elf_Ehdr = typename ELFT::Ehdr; \
103 using Elf_Word = typename ELFT::Word; \
104 using Elf_Hash = typename ELFT::Hash; \
105 using Elf_GnuHash = typename ELFT::GnuHash; \
106 using Elf_Note = typename ELFT::Note; \
107 using Elf_Sym_Range = typename ELFT::SymRange; \
108 using Elf_Versym = typename ELFT::Versym; \
109 using Elf_Verneed = typename ELFT::Verneed; \
110 using Elf_Vernaux = typename ELFT::Vernaux; \
111 using Elf_Verdef = typename ELFT::Verdef; \
112 using Elf_Verdaux = typename ELFT::Verdaux; \
113 using Elf_CGProfile = typename ELFT::CGProfile; \
114 using uintX_t = typename ELFT::uint;
118 template <class ELFT
> class DumpStyle
;
120 /// Represents a contiguous uniform range in the file. We cannot just create a
121 /// range directly because when creating one of these from the .dynamic table
122 /// the size, entity size and virtual address are different entries in arbitrary
123 /// order (DT_REL, DT_RELSZ, DT_RELENT for example).
124 struct DynRegionInfo
{
125 DynRegionInfo(StringRef ObjName
) : FileName(ObjName
) {}
126 DynRegionInfo(const void *A
, uint64_t S
, uint64_t ES
, StringRef ObjName
)
127 : Addr(A
), Size(S
), EntSize(ES
), FileName(ObjName
) {}
129 /// Address in current address space.
130 const void *Addr
= nullptr;
131 /// Size in bytes of the region.
133 /// Size of each entity in the region.
134 uint64_t EntSize
= 0;
136 /// Name of the file. Used for error reporting.
139 template <typename Type
> ArrayRef
<Type
> getAsArrayRef() const {
140 const Type
*Start
= reinterpret_cast<const Type
*>(Addr
);
142 return {Start
, Start
};
143 if (EntSize
!= sizeof(Type
) || Size
% EntSize
) {
144 // TODO: Add a section index to this warning.
145 reportWarning(createError("invalid section size (" + Twine(Size
) +
146 ") or entity size (" + Twine(EntSize
) + ")"),
148 return {Start
, Start
};
150 return {Start
, Start
+ (Size
/ EntSize
)};
154 template <typename ELFT
> class ELFDumper
: public ObjDumper
{
156 ELFDumper(const object::ELFObjectFile
<ELFT
> *ObjF
, ScopedPrinter
&Writer
);
158 void printFileHeaders() override
;
159 void printSectionHeaders() override
;
160 void printRelocations() override
;
161 void printDynamicRelocations() override
;
162 void printSymbols(bool PrintSymbols
, bool PrintDynamicSymbols
) override
;
163 void printHashSymbols() override
;
164 void printUnwindInfo() override
;
166 void printDynamicTable() override
;
167 void printNeededLibraries() override
;
168 void printProgramHeaders(bool PrintProgramHeaders
,
169 cl::boolOrDefault PrintSectionMapping
) override
;
170 void printHashTable() override
;
171 void printGnuHashTable() override
;
172 void printLoadName() override
;
173 void printVersionInfo() override
;
174 void printGroupSections() override
;
176 void printAttributes() override
;
177 void printMipsPLTGOT() override
;
178 void printMipsABIFlags() override
;
179 void printMipsReginfo() override
;
180 void printMipsOptions() override
;
182 void printStackMap() const override
;
184 void printHashHistogram() override
;
186 void printCGProfile() override
;
187 void printAddrsig() override
;
189 void printNotes() override
;
191 void printELFLinkerOptions() override
;
192 void printStackSizes() override
;
194 const object::ELFObjectFile
<ELFT
> *getElfObject() const { return ObjF
; };
197 std::unique_ptr
<DumpStyle
<ELFT
>> ELFDumperStyle
;
199 TYPEDEF_ELF_TYPES(ELFT
)
201 DynRegionInfo
checkDRI(DynRegionInfo DRI
) {
202 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
203 if (DRI
.Addr
< Obj
->base() ||
204 reinterpret_cast<const uint8_t *>(DRI
.Addr
) + DRI
.Size
>
205 Obj
->base() + Obj
->getBufSize())
206 reportError(errorCodeToError(llvm::object::object_error::parse_failed
),
207 ObjF
->getFileName());
211 DynRegionInfo
createDRIFrom(const Elf_Phdr
*P
, uintX_t EntSize
) {
212 return checkDRI({ObjF
->getELFFile()->base() + P
->p_offset
, P
->p_filesz
,
213 EntSize
, ObjF
->getFileName()});
216 DynRegionInfo
createDRIFrom(const Elf_Shdr
*S
) {
217 return checkDRI({ObjF
->getELFFile()->base() + S
->sh_offset
, S
->sh_size
,
218 S
->sh_entsize
, ObjF
->getFileName()});
221 void loadDynamicTable(const ELFFile
<ELFT
> *Obj
);
222 void parseDynamicTable();
224 StringRef
getSymbolVersion(StringRef StrTab
, const Elf_Sym
*symb
,
225 bool &IsDefault
) const;
226 void LoadVersionMap() const;
227 void LoadVersionNeeds(const Elf_Shdr
*ec
) const;
228 void LoadVersionDefs(const Elf_Shdr
*sec
) const;
230 const object::ELFObjectFile
<ELFT
> *ObjF
;
231 DynRegionInfo DynRelRegion
;
232 DynRegionInfo DynRelaRegion
;
233 DynRegionInfo DynRelrRegion
;
234 DynRegionInfo DynPLTRelRegion
;
235 DynRegionInfo DynSymRegion
;
236 DynRegionInfo DynamicTable
;
237 StringRef DynamicStringTable
;
238 std::string SOName
= "<Not found>";
239 const Elf_Hash
*HashTable
= nullptr;
240 const Elf_GnuHash
*GnuHashTable
= nullptr;
241 const Elf_Shdr
*DotSymtabSec
= nullptr;
242 const Elf_Shdr
*DotCGProfileSec
= nullptr;
243 const Elf_Shdr
*DotAddrsigSec
= nullptr;
244 StringRef DynSymtabName
;
245 ArrayRef
<Elf_Word
> ShndxTable
;
247 const Elf_Shdr
*SymbolVersionSection
= nullptr; // .gnu.version
248 const Elf_Shdr
*SymbolVersionNeedSection
= nullptr; // .gnu.version_r
249 const Elf_Shdr
*SymbolVersionDefSection
= nullptr; // .gnu.version_d
251 // Records for each version index the corresponding Verdef or Vernaux entry.
252 // This is filled the first time LoadVersionMap() is called.
253 class VersionMapEntry
: public PointerIntPair
<const void *, 1> {
255 // If the integer is 0, this is an Elf_Verdef*.
256 // If the integer is 1, this is an Elf_Vernaux*.
257 VersionMapEntry() : PointerIntPair
<const void *, 1>(nullptr, 0) {}
258 VersionMapEntry(const Elf_Verdef
*verdef
)
259 : PointerIntPair
<const void *, 1>(verdef
, 0) {}
260 VersionMapEntry(const Elf_Vernaux
*vernaux
)
261 : PointerIntPair
<const void *, 1>(vernaux
, 1) {}
263 bool isNull() const { return getPointer() == nullptr; }
264 bool isVerdef() const { return !isNull() && getInt() == 0; }
265 bool isVernaux() const { return !isNull() && getInt() == 1; }
266 const Elf_Verdef
*getVerdef() const {
267 return isVerdef() ? (const Elf_Verdef
*)getPointer() : nullptr;
269 const Elf_Vernaux
*getVernaux() const {
270 return isVernaux() ? (const Elf_Vernaux
*)getPointer() : nullptr;
273 mutable SmallVector
<VersionMapEntry
, 16> VersionMap
;
276 Elf_Dyn_Range
dynamic_table() const {
277 // A valid .dynamic section contains an array of entries terminated
278 // with a DT_NULL entry. However, sometimes the section content may
279 // continue past the DT_NULL entry, so to dump the section correctly,
280 // we first find the end of the entries by iterating over them.
281 Elf_Dyn_Range Table
= DynamicTable
.getAsArrayRef
<Elf_Dyn
>();
284 while (Size
< Table
.size())
285 if (Table
[Size
++].getTag() == DT_NULL
)
288 return Table
.slice(0, Size
);
291 Elf_Sym_Range
dynamic_symbols() const {
292 return DynSymRegion
.getAsArrayRef
<Elf_Sym
>();
295 Elf_Rel_Range
dyn_rels() const;
296 Elf_Rela_Range
dyn_relas() const;
297 Elf_Relr_Range
dyn_relrs() const;
298 std::string
getFullSymbolName(const Elf_Sym
*Symbol
, StringRef StrTable
,
299 bool IsDynamic
) const;
300 void getSectionNameIndex(const Elf_Sym
*Symbol
, const Elf_Sym
*FirstSym
,
301 StringRef
&SectionName
,
302 unsigned &SectionIndex
) const;
303 std::string
getStaticSymbolName(uint32_t Index
) const;
304 std::string
getDynamicString(uint64_t Value
) const;
305 StringRef
getSymbolVersionByIndex(StringRef StrTab
,
306 uint32_t VersionSymbolIndex
,
307 bool &IsDefault
) const;
309 void printSymbolsHelper(bool IsDynamic
) const;
310 void printDynamicEntry(raw_ostream
&OS
, uint64_t Type
, uint64_t Value
) const;
312 const Elf_Shdr
*getDotSymtabSec() const { return DotSymtabSec
; }
313 const Elf_Shdr
*getDotCGProfileSec() const { return DotCGProfileSec
; }
314 const Elf_Shdr
*getDotAddrsigSec() const { return DotAddrsigSec
; }
315 ArrayRef
<Elf_Word
> getShndxTable() const { return ShndxTable
; }
316 StringRef
getDynamicStringTable() const { return DynamicStringTable
; }
317 const DynRegionInfo
&getDynRelRegion() const { return DynRelRegion
; }
318 const DynRegionInfo
&getDynRelaRegion() const { return DynRelaRegion
; }
319 const DynRegionInfo
&getDynRelrRegion() const { return DynRelrRegion
; }
320 const DynRegionInfo
&getDynPLTRelRegion() const { return DynPLTRelRegion
; }
321 const DynRegionInfo
&getDynamicTableRegion() const { return DynamicTable
; }
322 const Elf_Hash
*getHashTable() const { return HashTable
; }
323 const Elf_GnuHash
*getGnuHashTable() const { return GnuHashTable
; }
326 template <class ELFT
>
327 void ELFDumper
<ELFT
>::printSymbolsHelper(bool IsDynamic
) const {
328 StringRef StrTable
, SymtabName
;
330 Elf_Sym_Range
Syms(nullptr, nullptr);
331 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
333 StrTable
= DynamicStringTable
;
334 Syms
= dynamic_symbols();
335 SymtabName
= DynSymtabName
;
336 if (DynSymRegion
.Addr
)
337 Entries
= DynSymRegion
.Size
/ DynSymRegion
.EntSize
;
341 StrTable
= unwrapOrError(ObjF
->getFileName(),
342 Obj
->getStringTableForSymtab(*DotSymtabSec
));
343 Syms
= unwrapOrError(ObjF
->getFileName(), Obj
->symbols(DotSymtabSec
));
345 unwrapOrError(ObjF
->getFileName(), Obj
->getSectionName(DotSymtabSec
));
346 Entries
= DotSymtabSec
->getEntityCount();
348 if (Syms
.begin() == Syms
.end())
351 // The st_other field has 2 logical parts. The first two bits hold the symbol
352 // visibility (STV_*) and the remainder hold other platform-specific values.
353 bool NonVisibilityBitsUsed
= llvm::find_if(Syms
, [](const Elf_Sym
&S
) {
354 return S
.st_other
& ~0x3;
357 ELFDumperStyle
->printSymtabMessage(Obj
, SymtabName
, Entries
,
358 NonVisibilityBitsUsed
);
359 for (const auto &Sym
: Syms
)
360 ELFDumperStyle
->printSymbol(Obj
, &Sym
, Syms
.begin(), StrTable
, IsDynamic
,
361 NonVisibilityBitsUsed
);
364 template <class ELFT
> class MipsGOTParser
;
366 template <typename ELFT
> class DumpStyle
{
368 using Elf_Shdr
= typename
ELFT::Shdr
;
369 using Elf_Sym
= typename
ELFT::Sym
;
370 using Elf_Addr
= typename
ELFT::Addr
;
372 DumpStyle(ELFDumper
<ELFT
> *Dumper
) : Dumper(Dumper
) {
373 FileName
= this->Dumper
->getElfObject()->getFileName();
375 // Dumper reports all non-critical errors as warnings.
376 // It does not print the same warning more than once.
377 WarningHandler
= [this](const Twine
&Msg
) {
378 if (Warnings
.insert(Msg
.str()).second
)
379 reportWarning(createError(Msg
), FileName
);
380 return Error::success();
384 virtual ~DumpStyle() = default;
386 virtual void printFileHeaders(const ELFFile
<ELFT
> *Obj
) = 0;
387 virtual void printGroupSections(const ELFFile
<ELFT
> *Obj
) = 0;
388 virtual void printRelocations(const ELFFile
<ELFT
> *Obj
) = 0;
389 virtual void printSectionHeaders(const ELFFile
<ELFT
> *Obj
) = 0;
390 virtual void printSymbols(const ELFFile
<ELFT
> *Obj
, bool PrintSymbols
,
391 bool PrintDynamicSymbols
) = 0;
392 virtual void printHashSymbols(const ELFFile
<ELFT
> *Obj
) {}
393 virtual void printDynamic(const ELFFile
<ELFT
> *Obj
) {}
394 virtual void printDynamicRelocations(const ELFFile
<ELFT
> *Obj
) = 0;
395 virtual void printSymtabMessage(const ELFFile
<ELFT
> *Obj
, StringRef Name
,
396 size_t Offset
, bool NonVisibilityBitsUsed
) {}
397 virtual void printSymbol(const ELFFile
<ELFT
> *Obj
, const Elf_Sym
*Symbol
,
398 const Elf_Sym
*FirstSym
, StringRef StrTable
,
399 bool IsDynamic
, bool NonVisibilityBitsUsed
) = 0;
400 virtual void printProgramHeaders(const ELFFile
<ELFT
> *Obj
,
401 bool PrintProgramHeaders
,
402 cl::boolOrDefault PrintSectionMapping
) = 0;
403 virtual void printVersionSymbolSection(const ELFFile
<ELFT
> *Obj
,
404 const Elf_Shdr
*Sec
) = 0;
405 virtual void printVersionDefinitionSection(const ELFFile
<ELFT
> *Obj
,
406 const Elf_Shdr
*Sec
) = 0;
407 virtual void printVersionDependencySection(const ELFFile
<ELFT
> *Obj
,
408 const Elf_Shdr
*Sec
) = 0;
409 virtual void printHashHistogram(const ELFFile
<ELFT
> *Obj
) = 0;
410 virtual void printCGProfile(const ELFFile
<ELFT
> *Obj
) = 0;
411 virtual void printAddrsig(const ELFFile
<ELFT
> *Obj
) = 0;
412 virtual void printNotes(const ELFFile
<ELFT
> *Obj
) = 0;
413 virtual void printELFLinkerOptions(const ELFFile
<ELFT
> *Obj
) = 0;
414 virtual void printStackSizes(const ELFObjectFile
<ELFT
> *Obj
) = 0;
415 void printNonRelocatableStackSizes(const ELFObjectFile
<ELFT
> *Obj
,
416 std::function
<void()> PrintHeader
);
417 void printRelocatableStackSizes(const ELFObjectFile
<ELFT
> *Obj
,
418 std::function
<void()> PrintHeader
);
419 void printFunctionStackSize(const ELFObjectFile
<ELFT
> *Obj
, uint64_t SymValue
,
420 SectionRef FunctionSec
,
421 const StringRef SectionName
, DataExtractor Data
,
423 void printStackSize(const ELFObjectFile
<ELFT
> *Obj
, RelocationRef Rel
,
424 SectionRef FunctionSec
,
425 const StringRef
&StackSizeSectionName
,
426 const RelocationResolver
&Resolver
, DataExtractor Data
);
427 virtual void printStackSizeEntry(uint64_t Size
, StringRef FuncName
) = 0;
428 virtual void printMipsGOT(const MipsGOTParser
<ELFT
> &Parser
) = 0;
429 virtual void printMipsPLT(const MipsGOTParser
<ELFT
> &Parser
) = 0;
430 const ELFDumper
<ELFT
> *dumper() const { return Dumper
; }
433 std::function
<Error(const Twine
&Msg
)> WarningHandler
;
437 std::unordered_set
<std::string
> Warnings
;
438 const ELFDumper
<ELFT
> *Dumper
;
441 template <typename ELFT
> class GNUStyle
: public DumpStyle
<ELFT
> {
442 formatted_raw_ostream
&OS
;
445 TYPEDEF_ELF_TYPES(ELFT
)
447 GNUStyle(ScopedPrinter
&W
, ELFDumper
<ELFT
> *Dumper
)
448 : DumpStyle
<ELFT
>(Dumper
),
449 OS(static_cast<formatted_raw_ostream
&>(W
.getOStream())) {
450 assert (&W
.getOStream() == &llvm::fouts());
453 void printFileHeaders(const ELFO
*Obj
) override
;
454 void printGroupSections(const ELFFile
<ELFT
> *Obj
) override
;
455 void printRelocations(const ELFO
*Obj
) override
;
456 void printSectionHeaders(const ELFO
*Obj
) override
;
457 void printSymbols(const ELFO
*Obj
, bool PrintSymbols
,
458 bool PrintDynamicSymbols
) override
;
459 void printHashSymbols(const ELFO
*Obj
) override
;
460 void printDynamic(const ELFFile
<ELFT
> *Obj
) override
;
461 void printDynamicRelocations(const ELFO
*Obj
) override
;
462 void printSymtabMessage(const ELFO
*Obj
, StringRef Name
, size_t Offset
,
463 bool NonVisibilityBitsUsed
) override
;
464 void printProgramHeaders(const ELFO
*Obj
, bool PrintProgramHeaders
,
465 cl::boolOrDefault PrintSectionMapping
) override
;
466 void printVersionSymbolSection(const ELFFile
<ELFT
> *Obj
,
467 const Elf_Shdr
*Sec
) override
;
468 void printVersionDefinitionSection(const ELFFile
<ELFT
> *Obj
,
469 const Elf_Shdr
*Sec
) override
;
470 void printVersionDependencySection(const ELFFile
<ELFT
> *Obj
,
471 const Elf_Shdr
*Sec
) override
;
472 void printHashHistogram(const ELFFile
<ELFT
> *Obj
) override
;
473 void printCGProfile(const ELFFile
<ELFT
> *Obj
) override
;
474 void printAddrsig(const ELFFile
<ELFT
> *Obj
) override
;
475 void printNotes(const ELFFile
<ELFT
> *Obj
) override
;
476 void printELFLinkerOptions(const ELFFile
<ELFT
> *Obj
) override
;
477 void printStackSizes(const ELFObjectFile
<ELFT
> *Obj
) override
;
478 void printStackSizeEntry(uint64_t Size
, StringRef FuncName
) override
;
479 void printMipsGOT(const MipsGOTParser
<ELFT
> &Parser
) override
;
480 void printMipsPLT(const MipsGOTParser
<ELFT
> &Parser
) override
;
487 Field(StringRef S
, unsigned Col
) : Str(S
), Column(Col
) {}
488 Field(unsigned Col
) : Column(Col
) {}
491 template <typename T
, typename TEnum
>
492 std::string
printEnum(T Value
, ArrayRef
<EnumEntry
<TEnum
>> EnumValues
) {
493 for (const auto &EnumItem
: EnumValues
)
494 if (EnumItem
.Value
== Value
)
495 return EnumItem
.AltName
;
496 return to_hexString(Value
, false);
499 template <typename T
, typename TEnum
>
500 std::string
printFlags(T Value
, ArrayRef
<EnumEntry
<TEnum
>> EnumValues
,
501 TEnum EnumMask1
= {}, TEnum EnumMask2
= {},
502 TEnum EnumMask3
= {}) {
504 for (const auto &Flag
: EnumValues
) {
509 if (Flag
.Value
& EnumMask1
)
510 EnumMask
= EnumMask1
;
511 else if (Flag
.Value
& EnumMask2
)
512 EnumMask
= EnumMask2
;
513 else if (Flag
.Value
& EnumMask3
)
514 EnumMask
= EnumMask3
;
515 bool IsEnum
= (Flag
.Value
& EnumMask
) != 0;
516 if ((!IsEnum
&& (Value
& Flag
.Value
) == Flag
.Value
) ||
517 (IsEnum
&& (Value
& EnumMask
) == Flag
.Value
)) {
526 formatted_raw_ostream
&printField(struct Field F
) {
528 OS
.PadToColumn(F
.Column
);
533 void printHashedSymbol(const ELFO
*Obj
, const Elf_Sym
*FirstSym
, uint32_t Sym
,
534 StringRef StrTable
, uint32_t Bucket
);
535 void printRelocHeader(unsigned SType
);
536 void printRelocation(const ELFO
*Obj
, const Elf_Shdr
*SymTab
,
537 const Elf_Rela
&R
, bool IsRela
);
538 void printRelocation(const ELFO
*Obj
, const Elf_Sym
*Sym
,
539 StringRef SymbolName
, const Elf_Rela
&R
, bool IsRela
);
540 void printSymbol(const ELFO
*Obj
, const Elf_Sym
*Symbol
, const Elf_Sym
*First
,
541 StringRef StrTable
, bool IsDynamic
,
542 bool NonVisibilityBitsUsed
) override
;
543 std::string
getSymbolSectionNdx(const ELFO
*Obj
, const Elf_Sym
*Symbol
,
544 const Elf_Sym
*FirstSym
);
545 void printDynamicRelocation(const ELFO
*Obj
, Elf_Rela R
, bool IsRela
);
546 bool checkTLSSections(const Elf_Phdr
&Phdr
, const Elf_Shdr
&Sec
);
547 bool checkoffsets(const Elf_Phdr
&Phdr
, const Elf_Shdr
&Sec
);
548 bool checkVMA(const Elf_Phdr
&Phdr
, const Elf_Shdr
&Sec
);
549 bool checkPTDynamic(const Elf_Phdr
&Phdr
, const Elf_Shdr
&Sec
);
550 void printProgramHeaders(const ELFO
*Obj
);
551 void printSectionMapping(const ELFO
*Obj
);
554 template <typename ELFT
> class LLVMStyle
: public DumpStyle
<ELFT
> {
556 TYPEDEF_ELF_TYPES(ELFT
)
558 LLVMStyle(ScopedPrinter
&W
, ELFDumper
<ELFT
> *Dumper
)
559 : DumpStyle
<ELFT
>(Dumper
), W(W
) {}
561 void printFileHeaders(const ELFO
*Obj
) override
;
562 void printGroupSections(const ELFFile
<ELFT
> *Obj
) override
;
563 void printRelocations(const ELFO
*Obj
) override
;
564 void printRelocations(const Elf_Shdr
*Sec
, const ELFO
*Obj
);
565 void printSectionHeaders(const ELFO
*Obj
) override
;
566 void printSymbols(const ELFO
*Obj
, bool PrintSymbols
,
567 bool PrintDynamicSymbols
) override
;
568 void printDynamic(const ELFFile
<ELFT
> *Obj
) override
;
569 void printDynamicRelocations(const ELFO
*Obj
) override
;
570 void printProgramHeaders(const ELFO
*Obj
, bool PrintProgramHeaders
,
571 cl::boolOrDefault PrintSectionMapping
) override
;
572 void printVersionSymbolSection(const ELFFile
<ELFT
> *Obj
,
573 const Elf_Shdr
*Sec
) override
;
574 void printVersionDefinitionSection(const ELFFile
<ELFT
> *Obj
,
575 const Elf_Shdr
*Sec
) override
;
576 void printVersionDependencySection(const ELFFile
<ELFT
> *Obj
,
577 const Elf_Shdr
*Sec
) override
;
578 void printHashHistogram(const ELFFile
<ELFT
> *Obj
) override
;
579 void printCGProfile(const ELFFile
<ELFT
> *Obj
) override
;
580 void printAddrsig(const ELFFile
<ELFT
> *Obj
) override
;
581 void printNotes(const ELFFile
<ELFT
> *Obj
) override
;
582 void printELFLinkerOptions(const ELFFile
<ELFT
> *Obj
) override
;
583 void printStackSizes(const ELFObjectFile
<ELFT
> *Obj
) override
;
584 void printStackSizeEntry(uint64_t Size
, StringRef FuncName
) override
;
585 void printMipsGOT(const MipsGOTParser
<ELFT
> &Parser
) override
;
586 void printMipsPLT(const MipsGOTParser
<ELFT
> &Parser
) override
;
589 void printRelocation(const ELFO
*Obj
, Elf_Rela Rel
, const Elf_Shdr
*SymTab
);
590 void printDynamicRelocation(const ELFO
*Obj
, Elf_Rela Rel
);
591 void printSymbols(const ELFO
*Obj
);
592 void printDynamicSymbols(const ELFO
*Obj
);
593 void printSymbol(const ELFO
*Obj
, const Elf_Sym
*Symbol
, const Elf_Sym
*First
,
594 StringRef StrTable
, bool IsDynamic
,
595 bool /*NonVisibilityBitsUsed*/) override
;
596 void printProgramHeaders(const ELFO
*Obj
);
597 void printSectionMapping(const ELFO
*Obj
) {}
602 } // end anonymous namespace
606 template <class ELFT
>
607 static std::error_code
createELFDumper(const ELFObjectFile
<ELFT
> *Obj
,
608 ScopedPrinter
&Writer
,
609 std::unique_ptr
<ObjDumper
> &Result
) {
610 Result
.reset(new ELFDumper
<ELFT
>(Obj
, Writer
));
611 return readobj_error::success
;
614 std::error_code
createELFDumper(const object::ObjectFile
*Obj
,
615 ScopedPrinter
&Writer
,
616 std::unique_ptr
<ObjDumper
> &Result
) {
617 // Little-endian 32-bit
618 if (const ELF32LEObjectFile
*ELFObj
= dyn_cast
<ELF32LEObjectFile
>(Obj
))
619 return createELFDumper(ELFObj
, Writer
, Result
);
622 if (const ELF32BEObjectFile
*ELFObj
= dyn_cast
<ELF32BEObjectFile
>(Obj
))
623 return createELFDumper(ELFObj
, Writer
, Result
);
625 // Little-endian 64-bit
626 if (const ELF64LEObjectFile
*ELFObj
= dyn_cast
<ELF64LEObjectFile
>(Obj
))
627 return createELFDumper(ELFObj
, Writer
, Result
);
630 if (const ELF64BEObjectFile
*ELFObj
= dyn_cast
<ELF64BEObjectFile
>(Obj
))
631 return createELFDumper(ELFObj
, Writer
, Result
);
633 return readobj_error::unsupported_obj_file_format
;
636 } // end namespace llvm
638 // Iterate through the versions needed section, and place each Elf_Vernaux
639 // in the VersionMap according to its index.
640 template <class ELFT
>
641 void ELFDumper
<ELFT
>::LoadVersionNeeds(const Elf_Shdr
*Sec
) const {
642 unsigned VerneedSize
= Sec
->sh_size
; // Size of section in bytes
643 unsigned VerneedEntries
= Sec
->sh_info
; // Number of Verneed entries
644 const uint8_t *VerneedStart
= reinterpret_cast<const uint8_t *>(
645 ObjF
->getELFFile()->base() + Sec
->sh_offset
);
646 const uint8_t *VerneedEnd
= VerneedStart
+ VerneedSize
;
647 // The first Verneed entry is at the start of the section.
648 const uint8_t *VerneedBuf
= VerneedStart
;
649 for (unsigned VerneedIndex
= 0; VerneedIndex
< VerneedEntries
;
651 if (VerneedBuf
+ sizeof(Elf_Verneed
) > VerneedEnd
)
652 report_fatal_error("Section ended unexpectedly while scanning "
653 "version needed records.");
654 const Elf_Verneed
*Verneed
=
655 reinterpret_cast<const Elf_Verneed
*>(VerneedBuf
);
656 if (Verneed
->vn_version
!= ELF::VER_NEED_CURRENT
)
657 report_fatal_error("Unexpected verneed version");
658 // Iterate through the Vernaux entries
659 const uint8_t *VernauxBuf
= VerneedBuf
+ Verneed
->vn_aux
;
660 for (unsigned VernauxIndex
= 0; VernauxIndex
< Verneed
->vn_cnt
;
662 if (VernauxBuf
+ sizeof(Elf_Vernaux
) > VerneedEnd
)
663 report_fatal_error("Section ended unexpected while scanning auxiliary "
664 "version needed records.");
665 const Elf_Vernaux
*Vernaux
=
666 reinterpret_cast<const Elf_Vernaux
*>(VernauxBuf
);
667 size_t Index
= Vernaux
->vna_other
& ELF::VERSYM_VERSION
;
668 if (Index
>= VersionMap
.size())
669 VersionMap
.resize(Index
+ 1);
670 VersionMap
[Index
] = VersionMapEntry(Vernaux
);
671 VernauxBuf
+= Vernaux
->vna_next
;
673 VerneedBuf
+= Verneed
->vn_next
;
677 // Iterate through the version definitions, and place each Elf_Verdef
678 // in the VersionMap according to its index.
679 template <class ELFT
>
680 void ELFDumper
<ELFT
>::LoadVersionDefs(const Elf_Shdr
*Sec
) const {
681 unsigned VerdefSize
= Sec
->sh_size
; // Size of section in bytes
682 unsigned VerdefEntries
= Sec
->sh_info
; // Number of Verdef entries
683 const uint8_t *VerdefStart
= reinterpret_cast<const uint8_t *>(
684 ObjF
->getELFFile()->base() + Sec
->sh_offset
);
685 const uint8_t *VerdefEnd
= VerdefStart
+ VerdefSize
;
686 // The first Verdef entry is at the start of the section.
687 const uint8_t *VerdefBuf
= VerdefStart
;
688 for (unsigned VerdefIndex
= 0; VerdefIndex
< VerdefEntries
; ++VerdefIndex
) {
689 if (VerdefBuf
+ sizeof(Elf_Verdef
) > VerdefEnd
)
690 report_fatal_error("Section ended unexpectedly while scanning "
691 "version definitions.");
692 const Elf_Verdef
*Verdef
= reinterpret_cast<const Elf_Verdef
*>(VerdefBuf
);
693 if (Verdef
->vd_version
!= ELF::VER_DEF_CURRENT
)
694 report_fatal_error("Unexpected verdef version");
695 size_t Index
= Verdef
->vd_ndx
& ELF::VERSYM_VERSION
;
696 if (Index
>= VersionMap
.size())
697 VersionMap
.resize(Index
+ 1);
698 VersionMap
[Index
] = VersionMapEntry(Verdef
);
699 VerdefBuf
+= Verdef
->vd_next
;
703 template <class ELFT
> void ELFDumper
<ELFT
>::LoadVersionMap() const {
704 // If there is no dynamic symtab or version table, there is nothing to do.
705 if (!DynSymRegion
.Addr
|| !SymbolVersionSection
)
708 // Has the VersionMap already been loaded?
709 if (!VersionMap
.empty())
712 // The first two version indexes are reserved.
713 // Index 0 is LOCAL, index 1 is GLOBAL.
714 VersionMap
.push_back(VersionMapEntry());
715 VersionMap
.push_back(VersionMapEntry());
717 if (SymbolVersionDefSection
)
718 LoadVersionDefs(SymbolVersionDefSection
);
720 if (SymbolVersionNeedSection
)
721 LoadVersionNeeds(SymbolVersionNeedSection
);
724 template <typename ELFT
>
725 StringRef ELFDumper
<ELFT
>::getSymbolVersion(StringRef StrTab
,
727 bool &IsDefault
) const {
728 // This is a dynamic symbol. Look in the GNU symbol version table.
729 if (!SymbolVersionSection
) {
735 // Determine the position in the symbol table of this entry.
736 size_t EntryIndex
= (reinterpret_cast<uintptr_t>(Sym
) -
737 reinterpret_cast<uintptr_t>(DynSymRegion
.Addr
)) /
740 // Get the corresponding version index entry.
741 const Elf_Versym
*Versym
= unwrapOrError(
742 ObjF
->getFileName(), ObjF
->getELFFile()->template getEntry
<Elf_Versym
>(
743 SymbolVersionSection
, EntryIndex
));
744 return this->getSymbolVersionByIndex(StrTab
, Versym
->vs_index
, IsDefault
);
747 static std::string
maybeDemangle(StringRef Name
) {
748 return opts::Demangle
? demangle(Name
) : Name
.str();
751 template <typename ELFT
>
752 std::string ELFDumper
<ELFT
>::getStaticSymbolName(uint32_t Index
) const {
753 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
754 StringRef StrTable
= unwrapOrError(
755 ObjF
->getFileName(), Obj
->getStringTableForSymtab(*DotSymtabSec
));
757 unwrapOrError(ObjF
->getFileName(), Obj
->symbols(DotSymtabSec
));
758 if (Index
>= Syms
.size())
759 reportError(createError("Invalid symbol index"), ObjF
->getFileName());
760 const Elf_Sym
*Sym
= &Syms
[Index
];
761 return maybeDemangle(
762 unwrapOrError(ObjF
->getFileName(), Sym
->getName(StrTable
)));
765 template <typename ELFT
>
766 StringRef ELFDumper
<ELFT
>::getSymbolVersionByIndex(StringRef StrTab
,
767 uint32_t SymbolVersionIndex
,
768 bool &IsDefault
) const {
769 size_t VersionIndex
= SymbolVersionIndex
& VERSYM_VERSION
;
771 // Special markers for unversioned symbols.
772 if (VersionIndex
== VER_NDX_LOCAL
|| VersionIndex
== VER_NDX_GLOBAL
) {
777 // Lookup this symbol in the version table.
779 if (VersionIndex
>= VersionMap
.size() || VersionMap
[VersionIndex
].isNull())
780 reportError(createError("Invalid version entry"), ObjF
->getFileName());
781 const VersionMapEntry
&Entry
= VersionMap
[VersionIndex
];
783 // Get the version name string.
785 if (Entry
.isVerdef()) {
786 // The first Verdaux entry holds the name.
787 NameOffset
= Entry
.getVerdef()->getAux()->vda_name
;
788 IsDefault
= !(SymbolVersionIndex
& VERSYM_HIDDEN
);
790 NameOffset
= Entry
.getVernaux()->vna_name
;
793 if (NameOffset
>= StrTab
.size())
794 reportError(createError("Invalid string offset"), ObjF
->getFileName());
795 return StrTab
.data() + NameOffset
;
798 template <typename ELFT
>
799 std::string ELFDumper
<ELFT
>::getFullSymbolName(const Elf_Sym
*Symbol
,
801 bool IsDynamic
) const {
802 std::string SymbolName
= maybeDemangle(
803 unwrapOrError(ObjF
->getFileName(), Symbol
->getName(StrTable
)));
805 if (SymbolName
.empty() && Symbol
->getType() == ELF::STT_SECTION
) {
806 unsigned SectionIndex
;
807 StringRef SectionName
;
808 Elf_Sym_Range Syms
= unwrapOrError(
809 ObjF
->getFileName(), ObjF
->getELFFile()->symbols(DotSymtabSec
));
810 getSectionNameIndex(Symbol
, Syms
.begin(), SectionName
, SectionIndex
);
818 StringRef Version
= getSymbolVersion(StrTable
, &*Symbol
, IsDefault
);
819 if (!Version
.empty()) {
820 SymbolName
+= (IsDefault
? "@@" : "@");
821 SymbolName
+= Version
;
826 template <typename ELFT
>
827 void ELFDumper
<ELFT
>::getSectionNameIndex(const Elf_Sym
*Symbol
,
828 const Elf_Sym
*FirstSym
,
829 StringRef
&SectionName
,
830 unsigned &SectionIndex
) const {
831 SectionIndex
= Symbol
->st_shndx
;
832 if (Symbol
->isUndefined())
833 SectionName
= "Undefined";
834 else if (Symbol
->isProcessorSpecific())
835 SectionName
= "Processor Specific";
836 else if (Symbol
->isOSSpecific())
837 SectionName
= "Operating System Specific";
838 else if (Symbol
->isAbsolute())
839 SectionName
= "Absolute";
840 else if (Symbol
->isCommon())
841 SectionName
= "Common";
842 else if (Symbol
->isReserved() && SectionIndex
!= SHN_XINDEX
)
843 SectionName
= "Reserved";
845 if (SectionIndex
== SHN_XINDEX
)
846 SectionIndex
= unwrapOrError(ObjF
->getFileName(),
847 object::getExtendedSymbolTableIndex
<ELFT
>(
848 Symbol
, FirstSym
, ShndxTable
));
849 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
850 const typename
ELFT::Shdr
*Sec
=
851 unwrapOrError(ObjF
->getFileName(), Obj
->getSection(SectionIndex
));
852 SectionName
= unwrapOrError(ObjF
->getFileName(), Obj
->getSectionName(Sec
));
856 template <class ELFO
>
857 static const typename
ELFO::Elf_Shdr
*
858 findNotEmptySectionByAddress(const ELFO
*Obj
, StringRef FileName
,
860 for (const auto &Shdr
: unwrapOrError(FileName
, Obj
->sections()))
861 if (Shdr
.sh_addr
== Addr
&& Shdr
.sh_size
> 0)
866 template <class ELFO
>
867 static const typename
ELFO::Elf_Shdr
*
868 findSectionByName(const ELFO
&Obj
, StringRef FileName
, StringRef Name
) {
869 for (const auto &Shdr
: unwrapOrError(FileName
, Obj
.sections()))
870 if (Name
== unwrapOrError(FileName
, Obj
.getSectionName(&Shdr
)))
875 static const EnumEntry
<unsigned> ElfClass
[] = {
876 {"None", "none", ELF::ELFCLASSNONE
},
877 {"32-bit", "ELF32", ELF::ELFCLASS32
},
878 {"64-bit", "ELF64", ELF::ELFCLASS64
},
881 static const EnumEntry
<unsigned> ElfDataEncoding
[] = {
882 {"None", "none", ELF::ELFDATANONE
},
883 {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB
},
884 {"BigEndian", "2's complement, big endian", ELF::ELFDATA2MSB
},
887 static const EnumEntry
<unsigned> ElfObjectFileType
[] = {
888 {"None", "NONE (none)", ELF::ET_NONE
},
889 {"Relocatable", "REL (Relocatable file)", ELF::ET_REL
},
890 {"Executable", "EXEC (Executable file)", ELF::ET_EXEC
},
891 {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN
},
892 {"Core", "CORE (Core file)", ELF::ET_CORE
},
895 static const EnumEntry
<unsigned> ElfOSABI
[] = {
896 {"SystemV", "UNIX - System V", ELF::ELFOSABI_NONE
},
897 {"HPUX", "UNIX - HP-UX", ELF::ELFOSABI_HPUX
},
898 {"NetBSD", "UNIX - NetBSD", ELF::ELFOSABI_NETBSD
},
899 {"GNU/Linux", "UNIX - GNU", ELF::ELFOSABI_LINUX
},
900 {"GNU/Hurd", "GNU/Hurd", ELF::ELFOSABI_HURD
},
901 {"Solaris", "UNIX - Solaris", ELF::ELFOSABI_SOLARIS
},
902 {"AIX", "UNIX - AIX", ELF::ELFOSABI_AIX
},
903 {"IRIX", "UNIX - IRIX", ELF::ELFOSABI_IRIX
},
904 {"FreeBSD", "UNIX - FreeBSD", ELF::ELFOSABI_FREEBSD
},
905 {"TRU64", "UNIX - TRU64", ELF::ELFOSABI_TRU64
},
906 {"Modesto", "Novell - Modesto", ELF::ELFOSABI_MODESTO
},
907 {"OpenBSD", "UNIX - OpenBSD", ELF::ELFOSABI_OPENBSD
},
908 {"OpenVMS", "VMS - OpenVMS", ELF::ELFOSABI_OPENVMS
},
909 {"NSK", "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK
},
910 {"AROS", "AROS", ELF::ELFOSABI_AROS
},
911 {"FenixOS", "FenixOS", ELF::ELFOSABI_FENIXOS
},
912 {"CloudABI", "CloudABI", ELF::ELFOSABI_CLOUDABI
},
913 {"Standalone", "Standalone App", ELF::ELFOSABI_STANDALONE
}
916 static const EnumEntry
<unsigned> SymVersionFlags
[] = {
917 {"Base", "BASE", VER_FLG_BASE
},
918 {"Weak", "WEAK", VER_FLG_WEAK
},
919 {"Info", "INFO", VER_FLG_INFO
}};
921 static const EnumEntry
<unsigned> AMDGPUElfOSABI
[] = {
922 {"AMDGPU_HSA", "AMDGPU - HSA", ELF::ELFOSABI_AMDGPU_HSA
},
923 {"AMDGPU_PAL", "AMDGPU - PAL", ELF::ELFOSABI_AMDGPU_PAL
},
924 {"AMDGPU_MESA3D", "AMDGPU - MESA3D", ELF::ELFOSABI_AMDGPU_MESA3D
}
927 static const EnumEntry
<unsigned> ARMElfOSABI
[] = {
928 {"ARM", "ARM", ELF::ELFOSABI_ARM
}
931 static const EnumEntry
<unsigned> C6000ElfOSABI
[] = {
932 {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI
},
933 {"C6000_LINUX", "Linux C6000", ELF::ELFOSABI_C6000_LINUX
}
936 static const EnumEntry
<unsigned> ElfMachineType
[] = {
937 ENUM_ENT(EM_NONE
, "None"),
938 ENUM_ENT(EM_M32
, "WE32100"),
939 ENUM_ENT(EM_SPARC
, "Sparc"),
940 ENUM_ENT(EM_386
, "Intel 80386"),
941 ENUM_ENT(EM_68K
, "MC68000"),
942 ENUM_ENT(EM_88K
, "MC88000"),
943 ENUM_ENT(EM_IAMCU
, "EM_IAMCU"),
944 ENUM_ENT(EM_860
, "Intel 80860"),
945 ENUM_ENT(EM_MIPS
, "MIPS R3000"),
946 ENUM_ENT(EM_S370
, "IBM System/370"),
947 ENUM_ENT(EM_MIPS_RS3_LE
, "MIPS R3000 little-endian"),
948 ENUM_ENT(EM_PARISC
, "HPPA"),
949 ENUM_ENT(EM_VPP500
, "Fujitsu VPP500"),
950 ENUM_ENT(EM_SPARC32PLUS
, "Sparc v8+"),
951 ENUM_ENT(EM_960
, "Intel 80960"),
952 ENUM_ENT(EM_PPC
, "PowerPC"),
953 ENUM_ENT(EM_PPC64
, "PowerPC64"),
954 ENUM_ENT(EM_S390
, "IBM S/390"),
955 ENUM_ENT(EM_SPU
, "SPU"),
956 ENUM_ENT(EM_V800
, "NEC V800 series"),
957 ENUM_ENT(EM_FR20
, "Fujistsu FR20"),
958 ENUM_ENT(EM_RH32
, "TRW RH-32"),
959 ENUM_ENT(EM_RCE
, "Motorola RCE"),
960 ENUM_ENT(EM_ARM
, "ARM"),
961 ENUM_ENT(EM_ALPHA
, "EM_ALPHA"),
962 ENUM_ENT(EM_SH
, "Hitachi SH"),
963 ENUM_ENT(EM_SPARCV9
, "Sparc v9"),
964 ENUM_ENT(EM_TRICORE
, "Siemens Tricore"),
965 ENUM_ENT(EM_ARC
, "ARC"),
966 ENUM_ENT(EM_H8_300
, "Hitachi H8/300"),
967 ENUM_ENT(EM_H8_300H
, "Hitachi H8/300H"),
968 ENUM_ENT(EM_H8S
, "Hitachi H8S"),
969 ENUM_ENT(EM_H8_500
, "Hitachi H8/500"),
970 ENUM_ENT(EM_IA_64
, "Intel IA-64"),
971 ENUM_ENT(EM_MIPS_X
, "Stanford MIPS-X"),
972 ENUM_ENT(EM_COLDFIRE
, "Motorola Coldfire"),
973 ENUM_ENT(EM_68HC12
, "Motorola MC68HC12 Microcontroller"),
974 ENUM_ENT(EM_MMA
, "Fujitsu Multimedia Accelerator"),
975 ENUM_ENT(EM_PCP
, "Siemens PCP"),
976 ENUM_ENT(EM_NCPU
, "Sony nCPU embedded RISC processor"),
977 ENUM_ENT(EM_NDR1
, "Denso NDR1 microprocesspr"),
978 ENUM_ENT(EM_STARCORE
, "Motorola Star*Core processor"),
979 ENUM_ENT(EM_ME16
, "Toyota ME16 processor"),
980 ENUM_ENT(EM_ST100
, "STMicroelectronics ST100 processor"),
981 ENUM_ENT(EM_TINYJ
, "Advanced Logic Corp. TinyJ embedded processor"),
982 ENUM_ENT(EM_X86_64
, "Advanced Micro Devices X86-64"),
983 ENUM_ENT(EM_PDSP
, "Sony DSP processor"),
984 ENUM_ENT(EM_PDP10
, "Digital Equipment Corp. PDP-10"),
985 ENUM_ENT(EM_PDP11
, "Digital Equipment Corp. PDP-11"),
986 ENUM_ENT(EM_FX66
, "Siemens FX66 microcontroller"),
987 ENUM_ENT(EM_ST9PLUS
, "STMicroelectronics ST9+ 8/16 bit microcontroller"),
988 ENUM_ENT(EM_ST7
, "STMicroelectronics ST7 8-bit microcontroller"),
989 ENUM_ENT(EM_68HC16
, "Motorola MC68HC16 Microcontroller"),
990 ENUM_ENT(EM_68HC11
, "Motorola MC68HC11 Microcontroller"),
991 ENUM_ENT(EM_68HC08
, "Motorola MC68HC08 Microcontroller"),
992 ENUM_ENT(EM_68HC05
, "Motorola MC68HC05 Microcontroller"),
993 ENUM_ENT(EM_SVX
, "Silicon Graphics SVx"),
994 ENUM_ENT(EM_ST19
, "STMicroelectronics ST19 8-bit microcontroller"),
995 ENUM_ENT(EM_VAX
, "Digital VAX"),
996 ENUM_ENT(EM_CRIS
, "Axis Communications 32-bit embedded processor"),
997 ENUM_ENT(EM_JAVELIN
, "Infineon Technologies 32-bit embedded cpu"),
998 ENUM_ENT(EM_FIREPATH
, "Element 14 64-bit DSP processor"),
999 ENUM_ENT(EM_ZSP
, "LSI Logic's 16-bit DSP processor"),
1000 ENUM_ENT(EM_MMIX
, "Donald Knuth's educational 64-bit processor"),
1001 ENUM_ENT(EM_HUANY
, "Harvard Universitys's machine-independent object format"),
1002 ENUM_ENT(EM_PRISM
, "Vitesse Prism"),
1003 ENUM_ENT(EM_AVR
, "Atmel AVR 8-bit microcontroller"),
1004 ENUM_ENT(EM_FR30
, "Fujitsu FR30"),
1005 ENUM_ENT(EM_D10V
, "Mitsubishi D10V"),
1006 ENUM_ENT(EM_D30V
, "Mitsubishi D30V"),
1007 ENUM_ENT(EM_V850
, "NEC v850"),
1008 ENUM_ENT(EM_M32R
, "Renesas M32R (formerly Mitsubishi M32r)"),
1009 ENUM_ENT(EM_MN10300
, "Matsushita MN10300"),
1010 ENUM_ENT(EM_MN10200
, "Matsushita MN10200"),
1011 ENUM_ENT(EM_PJ
, "picoJava"),
1012 ENUM_ENT(EM_OPENRISC
, "OpenRISC 32-bit embedded processor"),
1013 ENUM_ENT(EM_ARC_COMPACT
, "EM_ARC_COMPACT"),
1014 ENUM_ENT(EM_XTENSA
, "Tensilica Xtensa Processor"),
1015 ENUM_ENT(EM_VIDEOCORE
, "Alphamosaic VideoCore processor"),
1016 ENUM_ENT(EM_TMM_GPP
, "Thompson Multimedia General Purpose Processor"),
1017 ENUM_ENT(EM_NS32K
, "National Semiconductor 32000 series"),
1018 ENUM_ENT(EM_TPC
, "Tenor Network TPC processor"),
1019 ENUM_ENT(EM_SNP1K
, "EM_SNP1K"),
1020 ENUM_ENT(EM_ST200
, "STMicroelectronics ST200 microcontroller"),
1021 ENUM_ENT(EM_IP2K
, "Ubicom IP2xxx 8-bit microcontrollers"),
1022 ENUM_ENT(EM_MAX
, "MAX Processor"),
1023 ENUM_ENT(EM_CR
, "National Semiconductor CompactRISC"),
1024 ENUM_ENT(EM_F2MC16
, "Fujitsu F2MC16"),
1025 ENUM_ENT(EM_MSP430
, "Texas Instruments msp430 microcontroller"),
1026 ENUM_ENT(EM_BLACKFIN
, "Analog Devices Blackfin"),
1027 ENUM_ENT(EM_SE_C33
, "S1C33 Family of Seiko Epson processors"),
1028 ENUM_ENT(EM_SEP
, "Sharp embedded microprocessor"),
1029 ENUM_ENT(EM_ARCA
, "Arca RISC microprocessor"),
1030 ENUM_ENT(EM_UNICORE
, "Unicore"),
1031 ENUM_ENT(EM_EXCESS
, "eXcess 16/32/64-bit configurable embedded CPU"),
1032 ENUM_ENT(EM_DXP
, "Icera Semiconductor Inc. Deep Execution Processor"),
1033 ENUM_ENT(EM_ALTERA_NIOS2
, "Altera Nios"),
1034 ENUM_ENT(EM_CRX
, "National Semiconductor CRX microprocessor"),
1035 ENUM_ENT(EM_XGATE
, "Motorola XGATE embedded processor"),
1036 ENUM_ENT(EM_C166
, "Infineon Technologies xc16x"),
1037 ENUM_ENT(EM_M16C
, "Renesas M16C"),
1038 ENUM_ENT(EM_DSPIC30F
, "Microchip Technology dsPIC30F Digital Signal Controller"),
1039 ENUM_ENT(EM_CE
, "Freescale Communication Engine RISC core"),
1040 ENUM_ENT(EM_M32C
, "Renesas M32C"),
1041 ENUM_ENT(EM_TSK3000
, "Altium TSK3000 core"),
1042 ENUM_ENT(EM_RS08
, "Freescale RS08 embedded processor"),
1043 ENUM_ENT(EM_SHARC
, "EM_SHARC"),
1044 ENUM_ENT(EM_ECOG2
, "Cyan Technology eCOG2 microprocessor"),
1045 ENUM_ENT(EM_SCORE7
, "SUNPLUS S+Core"),
1046 ENUM_ENT(EM_DSP24
, "New Japan Radio (NJR) 24-bit DSP Processor"),
1047 ENUM_ENT(EM_VIDEOCORE3
, "Broadcom VideoCore III processor"),
1048 ENUM_ENT(EM_LATTICEMICO32
, "Lattice Mico32"),
1049 ENUM_ENT(EM_SE_C17
, "Seiko Epson C17 family"),
1050 ENUM_ENT(EM_TI_C6000
, "Texas Instruments TMS320C6000 DSP family"),
1051 ENUM_ENT(EM_TI_C2000
, "Texas Instruments TMS320C2000 DSP family"),
1052 ENUM_ENT(EM_TI_C5500
, "Texas Instruments TMS320C55x DSP family"),
1053 ENUM_ENT(EM_MMDSP_PLUS
, "STMicroelectronics 64bit VLIW Data Signal Processor"),
1054 ENUM_ENT(EM_CYPRESS_M8C
, "Cypress M8C microprocessor"),
1055 ENUM_ENT(EM_R32C
, "Renesas R32C series microprocessors"),
1056 ENUM_ENT(EM_TRIMEDIA
, "NXP Semiconductors TriMedia architecture family"),
1057 ENUM_ENT(EM_HEXAGON
, "Qualcomm Hexagon"),
1058 ENUM_ENT(EM_8051
, "Intel 8051 and variants"),
1059 ENUM_ENT(EM_STXP7X
, "STMicroelectronics STxP7x family"),
1060 ENUM_ENT(EM_NDS32
, "Andes Technology compact code size embedded RISC processor family"),
1061 ENUM_ENT(EM_ECOG1
, "Cyan Technology eCOG1 microprocessor"),
1062 ENUM_ENT(EM_ECOG1X
, "Cyan Technology eCOG1X family"),
1063 ENUM_ENT(EM_MAXQ30
, "Dallas Semiconductor MAXQ30 Core microcontrollers"),
1064 ENUM_ENT(EM_XIMO16
, "New Japan Radio (NJR) 16-bit DSP Processor"),
1065 ENUM_ENT(EM_MANIK
, "M2000 Reconfigurable RISC Microprocessor"),
1066 ENUM_ENT(EM_CRAYNV2
, "Cray Inc. NV2 vector architecture"),
1067 ENUM_ENT(EM_RX
, "Renesas RX"),
1068 ENUM_ENT(EM_METAG
, "Imagination Technologies Meta processor architecture"),
1069 ENUM_ENT(EM_MCST_ELBRUS
, "MCST Elbrus general purpose hardware architecture"),
1070 ENUM_ENT(EM_ECOG16
, "Cyan Technology eCOG16 family"),
1071 ENUM_ENT(EM_CR16
, "Xilinx MicroBlaze"),
1072 ENUM_ENT(EM_ETPU
, "Freescale Extended Time Processing Unit"),
1073 ENUM_ENT(EM_SLE9X
, "Infineon Technologies SLE9X core"),
1074 ENUM_ENT(EM_L10M
, "EM_L10M"),
1075 ENUM_ENT(EM_K10M
, "EM_K10M"),
1076 ENUM_ENT(EM_AARCH64
, "AArch64"),
1077 ENUM_ENT(EM_AVR32
, "Atmel Corporation 32-bit microprocessor family"),
1078 ENUM_ENT(EM_STM8
, "STMicroeletronics STM8 8-bit microcontroller"),
1079 ENUM_ENT(EM_TILE64
, "Tilera TILE64 multicore architecture family"),
1080 ENUM_ENT(EM_TILEPRO
, "Tilera TILEPro multicore architecture family"),
1081 ENUM_ENT(EM_CUDA
, "NVIDIA CUDA architecture"),
1082 ENUM_ENT(EM_TILEGX
, "Tilera TILE-Gx multicore architecture family"),
1083 ENUM_ENT(EM_CLOUDSHIELD
, "EM_CLOUDSHIELD"),
1084 ENUM_ENT(EM_COREA_1ST
, "EM_COREA_1ST"),
1085 ENUM_ENT(EM_COREA_2ND
, "EM_COREA_2ND"),
1086 ENUM_ENT(EM_ARC_COMPACT2
, "EM_ARC_COMPACT2"),
1087 ENUM_ENT(EM_OPEN8
, "EM_OPEN8"),
1088 ENUM_ENT(EM_RL78
, "Renesas RL78"),
1089 ENUM_ENT(EM_VIDEOCORE5
, "Broadcom VideoCore V processor"),
1090 ENUM_ENT(EM_78KOR
, "EM_78KOR"),
1091 ENUM_ENT(EM_56800EX
, "EM_56800EX"),
1092 ENUM_ENT(EM_AMDGPU
, "EM_AMDGPU"),
1093 ENUM_ENT(EM_RISCV
, "RISC-V"),
1094 ENUM_ENT(EM_LANAI
, "EM_LANAI"),
1095 ENUM_ENT(EM_BPF
, "EM_BPF"),
1098 static const EnumEntry
<unsigned> ElfSymbolBindings
[] = {
1099 {"Local", "LOCAL", ELF::STB_LOCAL
},
1100 {"Global", "GLOBAL", ELF::STB_GLOBAL
},
1101 {"Weak", "WEAK", ELF::STB_WEAK
},
1102 {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE
}};
1104 static const EnumEntry
<unsigned> ElfSymbolVisibilities
[] = {
1105 {"DEFAULT", "DEFAULT", ELF::STV_DEFAULT
},
1106 {"INTERNAL", "INTERNAL", ELF::STV_INTERNAL
},
1107 {"HIDDEN", "HIDDEN", ELF::STV_HIDDEN
},
1108 {"PROTECTED", "PROTECTED", ELF::STV_PROTECTED
}};
1110 static const EnumEntry
<unsigned> AMDGPUSymbolTypes
[] = {
1111 { "AMDGPU_HSA_KERNEL", ELF::STT_AMDGPU_HSA_KERNEL
}
1114 static const char *getGroupType(uint32_t Flag
) {
1115 if (Flag
& ELF::GRP_COMDAT
)
1121 static const EnumEntry
<unsigned> ElfSectionFlags
[] = {
1122 ENUM_ENT(SHF_WRITE
, "W"),
1123 ENUM_ENT(SHF_ALLOC
, "A"),
1124 ENUM_ENT(SHF_EXCLUDE
, "E"),
1125 ENUM_ENT(SHF_EXECINSTR
, "X"),
1126 ENUM_ENT(SHF_MERGE
, "M"),
1127 ENUM_ENT(SHF_STRINGS
, "S"),
1128 ENUM_ENT(SHF_INFO_LINK
, "I"),
1129 ENUM_ENT(SHF_LINK_ORDER
, "L"),
1130 ENUM_ENT(SHF_OS_NONCONFORMING
, "o"),
1131 ENUM_ENT(SHF_GROUP
, "G"),
1132 ENUM_ENT(SHF_TLS
, "T"),
1133 ENUM_ENT(SHF_MASKOS
, "o"),
1134 ENUM_ENT(SHF_MASKPROC
, "p"),
1135 ENUM_ENT_1(SHF_COMPRESSED
),
1138 static const EnumEntry
<unsigned> ElfXCoreSectionFlags
[] = {
1139 LLVM_READOBJ_ENUM_ENT(ELF
, XCORE_SHF_CP_SECTION
),
1140 LLVM_READOBJ_ENUM_ENT(ELF
, XCORE_SHF_DP_SECTION
)
1143 static const EnumEntry
<unsigned> ElfARMSectionFlags
[] = {
1144 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_ARM_PURECODE
)
1147 static const EnumEntry
<unsigned> ElfHexagonSectionFlags
[] = {
1148 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_HEX_GPREL
)
1151 static const EnumEntry
<unsigned> ElfMipsSectionFlags
[] = {
1152 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_MIPS_NODUPES
),
1153 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_MIPS_NAMES
),
1154 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_MIPS_LOCAL
),
1155 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_MIPS_NOSTRIP
),
1156 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_MIPS_GPREL
),
1157 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_MIPS_MERGE
),
1158 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_MIPS_ADDR
),
1159 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_MIPS_STRING
)
1162 static const EnumEntry
<unsigned> ElfX86_64SectionFlags
[] = {
1163 LLVM_READOBJ_ENUM_ENT(ELF
, SHF_X86_64_LARGE
)
1166 static std::string
getGNUFlags(uint64_t Flags
) {
1168 for (auto Entry
: ElfSectionFlags
) {
1169 uint64_t Flag
= Entry
.Value
& Flags
;
1170 Flags
&= ~Entry
.Value
;
1172 case ELF::SHF_WRITE
:
1173 case ELF::SHF_ALLOC
:
1174 case ELF::SHF_EXECINSTR
:
1175 case ELF::SHF_MERGE
:
1176 case ELF::SHF_STRINGS
:
1177 case ELF::SHF_INFO_LINK
:
1178 case ELF::SHF_LINK_ORDER
:
1179 case ELF::SHF_OS_NONCONFORMING
:
1180 case ELF::SHF_GROUP
:
1182 case ELF::SHF_EXCLUDE
:
1183 Str
+= Entry
.AltName
;
1186 if (Flag
& ELF::SHF_MASKOS
)
1188 else if (Flag
& ELF::SHF_MASKPROC
)
1197 static const char *getElfSegmentType(unsigned Arch
, unsigned Type
) {
1198 // Check potentially overlapped processor-specific
1199 // program header type.
1202 switch (Type
) { LLVM_READOBJ_ENUM_CASE(ELF
, PT_ARM_EXIDX
); }
1205 case ELF::EM_MIPS_RS3_LE
:
1207 LLVM_READOBJ_ENUM_CASE(ELF
, PT_MIPS_REGINFO
);
1208 LLVM_READOBJ_ENUM_CASE(ELF
, PT_MIPS_RTPROC
);
1209 LLVM_READOBJ_ENUM_CASE(ELF
, PT_MIPS_OPTIONS
);
1210 LLVM_READOBJ_ENUM_CASE(ELF
, PT_MIPS_ABIFLAGS
);
1216 LLVM_READOBJ_ENUM_CASE(ELF
, PT_NULL
);
1217 LLVM_READOBJ_ENUM_CASE(ELF
, PT_LOAD
);
1218 LLVM_READOBJ_ENUM_CASE(ELF
, PT_DYNAMIC
);
1219 LLVM_READOBJ_ENUM_CASE(ELF
, PT_INTERP
);
1220 LLVM_READOBJ_ENUM_CASE(ELF
, PT_NOTE
);
1221 LLVM_READOBJ_ENUM_CASE(ELF
, PT_SHLIB
);
1222 LLVM_READOBJ_ENUM_CASE(ELF
, PT_PHDR
);
1223 LLVM_READOBJ_ENUM_CASE(ELF
, PT_TLS
);
1225 LLVM_READOBJ_ENUM_CASE(ELF
, PT_GNU_EH_FRAME
);
1226 LLVM_READOBJ_ENUM_CASE(ELF
, PT_SUNW_UNWIND
);
1228 LLVM_READOBJ_ENUM_CASE(ELF
, PT_GNU_STACK
);
1229 LLVM_READOBJ_ENUM_CASE(ELF
, PT_GNU_RELRO
);
1231 LLVM_READOBJ_ENUM_CASE(ELF
, PT_OPENBSD_RANDOMIZE
);
1232 LLVM_READOBJ_ENUM_CASE(ELF
, PT_OPENBSD_WXNEEDED
);
1233 LLVM_READOBJ_ENUM_CASE(ELF
, PT_OPENBSD_BOOTDATA
);
1240 static std::string
getElfPtType(unsigned Arch
, unsigned Type
) {
1242 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_NULL
)
1243 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_LOAD
)
1244 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_DYNAMIC
)
1245 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_INTERP
)
1246 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_NOTE
)
1247 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_SHLIB
)
1248 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_PHDR
)
1249 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_TLS
)
1250 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_GNU_EH_FRAME
)
1251 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_SUNW_UNWIND
)
1252 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_GNU_STACK
)
1253 LLVM_READOBJ_PHDR_ENUM(ELF
, PT_GNU_RELRO
)
1255 // All machine specific PT_* types
1258 if (Type
== ELF::PT_ARM_EXIDX
)
1262 case ELF::EM_MIPS_RS3_LE
:
1264 case PT_MIPS_REGINFO
:
1266 case PT_MIPS_RTPROC
:
1268 case PT_MIPS_OPTIONS
:
1270 case PT_MIPS_ABIFLAGS
:
1276 return std::string("<unknown>: ") + to_string(format_hex(Type
, 1));
1279 static const EnumEntry
<unsigned> ElfSegmentFlags
[] = {
1280 LLVM_READOBJ_ENUM_ENT(ELF
, PF_X
),
1281 LLVM_READOBJ_ENUM_ENT(ELF
, PF_W
),
1282 LLVM_READOBJ_ENUM_ENT(ELF
, PF_R
)
1285 static const EnumEntry
<unsigned> ElfHeaderMipsFlags
[] = {
1286 ENUM_ENT(EF_MIPS_NOREORDER
, "noreorder"),
1287 ENUM_ENT(EF_MIPS_PIC
, "pic"),
1288 ENUM_ENT(EF_MIPS_CPIC
, "cpic"),
1289 ENUM_ENT(EF_MIPS_ABI2
, "abi2"),
1290 ENUM_ENT(EF_MIPS_32BITMODE
, "32bitmode"),
1291 ENUM_ENT(EF_MIPS_FP64
, "fp64"),
1292 ENUM_ENT(EF_MIPS_NAN2008
, "nan2008"),
1293 ENUM_ENT(EF_MIPS_ABI_O32
, "o32"),
1294 ENUM_ENT(EF_MIPS_ABI_O64
, "o64"),
1295 ENUM_ENT(EF_MIPS_ABI_EABI32
, "eabi32"),
1296 ENUM_ENT(EF_MIPS_ABI_EABI64
, "eabi64"),
1297 ENUM_ENT(EF_MIPS_MACH_3900
, "3900"),
1298 ENUM_ENT(EF_MIPS_MACH_4010
, "4010"),
1299 ENUM_ENT(EF_MIPS_MACH_4100
, "4100"),
1300 ENUM_ENT(EF_MIPS_MACH_4650
, "4650"),
1301 ENUM_ENT(EF_MIPS_MACH_4120
, "4120"),
1302 ENUM_ENT(EF_MIPS_MACH_4111
, "4111"),
1303 ENUM_ENT(EF_MIPS_MACH_SB1
, "sb1"),
1304 ENUM_ENT(EF_MIPS_MACH_OCTEON
, "octeon"),
1305 ENUM_ENT(EF_MIPS_MACH_XLR
, "xlr"),
1306 ENUM_ENT(EF_MIPS_MACH_OCTEON2
, "octeon2"),
1307 ENUM_ENT(EF_MIPS_MACH_OCTEON3
, "octeon3"),
1308 ENUM_ENT(EF_MIPS_MACH_5400
, "5400"),
1309 ENUM_ENT(EF_MIPS_MACH_5900
, "5900"),
1310 ENUM_ENT(EF_MIPS_MACH_5500
, "5500"),
1311 ENUM_ENT(EF_MIPS_MACH_9000
, "9000"),
1312 ENUM_ENT(EF_MIPS_MACH_LS2E
, "loongson-2e"),
1313 ENUM_ENT(EF_MIPS_MACH_LS2F
, "loongson-2f"),
1314 ENUM_ENT(EF_MIPS_MACH_LS3A
, "loongson-3a"),
1315 ENUM_ENT(EF_MIPS_MICROMIPS
, "micromips"),
1316 ENUM_ENT(EF_MIPS_ARCH_ASE_M16
, "mips16"),
1317 ENUM_ENT(EF_MIPS_ARCH_ASE_MDMX
, "mdmx"),
1318 ENUM_ENT(EF_MIPS_ARCH_1
, "mips1"),
1319 ENUM_ENT(EF_MIPS_ARCH_2
, "mips2"),
1320 ENUM_ENT(EF_MIPS_ARCH_3
, "mips3"),
1321 ENUM_ENT(EF_MIPS_ARCH_4
, "mips4"),
1322 ENUM_ENT(EF_MIPS_ARCH_5
, "mips5"),
1323 ENUM_ENT(EF_MIPS_ARCH_32
, "mips32"),
1324 ENUM_ENT(EF_MIPS_ARCH_64
, "mips64"),
1325 ENUM_ENT(EF_MIPS_ARCH_32R2
, "mips32r2"),
1326 ENUM_ENT(EF_MIPS_ARCH_64R2
, "mips64r2"),
1327 ENUM_ENT(EF_MIPS_ARCH_32R6
, "mips32r6"),
1328 ENUM_ENT(EF_MIPS_ARCH_64R6
, "mips64r6")
1331 static const EnumEntry
<unsigned> ElfHeaderAMDGPUFlags
[] = {
1332 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_NONE
),
1333 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_R600
),
1334 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_R630
),
1335 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_RS880
),
1336 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_RV670
),
1337 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_RV710
),
1338 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_RV730
),
1339 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_RV770
),
1340 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_CEDAR
),
1341 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_CYPRESS
),
1342 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_JUNIPER
),
1343 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_REDWOOD
),
1344 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_SUMO
),
1345 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_BARTS
),
1346 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_CAICOS
),
1347 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_CAYMAN
),
1348 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_R600_TURKS
),
1349 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX600
),
1350 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX601
),
1351 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX700
),
1352 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX701
),
1353 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX702
),
1354 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX703
),
1355 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX704
),
1356 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX801
),
1357 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX802
),
1358 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX803
),
1359 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX810
),
1360 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX900
),
1361 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX902
),
1362 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX904
),
1363 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX906
),
1364 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX908
),
1365 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX909
),
1366 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX1010
),
1367 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX1011
),
1368 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_MACH_AMDGCN_GFX1012
),
1369 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_XNACK
),
1370 LLVM_READOBJ_ENUM_ENT(ELF
, EF_AMDGPU_SRAM_ECC
)
1373 static const EnumEntry
<unsigned> ElfHeaderRISCVFlags
[] = {
1374 ENUM_ENT(EF_RISCV_RVC
, "RVC"),
1375 ENUM_ENT(EF_RISCV_FLOAT_ABI_SINGLE
, "single-float ABI"),
1376 ENUM_ENT(EF_RISCV_FLOAT_ABI_DOUBLE
, "double-float ABI"),
1377 ENUM_ENT(EF_RISCV_FLOAT_ABI_QUAD
, "quad-float ABI"),
1378 ENUM_ENT(EF_RISCV_RVE
, "RVE")
1381 static const EnumEntry
<unsigned> ElfSymOtherFlags
[] = {
1382 LLVM_READOBJ_ENUM_ENT(ELF
, STV_INTERNAL
),
1383 LLVM_READOBJ_ENUM_ENT(ELF
, STV_HIDDEN
),
1384 LLVM_READOBJ_ENUM_ENT(ELF
, STV_PROTECTED
)
1387 static const EnumEntry
<unsigned> ElfMipsSymOtherFlags
[] = {
1388 LLVM_READOBJ_ENUM_ENT(ELF
, STO_MIPS_OPTIONAL
),
1389 LLVM_READOBJ_ENUM_ENT(ELF
, STO_MIPS_PLT
),
1390 LLVM_READOBJ_ENUM_ENT(ELF
, STO_MIPS_PIC
),
1391 LLVM_READOBJ_ENUM_ENT(ELF
, STO_MIPS_MICROMIPS
)
1394 static const EnumEntry
<unsigned> ElfMips16SymOtherFlags
[] = {
1395 LLVM_READOBJ_ENUM_ENT(ELF
, STO_MIPS_OPTIONAL
),
1396 LLVM_READOBJ_ENUM_ENT(ELF
, STO_MIPS_PLT
),
1397 LLVM_READOBJ_ENUM_ENT(ELF
, STO_MIPS_MIPS16
)
1400 static const char *getElfMipsOptionsOdkType(unsigned Odk
) {
1402 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_NULL
);
1403 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_REGINFO
);
1404 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_EXCEPTIONS
);
1405 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_PAD
);
1406 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_HWPATCH
);
1407 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_FILL
);
1408 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_TAGS
);
1409 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_HWAND
);
1410 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_HWOR
);
1411 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_GP_GROUP
);
1412 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_IDENT
);
1413 LLVM_READOBJ_ENUM_CASE(ELF
, ODK_PAGESIZE
);
1419 template <typename ELFT
>
1420 void ELFDumper
<ELFT
>::loadDynamicTable(const ELFFile
<ELFT
> *Obj
) {
1421 // Try to locate the PT_DYNAMIC header.
1422 const Elf_Phdr
*DynamicPhdr
= nullptr;
1423 for (const Elf_Phdr
&Phdr
:
1424 unwrapOrError(ObjF
->getFileName(), Obj
->program_headers())) {
1425 if (Phdr
.p_type
!= ELF::PT_DYNAMIC
)
1427 DynamicPhdr
= &Phdr
;
1431 // Try to locate the .dynamic section in the sections header table.
1432 const Elf_Shdr
*DynamicSec
= nullptr;
1433 for (const Elf_Shdr
&Sec
:
1434 unwrapOrError(ObjF
->getFileName(), Obj
->sections())) {
1435 if (Sec
.sh_type
!= ELF::SHT_DYNAMIC
)
1441 // Information in the section header has priority over the information
1442 // in a PT_DYNAMIC header.
1443 // Ignore sh_entsize and use the expected value for entry size explicitly.
1444 // This allows us to dump the dynamic sections with a broken sh_entsize
1448 checkDRI({ObjF
->getELFFile()->base() + DynamicSec
->sh_offset
,
1449 DynamicSec
->sh_size
, sizeof(Elf_Dyn
), ObjF
->getFileName()});
1450 parseDynamicTable();
1453 // If we have a PT_DYNAMIC header, we will either check the found dynamic
1454 // section or take the dynamic table data directly from the header.
1458 if (DynamicPhdr
->p_offset
+ DynamicPhdr
->p_filesz
>
1459 ObjF
->getMemoryBufferRef().getBufferSize()) {
1462 "PT_DYNAMIC segment offset + size exceeds the size of the file"),
1463 ObjF
->getFileName());
1468 DynamicTable
= createDRIFrom(DynamicPhdr
, sizeof(Elf_Dyn
));
1469 parseDynamicTable();
1474 unwrapOrError(ObjF
->getFileName(), Obj
->getSectionName(DynamicSec
));
1475 if (DynamicSec
->sh_addr
+ DynamicSec
->sh_size
>
1476 DynamicPhdr
->p_vaddr
+ DynamicPhdr
->p_memsz
||
1477 DynamicSec
->sh_addr
< DynamicPhdr
->p_vaddr
)
1478 reportWarning(createError("The SHT_DYNAMIC section '" + Name
+
1479 "' is not contained within the "
1480 "PT_DYNAMIC segment"),
1481 ObjF
->getFileName());
1483 if (DynamicSec
->sh_addr
!= DynamicPhdr
->p_vaddr
)
1484 reportWarning(createError("The SHT_DYNAMIC section '" + Name
+
1485 "' is not at the start of "
1486 "PT_DYNAMIC segment"),
1487 ObjF
->getFileName());
1490 template <typename ELFT
>
1491 ELFDumper
<ELFT
>::ELFDumper(const object::ELFObjectFile
<ELFT
> *ObjF
,
1492 ScopedPrinter
&Writer
)
1493 : ObjDumper(Writer
), ObjF(ObjF
), DynRelRegion(ObjF
->getFileName()),
1494 DynRelaRegion(ObjF
->getFileName()), DynRelrRegion(ObjF
->getFileName()),
1495 DynPLTRelRegion(ObjF
->getFileName()), DynSymRegion(ObjF
->getFileName()),
1496 DynamicTable(ObjF
->getFileName()) {
1497 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
1498 for (const Elf_Shdr
&Sec
:
1499 unwrapOrError(ObjF
->getFileName(), Obj
->sections())) {
1500 switch (Sec
.sh_type
) {
1501 case ELF::SHT_SYMTAB
:
1503 DotSymtabSec
= &Sec
;
1505 case ELF::SHT_DYNSYM
:
1506 if (!DynSymRegion
.Size
) {
1507 DynSymRegion
= createDRIFrom(&Sec
);
1508 // This is only used (if Elf_Shdr present)for naming section in GNU
1511 unwrapOrError(ObjF
->getFileName(), Obj
->getSectionName(&Sec
));
1513 if (Expected
<StringRef
> E
= Obj
->getStringTableForSymtab(Sec
))
1514 DynamicStringTable
= *E
;
1516 reportWarning(E
.takeError(), ObjF
->getFileName());
1519 case ELF::SHT_SYMTAB_SHNDX
:
1520 ShndxTable
= unwrapOrError(ObjF
->getFileName(), Obj
->getSHNDXTable(Sec
));
1522 case ELF::SHT_GNU_versym
:
1523 if (!SymbolVersionSection
)
1524 SymbolVersionSection
= &Sec
;
1526 case ELF::SHT_GNU_verdef
:
1527 if (!SymbolVersionDefSection
)
1528 SymbolVersionDefSection
= &Sec
;
1530 case ELF::SHT_GNU_verneed
:
1531 if (!SymbolVersionNeedSection
)
1532 SymbolVersionNeedSection
= &Sec
;
1534 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE
:
1535 if (!DotCGProfileSec
)
1536 DotCGProfileSec
= &Sec
;
1538 case ELF::SHT_LLVM_ADDRSIG
:
1540 DotAddrsigSec
= &Sec
;
1545 loadDynamicTable(Obj
);
1547 if (opts::Output
== opts::GNU
)
1548 ELFDumperStyle
.reset(new GNUStyle
<ELFT
>(Writer
, this));
1550 ELFDumperStyle
.reset(new LLVMStyle
<ELFT
>(Writer
, this));
1553 static const char *getTypeString(unsigned Arch
, uint64_t Type
) {
1554 #define DYNAMIC_TAG(n, v)
1559 #define AARCH64_DYNAMIC_TAG(name, value) \
1562 #include "llvm/BinaryFormat/DynamicTags.def"
1563 #undef AARCH64_DYNAMIC_TAG
1569 #define HEXAGON_DYNAMIC_TAG(name, value) \
1572 #include "llvm/BinaryFormat/DynamicTags.def"
1573 #undef HEXAGON_DYNAMIC_TAG
1579 #define MIPS_DYNAMIC_TAG(name, value) \
1582 #include "llvm/BinaryFormat/DynamicTags.def"
1583 #undef MIPS_DYNAMIC_TAG
1589 #define PPC64_DYNAMIC_TAG(name, value) \
1592 #include "llvm/BinaryFormat/DynamicTags.def"
1593 #undef PPC64_DYNAMIC_TAG
1599 // Now handle all dynamic tags except the architecture specific ones
1600 #define AARCH64_DYNAMIC_TAG(name, value)
1601 #define MIPS_DYNAMIC_TAG(name, value)
1602 #define HEXAGON_DYNAMIC_TAG(name, value)
1603 #define PPC64_DYNAMIC_TAG(name, value)
1604 // Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
1605 #define DYNAMIC_TAG_MARKER(name, value)
1606 #define DYNAMIC_TAG(name, value) \
1609 #include "llvm/BinaryFormat/DynamicTags.def"
1611 #undef AARCH64_DYNAMIC_TAG
1612 #undef MIPS_DYNAMIC_TAG
1613 #undef HEXAGON_DYNAMIC_TAG
1614 #undef PPC64_DYNAMIC_TAG
1615 #undef DYNAMIC_TAG_MARKER
1621 template <typename ELFT
> void ELFDumper
<ELFT
>::parseDynamicTable() {
1622 auto toMappedAddr
= [&](uint64_t Tag
, uint64_t VAddr
) -> const uint8_t * {
1623 auto MappedAddrOrError
= ObjF
->getELFFile()->toMappedAddr(VAddr
);
1624 if (!MappedAddrOrError
) {
1626 createError("Unable to parse DT_" +
1627 Twine(getTypeString(
1628 ObjF
->getELFFile()->getHeader()->e_machine
, Tag
)) +
1629 ": " + llvm::toString(MappedAddrOrError
.takeError()));
1631 reportWarning(std::move(Err
), ObjF
->getFileName());
1634 return MappedAddrOrError
.get();
1637 uint64_t SONameOffset
= 0;
1638 const char *StringTableBegin
= nullptr;
1639 uint64_t StringTableSize
= 0;
1640 for (const Elf_Dyn
&Dyn
: dynamic_table()) {
1641 switch (Dyn
.d_tag
) {
1643 HashTable
= reinterpret_cast<const Elf_Hash
*>(
1644 toMappedAddr(Dyn
.getTag(), Dyn
.getPtr()));
1646 case ELF::DT_GNU_HASH
:
1647 GnuHashTable
= reinterpret_cast<const Elf_GnuHash
*>(
1648 toMappedAddr(Dyn
.getTag(), Dyn
.getPtr()));
1650 case ELF::DT_STRTAB
:
1651 StringTableBegin
= reinterpret_cast<const char *>(
1652 toMappedAddr(Dyn
.getTag(), Dyn
.getPtr()));
1655 StringTableSize
= Dyn
.getVal();
1657 case ELF::DT_SYMTAB
: {
1658 // Often we find the information about the dynamic symbol table
1659 // location in the SHT_DYNSYM section header. However, the value in
1660 // DT_SYMTAB has priority, because it is used by dynamic loaders to
1661 // locate .dynsym at runtime. The location we find in the section header
1662 // and the location we find here should match. If we can't map the
1663 // DT_SYMTAB value to an address (e.g. when there are no program headers), we
1664 // ignore its value.
1665 if (const uint8_t *VA
= toMappedAddr(Dyn
.getTag(), Dyn
.getPtr())) {
1666 // EntSize is non-zero if the dynamic symbol table has been found via a
1668 if (DynSymRegion
.EntSize
&& VA
!= DynSymRegion
.Addr
)
1671 "SHT_DYNSYM section header and DT_SYMTAB disagree about "
1672 "the location of the dynamic symbol table"),
1673 ObjF
->getFileName());
1675 DynSymRegion
.Addr
= VA
;
1676 DynSymRegion
.EntSize
= sizeof(Elf_Sym
);
1681 DynRelaRegion
.Addr
= toMappedAddr(Dyn
.getTag(), Dyn
.getPtr());
1683 case ELF::DT_RELASZ
:
1684 DynRelaRegion
.Size
= Dyn
.getVal();
1686 case ELF::DT_RELAENT
:
1687 DynRelaRegion
.EntSize
= Dyn
.getVal();
1689 case ELF::DT_SONAME
:
1690 SONameOffset
= Dyn
.getVal();
1693 DynRelRegion
.Addr
= toMappedAddr(Dyn
.getTag(), Dyn
.getPtr());
1696 DynRelRegion
.Size
= Dyn
.getVal();
1698 case ELF::DT_RELENT
:
1699 DynRelRegion
.EntSize
= Dyn
.getVal();
1702 case ELF::DT_ANDROID_RELR
:
1703 DynRelrRegion
.Addr
= toMappedAddr(Dyn
.getTag(), Dyn
.getPtr());
1705 case ELF::DT_RELRSZ
:
1706 case ELF::DT_ANDROID_RELRSZ
:
1707 DynRelrRegion
.Size
= Dyn
.getVal();
1709 case ELF::DT_RELRENT
:
1710 case ELF::DT_ANDROID_RELRENT
:
1711 DynRelrRegion
.EntSize
= Dyn
.getVal();
1713 case ELF::DT_PLTREL
:
1714 if (Dyn
.getVal() == DT_REL
)
1715 DynPLTRelRegion
.EntSize
= sizeof(Elf_Rel
);
1716 else if (Dyn
.getVal() == DT_RELA
)
1717 DynPLTRelRegion
.EntSize
= sizeof(Elf_Rela
);
1719 reportError(createError(Twine("unknown DT_PLTREL value of ") +
1720 Twine((uint64_t)Dyn
.getVal())),
1721 ObjF
->getFileName());
1723 case ELF::DT_JMPREL
:
1724 DynPLTRelRegion
.Addr
= toMappedAddr(Dyn
.getTag(), Dyn
.getPtr());
1726 case ELF::DT_PLTRELSZ
:
1727 DynPLTRelRegion
.Size
= Dyn
.getVal();
1731 if (StringTableBegin
)
1732 DynamicStringTable
= StringRef(StringTableBegin
, StringTableSize
);
1733 SOName
= getDynamicString(SONameOffset
);
1736 template <typename ELFT
>
1737 typename ELFDumper
<ELFT
>::Elf_Rel_Range ELFDumper
<ELFT
>::dyn_rels() const {
1738 return DynRelRegion
.getAsArrayRef
<Elf_Rel
>();
1741 template <typename ELFT
>
1742 typename ELFDumper
<ELFT
>::Elf_Rela_Range ELFDumper
<ELFT
>::dyn_relas() const {
1743 return DynRelaRegion
.getAsArrayRef
<Elf_Rela
>();
1746 template <typename ELFT
>
1747 typename ELFDumper
<ELFT
>::Elf_Relr_Range ELFDumper
<ELFT
>::dyn_relrs() const {
1748 return DynRelrRegion
.getAsArrayRef
<Elf_Relr
>();
1751 template <class ELFT
> void ELFDumper
<ELFT
>::printFileHeaders() {
1752 ELFDumperStyle
->printFileHeaders(ObjF
->getELFFile());
1755 template <class ELFT
> void ELFDumper
<ELFT
>::printSectionHeaders() {
1756 ELFDumperStyle
->printSectionHeaders(ObjF
->getELFFile());
1759 template <class ELFT
> void ELFDumper
<ELFT
>::printRelocations() {
1760 ELFDumperStyle
->printRelocations(ObjF
->getELFFile());
1763 template <class ELFT
>
1764 void ELFDumper
<ELFT
>::printProgramHeaders(
1765 bool PrintProgramHeaders
, cl::boolOrDefault PrintSectionMapping
) {
1766 ELFDumperStyle
->printProgramHeaders(ObjF
->getELFFile(), PrintProgramHeaders
,
1767 PrintSectionMapping
);
1770 template <typename ELFT
> void ELFDumper
<ELFT
>::printVersionInfo() {
1771 // Dump version symbol section.
1772 ELFDumperStyle
->printVersionSymbolSection(ObjF
->getELFFile(),
1773 SymbolVersionSection
);
1775 // Dump version definition section.
1776 ELFDumperStyle
->printVersionDefinitionSection(ObjF
->getELFFile(),
1777 SymbolVersionDefSection
);
1779 // Dump version dependency section.
1780 ELFDumperStyle
->printVersionDependencySection(ObjF
->getELFFile(),
1781 SymbolVersionNeedSection
);
1784 template <class ELFT
> void ELFDumper
<ELFT
>::printDynamicRelocations() {
1785 ELFDumperStyle
->printDynamicRelocations(ObjF
->getELFFile());
1788 template <class ELFT
>
1789 void ELFDumper
<ELFT
>::printSymbols(bool PrintSymbols
,
1790 bool PrintDynamicSymbols
) {
1791 ELFDumperStyle
->printSymbols(ObjF
->getELFFile(), PrintSymbols
,
1792 PrintDynamicSymbols
);
1795 template <class ELFT
> void ELFDumper
<ELFT
>::printHashSymbols() {
1796 ELFDumperStyle
->printHashSymbols(ObjF
->getELFFile());
1799 template <class ELFT
> void ELFDumper
<ELFT
>::printHashHistogram() {
1800 ELFDumperStyle
->printHashHistogram(ObjF
->getELFFile());
1803 template <class ELFT
> void ELFDumper
<ELFT
>::printCGProfile() {
1804 ELFDumperStyle
->printCGProfile(ObjF
->getELFFile());
1807 template <class ELFT
> void ELFDumper
<ELFT
>::printNotes() {
1808 ELFDumperStyle
->printNotes(ObjF
->getELFFile());
1811 template <class ELFT
> void ELFDumper
<ELFT
>::printELFLinkerOptions() {
1812 ELFDumperStyle
->printELFLinkerOptions(ObjF
->getELFFile());
1815 template <class ELFT
> void ELFDumper
<ELFT
>::printStackSizes() {
1816 ELFDumperStyle
->printStackSizes(ObjF
);
1819 #define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \
1820 { #enum, prefix##_##enum }
1822 static const EnumEntry
<unsigned> ElfDynamicDTFlags
[] = {
1823 LLVM_READOBJ_DT_FLAG_ENT(DF
, ORIGIN
),
1824 LLVM_READOBJ_DT_FLAG_ENT(DF
, SYMBOLIC
),
1825 LLVM_READOBJ_DT_FLAG_ENT(DF
, TEXTREL
),
1826 LLVM_READOBJ_DT_FLAG_ENT(DF
, BIND_NOW
),
1827 LLVM_READOBJ_DT_FLAG_ENT(DF
, STATIC_TLS
)
1830 static const EnumEntry
<unsigned> ElfDynamicDTFlags1
[] = {
1831 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, NOW
),
1832 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, GLOBAL
),
1833 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, GROUP
),
1834 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, NODELETE
),
1835 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, LOADFLTR
),
1836 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, INITFIRST
),
1837 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, NOOPEN
),
1838 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, ORIGIN
),
1839 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, DIRECT
),
1840 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, TRANS
),
1841 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, INTERPOSE
),
1842 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, NODEFLIB
),
1843 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, NODUMP
),
1844 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, CONFALT
),
1845 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, ENDFILTEE
),
1846 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, DISPRELDNE
),
1847 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, DISPRELPND
),
1848 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, NODIRECT
),
1849 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, IGNMULDEF
),
1850 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, NOKSYMS
),
1851 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, NOHDR
),
1852 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, EDITED
),
1853 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, NORELOC
),
1854 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, SYMINTPOSE
),
1855 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, GLOBAUDIT
),
1856 LLVM_READOBJ_DT_FLAG_ENT(DF_1
, SINGLETON
)
1859 static const EnumEntry
<unsigned> ElfDynamicDTMipsFlags
[] = {
1860 LLVM_READOBJ_DT_FLAG_ENT(RHF
, NONE
),
1861 LLVM_READOBJ_DT_FLAG_ENT(RHF
, QUICKSTART
),
1862 LLVM_READOBJ_DT_FLAG_ENT(RHF
, NOTPOT
),
1863 LLVM_READOBJ_DT_FLAG_ENT(RHS
, NO_LIBRARY_REPLACEMENT
),
1864 LLVM_READOBJ_DT_FLAG_ENT(RHF
, NO_MOVE
),
1865 LLVM_READOBJ_DT_FLAG_ENT(RHF
, SGI_ONLY
),
1866 LLVM_READOBJ_DT_FLAG_ENT(RHF
, GUARANTEE_INIT
),
1867 LLVM_READOBJ_DT_FLAG_ENT(RHF
, DELTA_C_PLUS_PLUS
),
1868 LLVM_READOBJ_DT_FLAG_ENT(RHF
, GUARANTEE_START_INIT
),
1869 LLVM_READOBJ_DT_FLAG_ENT(RHF
, PIXIE
),
1870 LLVM_READOBJ_DT_FLAG_ENT(RHF
, DEFAULT_DELAY_LOAD
),
1871 LLVM_READOBJ_DT_FLAG_ENT(RHF
, REQUICKSTART
),
1872 LLVM_READOBJ_DT_FLAG_ENT(RHF
, REQUICKSTARTED
),
1873 LLVM_READOBJ_DT_FLAG_ENT(RHF
, CORD
),
1874 LLVM_READOBJ_DT_FLAG_ENT(RHF
, NO_UNRES_UNDEF
),
1875 LLVM_READOBJ_DT_FLAG_ENT(RHF
, RLD_ORDER_SAFE
)
1878 #undef LLVM_READOBJ_DT_FLAG_ENT
1880 template <typename T
, typename TFlag
>
1881 void printFlags(T Value
, ArrayRef
<EnumEntry
<TFlag
>> Flags
, raw_ostream
&OS
) {
1882 using FlagEntry
= EnumEntry
<TFlag
>;
1883 using FlagVector
= SmallVector
<FlagEntry
, 10>;
1884 FlagVector SetFlags
;
1886 for (const auto &Flag
: Flags
) {
1887 if (Flag
.Value
== 0)
1890 if ((Value
& Flag
.Value
) == Flag
.Value
)
1891 SetFlags
.push_back(Flag
);
1894 for (const auto &Flag
: SetFlags
) {
1895 OS
<< Flag
.Name
<< " ";
1899 template <class ELFT
>
1900 void ELFDumper
<ELFT
>::printDynamicEntry(raw_ostream
&OS
, uint64_t Type
,
1901 uint64_t Value
) const {
1902 const char *ConvChar
=
1903 (opts::Output
== opts::GNU
) ? "0x%" PRIx64
: "0x%" PRIX64
;
1905 // Handle custom printing of architecture specific tags
1906 switch (ObjF
->getELFFile()->getHeader()->e_machine
) {
1909 case DT_AARCH64_BTI_PLT
:
1910 case DT_AARCH64_PAC_PLT
:
1919 case DT_HEXAGON_VER
:
1922 case DT_HEXAGON_SYMSZ
:
1923 case DT_HEXAGON_PLT
:
1924 OS
<< format(ConvChar
, Value
);
1932 case DT_MIPS_RLD_VERSION
:
1933 case DT_MIPS_LOCAL_GOTNO
:
1934 case DT_MIPS_SYMTABNO
:
1935 case DT_MIPS_UNREFEXTNO
:
1938 case DT_MIPS_TIME_STAMP
:
1939 case DT_MIPS_ICHECKSUM
:
1940 case DT_MIPS_IVERSION
:
1941 case DT_MIPS_BASE_ADDRESS
:
1943 case DT_MIPS_CONFLICT
:
1944 case DT_MIPS_LIBLIST
:
1945 case DT_MIPS_CONFLICTNO
:
1946 case DT_MIPS_LIBLISTNO
:
1947 case DT_MIPS_GOTSYM
:
1948 case DT_MIPS_HIPAGENO
:
1949 case DT_MIPS_RLD_MAP
:
1950 case DT_MIPS_DELTA_CLASS
:
1951 case DT_MIPS_DELTA_CLASS_NO
:
1952 case DT_MIPS_DELTA_INSTANCE
:
1953 case DT_MIPS_DELTA_RELOC
:
1954 case DT_MIPS_DELTA_RELOC_NO
:
1955 case DT_MIPS_DELTA_SYM
:
1956 case DT_MIPS_DELTA_SYM_NO
:
1957 case DT_MIPS_DELTA_CLASSSYM
:
1958 case DT_MIPS_DELTA_CLASSSYM_NO
:
1959 case DT_MIPS_CXX_FLAGS
:
1960 case DT_MIPS_PIXIE_INIT
:
1961 case DT_MIPS_SYMBOL_LIB
:
1962 case DT_MIPS_LOCALPAGE_GOTIDX
:
1963 case DT_MIPS_LOCAL_GOTIDX
:
1964 case DT_MIPS_HIDDEN_GOTIDX
:
1965 case DT_MIPS_PROTECTED_GOTIDX
:
1966 case DT_MIPS_OPTIONS
:
1967 case DT_MIPS_INTERFACE
:
1968 case DT_MIPS_DYNSTR_ALIGN
:
1969 case DT_MIPS_INTERFACE_SIZE
:
1970 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR
:
1971 case DT_MIPS_PERF_SUFFIX
:
1972 case DT_MIPS_COMPACT_SIZE
:
1973 case DT_MIPS_GP_VALUE
:
1974 case DT_MIPS_AUX_DYNAMIC
:
1975 case DT_MIPS_PLTGOT
:
1977 case DT_MIPS_RLD_MAP_REL
:
1978 OS
<< format(ConvChar
, Value
);
1981 printFlags(Value
, makeArrayRef(ElfDynamicDTMipsFlags
), OS
);
1993 if (Value
== DT_REL
) {
1996 } else if (Value
== DT_RELA
) {
2012 case DT_PREINIT_ARRAY
:
2019 OS
<< format(ConvChar
, Value
);
2034 case DT_INIT_ARRAYSZ
:
2035 case DT_FINI_ARRAYSZ
:
2036 case DT_PREINIT_ARRAYSZ
:
2037 case DT_ANDROID_RELSZ
:
2038 case DT_ANDROID_RELASZ
:
2039 OS
<< Value
<< " (bytes)";
2048 const std::map
<uint64_t, const char*> TagNames
= {
2049 {DT_NEEDED
, "Shared library"},
2050 {DT_SONAME
, "Library soname"},
2051 {DT_AUXILIARY
, "Auxiliary library"},
2052 {DT_USED
, "Not needed object"},
2053 {DT_FILTER
, "Filter library"},
2054 {DT_RPATH
, "Library rpath"},
2055 {DT_RUNPATH
, "Library runpath"},
2057 OS
<< TagNames
.at(Type
) << ": [" << getDynamicString(Value
) << "]";
2061 printFlags(Value
, makeArrayRef(ElfDynamicDTFlags
), OS
);
2064 printFlags(Value
, makeArrayRef(ElfDynamicDTFlags1
), OS
);
2067 OS
<< format(ConvChar
, Value
);
2072 template <class ELFT
>
2073 std::string ELFDumper
<ELFT
>::getDynamicString(uint64_t Value
) const {
2074 if (DynamicStringTable
.empty())
2075 return "<String table is empty or was not found>";
2076 if (Value
< DynamicStringTable
.size())
2077 return DynamicStringTable
.data() + Value
;
2078 return Twine("<Invalid offset 0x" + utohexstr(Value
) + ">").str();
2081 template <class ELFT
> void ELFDumper
<ELFT
>::printUnwindInfo() {
2082 DwarfCFIEH::PrinterContext
<ELFT
> Ctx(W
, ObjF
);
2083 Ctx
.printUnwindInformation();
2088 template <> void ELFDumper
<ELF32LE
>::printUnwindInfo() {
2089 const ELFFile
<ELF32LE
> *Obj
= ObjF
->getELFFile();
2090 const unsigned Machine
= Obj
->getHeader()->e_machine
;
2091 if (Machine
== EM_ARM
) {
2092 ARM::EHABI::PrinterContext
<ELF32LE
> Ctx(W
, Obj
, ObjF
->getFileName(),
2094 Ctx
.PrintUnwindInformation();
2096 DwarfCFIEH::PrinterContext
<ELF32LE
> Ctx(W
, ObjF
);
2097 Ctx
.printUnwindInformation();
2100 } // end anonymous namespace
2102 template <class ELFT
> void ELFDumper
<ELFT
>::printDynamicTable() {
2103 ELFDumperStyle
->printDynamic(ObjF
->getELFFile());
2106 template <class ELFT
> void ELFDumper
<ELFT
>::printNeededLibraries() {
2107 ListScope
D(W
, "NeededLibraries");
2109 std::vector
<std::string
> Libs
;
2110 for (const auto &Entry
: dynamic_table())
2111 if (Entry
.d_tag
== ELF::DT_NEEDED
)
2112 Libs
.push_back(getDynamicString(Entry
.d_un
.d_val
));
2114 llvm::stable_sort(Libs
);
2116 for (const auto &L
: Libs
)
2117 W
.startLine() << L
<< "\n";
2120 template <typename ELFT
> void ELFDumper
<ELFT
>::printHashTable() {
2121 DictScope
D(W
, "HashTable");
2124 W
.printNumber("Num Buckets", HashTable
->nbucket
);
2125 W
.printNumber("Num Chains", HashTable
->nchain
);
2126 W
.printList("Buckets", HashTable
->buckets());
2127 W
.printList("Chains", HashTable
->chains());
2130 template <typename ELFT
> void ELFDumper
<ELFT
>::printGnuHashTable() {
2131 DictScope
D(W
, "GnuHashTable");
2134 W
.printNumber("Num Buckets", GnuHashTable
->nbuckets
);
2135 W
.printNumber("First Hashed Symbol Index", GnuHashTable
->symndx
);
2136 W
.printNumber("Num Mask Words", GnuHashTable
->maskwords
);
2137 W
.printNumber("Shift Count", GnuHashTable
->shift2
);
2138 W
.printHexList("Bloom Filter", GnuHashTable
->filter());
2139 W
.printList("Buckets", GnuHashTable
->buckets());
2140 Elf_Sym_Range Syms
= dynamic_symbols();
2141 unsigned NumSyms
= std::distance(Syms
.begin(), Syms
.end());
2143 reportError(createError("No dynamic symbol section"), ObjF
->getFileName());
2144 W
.printHexList("Values", GnuHashTable
->values(NumSyms
));
2147 template <typename ELFT
> void ELFDumper
<ELFT
>::printLoadName() {
2148 W
.printString("LoadName", SOName
);
2151 template <class ELFT
> void ELFDumper
<ELFT
>::printAttributes() {
2152 W
.startLine() << "Attributes not implemented.\n";
2157 template <> void ELFDumper
<ELF32LE
>::printAttributes() {
2158 const ELFFile
<ELF32LE
> *Obj
= ObjF
->getELFFile();
2159 if (Obj
->getHeader()->e_machine
!= EM_ARM
) {
2160 W
.startLine() << "Attributes not implemented.\n";
2164 DictScope
BA(W
, "BuildAttributes");
2165 for (const ELFO::Elf_Shdr
&Sec
:
2166 unwrapOrError(ObjF
->getFileName(), Obj
->sections())) {
2167 if (Sec
.sh_type
!= ELF::SHT_ARM_ATTRIBUTES
)
2170 ArrayRef
<uint8_t> Contents
=
2171 unwrapOrError(ObjF
->getFileName(), Obj
->getSectionContents(&Sec
));
2172 if (Contents
[0] != ARMBuildAttrs::Format_Version
) {
2173 errs() << "unrecognised FormatVersion: 0x"
2174 << Twine::utohexstr(Contents
[0]) << '\n';
2178 W
.printHex("FormatVersion", Contents
[0]);
2179 if (Contents
.size() == 1)
2182 ARMAttributeParser(&W
).Parse(Contents
, true);
2186 template <class ELFT
> class MipsGOTParser
{
2188 TYPEDEF_ELF_TYPES(ELFT
)
2189 using Entry
= typename
ELFO::Elf_Addr
;
2190 using Entries
= ArrayRef
<Entry
>;
2192 const bool IsStatic
;
2193 const ELFO
* const Obj
;
2195 MipsGOTParser(const ELFO
*Obj
, StringRef FileName
, Elf_Dyn_Range DynTable
,
2196 Elf_Sym_Range DynSyms
);
2198 bool hasGot() const { return !GotEntries
.empty(); }
2199 bool hasPlt() const { return !PltEntries
.empty(); }
2201 uint64_t getGp() const;
2203 const Entry
*getGotLazyResolver() const;
2204 const Entry
*getGotModulePointer() const;
2205 const Entry
*getPltLazyResolver() const;
2206 const Entry
*getPltModulePointer() const;
2208 Entries
getLocalEntries() const;
2209 Entries
getGlobalEntries() const;
2210 Entries
getOtherEntries() const;
2211 Entries
getPltEntries() const;
2213 uint64_t getGotAddress(const Entry
* E
) const;
2214 int64_t getGotOffset(const Entry
* E
) const;
2215 const Elf_Sym
*getGotSym(const Entry
*E
) const;
2217 uint64_t getPltAddress(const Entry
* E
) const;
2218 const Elf_Sym
*getPltSym(const Entry
*E
) const;
2220 StringRef
getPltStrTable() const { return PltStrTable
; }
2223 const Elf_Shdr
*GotSec
;
2227 const Elf_Shdr
*PltSec
;
2228 const Elf_Shdr
*PltRelSec
;
2229 const Elf_Shdr
*PltSymTable
;
2232 Elf_Sym_Range GotDynSyms
;
2233 StringRef PltStrTable
;
2239 } // end anonymous namespace
2241 template <class ELFT
>
2242 MipsGOTParser
<ELFT
>::MipsGOTParser(const ELFO
*Obj
, StringRef FileName
,
2243 Elf_Dyn_Range DynTable
,
2244 Elf_Sym_Range DynSyms
)
2245 : IsStatic(DynTable
.empty()), Obj(Obj
), GotSec(nullptr), LocalNum(0),
2246 GlobalNum(0), PltSec(nullptr), PltRelSec(nullptr), PltSymTable(nullptr),
2247 FileName(FileName
) {
2248 // See "Global Offset Table" in Chapter 5 in the following document
2249 // for detailed GOT description.
2250 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
2252 // Find static GOT secton.
2254 GotSec
= findSectionByName(*Obj
, FileName
, ".got");
2256 reportError(createError("Cannot find .got section"), FileName
);
2258 ArrayRef
<uint8_t> Content
=
2259 unwrapOrError(FileName
, Obj
->getSectionContents(GotSec
));
2260 GotEntries
= Entries(reinterpret_cast<const Entry
*>(Content
.data()),
2261 Content
.size() / sizeof(Entry
));
2262 LocalNum
= GotEntries
.size();
2266 // Lookup dynamic table tags which define GOT/PLT layouts.
2267 Optional
<uint64_t> DtPltGot
;
2268 Optional
<uint64_t> DtLocalGotNum
;
2269 Optional
<uint64_t> DtGotSym
;
2270 Optional
<uint64_t> DtMipsPltGot
;
2271 Optional
<uint64_t> DtJmpRel
;
2272 for (const auto &Entry
: DynTable
) {
2273 switch (Entry
.getTag()) {
2274 case ELF::DT_PLTGOT
:
2275 DtPltGot
= Entry
.getVal();
2277 case ELF::DT_MIPS_LOCAL_GOTNO
:
2278 DtLocalGotNum
= Entry
.getVal();
2280 case ELF::DT_MIPS_GOTSYM
:
2281 DtGotSym
= Entry
.getVal();
2283 case ELF::DT_MIPS_PLTGOT
:
2284 DtMipsPltGot
= Entry
.getVal();
2286 case ELF::DT_JMPREL
:
2287 DtJmpRel
= Entry
.getVal();
2292 // Find dynamic GOT section.
2293 if (DtPltGot
|| DtLocalGotNum
|| DtGotSym
) {
2295 report_fatal_error("Cannot find PLTGOT dynamic table tag.");
2297 report_fatal_error("Cannot find MIPS_LOCAL_GOTNO dynamic table tag.");
2299 report_fatal_error("Cannot find MIPS_GOTSYM dynamic table tag.");
2301 size_t DynSymTotal
= DynSyms
.size();
2302 if (*DtGotSym
> DynSymTotal
)
2304 createError("MIPS_GOTSYM exceeds a number of dynamic symbols"),
2307 GotSec
= findNotEmptySectionByAddress(Obj
, FileName
, *DtPltGot
);
2309 reportError(createError("There is no not empty GOT section at 0x" +
2310 Twine::utohexstr(*DtPltGot
)),
2313 LocalNum
= *DtLocalGotNum
;
2314 GlobalNum
= DynSymTotal
- *DtGotSym
;
2316 ArrayRef
<uint8_t> Content
=
2317 unwrapOrError(FileName
, Obj
->getSectionContents(GotSec
));
2318 GotEntries
= Entries(reinterpret_cast<const Entry
*>(Content
.data()),
2319 Content
.size() / sizeof(Entry
));
2320 GotDynSyms
= DynSyms
.drop_front(*DtGotSym
);
2323 // Find PLT section.
2324 if (DtMipsPltGot
|| DtJmpRel
) {
2326 report_fatal_error("Cannot find MIPS_PLTGOT dynamic table tag.");
2328 report_fatal_error("Cannot find JMPREL dynamic table tag.");
2330 PltSec
= findNotEmptySectionByAddress(Obj
, FileName
, * DtMipsPltGot
);
2332 report_fatal_error("There is no not empty PLTGOT section at 0x " +
2333 Twine::utohexstr(*DtMipsPltGot
));
2335 PltRelSec
= findNotEmptySectionByAddress(Obj
, FileName
, * DtJmpRel
);
2337 report_fatal_error("There is no not empty RELPLT section at 0x" +
2338 Twine::utohexstr(*DtJmpRel
));
2340 ArrayRef
<uint8_t> PltContent
=
2341 unwrapOrError(FileName
, Obj
->getSectionContents(PltSec
));
2342 PltEntries
= Entries(reinterpret_cast<const Entry
*>(PltContent
.data()),
2343 PltContent
.size() / sizeof(Entry
));
2345 PltSymTable
= unwrapOrError(FileName
, Obj
->getSection(PltRelSec
->sh_link
));
2347 unwrapOrError(FileName
, Obj
->getStringTableForSymtab(*PltSymTable
));
2351 template <class ELFT
> uint64_t MipsGOTParser
<ELFT
>::getGp() const {
2352 return GotSec
->sh_addr
+ 0x7ff0;
2355 template <class ELFT
>
2356 const typename MipsGOTParser
<ELFT
>::Entry
*
2357 MipsGOTParser
<ELFT
>::getGotLazyResolver() const {
2358 return LocalNum
> 0 ? &GotEntries
[0] : nullptr;
2361 template <class ELFT
>
2362 const typename MipsGOTParser
<ELFT
>::Entry
*
2363 MipsGOTParser
<ELFT
>::getGotModulePointer() const {
2366 const Entry
&E
= GotEntries
[1];
2367 if ((E
>> (sizeof(Entry
) * 8 - 1)) == 0)
2372 template <class ELFT
>
2373 typename MipsGOTParser
<ELFT
>::Entries
2374 MipsGOTParser
<ELFT
>::getLocalEntries() const {
2375 size_t Skip
= getGotModulePointer() ? 2 : 1;
2376 if (LocalNum
- Skip
<= 0)
2378 return GotEntries
.slice(Skip
, LocalNum
- Skip
);
2381 template <class ELFT
>
2382 typename MipsGOTParser
<ELFT
>::Entries
2383 MipsGOTParser
<ELFT
>::getGlobalEntries() const {
2386 return GotEntries
.slice(LocalNum
, GlobalNum
);
2389 template <class ELFT
>
2390 typename MipsGOTParser
<ELFT
>::Entries
2391 MipsGOTParser
<ELFT
>::getOtherEntries() const {
2392 size_t OtherNum
= GotEntries
.size() - LocalNum
- GlobalNum
;
2395 return GotEntries
.slice(LocalNum
+ GlobalNum
, OtherNum
);
2398 template <class ELFT
>
2399 uint64_t MipsGOTParser
<ELFT
>::getGotAddress(const Entry
*E
) const {
2400 int64_t Offset
= std::distance(GotEntries
.data(), E
) * sizeof(Entry
);
2401 return GotSec
->sh_addr
+ Offset
;
2404 template <class ELFT
>
2405 int64_t MipsGOTParser
<ELFT
>::getGotOffset(const Entry
*E
) const {
2406 int64_t Offset
= std::distance(GotEntries
.data(), E
) * sizeof(Entry
);
2407 return Offset
- 0x7ff0;
2410 template <class ELFT
>
2411 const typename MipsGOTParser
<ELFT
>::Elf_Sym
*
2412 MipsGOTParser
<ELFT
>::getGotSym(const Entry
*E
) const {
2413 int64_t Offset
= std::distance(GotEntries
.data(), E
);
2414 return &GotDynSyms
[Offset
- LocalNum
];
2417 template <class ELFT
>
2418 const typename MipsGOTParser
<ELFT
>::Entry
*
2419 MipsGOTParser
<ELFT
>::getPltLazyResolver() const {
2420 return PltEntries
.empty() ? nullptr : &PltEntries
[0];
2423 template <class ELFT
>
2424 const typename MipsGOTParser
<ELFT
>::Entry
*
2425 MipsGOTParser
<ELFT
>::getPltModulePointer() const {
2426 return PltEntries
.size() < 2 ? nullptr : &PltEntries
[1];
2429 template <class ELFT
>
2430 typename MipsGOTParser
<ELFT
>::Entries
2431 MipsGOTParser
<ELFT
>::getPltEntries() const {
2432 if (PltEntries
.size() <= 2)
2434 return PltEntries
.slice(2, PltEntries
.size() - 2);
2437 template <class ELFT
>
2438 uint64_t MipsGOTParser
<ELFT
>::getPltAddress(const Entry
*E
) const {
2439 int64_t Offset
= std::distance(PltEntries
.data(), E
) * sizeof(Entry
);
2440 return PltSec
->sh_addr
+ Offset
;
2443 template <class ELFT
>
2444 const typename MipsGOTParser
<ELFT
>::Elf_Sym
*
2445 MipsGOTParser
<ELFT
>::getPltSym(const Entry
*E
) const {
2446 int64_t Offset
= std::distance(getPltEntries().data(), E
);
2447 if (PltRelSec
->sh_type
== ELF::SHT_REL
) {
2448 Elf_Rel_Range Rels
= unwrapOrError(FileName
, Obj
->rels(PltRelSec
));
2449 return unwrapOrError(FileName
,
2450 Obj
->getRelocationSymbol(&Rels
[Offset
], PltSymTable
));
2452 Elf_Rela_Range Rels
= unwrapOrError(FileName
, Obj
->relas(PltRelSec
));
2453 return unwrapOrError(FileName
,
2454 Obj
->getRelocationSymbol(&Rels
[Offset
], PltSymTable
));
2458 template <class ELFT
> void ELFDumper
<ELFT
>::printMipsPLTGOT() {
2459 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
2460 if (Obj
->getHeader()->e_machine
!= EM_MIPS
)
2461 reportError(createError("MIPS PLT GOT is available for MIPS targets only"),
2462 ObjF
->getFileName());
2464 MipsGOTParser
<ELFT
> Parser(Obj
, ObjF
->getFileName(), dynamic_table(),
2466 if (Parser
.hasGot())
2467 ELFDumperStyle
->printMipsGOT(Parser
);
2468 if (Parser
.hasPlt())
2469 ELFDumperStyle
->printMipsPLT(Parser
);
2472 static const EnumEntry
<unsigned> ElfMipsISAExtType
[] = {
2473 {"None", Mips::AFL_EXT_NONE
},
2474 {"Broadcom SB-1", Mips::AFL_EXT_SB1
},
2475 {"Cavium Networks Octeon", Mips::AFL_EXT_OCTEON
},
2476 {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2
},
2477 {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP
},
2478 {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3
},
2479 {"LSI R4010", Mips::AFL_EXT_4010
},
2480 {"Loongson 2E", Mips::AFL_EXT_LOONGSON_2E
},
2481 {"Loongson 2F", Mips::AFL_EXT_LOONGSON_2F
},
2482 {"Loongson 3A", Mips::AFL_EXT_LOONGSON_3A
},
2483 {"MIPS R4650", Mips::AFL_EXT_4650
},
2484 {"MIPS R5900", Mips::AFL_EXT_5900
},
2485 {"MIPS R10000", Mips::AFL_EXT_10000
},
2486 {"NEC VR4100", Mips::AFL_EXT_4100
},
2487 {"NEC VR4111/VR4181", Mips::AFL_EXT_4111
},
2488 {"NEC VR4120", Mips::AFL_EXT_4120
},
2489 {"NEC VR5400", Mips::AFL_EXT_5400
},
2490 {"NEC VR5500", Mips::AFL_EXT_5500
},
2491 {"RMI Xlr", Mips::AFL_EXT_XLR
},
2492 {"Toshiba R3900", Mips::AFL_EXT_3900
}
2495 static const EnumEntry
<unsigned> ElfMipsASEFlags
[] = {
2496 {"DSP", Mips::AFL_ASE_DSP
},
2497 {"DSPR2", Mips::AFL_ASE_DSPR2
},
2498 {"Enhanced VA Scheme", Mips::AFL_ASE_EVA
},
2499 {"MCU", Mips::AFL_ASE_MCU
},
2500 {"MDMX", Mips::AFL_ASE_MDMX
},
2501 {"MIPS-3D", Mips::AFL_ASE_MIPS3D
},
2502 {"MT", Mips::AFL_ASE_MT
},
2503 {"SmartMIPS", Mips::AFL_ASE_SMARTMIPS
},
2504 {"VZ", Mips::AFL_ASE_VIRT
},
2505 {"MSA", Mips::AFL_ASE_MSA
},
2506 {"MIPS16", Mips::AFL_ASE_MIPS16
},
2507 {"microMIPS", Mips::AFL_ASE_MICROMIPS
},
2508 {"XPA", Mips::AFL_ASE_XPA
},
2509 {"CRC", Mips::AFL_ASE_CRC
},
2510 {"GINV", Mips::AFL_ASE_GINV
},
2513 static const EnumEntry
<unsigned> ElfMipsFpABIType
[] = {
2514 {"Hard or soft float", Mips::Val_GNU_MIPS_ABI_FP_ANY
},
2515 {"Hard float (double precision)", Mips::Val_GNU_MIPS_ABI_FP_DOUBLE
},
2516 {"Hard float (single precision)", Mips::Val_GNU_MIPS_ABI_FP_SINGLE
},
2517 {"Soft float", Mips::Val_GNU_MIPS_ABI_FP_SOFT
},
2518 {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)",
2519 Mips::Val_GNU_MIPS_ABI_FP_OLD_64
},
2520 {"Hard float (32-bit CPU, Any FPU)", Mips::Val_GNU_MIPS_ABI_FP_XX
},
2521 {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64
},
2522 {"Hard float compat (32-bit CPU, 64-bit FPU)",
2523 Mips::Val_GNU_MIPS_ABI_FP_64A
}
2526 static const EnumEntry
<unsigned> ElfMipsFlags1
[] {
2527 {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG
},
2530 static int getMipsRegisterSize(uint8_t Flag
) {
2532 case Mips::AFL_REG_NONE
:
2534 case Mips::AFL_REG_32
:
2536 case Mips::AFL_REG_64
:
2538 case Mips::AFL_REG_128
:
2545 template <class ELFT
> void ELFDumper
<ELFT
>::printMipsABIFlags() {
2546 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
2547 const Elf_Shdr
*Shdr
=
2548 findSectionByName(*Obj
, ObjF
->getFileName(), ".MIPS.abiflags");
2550 W
.startLine() << "There is no .MIPS.abiflags section in the file.\n";
2553 ArrayRef
<uint8_t> Sec
=
2554 unwrapOrError(ObjF
->getFileName(), Obj
->getSectionContents(Shdr
));
2555 if (Sec
.size() != sizeof(Elf_Mips_ABIFlags
<ELFT
>)) {
2556 W
.startLine() << "The .MIPS.abiflags section has a wrong size.\n";
2560 auto *Flags
= reinterpret_cast<const Elf_Mips_ABIFlags
<ELFT
> *>(Sec
.data());
2562 raw_ostream
&OS
= W
.getOStream();
2563 DictScope
GS(W
, "MIPS ABI Flags");
2565 W
.printNumber("Version", Flags
->version
);
2566 W
.startLine() << "ISA: ";
2567 if (Flags
->isa_rev
<= 1)
2568 OS
<< format("MIPS%u", Flags
->isa_level
);
2570 OS
<< format("MIPS%ur%u", Flags
->isa_level
, Flags
->isa_rev
);
2572 W
.printEnum("ISA Extension", Flags
->isa_ext
, makeArrayRef(ElfMipsISAExtType
));
2573 W
.printFlags("ASEs", Flags
->ases
, makeArrayRef(ElfMipsASEFlags
));
2574 W
.printEnum("FP ABI", Flags
->fp_abi
, makeArrayRef(ElfMipsFpABIType
));
2575 W
.printNumber("GPR size", getMipsRegisterSize(Flags
->gpr_size
));
2576 W
.printNumber("CPR1 size", getMipsRegisterSize(Flags
->cpr1_size
));
2577 W
.printNumber("CPR2 size", getMipsRegisterSize(Flags
->cpr2_size
));
2578 W
.printFlags("Flags 1", Flags
->flags1
, makeArrayRef(ElfMipsFlags1
));
2579 W
.printHex("Flags 2", Flags
->flags2
);
2582 template <class ELFT
>
2583 static void printMipsReginfoData(ScopedPrinter
&W
,
2584 const Elf_Mips_RegInfo
<ELFT
> &Reginfo
) {
2585 W
.printHex("GP", Reginfo
.ri_gp_value
);
2586 W
.printHex("General Mask", Reginfo
.ri_gprmask
);
2587 W
.printHex("Co-Proc Mask0", Reginfo
.ri_cprmask
[0]);
2588 W
.printHex("Co-Proc Mask1", Reginfo
.ri_cprmask
[1]);
2589 W
.printHex("Co-Proc Mask2", Reginfo
.ri_cprmask
[2]);
2590 W
.printHex("Co-Proc Mask3", Reginfo
.ri_cprmask
[3]);
2593 template <class ELFT
> void ELFDumper
<ELFT
>::printMipsReginfo() {
2594 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
2595 const Elf_Shdr
*Shdr
= findSectionByName(*Obj
, ObjF
->getFileName(), ".reginfo");
2597 W
.startLine() << "There is no .reginfo section in the file.\n";
2600 ArrayRef
<uint8_t> Sec
=
2601 unwrapOrError(ObjF
->getFileName(), Obj
->getSectionContents(Shdr
));
2602 if (Sec
.size() != sizeof(Elf_Mips_RegInfo
<ELFT
>)) {
2603 W
.startLine() << "The .reginfo section has a wrong size.\n";
2607 DictScope
GS(W
, "MIPS RegInfo");
2608 auto *Reginfo
= reinterpret_cast<const Elf_Mips_RegInfo
<ELFT
> *>(Sec
.data());
2609 printMipsReginfoData(W
, *Reginfo
);
2612 template <class ELFT
> void ELFDumper
<ELFT
>::printMipsOptions() {
2613 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
2614 const Elf_Shdr
*Shdr
=
2615 findSectionByName(*Obj
, ObjF
->getFileName(), ".MIPS.options");
2617 W
.startLine() << "There is no .MIPS.options section in the file.\n";
2621 DictScope
GS(W
, "MIPS Options");
2623 ArrayRef
<uint8_t> Sec
=
2624 unwrapOrError(ObjF
->getFileName(), Obj
->getSectionContents(Shdr
));
2625 while (!Sec
.empty()) {
2626 if (Sec
.size() < sizeof(Elf_Mips_Options
<ELFT
>)) {
2627 W
.startLine() << "The .MIPS.options section has a wrong size.\n";
2630 auto *O
= reinterpret_cast<const Elf_Mips_Options
<ELFT
> *>(Sec
.data());
2631 DictScope
GS(W
, getElfMipsOptionsOdkType(O
->kind
));
2634 printMipsReginfoData(W
, O
->getRegInfo());
2637 W
.startLine() << "Unsupported MIPS options tag.\n";
2640 Sec
= Sec
.slice(O
->size
);
2644 template <class ELFT
> void ELFDumper
<ELFT
>::printStackMap() const {
2645 const ELFFile
<ELFT
> *Obj
= ObjF
->getELFFile();
2646 const Elf_Shdr
*StackMapSection
= nullptr;
2647 for (const auto &Sec
: unwrapOrError(ObjF
->getFileName(), Obj
->sections())) {
2649 unwrapOrError(ObjF
->getFileName(), Obj
->getSectionName(&Sec
));
2650 if (Name
== ".llvm_stackmaps") {
2651 StackMapSection
= &Sec
;
2656 if (!StackMapSection
)
2659 ArrayRef
<uint8_t> StackMapContentsArray
= unwrapOrError(
2660 ObjF
->getFileName(), Obj
->getSectionContents(StackMapSection
));
2662 prettyPrintStackMap(
2663 W
, StackMapParser
<ELFT::TargetEndianness
>(StackMapContentsArray
));
2666 template <class ELFT
> void ELFDumper
<ELFT
>::printGroupSections() {
2667 ELFDumperStyle
->printGroupSections(ObjF
->getELFFile());
2670 template <class ELFT
> void ELFDumper
<ELFT
>::printAddrsig() {
2671 ELFDumperStyle
->printAddrsig(ObjF
->getELFFile());
2674 static inline void printFields(formatted_raw_ostream
&OS
, StringRef Str1
,
2678 OS
.PadToColumn(37u);
2683 template <class ELFT
>
2684 static std::string
getSectionHeadersNumString(const ELFFile
<ELFT
> *Obj
,
2685 StringRef FileName
) {
2686 const typename
ELFT::Ehdr
*ElfHeader
= Obj
->getHeader();
2687 if (ElfHeader
->e_shnum
!= 0)
2688 return to_string(ElfHeader
->e_shnum
);
2690 ArrayRef
<typename
ELFT::Shdr
> Arr
= unwrapOrError(FileName
, Obj
->sections());
2693 return "0 (" + to_string(Arr
[0].sh_size
) + ")";
2696 template <class ELFT
>
2697 static std::string
getSectionHeaderTableIndexString(const ELFFile
<ELFT
> *Obj
,
2698 StringRef FileName
) {
2699 const typename
ELFT::Ehdr
*ElfHeader
= Obj
->getHeader();
2700 if (ElfHeader
->e_shstrndx
!= SHN_XINDEX
)
2701 return to_string(ElfHeader
->e_shstrndx
);
2703 ArrayRef
<typename
ELFT::Shdr
> Arr
= unwrapOrError(FileName
, Obj
->sections());
2705 return "65535 (corrupt: out of range)";
2706 return to_string(ElfHeader
->e_shstrndx
) + " (" + to_string(Arr
[0].sh_link
) +
2710 template <class ELFT
> void GNUStyle
<ELFT
>::printFileHeaders(const ELFO
*Obj
) {
2711 const Elf_Ehdr
*e
= Obj
->getHeader();
2712 OS
<< "ELF Header:\n";
2715 for (int i
= 0; i
< ELF::EI_NIDENT
; i
++)
2716 OS
<< format(" %02x", static_cast<int>(e
->e_ident
[i
]));
2718 Str
= printEnum(e
->e_ident
[ELF::EI_CLASS
], makeArrayRef(ElfClass
));
2719 printFields(OS
, "Class:", Str
);
2720 Str
= printEnum(e
->e_ident
[ELF::EI_DATA
], makeArrayRef(ElfDataEncoding
));
2721 printFields(OS
, "Data:", Str
);
2724 OS
.PadToColumn(37u);
2725 OS
<< to_hexString(e
->e_ident
[ELF::EI_VERSION
]);
2726 if (e
->e_version
== ELF::EV_CURRENT
)
2729 Str
= printEnum(e
->e_ident
[ELF::EI_OSABI
], makeArrayRef(ElfOSABI
));
2730 printFields(OS
, "OS/ABI:", Str
);
2731 Str
= "0x" + to_hexString(e
->e_ident
[ELF::EI_ABIVERSION
]);
2732 printFields(OS
, "ABI Version:", Str
);
2733 Str
= printEnum(e
->e_type
, makeArrayRef(ElfObjectFileType
));
2734 printFields(OS
, "Type:", Str
);
2735 Str
= printEnum(e
->e_machine
, makeArrayRef(ElfMachineType
));
2736 printFields(OS
, "Machine:", Str
);
2737 Str
= "0x" + to_hexString(e
->e_version
);
2738 printFields(OS
, "Version:", Str
);
2739 Str
= "0x" + to_hexString(e
->e_entry
);
2740 printFields(OS
, "Entry point address:", Str
);
2741 Str
= to_string(e
->e_phoff
) + " (bytes into file)";
2742 printFields(OS
, "Start of program headers:", Str
);
2743 Str
= to_string(e
->e_shoff
) + " (bytes into file)";
2744 printFields(OS
, "Start of section headers:", Str
);
2745 std::string ElfFlags
;
2746 if (e
->e_machine
== EM_MIPS
)
2748 printFlags(e
->e_flags
, makeArrayRef(ElfHeaderMipsFlags
),
2749 unsigned(ELF::EF_MIPS_ARCH
), unsigned(ELF::EF_MIPS_ABI
),
2750 unsigned(ELF::EF_MIPS_MACH
));
2751 else if (e
->e_machine
== EM_RISCV
)
2752 ElfFlags
= printFlags(e
->e_flags
, makeArrayRef(ElfHeaderRISCVFlags
));
2753 Str
= "0x" + to_hexString(e
->e_flags
);
2754 if (!ElfFlags
.empty())
2755 Str
= Str
+ ", " + ElfFlags
;
2756 printFields(OS
, "Flags:", Str
);
2757 Str
= to_string(e
->e_ehsize
) + " (bytes)";
2758 printFields(OS
, "Size of this header:", Str
);
2759 Str
= to_string(e
->e_phentsize
) + " (bytes)";
2760 printFields(OS
, "Size of program headers:", Str
);
2761 Str
= to_string(e
->e_phnum
);
2762 printFields(OS
, "Number of program headers:", Str
);
2763 Str
= to_string(e
->e_shentsize
) + " (bytes)";
2764 printFields(OS
, "Size of section headers:", Str
);
2765 Str
= getSectionHeadersNumString(Obj
, this->FileName
);
2766 printFields(OS
, "Number of section headers:", Str
);
2767 Str
= getSectionHeaderTableIndexString(Obj
, this->FileName
);
2768 printFields(OS
, "Section header string table index:", Str
);
2772 struct GroupMember
{
2777 struct GroupSection
{
2779 std::string Signature
;
2785 std::vector
<GroupMember
> Members
;
2788 template <class ELFT
>
2789 std::vector
<GroupSection
> getGroups(const ELFFile
<ELFT
> *Obj
,
2790 StringRef FileName
) {
2791 using Elf_Shdr
= typename
ELFT::Shdr
;
2792 using Elf_Sym
= typename
ELFT::Sym
;
2793 using Elf_Word
= typename
ELFT::Word
;
2795 std::vector
<GroupSection
> Ret
;
2797 for (const Elf_Shdr
&Sec
: unwrapOrError(FileName
, Obj
->sections())) {
2799 if (Sec
.sh_type
!= ELF::SHT_GROUP
)
2802 const Elf_Shdr
*Symtab
=
2803 unwrapOrError(FileName
, Obj
->getSection(Sec
.sh_link
));
2804 StringRef StrTable
=
2805 unwrapOrError(FileName
, Obj
->getStringTableForSymtab(*Symtab
));
2806 const Elf_Sym
*Sym
= unwrapOrError(
2807 FileName
, Obj
->template getEntry
<Elf_Sym
>(Symtab
, Sec
.sh_info
));
2808 auto Data
= unwrapOrError(
2809 FileName
, Obj
->template getSectionContentsAsArray
<Elf_Word
>(&Sec
));
2811 StringRef Name
= unwrapOrError(FileName
, Obj
->getSectionName(&Sec
));
2812 StringRef Signature
= StrTable
.data() + Sym
->st_name
;
2813 Ret
.push_back({Name
,
2814 maybeDemangle(Signature
),
2822 std::vector
<GroupMember
> &GM
= Ret
.back().Members
;
2823 for (uint32_t Ndx
: Data
.slice(1)) {
2824 auto Sec
= unwrapOrError(FileName
, Obj
->getSection(Ndx
));
2825 const StringRef Name
= unwrapOrError(FileName
, Obj
->getSectionName(Sec
));
2826 GM
.push_back({Name
, Ndx
});
2832 DenseMap
<uint64_t, const GroupSection
*>
2833 mapSectionsToGroups(ArrayRef
<GroupSection
> Groups
) {
2834 DenseMap
<uint64_t, const GroupSection
*> Ret
;
2835 for (const GroupSection
&G
: Groups
)
2836 for (const GroupMember
&GM
: G
.Members
)
2837 Ret
.insert({GM
.Index
, &G
});
2843 template <class ELFT
> void GNUStyle
<ELFT
>::printGroupSections(const ELFO
*Obj
) {
2844 std::vector
<GroupSection
> V
= getGroups
<ELFT
>(Obj
, this->FileName
);
2845 DenseMap
<uint64_t, const GroupSection
*> Map
= mapSectionsToGroups(V
);
2846 for (const GroupSection
&G
: V
) {
2848 << getGroupType(G
.Type
) << " group section ["
2849 << format_decimal(G
.Index
, 5) << "] `" << G
.Name
<< "' [" << G
.Signature
2850 << "] contains " << G
.Members
.size() << " sections:\n"
2851 << " [Index] Name\n";
2852 for (const GroupMember
&GM
: G
.Members
) {
2853 const GroupSection
*MainGroup
= Map
[GM
.Index
];
2854 if (MainGroup
!= &G
) {
2856 errs() << "Error: section [" << format_decimal(GM
.Index
, 5)
2857 << "] in group section [" << format_decimal(G
.Index
, 5)
2858 << "] already in group section ["
2859 << format_decimal(MainGroup
->Index
, 5) << "]";
2863 OS
<< " [" << format_decimal(GM
.Index
, 5) << "] " << GM
.Name
<< "\n";
2868 OS
<< "There are no section groups in this file.\n";
2871 template <class ELFT
>
2872 void GNUStyle
<ELFT
>::printRelocation(const ELFO
*Obj
, const Elf_Shdr
*SymTab
,
2873 const Elf_Rela
&R
, bool IsRela
) {
2874 const Elf_Sym
*Sym
=
2875 unwrapOrError(this->FileName
, Obj
->getRelocationSymbol(&R
, SymTab
));
2876 std::string TargetName
;
2877 if (Sym
&& Sym
->getType() == ELF::STT_SECTION
) {
2878 const Elf_Shdr
*Sec
= unwrapOrError(
2880 Obj
->getSection(Sym
, SymTab
, this->dumper()->getShndxTable()));
2881 TargetName
= unwrapOrError(this->FileName
, Obj
->getSectionName(Sec
));
2883 StringRef StrTable
=
2884 unwrapOrError(this->FileName
, Obj
->getStringTableForSymtab(*SymTab
));
2885 TargetName
= this->dumper()->getFullSymbolName(
2886 Sym
, StrTable
, SymTab
->sh_type
== SHT_DYNSYM
/* IsDynamic */);
2888 printRelocation(Obj
, Sym
, TargetName
, R
, IsRela
);
2891 template <class ELFT
>
2892 void GNUStyle
<ELFT
>::printRelocation(const ELFO
*Obj
, const Elf_Sym
*Sym
,
2893 StringRef SymbolName
, const Elf_Rela
&R
,
2895 // First two fields are bit width dependent. The rest of them are fixed width.
2896 unsigned Bias
= ELFT::Is64Bits
? 8 : 0;
2897 Field Fields
[5] = {0, 10 + Bias
, 19 + 2 * Bias
, 42 + 2 * Bias
, 53 + 2 * Bias
};
2898 unsigned Width
= ELFT::Is64Bits
? 16 : 8;
2900 Fields
[0].Str
= to_string(format_hex_no_prefix(R
.r_offset
, Width
));
2901 Fields
[1].Str
= to_string(format_hex_no_prefix(R
.r_info
, Width
));
2903 SmallString
<32> RelocName
;
2904 Obj
->getRelocationTypeName(R
.getType(Obj
->isMips64EL()), RelocName
);
2905 Fields
[2].Str
= RelocName
.c_str();
2907 if (Sym
&& (!SymbolName
.empty() || Sym
->getValue() != 0))
2908 Fields
[3].Str
= to_string(format_hex_no_prefix(Sym
->getValue(), Width
));
2910 Fields
[4].Str
= SymbolName
;
2911 for (const Field
&F
: Fields
)
2916 int64_t RelAddend
= R
.r_addend
;
2917 if (!SymbolName
.empty()) {
2918 if (R
.r_addend
< 0) {
2920 RelAddend
= std::abs(RelAddend
);
2925 Addend
+= to_hexString(RelAddend
, false);
2927 OS
<< Addend
<< "\n";
2930 template <class ELFT
> void GNUStyle
<ELFT
>::printRelocHeader(unsigned SType
) {
2931 bool IsRela
= SType
== ELF::SHT_RELA
|| SType
== ELF::SHT_ANDROID_RELA
;
2932 bool IsRelr
= SType
== ELF::SHT_RELR
|| SType
== ELF::SHT_ANDROID_RELR
;
2937 if (IsRelr
&& opts::RawRelr
)
2943 << " Symbol's Value Symbol's Name";
2945 OS
<< " Info Type Sym. Value Symbol's Name";
2951 template <class ELFT
> void GNUStyle
<ELFT
>::printRelocations(const ELFO
*Obj
) {
2952 bool HasRelocSections
= false;
2953 for (const Elf_Shdr
&Sec
: unwrapOrError(this->FileName
, Obj
->sections())) {
2954 if (Sec
.sh_type
!= ELF::SHT_REL
&& Sec
.sh_type
!= ELF::SHT_RELA
&&
2955 Sec
.sh_type
!= ELF::SHT_RELR
&& Sec
.sh_type
!= ELF::SHT_ANDROID_REL
&&
2956 Sec
.sh_type
!= ELF::SHT_ANDROID_RELA
&&
2957 Sec
.sh_type
!= ELF::SHT_ANDROID_RELR
)
2959 HasRelocSections
= true;
2960 StringRef Name
= unwrapOrError(this->FileName
, Obj
->getSectionName(&Sec
));
2961 unsigned Entries
= Sec
.getEntityCount();
2962 std::vector
<Elf_Rela
> AndroidRelas
;
2963 if (Sec
.sh_type
== ELF::SHT_ANDROID_REL
||
2964 Sec
.sh_type
== ELF::SHT_ANDROID_RELA
) {
2965 // Android's packed relocation section needs to be unpacked first
2966 // to get the actual number of entries.
2967 AndroidRelas
= unwrapOrError(this->FileName
, Obj
->android_relas(&Sec
));
2968 Entries
= AndroidRelas
.size();
2970 std::vector
<Elf_Rela
> RelrRelas
;
2971 if (!opts::RawRelr
&& (Sec
.sh_type
== ELF::SHT_RELR
||
2972 Sec
.sh_type
== ELF::SHT_ANDROID_RELR
)) {
2973 // .relr.dyn relative relocation section needs to be unpacked first
2974 // to get the actual number of entries.
2975 Elf_Relr_Range Relrs
= unwrapOrError(this->FileName
, Obj
->relrs(&Sec
));
2976 RelrRelas
= unwrapOrError(this->FileName
, Obj
->decode_relrs(Relrs
));
2977 Entries
= RelrRelas
.size();
2979 uintX_t Offset
= Sec
.sh_offset
;
2980 OS
<< "\nRelocation section '" << Name
<< "' at offset 0x"
2981 << to_hexString(Offset
, false) << " contains " << Entries
2983 printRelocHeader(Sec
.sh_type
);
2984 const Elf_Shdr
*SymTab
=
2985 unwrapOrError(this->FileName
, Obj
->getSection(Sec
.sh_link
));
2986 switch (Sec
.sh_type
) {
2988 for (const auto &R
: unwrapOrError(this->FileName
, Obj
->rels(&Sec
))) {
2990 Rela
.r_offset
= R
.r_offset
;
2991 Rela
.r_info
= R
.r_info
;
2993 printRelocation(Obj
, SymTab
, Rela
, false);
2997 for (const auto &R
: unwrapOrError(this->FileName
, Obj
->relas(&Sec
)))
2998 printRelocation(Obj
, SymTab
, R
, true);
3001 case ELF::SHT_ANDROID_RELR
:
3003 for (const auto &R
: unwrapOrError(this->FileName
, Obj
->relrs(&Sec
)))
3004 OS
<< to_string(format_hex_no_prefix(R
, ELFT::Is64Bits
? 16 : 8))
3007 for (const auto &R
: RelrRelas
)
3008 printRelocation(Obj
, SymTab
, R
, false);
3010 case ELF::SHT_ANDROID_REL
:
3011 case ELF::SHT_ANDROID_RELA
:
3012 for (const auto &R
: AndroidRelas
)
3013 printRelocation(Obj
, SymTab
, R
, Sec
.sh_type
== ELF::SHT_ANDROID_RELA
);
3017 if (!HasRelocSections
)
3018 OS
<< "\nThere are no relocations in this file.\n";
3021 // Print the offset of a particular section from anyone of the ranges:
3022 // [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].
3023 // If 'Type' does not fall within any of those ranges, then a string is
3024 // returned as '<unknown>' followed by the type value.
3025 static std::string
getSectionTypeOffsetString(unsigned Type
) {
3026 if (Type
>= SHT_LOOS
&& Type
<= SHT_HIOS
)
3027 return "LOOS+0x" + to_hexString(Type
- SHT_LOOS
);
3028 else if (Type
>= SHT_LOPROC
&& Type
<= SHT_HIPROC
)
3029 return "LOPROC+0x" + to_hexString(Type
- SHT_LOPROC
);
3030 else if (Type
>= SHT_LOUSER
&& Type
<= SHT_HIUSER
)
3031 return "LOUSER+0x" + to_hexString(Type
- SHT_LOUSER
);
3032 return "0x" + to_hexString(Type
) + ": <unknown>";
3035 static std::string
getSectionTypeString(unsigned Arch
, unsigned Type
) {
3036 using namespace ELF
;
3043 case SHT_ARM_PREEMPTMAP
:
3044 return "ARM_PREEMPTMAP";
3045 case SHT_ARM_ATTRIBUTES
:
3046 return "ARM_ATTRIBUTES";
3047 case SHT_ARM_DEBUGOVERLAY
:
3048 return "ARM_DEBUGOVERLAY";
3049 case SHT_ARM_OVERLAYSECTION
:
3050 return "ARM_OVERLAYSECTION";
3055 case SHT_X86_64_UNWIND
:
3056 return "X86_64_UNWIND";
3060 case EM_MIPS_RS3_LE
:
3062 case SHT_MIPS_REGINFO
:
3063 return "MIPS_REGINFO";
3064 case SHT_MIPS_OPTIONS
:
3065 return "MIPS_OPTIONS";
3066 case SHT_MIPS_DWARF
:
3067 return "MIPS_DWARF";
3068 case SHT_MIPS_ABIFLAGS
:
3069 return "MIPS_ABIFLAGS";
3098 case SHT_INIT_ARRAY
:
3099 return "INIT_ARRAY";
3100 case SHT_FINI_ARRAY
:
3101 return "FINI_ARRAY";
3102 case SHT_PREINIT_ARRAY
:
3103 return "PREINIT_ARRAY";
3106 case SHT_SYMTAB_SHNDX
:
3107 return "SYMTAB SECTION INDICES";
3108 case SHT_ANDROID_REL
:
3109 return "ANDROID_REL";
3110 case SHT_ANDROID_RELA
:
3111 return "ANDROID_RELA";
3113 case SHT_ANDROID_RELR
:
3115 case SHT_LLVM_ODRTAB
:
3116 return "LLVM_ODRTAB";
3117 case SHT_LLVM_LINKER_OPTIONS
:
3118 return "LLVM_LINKER_OPTIONS";
3119 case SHT_LLVM_CALL_GRAPH_PROFILE
:
3120 return "LLVM_CALL_GRAPH_PROFILE";
3121 case SHT_LLVM_ADDRSIG
:
3122 return "LLVM_ADDRSIG";
3123 case SHT_LLVM_DEPENDENT_LIBRARIES
:
3124 return "LLVM_DEPENDENT_LIBRARIES";
3125 case SHT_LLVM_SYMPART
:
3126 return "LLVM_SYMPART";
3127 case SHT_LLVM_PART_EHDR
:
3128 return "LLVM_PART_EHDR";
3129 case SHT_LLVM_PART_PHDR
:
3130 return "LLVM_PART_PHDR";
3131 // FIXME: Parse processor specific GNU attributes
3132 case SHT_GNU_ATTRIBUTES
:
3133 return "ATTRIBUTES";
3136 case SHT_GNU_verdef
:
3138 case SHT_GNU_verneed
:
3140 case SHT_GNU_versym
:
3143 return getSectionTypeOffsetString(Type
);
3148 template <class ELFT
>
3149 void GNUStyle
<ELFT
>::printSectionHeaders(const ELFO
*Obj
) {
3150 unsigned Bias
= ELFT::Is64Bits
? 0 : 8;
3151 ArrayRef
<Elf_Shdr
> Sections
= unwrapOrError(this->FileName
, Obj
->sections());
3152 OS
<< "There are " << to_string(Sections
.size())
3153 << " section headers, starting at offset "
3154 << "0x" << to_hexString(Obj
->getHeader()->e_shoff
, false) << ":\n\n";
3155 OS
<< "Section Headers:\n";
3156 Field Fields
[11] = {
3157 {"[Nr]", 2}, {"Name", 7}, {"Type", 25},
3158 {"Address", 41}, {"Off", 58 - Bias
}, {"Size", 65 - Bias
},
3159 {"ES", 72 - Bias
}, {"Flg", 75 - Bias
}, {"Lk", 79 - Bias
},
3160 {"Inf", 82 - Bias
}, {"Al", 86 - Bias
}};
3161 for (auto &F
: Fields
)
3165 const ELFObjectFile
<ELFT
> *ElfObj
= this->dumper()->getElfObject();
3166 size_t SectionIndex
= 0;
3167 for (const Elf_Shdr
&Sec
: Sections
) {
3168 Fields
[0].Str
= to_string(SectionIndex
);
3169 Fields
[1].Str
= unwrapOrError
<StringRef
>(
3170 ElfObj
->getFileName(), Obj
->getSectionName(&Sec
, this->WarningHandler
));
3172 getSectionTypeString(Obj
->getHeader()->e_machine
, Sec
.sh_type
);
3174 to_string(format_hex_no_prefix(Sec
.sh_addr
, ELFT::Is64Bits
? 16 : 8));
3175 Fields
[4].Str
= to_string(format_hex_no_prefix(Sec
.sh_offset
, 6));
3176 Fields
[5].Str
= to_string(format_hex_no_prefix(Sec
.sh_size
, 6));
3177 Fields
[6].Str
= to_string(format_hex_no_prefix(Sec
.sh_entsize
, 2));
3178 Fields
[7].Str
= getGNUFlags(Sec
.sh_flags
);
3179 Fields
[8].Str
= to_string(Sec
.sh_link
);
3180 Fields
[9].Str
= to_string(Sec
.sh_info
);
3181 Fields
[10].Str
= to_string(Sec
.sh_addralign
);
3183 OS
.PadToColumn(Fields
[0].Column
);
3184 OS
<< "[" << right_justify(Fields
[0].Str
, 2) << "]";
3185 for (int i
= 1; i
< 7; i
++)
3186 printField(Fields
[i
]);
3187 OS
.PadToColumn(Fields
[7].Column
);
3188 OS
<< right_justify(Fields
[7].Str
, 3);
3189 OS
.PadToColumn(Fields
[8].Column
);
3190 OS
<< right_justify(Fields
[8].Str
, 2);
3191 OS
.PadToColumn(Fields
[9].Column
);
3192 OS
<< right_justify(Fields
[9].Str
, 3);
3193 OS
.PadToColumn(Fields
[10].Column
);
3194 OS
<< right_justify(Fields
[10].Str
, 2);
3198 OS
<< "Key to Flags:\n"
3199 << " W (write), A (alloc), X (execute), M (merge), S (strings), l "
3201 << " I (info), L (link order), G (group), T (TLS), E (exclude),\
3203 << " O (extra OS processing required) o (OS specific),\
3204 p (processor specific)\n";
3207 template <class ELFT
>
3208 void GNUStyle
<ELFT
>::printSymtabMessage(const ELFO
*Obj
, StringRef Name
,
3210 bool NonVisibilityBitsUsed
) {
3212 OS
<< "\nSymbol table '" << Name
<< "' contains " << Entries
3215 OS
<< "\n Symbol table for image:\n";
3218 OS
<< " Num: Value Size Type Bind Vis";
3220 OS
<< " Num: Value Size Type Bind Vis";
3222 if (NonVisibilityBitsUsed
)
3224 OS
<< " Ndx Name\n";
3227 template <class ELFT
>
3228 std::string GNUStyle
<ELFT
>::getSymbolSectionNdx(const ELFO
*Obj
,
3229 const Elf_Sym
*Symbol
,
3230 const Elf_Sym
*FirstSym
) {
3231 unsigned SectionIndex
= Symbol
->st_shndx
;
3232 switch (SectionIndex
) {
3233 case ELF::SHN_UNDEF
:
3237 case ELF::SHN_COMMON
:
3239 case ELF::SHN_XINDEX
:
3240 return to_string(format_decimal(
3241 unwrapOrError(this->FileName
,
3242 object::getExtendedSymbolTableIndex
<ELFT
>(
3243 Symbol
, FirstSym
, this->dumper()->getShndxTable())),
3247 // Processor specific
3248 if (SectionIndex
>= ELF::SHN_LOPROC
&& SectionIndex
<= ELF::SHN_HIPROC
)
3249 return std::string("PRC[0x") +
3250 to_string(format_hex_no_prefix(SectionIndex
, 4)) + "]";
3252 if (SectionIndex
>= ELF::SHN_LOOS
&& SectionIndex
<= ELF::SHN_HIOS
)
3253 return std::string("OS[0x") +
3254 to_string(format_hex_no_prefix(SectionIndex
, 4)) + "]";
3255 // Architecture reserved:
3256 if (SectionIndex
>= ELF::SHN_LORESERVE
&&
3257 SectionIndex
<= ELF::SHN_HIRESERVE
)
3258 return std::string("RSV[0x") +
3259 to_string(format_hex_no_prefix(SectionIndex
, 4)) + "]";
3260 // A normal section with an index
3261 return to_string(format_decimal(SectionIndex
, 3));
3265 template <class ELFT
>
3266 void GNUStyle
<ELFT
>::printSymbol(const ELFO
*Obj
, const Elf_Sym
*Symbol
,
3267 const Elf_Sym
*FirstSym
, StringRef StrTable
,
3268 bool IsDynamic
, bool NonVisibilityBitsUsed
) {
3270 static bool Dynamic
= true;
3272 // If this function was called with a different value from IsDynamic
3273 // from last call, happens when we move from dynamic to static symbol
3274 // table, "Num" field should be reset.
3275 if (!Dynamic
!= !IsDynamic
) {
3280 unsigned Bias
= ELFT::Is64Bits
? 8 : 0;
3281 Field Fields
[8] = {0, 8, 17 + Bias
, 23 + Bias
,
3282 31 + Bias
, 38 + Bias
, 48 + Bias
, 51 + Bias
};
3283 Fields
[0].Str
= to_string(format_decimal(Idx
++, 6)) + ":";
3284 Fields
[1].Str
= to_string(
3285 format_hex_no_prefix(Symbol
->st_value
, ELFT::Is64Bits
? 16 : 8));
3286 Fields
[2].Str
= to_string(format_decimal(Symbol
->st_size
, 5));
3288 unsigned char SymbolType
= Symbol
->getType();
3289 if (Obj
->getHeader()->e_machine
== ELF::EM_AMDGPU
&&
3290 SymbolType
>= ELF::STT_LOOS
&& SymbolType
< ELF::STT_HIOS
)
3291 Fields
[3].Str
= printEnum(SymbolType
, makeArrayRef(AMDGPUSymbolTypes
));
3293 Fields
[3].Str
= printEnum(SymbolType
, makeArrayRef(ElfSymbolTypes
));
3296 printEnum(Symbol
->getBinding(), makeArrayRef(ElfSymbolBindings
));
3298 printEnum(Symbol
->getVisibility(), makeArrayRef(ElfSymbolVisibilities
));
3299 if (Symbol
->st_other
& ~0x3)
3301 " [<other: " + to_string(format_hex(Symbol
->st_other
, 2)) + ">]";
3303 Fields
[6].Column
+= NonVisibilityBitsUsed
? 13 : 0;
3304 Fields
[6].Str
= getSymbolSectionNdx(Obj
, Symbol
, FirstSym
);
3307 this->dumper()->getFullSymbolName(Symbol
, StrTable
, IsDynamic
);
3308 for (auto &Entry
: Fields
)
3313 template <class ELFT
>
3314 void GNUStyle
<ELFT
>::printHashedSymbol(const ELFO
*Obj
, const Elf_Sym
*FirstSym
,
3315 uint32_t Sym
, StringRef StrTable
,
3317 unsigned Bias
= ELFT::Is64Bits
? 8 : 0;
3318 Field Fields
[9] = {0, 6, 11, 20 + Bias
, 25 + Bias
,
3319 34 + Bias
, 41 + Bias
, 49 + Bias
, 53 + Bias
};
3320 Fields
[0].Str
= to_string(format_decimal(Sym
, 5));
3321 Fields
[1].Str
= to_string(format_decimal(Bucket
, 3)) + ":";
3323 const auto Symbol
= FirstSym
+ Sym
;
3324 Fields
[2].Str
= to_string(
3325 format_hex_no_prefix(Symbol
->st_value
, ELFT::Is64Bits
? 16 : 8));
3326 Fields
[3].Str
= to_string(format_decimal(Symbol
->st_size
, 5));
3328 unsigned char SymbolType
= Symbol
->getType();
3329 if (Obj
->getHeader()->e_machine
== ELF::EM_AMDGPU
&&
3330 SymbolType
>= ELF::STT_LOOS
&& SymbolType
< ELF::STT_HIOS
)
3331 Fields
[4].Str
= printEnum(SymbolType
, makeArrayRef(AMDGPUSymbolTypes
));
3333 Fields
[4].Str
= printEnum(SymbolType
, makeArrayRef(ElfSymbolTypes
));
3336 printEnum(Symbol
->getBinding(), makeArrayRef(ElfSymbolBindings
));
3338 printEnum(Symbol
->getVisibility(), makeArrayRef(ElfSymbolVisibilities
));
3339 Fields
[7].Str
= getSymbolSectionNdx(Obj
, Symbol
, FirstSym
);
3340 Fields
[8].Str
= this->dumper()->getFullSymbolName(Symbol
, StrTable
, true);
3342 for (auto &Entry
: Fields
)
3347 template <class ELFT
>
3348 void GNUStyle
<ELFT
>::printSymbols(const ELFO
*Obj
, bool PrintSymbols
,
3349 bool PrintDynamicSymbols
) {
3350 if (!PrintSymbols
&& !PrintDynamicSymbols
)
3352 // GNU readelf prints both the .dynsym and .symtab with --symbols.
3353 this->dumper()->printSymbolsHelper(true);
3355 this->dumper()->printSymbolsHelper(false);
3358 template <class ELFT
> void GNUStyle
<ELFT
>::printHashSymbols(const ELFO
*Obj
) {
3359 if (this->dumper()->getDynamicStringTable().empty())
3361 auto StringTable
= this->dumper()->getDynamicStringTable();
3362 auto DynSyms
= this->dumper()->dynamic_symbols();
3364 // Try printing .hash
3365 if (auto SysVHash
= this->dumper()->getHashTable()) {
3366 OS
<< "\n Symbol table of .hash for image:\n";
3368 OS
<< " Num Buc: Value Size Type Bind Vis Ndx Name";
3370 OS
<< " Num Buc: Value Size Type Bind Vis Ndx Name";
3373 auto Buckets
= SysVHash
->buckets();
3374 auto Chains
= SysVHash
->chains();
3375 for (uint32_t Buc
= 0; Buc
< SysVHash
->nbucket
; Buc
++) {
3376 if (Buckets
[Buc
] == ELF::STN_UNDEF
)
3378 for (uint32_t Ch
= Buckets
[Buc
]; Ch
< SysVHash
->nchain
; Ch
= Chains
[Ch
]) {
3379 if (Ch
== ELF::STN_UNDEF
)
3381 printHashedSymbol(Obj
, &DynSyms
[0], Ch
, StringTable
, Buc
);
3386 // Try printing .gnu.hash
3387 if (auto GnuHash
= this->dumper()->getGnuHashTable()) {
3388 OS
<< "\n Symbol table of .gnu.hash for image:\n";
3390 OS
<< " Num Buc: Value Size Type Bind Vis Ndx Name";
3392 OS
<< " Num Buc: Value Size Type Bind Vis Ndx Name";
3394 auto Buckets
= GnuHash
->buckets();
3395 for (uint32_t Buc
= 0; Buc
< GnuHash
->nbuckets
; Buc
++) {
3396 if (Buckets
[Buc
] == ELF::STN_UNDEF
)
3398 uint32_t Index
= Buckets
[Buc
];
3399 uint32_t GnuHashable
= Index
- GnuHash
->symndx
;
3400 // Print whole chain
3402 printHashedSymbol(Obj
, &DynSyms
[0], Index
++, StringTable
, Buc
);
3403 // Chain ends at symbol with stopper bit
3404 if ((GnuHash
->values(DynSyms
.size())[GnuHashable
++] & 1) == 1)
3411 static inline std::string
printPhdrFlags(unsigned Flag
) {
3413 Str
= (Flag
& PF_R
) ? "R" : " ";
3414 Str
+= (Flag
& PF_W
) ? "W" : " ";
3415 Str
+= (Flag
& PF_X
) ? "E" : " ";
3419 // SHF_TLS sections are only in PT_TLS, PT_LOAD or PT_GNU_RELRO
3420 // PT_TLS must only have SHF_TLS sections
3421 template <class ELFT
>
3422 bool GNUStyle
<ELFT
>::checkTLSSections(const Elf_Phdr
&Phdr
,
3423 const Elf_Shdr
&Sec
) {
3424 return (((Sec
.sh_flags
& ELF::SHF_TLS
) &&
3425 ((Phdr
.p_type
== ELF::PT_TLS
) || (Phdr
.p_type
== ELF::PT_LOAD
) ||
3426 (Phdr
.p_type
== ELF::PT_GNU_RELRO
))) ||
3427 (!(Sec
.sh_flags
& ELF::SHF_TLS
) && Phdr
.p_type
!= ELF::PT_TLS
));
3430 // Non-SHT_NOBITS must have its offset inside the segment
3431 // Only non-zero section can be at end of segment
3432 template <class ELFT
>
3433 bool GNUStyle
<ELFT
>::checkoffsets(const Elf_Phdr
&Phdr
, const Elf_Shdr
&Sec
) {
3434 if (Sec
.sh_type
== ELF::SHT_NOBITS
)
3437 (Sec
.sh_type
== ELF::SHT_NOBITS
) && ((Sec
.sh_flags
& ELF::SHF_TLS
) != 0);
3438 // .tbss is special, it only has memory in PT_TLS and has NOBITS properties
3440 (IsSpecial
&& Phdr
.p_type
!= ELF::PT_TLS
) ? 0 : Sec
.sh_size
;
3441 if (Sec
.sh_offset
>= Phdr
.p_offset
)
3442 return ((Sec
.sh_offset
+ SectionSize
<= Phdr
.p_filesz
+ Phdr
.p_offset
)
3443 /*only non-zero sized sections at end*/
3444 && (Sec
.sh_offset
+ 1 <= Phdr
.p_offset
+ Phdr
.p_filesz
));
3448 // SHF_ALLOC must have VMA inside segment
3449 // Only non-zero section can be at end of segment
3450 template <class ELFT
>
3451 bool GNUStyle
<ELFT
>::checkVMA(const Elf_Phdr
&Phdr
, const Elf_Shdr
&Sec
) {
3452 if (!(Sec
.sh_flags
& ELF::SHF_ALLOC
))
3455 (Sec
.sh_type
== ELF::SHT_NOBITS
) && ((Sec
.sh_flags
& ELF::SHF_TLS
) != 0);
3456 // .tbss is special, it only has memory in PT_TLS and has NOBITS properties
3458 (IsSpecial
&& Phdr
.p_type
!= ELF::PT_TLS
) ? 0 : Sec
.sh_size
;
3459 if (Sec
.sh_addr
>= Phdr
.p_vaddr
)
3460 return ((Sec
.sh_addr
+ SectionSize
<= Phdr
.p_vaddr
+ Phdr
.p_memsz
) &&
3461 (Sec
.sh_addr
+ 1 <= Phdr
.p_vaddr
+ Phdr
.p_memsz
));
3465 // No section with zero size must be at start or end of PT_DYNAMIC
3466 template <class ELFT
>
3467 bool GNUStyle
<ELFT
>::checkPTDynamic(const Elf_Phdr
&Phdr
, const Elf_Shdr
&Sec
) {
3468 if (Phdr
.p_type
!= ELF::PT_DYNAMIC
|| Sec
.sh_size
!= 0 || Phdr
.p_memsz
== 0)
3470 // Is section within the phdr both based on offset and VMA ?
3471 return ((Sec
.sh_type
== ELF::SHT_NOBITS
) ||
3472 (Sec
.sh_offset
> Phdr
.p_offset
&&
3473 Sec
.sh_offset
< Phdr
.p_offset
+ Phdr
.p_filesz
)) &&
3474 (!(Sec
.sh_flags
& ELF::SHF_ALLOC
) ||
3475 (Sec
.sh_addr
> Phdr
.p_vaddr
&& Sec
.sh_addr
< Phdr
.p_memsz
));
3478 template <class ELFT
>
3479 void GNUStyle
<ELFT
>::printProgramHeaders(
3480 const ELFO
*Obj
, bool PrintProgramHeaders
,
3481 cl::boolOrDefault PrintSectionMapping
) {
3482 if (PrintProgramHeaders
)
3483 printProgramHeaders(Obj
);
3485 // Display the section mapping along with the program headers, unless
3486 // -section-mapping is explicitly set to false.
3487 if (PrintSectionMapping
!= cl::BOU_FALSE
)
3488 printSectionMapping(Obj
);
3491 template <class ELFT
>
3492 void GNUStyle
<ELFT
>::printProgramHeaders(const ELFO
*Obj
) {
3493 unsigned Bias
= ELFT::Is64Bits
? 8 : 0;
3494 const Elf_Ehdr
*Header
= Obj
->getHeader();
3495 Field Fields
[8] = {2, 17, 26, 37 + Bias
,
3496 48 + Bias
, 56 + Bias
, 64 + Bias
, 68 + Bias
};
3497 OS
<< "\nElf file type is "
3498 << printEnum(Header
->e_type
, makeArrayRef(ElfObjectFileType
)) << "\n"
3499 << "Entry point " << format_hex(Header
->e_entry
, 3) << "\n"
3500 << "There are " << Header
->e_phnum
<< " program headers,"
3501 << " starting at offset " << Header
->e_phoff
<< "\n\n"
3502 << "Program Headers:\n";
3504 OS
<< " Type Offset VirtAddr PhysAddr "
3505 << " FileSiz MemSiz Flg Align\n";
3507 OS
<< " Type Offset VirtAddr PhysAddr FileSiz "
3508 << "MemSiz Flg Align\n";
3510 unsigned Width
= ELFT::Is64Bits
? 18 : 10;
3511 unsigned SizeWidth
= ELFT::Is64Bits
? 8 : 7;
3512 for (const auto &Phdr
:
3513 unwrapOrError(this->FileName
, Obj
->program_headers())) {
3514 Fields
[0].Str
= getElfPtType(Header
->e_machine
, Phdr
.p_type
);
3515 Fields
[1].Str
= to_string(format_hex(Phdr
.p_offset
, 8));
3516 Fields
[2].Str
= to_string(format_hex(Phdr
.p_vaddr
, Width
));
3517 Fields
[3].Str
= to_string(format_hex(Phdr
.p_paddr
, Width
));
3518 Fields
[4].Str
= to_string(format_hex(Phdr
.p_filesz
, SizeWidth
));
3519 Fields
[5].Str
= to_string(format_hex(Phdr
.p_memsz
, SizeWidth
));
3520 Fields
[6].Str
= printPhdrFlags(Phdr
.p_flags
);
3521 Fields
[7].Str
= to_string(format_hex(Phdr
.p_align
, 1));
3522 for (auto Field
: Fields
)
3524 if (Phdr
.p_type
== ELF::PT_INTERP
) {
3525 OS
<< "\n [Requesting program interpreter: ";
3526 OS
<< reinterpret_cast<const char *>(Obj
->base()) + Phdr
.p_offset
<< "]";
3532 template <class ELFT
>
3533 void GNUStyle
<ELFT
>::printSectionMapping(const ELFO
*Obj
) {
3534 OS
<< "\n Section to Segment mapping:\n Segment Sections...\n";
3535 DenseSet
<const Elf_Shdr
*> BelongsToSegment
;
3537 for (const Elf_Phdr
&Phdr
:
3538 unwrapOrError(this->FileName
, Obj
->program_headers())) {
3539 std::string Sections
;
3540 OS
<< format(" %2.2d ", Phnum
++);
3541 for (const Elf_Shdr
&Sec
: unwrapOrError(this->FileName
, Obj
->sections())) {
3542 // Check if each section is in a segment and then print mapping.
3543 // readelf additionally makes sure it does not print zero sized sections
3544 // at end of segments and for PT_DYNAMIC both start and end of section
3545 // .tbss must only be shown in PT_TLS section.
3546 bool TbssInNonTLS
= (Sec
.sh_type
== ELF::SHT_NOBITS
) &&
3547 ((Sec
.sh_flags
& ELF::SHF_TLS
) != 0) &&
3548 Phdr
.p_type
!= ELF::PT_TLS
;
3549 if (!TbssInNonTLS
&& checkTLSSections(Phdr
, Sec
) &&
3550 checkoffsets(Phdr
, Sec
) && checkVMA(Phdr
, Sec
) &&
3551 checkPTDynamic(Phdr
, Sec
) && (Sec
.sh_type
!= ELF::SHT_NULL
)) {
3553 unwrapOrError(this->FileName
, Obj
->getSectionName(&Sec
)).str() +
3555 BelongsToSegment
.insert(&Sec
);
3558 OS
<< Sections
<< "\n";
3562 // Display sections that do not belong to a segment.
3563 std::string Sections
;
3564 for (const Elf_Shdr
&Sec
: unwrapOrError(this->FileName
, Obj
->sections())) {
3565 if (BelongsToSegment
.find(&Sec
) == BelongsToSegment
.end())
3567 unwrapOrError(this->FileName
, Obj
->getSectionName(&Sec
)).str() + ' ';
3569 if (!Sections
.empty()) {
3570 OS
<< " None " << Sections
<< '\n';
3576 template <class ELFT
> struct RelSymbol
{
3577 const typename
ELFT::Sym
*Sym
;
3581 template <class ELFT
>
3582 RelSymbol
<ELFT
> getSymbolForReloc(const ELFFile
<ELFT
> *Obj
, StringRef FileName
,
3583 const ELFDumper
<ELFT
> *Dumper
,
3584 const typename
ELFT::Rela
&Reloc
) {
3585 uint32_t SymIndex
= Reloc
.getSymbol(Obj
->isMips64EL());
3586 const typename
ELFT::Sym
*Sym
= Dumper
->dynamic_symbols().begin() + SymIndex
;
3587 Expected
<StringRef
> ErrOrName
= Sym
->getName(Dumper
->getDynamicStringTable());
3591 Name
= maybeDemangle(*ErrOrName
);
3594 createError("unable to get name of the dynamic symbol with index " +
3595 Twine(SymIndex
) + ": " + toString(ErrOrName
.takeError())),
3600 return {Sym
, std::move(Name
)};
3604 template <class ELFT
>
3605 void GNUStyle
<ELFT
>::printDynamicRelocation(const ELFO
*Obj
, Elf_Rela R
,
3607 RelSymbol
<ELFT
> S
= getSymbolForReloc(Obj
, this->FileName
, this->dumper(), R
);
3608 printRelocation(Obj
, S
.Sym
, S
.Name
, R
, IsRela
);
3611 template <class ELFT
> void GNUStyle
<ELFT
>::printDynamic(const ELFO
*Obj
) {
3612 Elf_Dyn_Range Table
= this->dumper()->dynamic_table();
3616 const DynRegionInfo
&DynamicTableRegion
=
3617 this->dumper()->getDynamicTableRegion();
3619 OS
<< "Dynamic section at offset "
3620 << format_hex(reinterpret_cast<const uint8_t *>(DynamicTableRegion
.Addr
) -
3623 << " contains " << Table
.size() << " entries:\n";
3625 bool Is64
= ELFT::Is64Bits
;
3627 OS
<< " Tag Type Name/Value\n";
3629 OS
<< " Tag Type Name/Value\n";
3630 for (auto Entry
: Table
) {
3631 uintX_t Tag
= Entry
.getTag();
3632 std::string TypeString
= std::string("(") +
3633 getTypeString(Obj
->getHeader()->e_machine
, Tag
) +
3635 OS
<< " " << format_hex(Tag
, Is64
? 18 : 10)
3636 << format(" %-20s ", TypeString
.c_str());
3637 this->dumper()->printDynamicEntry(OS
, Tag
, Entry
.getVal());
3642 template <class ELFT
>
3643 void GNUStyle
<ELFT
>::printDynamicRelocations(const ELFO
*Obj
) {
3644 const DynRegionInfo
&DynRelRegion
= this->dumper()->getDynRelRegion();
3645 const DynRegionInfo
&DynRelaRegion
= this->dumper()->getDynRelaRegion();
3646 const DynRegionInfo
&DynRelrRegion
= this->dumper()->getDynRelrRegion();
3647 const DynRegionInfo
&DynPLTRelRegion
= this->dumper()->getDynPLTRelRegion();
3648 if (DynRelaRegion
.Size
> 0) {
3649 OS
<< "\n'RELA' relocation section at offset "
3650 << format_hex(reinterpret_cast<const uint8_t *>(DynRelaRegion
.Addr
) -
3653 << " contains " << DynRelaRegion
.Size
<< " bytes:\n";
3654 printRelocHeader(ELF::SHT_RELA
);
3655 for (const Elf_Rela
&Rela
: this->dumper()->dyn_relas())
3656 printDynamicRelocation(Obj
, Rela
, true);
3658 if (DynRelRegion
.Size
> 0) {
3659 OS
<< "\n'REL' relocation section at offset "
3660 << format_hex(reinterpret_cast<const uint8_t *>(DynRelRegion
.Addr
) -
3663 << " contains " << DynRelRegion
.Size
<< " bytes:\n";
3664 printRelocHeader(ELF::SHT_REL
);
3665 for (const Elf_Rel
&Rel
: this->dumper()->dyn_rels()) {
3667 Rela
.r_offset
= Rel
.r_offset
;
3668 Rela
.r_info
= Rel
.r_info
;
3670 printDynamicRelocation(Obj
, Rela
, false);
3673 if (DynRelrRegion
.Size
> 0) {
3674 OS
<< "\n'RELR' relocation section at offset "
3675 << format_hex(reinterpret_cast<const uint8_t *>(DynRelrRegion
.Addr
) -
3678 << " contains " << DynRelrRegion
.Size
<< " bytes:\n";
3679 printRelocHeader(ELF::SHT_REL
);
3680 Elf_Relr_Range Relrs
= this->dumper()->dyn_relrs();
3681 std::vector
<Elf_Rela
> RelrRelas
=
3682 unwrapOrError(this->FileName
, Obj
->decode_relrs(Relrs
));
3683 for (const Elf_Rela
&Rela
: RelrRelas
) {
3684 printDynamicRelocation(Obj
, Rela
, false);
3687 if (DynPLTRelRegion
.Size
) {
3688 OS
<< "\n'PLT' relocation section at offset "
3689 << format_hex(reinterpret_cast<const uint8_t *>(DynPLTRelRegion
.Addr
) -
3692 << " contains " << DynPLTRelRegion
.Size
<< " bytes:\n";
3694 if (DynPLTRelRegion
.EntSize
== sizeof(Elf_Rela
)) {
3695 printRelocHeader(ELF::SHT_RELA
);
3696 for (const Elf_Rela
&Rela
: DynPLTRelRegion
.getAsArrayRef
<Elf_Rela
>())
3697 printDynamicRelocation(Obj
, Rela
, true);
3699 printRelocHeader(ELF::SHT_REL
);
3700 for (const Elf_Rel
&Rel
: DynPLTRelRegion
.getAsArrayRef
<Elf_Rel
>()) {
3702 Rela
.r_offset
= Rel
.r_offset
;
3703 Rela
.r_info
= Rel
.r_info
;
3705 printDynamicRelocation(Obj
, Rela
, false);
3710 template <class ELFT
>
3711 static void printGNUVersionSectionProlog(formatted_raw_ostream
&OS
,
3712 const Twine
&Name
, unsigned EntriesNum
,
3713 const ELFFile
<ELFT
> *Obj
,
3714 const typename
ELFT::Shdr
*Sec
,
3715 StringRef FileName
) {
3716 StringRef SecName
= unwrapOrError(FileName
, Obj
->getSectionName(Sec
));
3717 OS
<< Name
<< " section '" << SecName
<< "' "
3718 << "contains " << EntriesNum
<< " entries:\n";
3720 const typename
ELFT::Shdr
*SymTab
=
3721 unwrapOrError(FileName
, Obj
->getSection(Sec
->sh_link
));
3722 StringRef SymTabName
= unwrapOrError(FileName
, Obj
->getSectionName(SymTab
));
3723 OS
<< " Addr: " << format_hex_no_prefix(Sec
->sh_addr
, 16)
3724 << " Offset: " << format_hex(Sec
->sh_offset
, 8)
3725 << " Link: " << Sec
->sh_link
<< " (" << SymTabName
<< ")\n";
3728 template <class ELFT
>
3729 void GNUStyle
<ELFT
>::printVersionSymbolSection(const ELFFile
<ELFT
> *Obj
,
3730 const Elf_Shdr
*Sec
) {
3734 unsigned Entries
= Sec
->sh_size
/ sizeof(Elf_Versym
);
3735 printGNUVersionSectionProlog(OS
, "Version symbols", Entries
, Obj
, Sec
,
3738 const uint8_t *VersymBuf
=
3739 reinterpret_cast<const uint8_t *>(Obj
->base() + Sec
->sh_offset
);
3740 const ELFDumper
<ELFT
> *Dumper
= this->dumper();
3741 StringRef StrTable
= Dumper
->getDynamicStringTable();
3743 // readelf prints 4 entries per line.
3744 for (uint64_t VersymRow
= 0; VersymRow
< Entries
; VersymRow
+= 4) {
3745 OS
<< " " << format_hex_no_prefix(VersymRow
, 3) << ":";
3747 for (uint64_t VersymIndex
= 0;
3748 (VersymIndex
< 4) && (VersymIndex
+ VersymRow
) < Entries
;
3750 const Elf_Versym
*Versym
=
3751 reinterpret_cast<const Elf_Versym
*>(VersymBuf
);
3752 switch (Versym
->vs_index
) {
3754 OS
<< " 0 (*local*) ";
3757 OS
<< " 1 (*global*) ";
3760 OS
<< format("%4x%c", Versym
->vs_index
& VERSYM_VERSION
,
3761 Versym
->vs_index
& VERSYM_HIDDEN
? 'h' : ' ');
3763 bool IsDefault
= true;
3764 std::string VersionName
= Dumper
->getSymbolVersionByIndex(
3765 StrTable
, Versym
->vs_index
, IsDefault
);
3767 if (!VersionName
.empty())
3768 VersionName
= "(" + VersionName
+ ")";
3770 VersionName
= "(*invalid*)";
3771 OS
<< left_justify(VersionName
, 13);
3773 VersymBuf
+= sizeof(Elf_Versym
);
3780 static std::string
versionFlagToString(unsigned Flags
) {
3785 auto AddFlag
= [&Ret
, &Flags
](unsigned Flag
, StringRef Name
) {
3786 if (!(Flags
& Flag
))
3794 AddFlag(VER_FLG_BASE
, "BASE");
3795 AddFlag(VER_FLG_WEAK
, "WEAK");
3796 AddFlag(VER_FLG_INFO
, "INFO");
3797 AddFlag(~0, "<unknown>");
3801 template <class ELFT
>
3802 void GNUStyle
<ELFT
>::printVersionDefinitionSection(const ELFFile
<ELFT
> *Obj
,
3803 const Elf_Shdr
*Sec
) {
3807 unsigned VerDefsNum
= Sec
->sh_info
;
3808 printGNUVersionSectionProlog(OS
, "Version definition", VerDefsNum
, Obj
, Sec
,
3811 const Elf_Shdr
*StrTabSec
=
3812 unwrapOrError(this->FileName
, Obj
->getSection(Sec
->sh_link
));
3813 StringRef
StringTable(
3814 reinterpret_cast<const char *>(Obj
->base() + StrTabSec
->sh_offset
),
3815 (size_t)StrTabSec
->sh_size
);
3817 const uint8_t *VerdefBuf
=
3818 unwrapOrError(this->FileName
, Obj
->getSectionContents(Sec
)).data();
3819 const uint8_t *Begin
= VerdefBuf
;
3821 while (VerDefsNum
--) {
3822 const Elf_Verdef
*Verdef
= reinterpret_cast<const Elf_Verdef
*>(VerdefBuf
);
3823 OS
<< format(" 0x%04x: Rev: %u Flags: %s Index: %u Cnt: %u",
3824 VerdefBuf
- Begin
, (unsigned)Verdef
->vd_version
,
3825 versionFlagToString(Verdef
->vd_flags
).c_str(),
3826 (unsigned)Verdef
->vd_ndx
, (unsigned)Verdef
->vd_cnt
);
3828 const uint8_t *VerdauxBuf
= VerdefBuf
+ Verdef
->vd_aux
;
3829 const Elf_Verdaux
*Verdaux
=
3830 reinterpret_cast<const Elf_Verdaux
*>(VerdauxBuf
);
3831 OS
<< format(" Name: %s\n",
3832 StringTable
.drop_front(Verdaux
->vda_name
).data());
3834 for (unsigned I
= 1; I
< Verdef
->vd_cnt
; ++I
) {
3835 VerdauxBuf
+= Verdaux
->vda_next
;
3836 Verdaux
= reinterpret_cast<const Elf_Verdaux
*>(VerdauxBuf
);
3837 OS
<< format(" 0x%04x: Parent %u: %s\n", VerdauxBuf
- Begin
, I
,
3838 StringTable
.drop_front(Verdaux
->vda_name
).data());
3841 VerdefBuf
+= Verdef
->vd_next
;
3846 template <class ELFT
>
3847 void GNUStyle
<ELFT
>::printVersionDependencySection(const ELFFile
<ELFT
> *Obj
,
3848 const Elf_Shdr
*Sec
) {
3852 unsigned VerneedNum
= Sec
->sh_info
;
3853 printGNUVersionSectionProlog(OS
, "Version needs", VerneedNum
, Obj
, Sec
,
3856 ArrayRef
<uint8_t> SecData
=
3857 unwrapOrError(this->FileName
, Obj
->getSectionContents(Sec
));
3859 const Elf_Shdr
*StrTabSec
=
3860 unwrapOrError(this->FileName
, Obj
->getSection(Sec
->sh_link
));
3861 StringRef StringTable
= {
3862 reinterpret_cast<const char *>(Obj
->base() + StrTabSec
->sh_offset
),
3863 (size_t)StrTabSec
->sh_size
};
3865 const uint8_t *VerneedBuf
= SecData
.data();
3866 for (unsigned I
= 0; I
< VerneedNum
; ++I
) {
3867 const Elf_Verneed
*Verneed
=
3868 reinterpret_cast<const Elf_Verneed
*>(VerneedBuf
);
3870 OS
<< format(" 0x%04x: Version: %u File: %s Cnt: %u\n",
3871 reinterpret_cast<const uint8_t *>(Verneed
) - SecData
.begin(),
3872 (unsigned)Verneed
->vn_version
,
3873 StringTable
.drop_front(Verneed
->vn_file
).data(),
3874 (unsigned)Verneed
->vn_cnt
);
3876 const uint8_t *VernauxBuf
= VerneedBuf
+ Verneed
->vn_aux
;
3877 for (unsigned J
= 0; J
< Verneed
->vn_cnt
; ++J
) {
3878 const Elf_Vernaux
*Vernaux
=
3879 reinterpret_cast<const Elf_Vernaux
*>(VernauxBuf
);
3881 OS
<< format(" 0x%04x: Name: %s Flags: %s Version: %u\n",
3882 reinterpret_cast<const uint8_t *>(Vernaux
) - SecData
.begin(),
3883 StringTable
.drop_front(Vernaux
->vna_name
).data(),
3884 versionFlagToString(Vernaux
->vna_flags
).c_str(),
3885 (unsigned)Vernaux
->vna_other
);
3886 VernauxBuf
+= Vernaux
->vna_next
;
3888 VerneedBuf
+= Verneed
->vn_next
;
3893 // Hash histogram shows statistics of how efficient the hash was for the
3894 // dynamic symbol table. The table shows number of hash buckets for different
3895 // lengths of chains as absolute number and percentage of the total buckets.
3896 // Additionally cumulative coverage of symbols for each set of buckets.
3897 template <class ELFT
>
3898 void GNUStyle
<ELFT
>::printHashHistogram(const ELFFile
<ELFT
> *Obj
) {
3899 // Print histogram for .hash section
3900 if (const Elf_Hash
*HashTable
= this->dumper()->getHashTable()) {
3901 size_t NBucket
= HashTable
->nbucket
;
3902 size_t NChain
= HashTable
->nchain
;
3903 ArrayRef
<Elf_Word
> Buckets
= HashTable
->buckets();
3904 ArrayRef
<Elf_Word
> Chains
= HashTable
->chains();
3905 size_t TotalSyms
= 0;
3906 // If hash table is correct, we have at least chains with 0 length
3907 size_t MaxChain
= 1;
3908 size_t CumulativeNonZero
= 0;
3910 if (NChain
== 0 || NBucket
== 0)
3913 std::vector
<size_t> ChainLen(NBucket
, 0);
3914 // Go over all buckets and and note chain lengths of each bucket (total
3915 // unique chain lengths).
3916 for (size_t B
= 0; B
< NBucket
; B
++) {
3917 for (size_t C
= Buckets
[B
]; C
> 0 && C
< NChain
; C
= Chains
[C
])
3918 if (MaxChain
<= ++ChainLen
[B
])
3920 TotalSyms
+= ChainLen
[B
];
3926 std::vector
<size_t> Count(MaxChain
, 0) ;
3927 // Count how long is the chain for each bucket
3928 for (size_t B
= 0; B
< NBucket
; B
++)
3929 ++Count
[ChainLen
[B
]];
3930 // Print Number of buckets with each chain lengths and their cumulative
3931 // coverage of the symbols
3932 OS
<< "Histogram for bucket list length (total of " << NBucket
3934 << " Length Number % of total Coverage\n";
3935 for (size_t I
= 0; I
< MaxChain
; I
++) {
3936 CumulativeNonZero
+= Count
[I
] * I
;
3937 OS
<< format("%7lu %-10lu (%5.1f%%) %5.1f%%\n", I
, Count
[I
],
3938 (Count
[I
] * 100.0) / NBucket
,
3939 (CumulativeNonZero
* 100.0) / TotalSyms
);
3943 // Print histogram for .gnu.hash section
3944 if (const Elf_GnuHash
*GnuHashTable
= this->dumper()->getGnuHashTable()) {
3945 size_t NBucket
= GnuHashTable
->nbuckets
;
3946 ArrayRef
<Elf_Word
> Buckets
= GnuHashTable
->buckets();
3947 unsigned NumSyms
= this->dumper()->dynamic_symbols().size();
3950 ArrayRef
<Elf_Word
> Chains
= GnuHashTable
->values(NumSyms
);
3951 size_t Symndx
= GnuHashTable
->symndx
;
3952 size_t TotalSyms
= 0;
3953 size_t MaxChain
= 1;
3954 size_t CumulativeNonZero
= 0;
3956 if (Chains
.empty() || NBucket
== 0)
3959 std::vector
<size_t> ChainLen(NBucket
, 0);
3961 for (size_t B
= 0; B
< NBucket
; B
++) {
3965 for (size_t C
= Buckets
[B
] - Symndx
;
3966 C
< Chains
.size() && (Chains
[C
] & 1) == 0; C
++)
3967 if (MaxChain
< ++Len
)
3977 std::vector
<size_t> Count(MaxChain
, 0) ;
3978 for (size_t B
= 0; B
< NBucket
; B
++)
3979 ++Count
[ChainLen
[B
]];
3980 // Print Number of buckets with each chain lengths and their cumulative
3981 // coverage of the symbols
3982 OS
<< "Histogram for `.gnu.hash' bucket list length (total of " << NBucket
3984 << " Length Number % of total Coverage\n";
3985 for (size_t I
= 0; I
<MaxChain
; I
++) {
3986 CumulativeNonZero
+= Count
[I
] * I
;
3987 OS
<< format("%7lu %-10lu (%5.1f%%) %5.1f%%\n", I
, Count
[I
],
3988 (Count
[I
] * 100.0) / NBucket
,
3989 (CumulativeNonZero
* 100.0) / TotalSyms
);
3994 template <class ELFT
>
3995 void GNUStyle
<ELFT
>::printCGProfile(const ELFFile
<ELFT
> *Obj
) {
3996 OS
<< "GNUStyle::printCGProfile not implemented\n";
3999 template <class ELFT
>
4000 void GNUStyle
<ELFT
>::printAddrsig(const ELFFile
<ELFT
> *Obj
) {
4001 OS
<< "GNUStyle::printAddrsig not implemented\n";
4004 static StringRef
getGenericNoteTypeName(const uint32_t NT
) {
4005 static const struct {
4009 {ELF::NT_VERSION
, "NT_VERSION (version)"},
4010 {ELF::NT_ARCH
, "NT_ARCH (architecture)"},
4011 {ELF::NT_GNU_BUILD_ATTRIBUTE_OPEN
, "OPEN"},
4012 {ELF::NT_GNU_BUILD_ATTRIBUTE_FUNC
, "func"},
4015 for (const auto &Note
: Notes
)
4022 static StringRef
getCoreNoteTypeName(const uint32_t NT
) {
4023 static const struct {
4027 {ELF::NT_PRSTATUS
, "NT_PRSTATUS (prstatus structure)"},
4028 {ELF::NT_FPREGSET
, "NT_FPREGSET (floating point registers)"},
4029 {ELF::NT_PRPSINFO
, "NT_PRPSINFO (prpsinfo structure)"},
4030 {ELF::NT_TASKSTRUCT
, "NT_TASKSTRUCT (task structure)"},
4031 {ELF::NT_AUXV
, "NT_AUXV (auxiliary vector)"},
4032 {ELF::NT_PSTATUS
, "NT_PSTATUS (pstatus structure)"},
4033 {ELF::NT_FPREGS
, "NT_FPREGS (floating point registers)"},
4034 {ELF::NT_PSINFO
, "NT_PSINFO (psinfo structure)"},
4035 {ELF::NT_LWPSTATUS
, "NT_LWPSTATUS (lwpstatus_t structure)"},
4036 {ELF::NT_LWPSINFO
, "NT_LWPSINFO (lwpsinfo_t structure)"},
4037 {ELF::NT_WIN32PSTATUS
, "NT_WIN32PSTATUS (win32_pstatus structure)"},
4039 {ELF::NT_PPC_VMX
, "NT_PPC_VMX (ppc Altivec registers)"},
4040 {ELF::NT_PPC_VSX
, "NT_PPC_VSX (ppc VSX registers)"},
4041 {ELF::NT_PPC_TAR
, "NT_PPC_TAR (ppc TAR register)"},
4042 {ELF::NT_PPC_PPR
, "NT_PPC_PPR (ppc PPR register)"},
4043 {ELF::NT_PPC_DSCR
, "NT_PPC_DSCR (ppc DSCR register)"},
4044 {ELF::NT_PPC_EBB
, "NT_PPC_EBB (ppc EBB registers)"},
4045 {ELF::NT_PPC_PMU
, "NT_PPC_PMU (ppc PMU registers)"},
4046 {ELF::NT_PPC_TM_CGPR
, "NT_PPC_TM_CGPR (ppc checkpointed GPR registers)"},
4047 {ELF::NT_PPC_TM_CFPR
,
4048 "NT_PPC_TM_CFPR (ppc checkpointed floating point registers)"},
4049 {ELF::NT_PPC_TM_CVMX
,
4050 "NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)"},
4051 {ELF::NT_PPC_TM_CVSX
, "NT_PPC_TM_CVSX (ppc checkpointed VSX registers)"},
4052 {ELF::NT_PPC_TM_SPR
, "NT_PPC_TM_SPR (ppc TM special purpose registers)"},
4053 {ELF::NT_PPC_TM_CTAR
, "NT_PPC_TM_CTAR (ppc checkpointed TAR register)"},
4054 {ELF::NT_PPC_TM_CPPR
, "NT_PPC_TM_CPPR (ppc checkpointed PPR register)"},
4055 {ELF::NT_PPC_TM_CDSCR
,
4056 "NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)"},
4058 {ELF::NT_386_TLS
, "NT_386_TLS (x86 TLS information)"},
4059 {ELF::NT_386_IOPERM
, "NT_386_IOPERM (x86 I/O permissions)"},
4060 {ELF::NT_X86_XSTATE
, "NT_X86_XSTATE (x86 XSAVE extended state)"},
4062 {ELF::NT_S390_HIGH_GPRS
,
4063 "NT_S390_HIGH_GPRS (s390 upper register halves)"},
4064 {ELF::NT_S390_TIMER
, "NT_S390_TIMER (s390 timer register)"},
4065 {ELF::NT_S390_TODCMP
, "NT_S390_TODCMP (s390 TOD comparator register)"},
4066 {ELF::NT_S390_TODPREG
,
4067 "NT_S390_TODPREG (s390 TOD programmable register)"},
4068 {ELF::NT_S390_CTRS
, "NT_S390_CTRS (s390 control registers)"},
4069 {ELF::NT_S390_PREFIX
, "NT_S390_PREFIX (s390 prefix register)"},
4070 {ELF::NT_S390_LAST_BREAK
,
4071 "NT_S390_LAST_BREAK (s390 last breaking event address)"},
4072 {ELF::NT_S390_SYSTEM_CALL
,
4073 "NT_S390_SYSTEM_CALL (s390 system call restart data)"},
4074 {ELF::NT_S390_TDB
, "NT_S390_TDB (s390 transaction diagnostic block)"},
4075 {ELF::NT_S390_VXRS_LOW
,
4076 "NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)"},
4077 {ELF::NT_S390_VXRS_HIGH
,
4078 "NT_S390_VXRS_HIGH (s390 vector registers 16-31)"},
4079 {ELF::NT_S390_GS_CB
, "NT_S390_GS_CB (s390 guarded-storage registers)"},
4080 {ELF::NT_S390_GS_BC
,
4081 "NT_S390_GS_BC (s390 guarded-storage broadcast control)"},
4083 {ELF::NT_ARM_VFP
, "NT_ARM_VFP (arm VFP registers)"},
4084 {ELF::NT_ARM_TLS
, "NT_ARM_TLS (AArch TLS registers)"},
4085 {ELF::NT_ARM_HW_BREAK
,
4086 "NT_ARM_HW_BREAK (AArch hardware breakpoint registers)"},
4087 {ELF::NT_ARM_HW_WATCH
,
4088 "NT_ARM_HW_WATCH (AArch hardware watchpoint registers)"},
4090 {ELF::NT_FILE
, "NT_FILE (mapped files)"},
4091 {ELF::NT_PRXFPREG
, "NT_PRXFPREG (user_xfpregs structure)"},
4092 {ELF::NT_SIGINFO
, "NT_SIGINFO (siginfo_t data)"},
4095 for (const auto &Note
: Notes
)
4102 static std::string
getGNUNoteTypeName(const uint32_t NT
) {
4103 static const struct {
4107 {ELF::NT_GNU_ABI_TAG
, "NT_GNU_ABI_TAG (ABI version tag)"},
4108 {ELF::NT_GNU_HWCAP
, "NT_GNU_HWCAP (DSO-supplied software HWCAP info)"},
4109 {ELF::NT_GNU_BUILD_ID
, "NT_GNU_BUILD_ID (unique build ID bitstring)"},
4110 {ELF::NT_GNU_GOLD_VERSION
, "NT_GNU_GOLD_VERSION (gold version)"},
4111 {ELF::NT_GNU_PROPERTY_TYPE_0
, "NT_GNU_PROPERTY_TYPE_0 (property note)"},
4114 for (const auto &Note
: Notes
)
4116 return std::string(Note
.Name
);
4119 raw_string_ostream
OS(string
);
4120 OS
<< format("Unknown note type (0x%08x)", NT
);
4124 static std::string
getFreeBSDNoteTypeName(const uint32_t NT
) {
4125 static const struct {
4129 {ELF::NT_FREEBSD_THRMISC
, "NT_THRMISC (thrmisc structure)"},
4130 {ELF::NT_FREEBSD_PROCSTAT_PROC
, "NT_PROCSTAT_PROC (proc data)"},
4131 {ELF::NT_FREEBSD_PROCSTAT_FILES
, "NT_PROCSTAT_FILES (files data)"},
4132 {ELF::NT_FREEBSD_PROCSTAT_VMMAP
, "NT_PROCSTAT_VMMAP (vmmap data)"},
4133 {ELF::NT_FREEBSD_PROCSTAT_GROUPS
, "NT_PROCSTAT_GROUPS (groups data)"},
4134 {ELF::NT_FREEBSD_PROCSTAT_UMASK
, "NT_PROCSTAT_UMASK (umask data)"},
4135 {ELF::NT_FREEBSD_PROCSTAT_RLIMIT
, "NT_PROCSTAT_RLIMIT (rlimit data)"},
4136 {ELF::NT_FREEBSD_PROCSTAT_OSREL
, "NT_PROCSTAT_OSREL (osreldate data)"},
4137 {ELF::NT_FREEBSD_PROCSTAT_PSSTRINGS
,
4138 "NT_PROCSTAT_PSSTRINGS (ps_strings data)"},
4139 {ELF::NT_FREEBSD_PROCSTAT_AUXV
, "NT_PROCSTAT_AUXV (auxv data)"},
4142 for (const auto &Note
: Notes
)
4144 return std::string(Note
.Name
);
4147 raw_string_ostream
OS(string
);
4148 OS
<< format("Unknown note type (0x%08x)", NT
);
4152 static std::string
getAMDNoteTypeName(const uint32_t NT
) {
4153 static const struct {
4156 } Notes
[] = {{ELF::NT_AMD_AMDGPU_HSA_METADATA
,
4157 "NT_AMD_AMDGPU_HSA_METADATA (HSA Metadata)"},
4158 {ELF::NT_AMD_AMDGPU_ISA
, "NT_AMD_AMDGPU_ISA (ISA Version)"},
4159 {ELF::NT_AMD_AMDGPU_PAL_METADATA
,
4160 "NT_AMD_AMDGPU_PAL_METADATA (PAL Metadata)"}};
4162 for (const auto &Note
: Notes
)
4164 return std::string(Note
.Name
);
4167 raw_string_ostream
OS(string
);
4168 OS
<< format("Unknown note type (0x%08x)", NT
);
4172 static std::string
getAMDGPUNoteTypeName(const uint32_t NT
) {
4173 if (NT
== ELF::NT_AMDGPU_METADATA
)
4174 return std::string("NT_AMDGPU_METADATA (AMDGPU Metadata)");
4177 raw_string_ostream
OS(string
);
4178 OS
<< format("Unknown note type (0x%08x)", NT
);
4182 template <typename ELFT
>
4183 static std::string
getGNUProperty(uint32_t Type
, uint32_t DataSize
,
4184 ArrayRef
<uint8_t> Data
) {
4186 raw_string_ostream
OS(str
);
4188 auto DumpBit
= [&](uint32_t Flag
, StringRef Name
) {
4189 if (PrData
& Flag
) {
4199 OS
<< format("<application-specific type 0x%x>", Type
);
4201 case GNU_PROPERTY_STACK_SIZE
: {
4202 OS
<< "stack size: ";
4203 if (DataSize
== sizeof(typename
ELFT::uint
))
4204 OS
<< formatv("{0:x}",
4205 (uint64_t)(*(const typename
ELFT::Addr
*)Data
.data()));
4207 OS
<< format("<corrupt length: 0x%x>", DataSize
);
4210 case GNU_PROPERTY_NO_COPY_ON_PROTECTED
:
4211 OS
<< "no copy on protected";
4213 OS
<< format(" <corrupt length: 0x%x>", DataSize
);
4215 case GNU_PROPERTY_AARCH64_FEATURE_1_AND
:
4216 case GNU_PROPERTY_X86_FEATURE_1_AND
:
4217 OS
<< ((Type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
) ? "aarch64 feature: "
4219 if (DataSize
!= 4) {
4220 OS
<< format("<corrupt length: 0x%x>", DataSize
);
4223 PrData
= support::endian::read32
<ELFT::TargetEndianness
>(Data
.data());
4228 if (Type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
) {
4229 DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI
, "BTI");
4230 DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC
, "PAC");
4232 DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT
, "IBT");
4233 DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK
, "SHSTK");
4236 OS
<< format("<unknown flags: 0x%x>", PrData
);
4238 case GNU_PROPERTY_X86_ISA_1_NEEDED
:
4239 case GNU_PROPERTY_X86_ISA_1_USED
:
4241 << (Type
== GNU_PROPERTY_X86_ISA_1_NEEDED
? "needed: " : "used: ");
4242 if (DataSize
!= 4) {
4243 OS
<< format("<corrupt length: 0x%x>", DataSize
);
4246 PrData
= support::endian::read32
<ELFT::TargetEndianness
>(Data
.data());
4251 DumpBit(GNU_PROPERTY_X86_ISA_1_CMOV
, "CMOV");
4252 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE
, "SSE");
4253 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE2
, "SSE2");
4254 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE3
, "SSE3");
4255 DumpBit(GNU_PROPERTY_X86_ISA_1_SSSE3
, "SSSE3");
4256 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE4_1
, "SSE4_1");
4257 DumpBit(GNU_PROPERTY_X86_ISA_1_SSE4_2
, "SSE4_2");
4258 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX
, "AVX");
4259 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX2
, "AVX2");
4260 DumpBit(GNU_PROPERTY_X86_ISA_1_FMA
, "FMA");
4261 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512F
, "AVX512F");
4262 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512CD
, "AVX512CD");
4263 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512ER
, "AVX512ER");
4264 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512PF
, "AVX512PF");
4265 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512VL
, "AVX512VL");
4266 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512DQ
, "AVX512DQ");
4267 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512BW
, "AVX512BW");
4268 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS
, "AVX512_4FMAPS");
4269 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW
, "AVX512_4VNNIW");
4270 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_BITALG
, "AVX512_BITALG");
4271 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_IFMA
, "AVX512_IFMA");
4272 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_VBMI
, "AVX512_VBMI");
4273 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2
, "AVX512_VBMI2");
4274 DumpBit(GNU_PROPERTY_X86_ISA_1_AVX512_VNNI
, "AVX512_VNNI");
4276 OS
<< format("<unknown flags: 0x%x>", PrData
);
4279 case GNU_PROPERTY_X86_FEATURE_2_NEEDED
:
4280 case GNU_PROPERTY_X86_FEATURE_2_USED
:
4281 OS
<< "x86 feature "
4282 << (Type
== GNU_PROPERTY_X86_FEATURE_2_NEEDED
? "needed: " : "used: ");
4283 if (DataSize
!= 4) {
4284 OS
<< format("<corrupt length: 0x%x>", DataSize
);
4287 PrData
= support::endian::read32
<ELFT::TargetEndianness
>(Data
.data());
4292 DumpBit(GNU_PROPERTY_X86_FEATURE_2_X86
, "x86");
4293 DumpBit(GNU_PROPERTY_X86_FEATURE_2_X87
, "x87");
4294 DumpBit(GNU_PROPERTY_X86_FEATURE_2_MMX
, "MMX");
4295 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XMM
, "XMM");
4296 DumpBit(GNU_PROPERTY_X86_FEATURE_2_YMM
, "YMM");
4297 DumpBit(GNU_PROPERTY_X86_FEATURE_2_ZMM
, "ZMM");
4298 DumpBit(GNU_PROPERTY_X86_FEATURE_2_FXSR
, "FXSR");
4299 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVE
, "XSAVE");
4300 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT
, "XSAVEOPT");
4301 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEC
, "XSAVEC");
4303 OS
<< format("<unknown flags: 0x%x>", PrData
);
4308 template <typename ELFT
>
4309 static SmallVector
<std::string
, 4> getGNUPropertyList(ArrayRef
<uint8_t> Arr
) {
4310 using Elf_Word
= typename
ELFT::Word
;
4312 SmallVector
<std::string
, 4> Properties
;
4313 while (Arr
.size() >= 8) {
4314 uint32_t Type
= *reinterpret_cast<const Elf_Word
*>(Arr
.data());
4315 uint32_t DataSize
= *reinterpret_cast<const Elf_Word
*>(Arr
.data() + 4);
4316 Arr
= Arr
.drop_front(8);
4318 // Take padding size into account if present.
4319 uint64_t PaddedSize
= alignTo(DataSize
, sizeof(typename
ELFT::uint
));
4321 raw_string_ostream
OS(str
);
4322 if (Arr
.size() < PaddedSize
) {
4323 OS
<< format("<corrupt type (0x%x) datasz: 0x%x>", Type
, DataSize
);
4324 Properties
.push_back(OS
.str());
4327 Properties
.push_back(
4328 getGNUProperty
<ELFT
>(Type
, DataSize
, Arr
.take_front(PaddedSize
)));
4329 Arr
= Arr
.drop_front(PaddedSize
);
4333 Properties
.push_back("<corrupted GNU_PROPERTY_TYPE_0>");
4344 template <typename ELFT
> static GNUAbiTag
getGNUAbiTag(ArrayRef
<uint8_t> Desc
) {
4345 typedef typename
ELFT::Word Elf_Word
;
4347 ArrayRef
<Elf_Word
> Words(reinterpret_cast<const Elf_Word
*>(Desc
.begin()),
4348 reinterpret_cast<const Elf_Word
*>(Desc
.end()));
4350 if (Words
.size() < 4)
4351 return {"", "", /*IsValid=*/false};
4353 static const char *OSNames
[] = {
4354 "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable", "NaCl",
4356 StringRef OSName
= "Unknown";
4357 if (Words
[0] < array_lengthof(OSNames
))
4358 OSName
= OSNames
[Words
[0]];
4359 uint32_t Major
= Words
[1], Minor
= Words
[2], Patch
= Words
[3];
4361 raw_string_ostream
ABI(str
);
4362 ABI
<< Major
<< "." << Minor
<< "." << Patch
;
4363 return {OSName
, ABI
.str(), /*IsValid=*/true};
4366 static std::string
getGNUBuildId(ArrayRef
<uint8_t> Desc
) {
4368 raw_string_ostream
OS(str
);
4369 for (const auto &B
: Desc
)
4370 OS
<< format_hex_no_prefix(B
, 2);
4374 static StringRef
getGNUGoldVersion(ArrayRef
<uint8_t> Desc
) {
4375 return StringRef(reinterpret_cast<const char *>(Desc
.data()), Desc
.size());
4378 template <typename ELFT
>
4379 static void printGNUNote(raw_ostream
&OS
, uint32_t NoteType
,
4380 ArrayRef
<uint8_t> Desc
) {
4384 case ELF::NT_GNU_ABI_TAG
: {
4385 const GNUAbiTag
&AbiTag
= getGNUAbiTag
<ELFT
>(Desc
);
4386 if (!AbiTag
.IsValid
)
4387 OS
<< " <corrupt GNU_ABI_TAG>";
4389 OS
<< " OS: " << AbiTag
.OSName
<< ", ABI: " << AbiTag
.ABI
;
4392 case ELF::NT_GNU_BUILD_ID
: {
4393 OS
<< " Build ID: " << getGNUBuildId(Desc
);
4396 case ELF::NT_GNU_GOLD_VERSION
:
4397 OS
<< " Version: " << getGNUGoldVersion(Desc
);
4399 case ELF::NT_GNU_PROPERTY_TYPE_0
:
4400 OS
<< " Properties:";
4401 for (const auto &Property
: getGNUPropertyList
<ELFT
>(Desc
))
4402 OS
<< " " << Property
<< "\n";
4413 template <typename ELFT
>
4414 static AMDNote
getAMDNote(uint32_t NoteType
, ArrayRef
<uint8_t> Desc
) {
4418 case ELF::NT_AMD_AMDGPU_HSA_METADATA
:
4421 std::string(reinterpret_cast<const char *>(Desc
.data()), Desc
.size())};
4422 case ELF::NT_AMD_AMDGPU_ISA
:
4425 std::string(reinterpret_cast<const char *>(Desc
.data()), Desc
.size())};
4434 template <typename ELFT
>
4435 static AMDGPUNote
getAMDGPUNote(uint32_t NoteType
, ArrayRef
<uint8_t> Desc
) {
4439 case ELF::NT_AMDGPU_METADATA
: {
4440 auto MsgPackString
=
4441 StringRef(reinterpret_cast<const char *>(Desc
.data()), Desc
.size());
4442 msgpack::Document MsgPackDoc
;
4443 if (!MsgPackDoc
.readFromBlob(MsgPackString
, /*Multi=*/false))
4444 return {"AMDGPU Metadata", "Invalid AMDGPU Metadata"};
4446 AMDGPU::HSAMD::V3::MetadataVerifier
Verifier(true);
4447 if (!Verifier
.verify(MsgPackDoc
.getRoot()))
4448 return {"AMDGPU Metadata", "Invalid AMDGPU Metadata"};
4450 std::string HSAMetadataString
;
4451 raw_string_ostream
StrOS(HSAMetadataString
);
4452 MsgPackDoc
.toYAML(StrOS
);
4454 return {"AMDGPU Metadata", StrOS
.str()};
4459 struct CoreFileMapping
{
4460 uint64_t Start
, End
, Offset
;
4466 std::vector
<CoreFileMapping
> Mappings
;
4469 static Expected
<CoreNote
> readCoreNote(DataExtractor Desc
) {
4470 // Expected format of the NT_FILE note description:
4471 // 1. # of file mappings (call it N)
4473 // 3. N (start, end, offset) triples
4474 // 4. N packed filenames (null delimited)
4475 // Each field is an Elf_Addr, except for filenames which are char* strings.
4478 const int Bytes
= Desc
.getAddressSize();
4480 if (!Desc
.isValidOffsetForAddress(2))
4481 return createStringError(object_error::parse_failed
,
4482 "malformed note: header too short");
4483 if (Desc
.getData().back() != 0)
4484 return createStringError(object_error::parse_failed
,
4485 "malformed note: not NUL terminated");
4487 uint64_t DescOffset
= 0;
4488 uint64_t FileCount
= Desc
.getAddress(&DescOffset
);
4489 Ret
.PageSize
= Desc
.getAddress(&DescOffset
);
4491 if (!Desc
.isValidOffsetForAddress(3 * FileCount
* Bytes
))
4492 return createStringError(object_error::parse_failed
,
4493 "malformed note: too short for number of files");
4495 uint64_t FilenamesOffset
= 0;
4496 DataExtractor
Filenames(
4497 Desc
.getData().drop_front(DescOffset
+ 3 * FileCount
* Bytes
),
4498 Desc
.isLittleEndian(), Desc
.getAddressSize());
4500 Ret
.Mappings
.resize(FileCount
);
4501 for (CoreFileMapping
&Mapping
: Ret
.Mappings
) {
4502 if (!Filenames
.isValidOffsetForDataOfSize(FilenamesOffset
, 1))
4503 return createStringError(object_error::parse_failed
,
4504 "malformed note: too few filenames");
4505 Mapping
.Start
= Desc
.getAddress(&DescOffset
);
4506 Mapping
.End
= Desc
.getAddress(&DescOffset
);
4507 Mapping
.Offset
= Desc
.getAddress(&DescOffset
);
4508 Mapping
.Filename
= Filenames
.getCStrRef(&FilenamesOffset
);
4514 template <typename ELFT
>
4515 static void printCoreNote(raw_ostream
&OS
, const CoreNote
&Note
) {
4516 // Length of "0x<address>" string.
4517 const int FieldWidth
= ELFT::Is64Bits
? 18 : 10;
4519 OS
<< " Page size: " << format_decimal(Note
.PageSize
, 0) << '\n';
4520 OS
<< " " << right_justify("Start", FieldWidth
) << " "
4521 << right_justify("End", FieldWidth
) << " "
4522 << right_justify("Page Offset", FieldWidth
) << '\n';
4523 for (const CoreFileMapping
&Mapping
: Note
.Mappings
) {
4524 OS
<< " " << format_hex(Mapping
.Start
, FieldWidth
) << " "
4525 << format_hex(Mapping
.End
, FieldWidth
) << " "
4526 << format_hex(Mapping
.Offset
, FieldWidth
) << "\n "
4527 << Mapping
.Filename
<< '\n';
4531 template <class ELFT
>
4532 void GNUStyle
<ELFT
>::printNotes(const ELFFile
<ELFT
> *Obj
) {
4533 auto PrintHeader
= [&](const typename
ELFT::Off Offset
,
4534 const typename
ELFT::Addr Size
) {
4535 OS
<< "Displaying notes found at file offset " << format_hex(Offset
, 10)
4536 << " with length " << format_hex(Size
, 10) << ":\n"
4537 << " Owner Data size \tDescription\n";
4540 auto ProcessNote
= [&](const Elf_Note
&Note
) {
4541 StringRef Name
= Note
.getName();
4542 ArrayRef
<uint8_t> Descriptor
= Note
.getDesc();
4543 Elf_Word Type
= Note
.getType();
4545 // Print the note owner/type.
4546 OS
<< " " << left_justify(Name
, 20) << ' '
4547 << format_hex(Descriptor
.size(), 10) << '\t';
4548 if (Name
== "GNU") {
4549 OS
<< getGNUNoteTypeName(Type
) << '\n';
4550 } else if (Name
== "FreeBSD") {
4551 OS
<< getFreeBSDNoteTypeName(Type
) << '\n';
4552 } else if (Name
== "AMD") {
4553 OS
<< getAMDNoteTypeName(Type
) << '\n';
4554 } else if (Name
== "AMDGPU") {
4555 OS
<< getAMDGPUNoteTypeName(Type
) << '\n';
4557 StringRef NoteType
= Obj
->getHeader()->e_type
== ELF::ET_CORE
4558 ? getCoreNoteTypeName(Type
)
4559 : getGenericNoteTypeName(Type
);
4560 if (!NoteType
.empty())
4561 OS
<< NoteType
<< '\n';
4563 OS
<< "Unknown note type: (" << format_hex(Type
, 10) << ")\n";
4566 // Print the description, or fallback to printing raw bytes for unknown
4568 if (Name
== "GNU") {
4569 printGNUNote
<ELFT
>(OS
, Type
, Descriptor
);
4570 } else if (Name
== "AMD") {
4571 const AMDNote N
= getAMDNote
<ELFT
>(Type
, Descriptor
);
4572 if (!N
.Type
.empty())
4573 OS
<< " " << N
.Type
<< ":\n " << N
.Value
<< '\n';
4574 } else if (Name
== "AMDGPU") {
4575 const AMDGPUNote N
= getAMDGPUNote
<ELFT
>(Type
, Descriptor
);
4576 if (!N
.Type
.empty())
4577 OS
<< " " << N
.Type
<< ":\n " << N
.Value
<< '\n';
4578 } else if (Name
== "CORE") {
4579 if (Type
== ELF::NT_FILE
) {
4580 DataExtractor
DescExtractor(
4581 StringRef(reinterpret_cast<const char *>(Descriptor
.data()),
4583 ELFT::TargetEndianness
== support::little
, sizeof(Elf_Addr
));
4584 Expected
<CoreNote
> Note
= readCoreNote(DescExtractor
);
4586 printCoreNote
<ELFT
>(OS
, *Note
);
4588 reportWarning(Note
.takeError(), this->FileName
);
4590 } else if (!Descriptor
.empty()) {
4591 OS
<< " description data:";
4592 for (uint8_t B
: Descriptor
)
4593 OS
<< " " << format("%02x", B
);
4598 ArrayRef
<Elf_Shdr
> Sections
= unwrapOrError(this->FileName
, Obj
->sections());
4599 if (Obj
->getHeader()->e_type
!= ELF::ET_CORE
&& !Sections
.empty()) {
4600 for (const auto &S
: Sections
) {
4601 if (S
.sh_type
!= SHT_NOTE
)
4603 PrintHeader(S
.sh_offset
, S
.sh_size
);
4604 Error Err
= Error::success();
4605 for (const auto &Note
: Obj
->notes(S
, Err
))
4608 reportError(std::move(Err
), this->FileName
);
4611 for (const auto &P
:
4612 unwrapOrError(this->FileName
, Obj
->program_headers())) {
4613 if (P
.p_type
!= PT_NOTE
)
4615 PrintHeader(P
.p_offset
, P
.p_filesz
);
4616 Error Err
= Error::success();
4617 for (const auto &Note
: Obj
->notes(P
, Err
))
4620 reportError(std::move(Err
), this->FileName
);
4625 template <class ELFT
>
4626 void GNUStyle
<ELFT
>::printELFLinkerOptions(const ELFFile
<ELFT
> *Obj
) {
4627 OS
<< "printELFLinkerOptions not implemented!\n";
4630 template <class ELFT
>
4631 void DumpStyle
<ELFT
>::printFunctionStackSize(
4632 const ELFObjectFile
<ELFT
> *Obj
, uint64_t SymValue
, SectionRef FunctionSec
,
4633 const StringRef SectionName
, DataExtractor Data
, uint64_t *Offset
) {
4634 // This function ignores potentially erroneous input, unless it is directly
4635 // related to stack size reporting.
4637 for (const ELFSymbolRef
&Symbol
: Obj
->symbols()) {
4638 Expected
<uint64_t> SymAddrOrErr
= Symbol
.getAddress();
4639 if (!SymAddrOrErr
) {
4640 consumeError(SymAddrOrErr
.takeError());
4643 if (Symbol
.getELFType() == ELF::STT_FUNC
&& *SymAddrOrErr
== SymValue
) {
4644 // Check if the symbol is in the right section.
4645 if (FunctionSec
.containsSymbol(Symbol
)) {
4652 std::string FuncName
= "?";
4653 // A valid SymbolRef has a non-null object file pointer.
4654 if (FuncSym
.BasicSymbolRef::getObject()) {
4655 // Extract the symbol name.
4656 Expected
<StringRef
> FuncNameOrErr
= FuncSym
.getName();
4658 FuncName
= maybeDemangle(*FuncNameOrErr
);
4660 consumeError(FuncNameOrErr
.takeError());
4663 createError("could not identify function symbol for stack size entry"),
4664 Obj
->getFileName());
4667 // Extract the size. The expectation is that Offset is pointing to the right
4668 // place, i.e. past the function address.
4669 uint64_t PrevOffset
= *Offset
;
4670 uint64_t StackSize
= Data
.getULEB128(Offset
);
4671 // getULEB128() does not advance Offset if it is not able to extract a valid
4673 if (*Offset
== PrevOffset
)
4675 createStringError(object_error::parse_failed
,
4676 "could not extract a valid stack size in section %s",
4677 SectionName
.data()),
4678 Obj
->getFileName());
4680 printStackSizeEntry(StackSize
, FuncName
);
4683 template <class ELFT
>
4684 void GNUStyle
<ELFT
>::printStackSizeEntry(uint64_t Size
, StringRef FuncName
) {
4686 OS
<< format_decimal(Size
, 11);
4688 OS
<< FuncName
<< "\n";
4691 template <class ELFT
>
4692 void DumpStyle
<ELFT
>::printStackSize(const ELFObjectFile
<ELFT
> *Obj
,
4693 RelocationRef Reloc
,
4694 SectionRef FunctionSec
,
4695 const StringRef
&StackSizeSectionName
,
4696 const RelocationResolver
&Resolver
,
4697 DataExtractor Data
) {
4698 // This function ignores potentially erroneous input, unless it is directly
4699 // related to stack size reporting.
4700 object::symbol_iterator RelocSym
= Reloc
.getSymbol();
4701 uint64_t RelocSymValue
= 0;
4702 StringRef FileStr
= Obj
->getFileName();
4703 if (RelocSym
!= Obj
->symbol_end()) {
4704 // Ensure that the relocation symbol is in the function section, i.e. the
4705 // section where the functions whose stack sizes we are reporting are
4707 StringRef SymName
= "?";
4708 Expected
<StringRef
> NameOrErr
= RelocSym
->getName();
4710 SymName
= *NameOrErr
;
4712 consumeError(NameOrErr
.takeError());
4714 auto SectionOrErr
= RelocSym
->getSection();
4715 if (!SectionOrErr
) {
4717 createError("cannot identify the section for relocation symbol " +
4720 consumeError(SectionOrErr
.takeError());
4721 } else if (*SectionOrErr
!= FunctionSec
) {
4722 reportWarning(createError("relocation symbol " + SymName
+
4723 " is not in the expected section"),
4725 // Pretend that the symbol is in the correct section and report its
4726 // stack size anyway.
4727 FunctionSec
= **SectionOrErr
;
4730 Expected
<uint64_t> RelocSymValueOrErr
= RelocSym
->getValue();
4731 if (RelocSymValueOrErr
)
4732 RelocSymValue
= *RelocSymValueOrErr
;
4734 consumeError(RelocSymValueOrErr
.takeError());
4737 uint64_t Offset
= Reloc
.getOffset();
4738 if (!Data
.isValidOffsetForDataOfSize(Offset
, sizeof(Elf_Addr
) + 1))
4740 createStringError(object_error::parse_failed
,
4741 "found invalid relocation offset into section %s "
4742 "while trying to extract a stack size entry",
4743 StackSizeSectionName
.data()),
4746 uint64_t Addend
= Data
.getAddress(&Offset
);
4747 uint64_t SymValue
= Resolver(Reloc
, RelocSymValue
, Addend
);
4748 this->printFunctionStackSize(Obj
, SymValue
, FunctionSec
, StackSizeSectionName
,
4752 template <class ELFT
>
4753 SectionRef
toSectionRef(const ObjectFile
*Obj
, const typename
ELFT::Shdr
*Sec
) {
4755 DRI
.p
= reinterpret_cast<uintptr_t>(Sec
);
4756 return SectionRef(DRI
, Obj
);
4759 template <class ELFT
>
4760 void DumpStyle
<ELFT
>::printNonRelocatableStackSizes(
4761 const ELFObjectFile
<ELFT
> *Obj
, std::function
<void()> PrintHeader
) {
4762 // This function ignores potentially erroneous input, unless it is directly
4763 // related to stack size reporting.
4764 const ELFFile
<ELFT
> *EF
= Obj
->getELFFile();
4765 StringRef FileStr
= Obj
->getFileName();
4766 for (const SectionRef
&Sec
: Obj
->sections()) {
4767 StringRef SectionName
;
4768 if (Expected
<StringRef
> NameOrErr
= Sec
.getName())
4769 SectionName
= *NameOrErr
;
4771 consumeError(NameOrErr
.takeError());
4773 const Elf_Shdr
*ElfSec
= Obj
->getSection(Sec
.getRawDataRefImpl());
4774 if (!SectionName
.startswith(".stack_sizes"))
4777 ArrayRef
<uint8_t> Contents
=
4778 unwrapOrError(this->FileName
, EF
->getSectionContents(ElfSec
));
4780 StringRef(reinterpret_cast<const char *>(Contents
.data()),
4782 Obj
->isLittleEndian(), sizeof(Elf_Addr
));
4783 // A .stack_sizes section header's sh_link field is supposed to point
4784 // to the section that contains the functions whose stack sizes are
4786 const Elf_Shdr
*FunctionELFSec
=
4787 unwrapOrError(this->FileName
, EF
->getSection(ElfSec
->sh_link
));
4788 uint64_t Offset
= 0;
4789 while (Offset
< Contents
.size()) {
4790 // The function address is followed by a ULEB representing the stack
4791 // size. Check for an extra byte before we try to process the entry.
4792 if (!Data
.isValidOffsetForDataOfSize(Offset
, sizeof(Elf_Addr
) + 1)) {
4795 object_error::parse_failed
,
4796 "section %s ended while trying to extract a stack size entry",
4797 SectionName
.data()),
4800 uint64_t SymValue
= Data
.getAddress(&Offset
);
4801 printFunctionStackSize(Obj
, SymValue
,
4802 toSectionRef
<ELFT
>(Obj
, FunctionELFSec
),
4803 SectionName
, Data
, &Offset
);
4808 template <class ELFT
>
4809 void DumpStyle
<ELFT
>::printRelocatableStackSizes(
4810 const ELFObjectFile
<ELFT
> *Obj
, std::function
<void()> PrintHeader
) {
4811 const ELFFile
<ELFT
> *EF
= Obj
->getELFFile();
4813 // Build a map between stack size sections and their corresponding relocation
4815 llvm::MapVector
<SectionRef
, SectionRef
> StackSizeRelocMap
;
4816 const SectionRef NullSection
{};
4818 for (const SectionRef
&Sec
: Obj
->sections()) {
4819 StringRef SectionName
;
4820 if (Expected
<StringRef
> NameOrErr
= Sec
.getName())
4821 SectionName
= *NameOrErr
;
4823 consumeError(NameOrErr
.takeError());
4825 // A stack size section that we haven't encountered yet is mapped to the
4826 // null section until we find its corresponding relocation section.
4827 if (SectionName
.startswith(".stack_sizes"))
4828 if (StackSizeRelocMap
.count(Sec
) == 0) {
4829 StackSizeRelocMap
[Sec
] = NullSection
;
4833 // Check relocation sections if they are relocating contents of a
4834 // stack sizes section.
4835 const Elf_Shdr
*ElfSec
= Obj
->getSection(Sec
.getRawDataRefImpl());
4836 uint32_t SectionType
= ElfSec
->sh_type
;
4837 if (SectionType
!= ELF::SHT_RELA
&& SectionType
!= ELF::SHT_REL
)
4840 SectionRef Contents
= *Sec
.getRelocatedSection();
4841 const Elf_Shdr
*ContentsSec
= Obj
->getSection(Contents
.getRawDataRefImpl());
4842 Expected
<StringRef
> ContentsSectionNameOrErr
=
4843 EF
->getSectionName(ContentsSec
);
4844 if (!ContentsSectionNameOrErr
) {
4845 consumeError(ContentsSectionNameOrErr
.takeError());
4848 if (!ContentsSectionNameOrErr
->startswith(".stack_sizes"))
4850 // Insert a mapping from the stack sizes section to its relocation section.
4851 StackSizeRelocMap
[toSectionRef
<ELFT
>(Obj
, ContentsSec
)] = Sec
;
4854 for (const auto &StackSizeMapEntry
: StackSizeRelocMap
) {
4856 const SectionRef
&StackSizesSec
= StackSizeMapEntry
.first
;
4857 const SectionRef
&RelocSec
= StackSizeMapEntry
.second
;
4859 // Warn about stack size sections without a relocation section.
4860 StringRef StackSizeSectionName
;
4861 if (Expected
<StringRef
> NameOrErr
= StackSizesSec
.getName())
4862 StackSizeSectionName
= *NameOrErr
;
4864 consumeError(NameOrErr
.takeError());
4866 if (RelocSec
== NullSection
) {
4867 reportWarning(createError("section " + StackSizeSectionName
+
4868 " does not have a corresponding "
4869 "relocation section"),
4870 Obj
->getFileName());
4874 // A .stack_sizes section header's sh_link field is supposed to point
4875 // to the section that contains the functions whose stack sizes are
4877 const Elf_Shdr
*StackSizesELFSec
=
4878 Obj
->getSection(StackSizesSec
.getRawDataRefImpl());
4879 const SectionRef FunctionSec
= toSectionRef
<ELFT
>(
4880 Obj
, unwrapOrError(this->FileName
,
4881 EF
->getSection(StackSizesELFSec
->sh_link
)));
4883 bool (*IsSupportedFn
)(uint64_t);
4884 RelocationResolver Resolver
;
4885 std::tie(IsSupportedFn
, Resolver
) = getRelocationResolver(*Obj
);
4886 auto Contents
= unwrapOrError(this->FileName
, StackSizesSec
.getContents());
4888 StringRef(reinterpret_cast<const char *>(Contents
.data()),
4890 Obj
->isLittleEndian(), sizeof(Elf_Addr
));
4891 for (const RelocationRef
&Reloc
: RelocSec
.relocations()) {
4892 if (!IsSupportedFn(Reloc
.getType())) {
4893 StringRef RelocSectionName
;
4894 Expected
<StringRef
> NameOrErr
= RelocSec
.getName();
4896 RelocSectionName
= *NameOrErr
;
4898 consumeError(NameOrErr
.takeError());
4900 StringRef RelocName
= EF
->getRelocationTypeName(Reloc
.getType());
4902 createStringError(object_error::parse_failed
,
4903 "unsupported relocation type in section %s: %s",
4904 RelocSectionName
.data(), RelocName
.data()),
4905 Obj
->getFileName());
4907 this->printStackSize(Obj
, Reloc
, FunctionSec
, StackSizeSectionName
,
4913 template <class ELFT
>
4914 void GNUStyle
<ELFT
>::printStackSizes(const ELFObjectFile
<ELFT
> *Obj
) {
4915 bool HeaderHasBeenPrinted
= false;
4916 auto PrintHeader
= [&]() {
4917 if (HeaderHasBeenPrinted
)
4919 OS
<< "\nStack Sizes:\n";
4924 HeaderHasBeenPrinted
= true;
4927 // For non-relocatable objects, look directly for sections whose name starts
4928 // with .stack_sizes and process the contents.
4929 if (Obj
->isRelocatableObject())
4930 this->printRelocatableStackSizes(Obj
, PrintHeader
);
4932 this->printNonRelocatableStackSizes(Obj
, PrintHeader
);
4935 template <class ELFT
>
4936 void GNUStyle
<ELFT
>::printMipsGOT(const MipsGOTParser
<ELFT
> &Parser
) {
4937 size_t Bias
= ELFT::Is64Bits
? 8 : 0;
4938 auto PrintEntry
= [&](const Elf_Addr
*E
, StringRef Purpose
) {
4940 OS
<< format_hex_no_prefix(Parser
.getGotAddress(E
), 8 + Bias
);
4941 OS
.PadToColumn(11 + Bias
);
4942 OS
<< format_decimal(Parser
.getGotOffset(E
), 6) << "(gp)";
4943 OS
.PadToColumn(22 + Bias
);
4944 OS
<< format_hex_no_prefix(*E
, 8 + Bias
);
4945 OS
.PadToColumn(31 + 2 * Bias
);
4946 OS
<< Purpose
<< "\n";
4949 OS
<< (Parser
.IsStatic
? "Static GOT:\n" : "Primary GOT:\n");
4950 OS
<< " Canonical gp value: "
4951 << format_hex_no_prefix(Parser
.getGp(), 8 + Bias
) << "\n\n";
4953 OS
<< " Reserved entries:\n";
4955 OS
<< " Address Access Initial Purpose\n";
4957 OS
<< " Address Access Initial Purpose\n";
4958 PrintEntry(Parser
.getGotLazyResolver(), "Lazy resolver");
4959 if (Parser
.getGotModulePointer())
4960 PrintEntry(Parser
.getGotModulePointer(), "Module pointer (GNU extension)");
4962 if (!Parser
.getLocalEntries().empty()) {
4964 OS
<< " Local entries:\n";
4966 OS
<< " Address Access Initial\n";
4968 OS
<< " Address Access Initial\n";
4969 for (auto &E
: Parser
.getLocalEntries())
4973 if (Parser
.IsStatic
)
4976 if (!Parser
.getGlobalEntries().empty()) {
4978 OS
<< " Global entries:\n";
4980 OS
<< " Address Access Initial Sym.Val."
4981 << " Type Ndx Name\n";
4983 OS
<< " Address Access Initial Sym.Val. Type Ndx Name\n";
4984 for (auto &E
: Parser
.getGlobalEntries()) {
4985 const Elf_Sym
*Sym
= Parser
.getGotSym(&E
);
4986 std::string SymName
= this->dumper()->getFullSymbolName(
4987 Sym
, this->dumper()->getDynamicStringTable(), false);
4990 OS
<< to_string(format_hex_no_prefix(Parser
.getGotAddress(&E
), 8 + Bias
));
4991 OS
.PadToColumn(11 + Bias
);
4992 OS
<< to_string(format_decimal(Parser
.getGotOffset(&E
), 6)) + "(gp)";
4993 OS
.PadToColumn(22 + Bias
);
4994 OS
<< to_string(format_hex_no_prefix(E
, 8 + Bias
));
4995 OS
.PadToColumn(31 + 2 * Bias
);
4996 OS
<< to_string(format_hex_no_prefix(Sym
->st_value
, 8 + Bias
));
4997 OS
.PadToColumn(40 + 3 * Bias
);
4998 OS
<< printEnum(Sym
->getType(), makeArrayRef(ElfSymbolTypes
));
4999 OS
.PadToColumn(48 + 3 * Bias
);
5000 OS
<< getSymbolSectionNdx(Parser
.Obj
, Sym
,
5001 this->dumper()->dynamic_symbols().begin());
5002 OS
.PadToColumn(52 + 3 * Bias
);
5003 OS
<< SymName
<< "\n";
5007 if (!Parser
.getOtherEntries().empty())
5008 OS
<< "\n Number of TLS and multi-GOT entries "
5009 << Parser
.getOtherEntries().size() << "\n";
5012 template <class ELFT
>
5013 void GNUStyle
<ELFT
>::printMipsPLT(const MipsGOTParser
<ELFT
> &Parser
) {
5014 size_t Bias
= ELFT::Is64Bits
? 8 : 0;
5015 auto PrintEntry
= [&](const Elf_Addr
*E
, StringRef Purpose
) {
5017 OS
<< format_hex_no_prefix(Parser
.getPltAddress(E
), 8 + Bias
);
5018 OS
.PadToColumn(11 + Bias
);
5019 OS
<< format_hex_no_prefix(*E
, 8 + Bias
);
5020 OS
.PadToColumn(20 + 2 * Bias
);
5021 OS
<< Purpose
<< "\n";
5024 OS
<< "PLT GOT:\n\n";
5026 OS
<< " Reserved entries:\n";
5027 OS
<< " Address Initial Purpose\n";
5028 PrintEntry(Parser
.getPltLazyResolver(), "PLT lazy resolver");
5029 if (Parser
.getPltModulePointer())
5030 PrintEntry(Parser
.getPltModulePointer(), "Module pointer");
5032 if (!Parser
.getPltEntries().empty()) {
5034 OS
<< " Entries:\n";
5035 OS
<< " Address Initial Sym.Val. Type Ndx Name\n";
5036 for (auto &E
: Parser
.getPltEntries()) {
5037 const Elf_Sym
*Sym
= Parser
.getPltSym(&E
);
5038 std::string SymName
= this->dumper()->getFullSymbolName(
5039 Sym
, this->dumper()->getDynamicStringTable(), false);
5042 OS
<< to_string(format_hex_no_prefix(Parser
.getPltAddress(&E
), 8 + Bias
));
5043 OS
.PadToColumn(11 + Bias
);
5044 OS
<< to_string(format_hex_no_prefix(E
, 8 + Bias
));
5045 OS
.PadToColumn(20 + 2 * Bias
);
5046 OS
<< to_string(format_hex_no_prefix(Sym
->st_value
, 8 + Bias
));
5047 OS
.PadToColumn(29 + 3 * Bias
);
5048 OS
<< printEnum(Sym
->getType(), makeArrayRef(ElfSymbolTypes
));
5049 OS
.PadToColumn(37 + 3 * Bias
);
5050 OS
<< getSymbolSectionNdx(Parser
.Obj
, Sym
,
5051 this->dumper()->dynamic_symbols().begin());
5052 OS
.PadToColumn(41 + 3 * Bias
);
5053 OS
<< SymName
<< "\n";
5058 template <class ELFT
> void LLVMStyle
<ELFT
>::printFileHeaders(const ELFO
*Obj
) {
5059 const Elf_Ehdr
*E
= Obj
->getHeader();
5061 DictScope
D(W
, "ElfHeader");
5063 DictScope
D(W
, "Ident");
5064 W
.printBinary("Magic", makeArrayRef(E
->e_ident
).slice(ELF::EI_MAG0
, 4));
5065 W
.printEnum("Class", E
->e_ident
[ELF::EI_CLASS
], makeArrayRef(ElfClass
));
5066 W
.printEnum("DataEncoding", E
->e_ident
[ELF::EI_DATA
],
5067 makeArrayRef(ElfDataEncoding
));
5068 W
.printNumber("FileVersion", E
->e_ident
[ELF::EI_VERSION
]);
5070 auto OSABI
= makeArrayRef(ElfOSABI
);
5071 if (E
->e_ident
[ELF::EI_OSABI
] >= ELF::ELFOSABI_FIRST_ARCH
&&
5072 E
->e_ident
[ELF::EI_OSABI
] <= ELF::ELFOSABI_LAST_ARCH
) {
5073 switch (E
->e_machine
) {
5074 case ELF::EM_AMDGPU
:
5075 OSABI
= makeArrayRef(AMDGPUElfOSABI
);
5078 OSABI
= makeArrayRef(ARMElfOSABI
);
5080 case ELF::EM_TI_C6000
:
5081 OSABI
= makeArrayRef(C6000ElfOSABI
);
5085 W
.printEnum("OS/ABI", E
->e_ident
[ELF::EI_OSABI
], OSABI
);
5086 W
.printNumber("ABIVersion", E
->e_ident
[ELF::EI_ABIVERSION
]);
5087 W
.printBinary("Unused", makeArrayRef(E
->e_ident
).slice(ELF::EI_PAD
));
5090 W
.printEnum("Type", E
->e_type
, makeArrayRef(ElfObjectFileType
));
5091 W
.printEnum("Machine", E
->e_machine
, makeArrayRef(ElfMachineType
));
5092 W
.printNumber("Version", E
->e_version
);
5093 W
.printHex("Entry", E
->e_entry
);
5094 W
.printHex("ProgramHeaderOffset", E
->e_phoff
);
5095 W
.printHex("SectionHeaderOffset", E
->e_shoff
);
5096 if (E
->e_machine
== EM_MIPS
)
5097 W
.printFlags("Flags", E
->e_flags
, makeArrayRef(ElfHeaderMipsFlags
),
5098 unsigned(ELF::EF_MIPS_ARCH
), unsigned(ELF::EF_MIPS_ABI
),
5099 unsigned(ELF::EF_MIPS_MACH
));
5100 else if (E
->e_machine
== EM_AMDGPU
)
5101 W
.printFlags("Flags", E
->e_flags
, makeArrayRef(ElfHeaderAMDGPUFlags
),
5102 unsigned(ELF::EF_AMDGPU_MACH
));
5103 else if (E
->e_machine
== EM_RISCV
)
5104 W
.printFlags("Flags", E
->e_flags
, makeArrayRef(ElfHeaderRISCVFlags
));
5106 W
.printFlags("Flags", E
->e_flags
);
5107 W
.printNumber("HeaderSize", E
->e_ehsize
);
5108 W
.printNumber("ProgramHeaderEntrySize", E
->e_phentsize
);
5109 W
.printNumber("ProgramHeaderCount", E
->e_phnum
);
5110 W
.printNumber("SectionHeaderEntrySize", E
->e_shentsize
);
5111 W
.printString("SectionHeaderCount",
5112 getSectionHeadersNumString(Obj
, this->FileName
));
5113 W
.printString("StringTableSectionIndex",
5114 getSectionHeaderTableIndexString(Obj
, this->FileName
));
5118 template <class ELFT
>
5119 void LLVMStyle
<ELFT
>::printGroupSections(const ELFO
*Obj
) {
5120 DictScope
Lists(W
, "Groups");
5121 std::vector
<GroupSection
> V
= getGroups
<ELFT
>(Obj
, this->FileName
);
5122 DenseMap
<uint64_t, const GroupSection
*> Map
= mapSectionsToGroups(V
);
5123 for (const GroupSection
&G
: V
) {
5124 DictScope
D(W
, "Group");
5125 W
.printNumber("Name", G
.Name
, G
.ShName
);
5126 W
.printNumber("Index", G
.Index
);
5127 W
.printNumber("Link", G
.Link
);
5128 W
.printNumber("Info", G
.Info
);
5129 W
.printHex("Type", getGroupType(G
.Type
), G
.Type
);
5130 W
.startLine() << "Signature: " << G
.Signature
<< "\n";
5132 ListScope
L(W
, "Section(s) in group");
5133 for (const GroupMember
&GM
: G
.Members
) {
5134 const GroupSection
*MainGroup
= Map
[GM
.Index
];
5135 if (MainGroup
!= &G
) {
5137 errs() << "Error: " << GM
.Name
<< " (" << GM
.Index
5138 << ") in a group " + G
.Name
+ " (" << G
.Index
5139 << ") is already in a group " + MainGroup
->Name
+ " ("
5140 << MainGroup
->Index
<< ")\n";
5144 W
.startLine() << GM
.Name
<< " (" << GM
.Index
<< ")\n";
5149 W
.startLine() << "There are no group sections in the file.\n";
5152 template <class ELFT
> void LLVMStyle
<ELFT
>::printRelocations(const ELFO
*Obj
) {
5153 ListScope
D(W
, "Relocations");
5155 int SectionNumber
= -1;
5156 for (const Elf_Shdr
&Sec
: unwrapOrError(this->FileName
, Obj
->sections())) {
5159 if (Sec
.sh_type
!= ELF::SHT_REL
&& Sec
.sh_type
!= ELF::SHT_RELA
&&
5160 Sec
.sh_type
!= ELF::SHT_RELR
&& Sec
.sh_type
!= ELF::SHT_ANDROID_REL
&&
5161 Sec
.sh_type
!= ELF::SHT_ANDROID_RELA
&&
5162 Sec
.sh_type
!= ELF::SHT_ANDROID_RELR
)
5165 StringRef Name
= unwrapOrError(this->FileName
, Obj
->getSectionName(&Sec
));
5167 W
.startLine() << "Section (" << SectionNumber
<< ") " << Name
<< " {\n";
5170 printRelocations(&Sec
, Obj
);
5173 W
.startLine() << "}\n";
5177 template <class ELFT
>
5178 void LLVMStyle
<ELFT
>::printRelocations(const Elf_Shdr
*Sec
, const ELFO
*Obj
) {
5179 const Elf_Shdr
*SymTab
=
5180 unwrapOrError(this->FileName
, Obj
->getSection(Sec
->sh_link
));
5182 switch (Sec
->sh_type
) {
5184 for (const Elf_Rel
&R
: unwrapOrError(this->FileName
, Obj
->rels(Sec
))) {
5186 Rela
.r_offset
= R
.r_offset
;
5187 Rela
.r_info
= R
.r_info
;
5189 printRelocation(Obj
, Rela
, SymTab
);
5193 for (const Elf_Rela
&R
: unwrapOrError(this->FileName
, Obj
->relas(Sec
)))
5194 printRelocation(Obj
, R
, SymTab
);
5197 case ELF::SHT_ANDROID_RELR
: {
5198 Elf_Relr_Range Relrs
= unwrapOrError(this->FileName
, Obj
->relrs(Sec
));
5199 if (opts::RawRelr
) {
5200 for (const Elf_Relr
&R
: Relrs
)
5201 W
.startLine() << W
.hex(R
) << "\n";
5203 std::vector
<Elf_Rela
> RelrRelas
=
5204 unwrapOrError(this->FileName
, Obj
->decode_relrs(Relrs
));
5205 for (const Elf_Rela
&R
: RelrRelas
)
5206 printRelocation(Obj
, R
, SymTab
);
5210 case ELF::SHT_ANDROID_REL
:
5211 case ELF::SHT_ANDROID_RELA
:
5212 for (const Elf_Rela
&R
:
5213 unwrapOrError(this->FileName
, Obj
->android_relas(Sec
)))
5214 printRelocation(Obj
, R
, SymTab
);
5219 template <class ELFT
>
5220 void LLVMStyle
<ELFT
>::printRelocation(const ELFO
*Obj
, Elf_Rela Rel
,
5221 const Elf_Shdr
*SymTab
) {
5222 SmallString
<32> RelocName
;
5223 Obj
->getRelocationTypeName(Rel
.getType(Obj
->isMips64EL()), RelocName
);
5224 std::string TargetName
;
5225 const Elf_Sym
*Sym
=
5226 unwrapOrError(this->FileName
, Obj
->getRelocationSymbol(&Rel
, SymTab
));
5227 if (Sym
&& Sym
->getType() == ELF::STT_SECTION
) {
5228 const Elf_Shdr
*Sec
= unwrapOrError(
5230 Obj
->getSection(Sym
, SymTab
, this->dumper()->getShndxTable()));
5231 TargetName
= unwrapOrError(this->FileName
, Obj
->getSectionName(Sec
));
5233 StringRef StrTable
=
5234 unwrapOrError(this->FileName
, Obj
->getStringTableForSymtab(*SymTab
));
5235 TargetName
= this->dumper()->getFullSymbolName(
5236 Sym
, StrTable
, SymTab
->sh_type
== SHT_DYNSYM
/* IsDynamic */);
5239 if (opts::ExpandRelocs
) {
5240 DictScope
Group(W
, "Relocation");
5241 W
.printHex("Offset", Rel
.r_offset
);
5242 W
.printNumber("Type", RelocName
, (int)Rel
.getType(Obj
->isMips64EL()));
5243 W
.printNumber("Symbol", !TargetName
.empty() ? TargetName
: "-",
5244 Rel
.getSymbol(Obj
->isMips64EL()));
5245 W
.printHex("Addend", Rel
.r_addend
);
5247 raw_ostream
&OS
= W
.startLine();
5248 OS
<< W
.hex(Rel
.r_offset
) << " " << RelocName
<< " "
5249 << (!TargetName
.empty() ? TargetName
: "-") << " " << W
.hex(Rel
.r_addend
)
5254 template <class ELFT
>
5255 void LLVMStyle
<ELFT
>::printSectionHeaders(const ELFO
*Obj
) {
5256 ListScope
SectionsD(W
, "Sections");
5258 int SectionIndex
= -1;
5259 ArrayRef
<Elf_Shdr
> Sections
= unwrapOrError(this->FileName
, Obj
->sections());
5260 const ELFObjectFile
<ELFT
> *ElfObj
= this->dumper()->getElfObject();
5261 for (const Elf_Shdr
&Sec
: Sections
) {
5262 StringRef Name
= unwrapOrError(
5263 ElfObj
->getFileName(), Obj
->getSectionName(&Sec
, this->WarningHandler
));
5264 DictScope
SectionD(W
, "Section");
5265 W
.printNumber("Index", ++SectionIndex
);
5266 W
.printNumber("Name", Name
, Sec
.sh_name
);
5269 object::getELFSectionTypeName(Obj
->getHeader()->e_machine
, Sec
.sh_type
),
5271 std::vector
<EnumEntry
<unsigned>> SectionFlags(std::begin(ElfSectionFlags
),
5272 std::end(ElfSectionFlags
));
5273 switch (Obj
->getHeader()->e_machine
) {
5275 SectionFlags
.insert(SectionFlags
.end(), std::begin(ElfARMSectionFlags
),
5276 std::end(ElfARMSectionFlags
));
5279 SectionFlags
.insert(SectionFlags
.end(),
5280 std::begin(ElfHexagonSectionFlags
),
5281 std::end(ElfHexagonSectionFlags
));
5284 SectionFlags
.insert(SectionFlags
.end(), std::begin(ElfMipsSectionFlags
),
5285 std::end(ElfMipsSectionFlags
));
5288 SectionFlags
.insert(SectionFlags
.end(), std::begin(ElfX86_64SectionFlags
),
5289 std::end(ElfX86_64SectionFlags
));
5292 SectionFlags
.insert(SectionFlags
.end(), std::begin(ElfXCoreSectionFlags
),
5293 std::end(ElfXCoreSectionFlags
));
5299 W
.printFlags("Flags", Sec
.sh_flags
, makeArrayRef(SectionFlags
));
5300 W
.printHex("Address", Sec
.sh_addr
);
5301 W
.printHex("Offset", Sec
.sh_offset
);
5302 W
.printNumber("Size", Sec
.sh_size
);
5303 W
.printNumber("Link", Sec
.sh_link
);
5304 W
.printNumber("Info", Sec
.sh_info
);
5305 W
.printNumber("AddressAlignment", Sec
.sh_addralign
);
5306 W
.printNumber("EntrySize", Sec
.sh_entsize
);
5308 if (opts::SectionRelocations
) {
5309 ListScope
D(W
, "Relocations");
5310 printRelocations(&Sec
, Obj
);
5313 if (opts::SectionSymbols
) {
5314 ListScope
D(W
, "Symbols");
5315 const Elf_Shdr
*Symtab
= this->dumper()->getDotSymtabSec();
5316 StringRef StrTable
=
5317 unwrapOrError(this->FileName
, Obj
->getStringTableForSymtab(*Symtab
));
5319 for (const Elf_Sym
&Sym
:
5320 unwrapOrError(this->FileName
, Obj
->symbols(Symtab
))) {
5321 const Elf_Shdr
*SymSec
= unwrapOrError(
5323 Obj
->getSection(&Sym
, Symtab
, this->dumper()->getShndxTable()));
5327 unwrapOrError(this->FileName
, Obj
->symbols(Symtab
)).begin(),
5328 StrTable
, false, false);
5332 if (opts::SectionData
&& Sec
.sh_type
!= ELF::SHT_NOBITS
) {
5333 ArrayRef
<uint8_t> Data
=
5334 unwrapOrError(this->FileName
, Obj
->getSectionContents(&Sec
));
5337 StringRef(reinterpret_cast<const char *>(Data
.data()), Data
.size()));
5342 template <class ELFT
>
5343 void LLVMStyle
<ELFT
>::printSymbol(const ELFO
*Obj
, const Elf_Sym
*Symbol
,
5344 const Elf_Sym
*First
, StringRef StrTable
,
5346 bool /*NonVisibilityBitsUsed*/) {
5347 unsigned SectionIndex
= 0;
5348 StringRef SectionName
;
5349 this->dumper()->getSectionNameIndex(Symbol
, First
, SectionName
, SectionIndex
);
5350 std::string FullSymbolName
=
5351 this->dumper()->getFullSymbolName(Symbol
, StrTable
, IsDynamic
);
5352 unsigned char SymbolType
= Symbol
->getType();
5354 DictScope
D(W
, "Symbol");
5355 W
.printNumber("Name", FullSymbolName
, Symbol
->st_name
);
5356 W
.printHex("Value", Symbol
->st_value
);
5357 W
.printNumber("Size", Symbol
->st_size
);
5358 W
.printEnum("Binding", Symbol
->getBinding(), makeArrayRef(ElfSymbolBindings
));
5359 if (Obj
->getHeader()->e_machine
== ELF::EM_AMDGPU
&&
5360 SymbolType
>= ELF::STT_LOOS
&& SymbolType
< ELF::STT_HIOS
)
5361 W
.printEnum("Type", SymbolType
, makeArrayRef(AMDGPUSymbolTypes
));
5363 W
.printEnum("Type", SymbolType
, makeArrayRef(ElfSymbolTypes
));
5364 if (Symbol
->st_other
== 0)
5365 // Usually st_other flag is zero. Do not pollute the output
5366 // by flags enumeration in that case.
5367 W
.printNumber("Other", 0);
5369 std::vector
<EnumEntry
<unsigned>> SymOtherFlags(std::begin(ElfSymOtherFlags
),
5370 std::end(ElfSymOtherFlags
));
5371 if (Obj
->getHeader()->e_machine
== EM_MIPS
) {
5372 // Someones in their infinite wisdom decided to make STO_MIPS_MIPS16
5373 // flag overlapped with other ST_MIPS_xxx flags. So consider both
5374 // cases separately.
5375 if ((Symbol
->st_other
& STO_MIPS_MIPS16
) == STO_MIPS_MIPS16
)
5376 SymOtherFlags
.insert(SymOtherFlags
.end(),
5377 std::begin(ElfMips16SymOtherFlags
),
5378 std::end(ElfMips16SymOtherFlags
));
5380 SymOtherFlags
.insert(SymOtherFlags
.end(),
5381 std::begin(ElfMipsSymOtherFlags
),
5382 std::end(ElfMipsSymOtherFlags
));
5384 W
.printFlags("Other", Symbol
->st_other
, makeArrayRef(SymOtherFlags
), 0x3u
);
5386 W
.printHex("Section", SectionName
, SectionIndex
);
5389 template <class ELFT
>
5390 void LLVMStyle
<ELFT
>::printSymbols(const ELFO
*Obj
, bool PrintSymbols
,
5391 bool PrintDynamicSymbols
) {
5394 if (PrintDynamicSymbols
)
5395 printDynamicSymbols(Obj
);
5398 template <class ELFT
> void LLVMStyle
<ELFT
>::printSymbols(const ELFO
*Obj
) {
5399 ListScope
Group(W
, "Symbols");
5400 this->dumper()->printSymbolsHelper(false);
5403 template <class ELFT
>
5404 void LLVMStyle
<ELFT
>::printDynamicSymbols(const ELFO
*Obj
) {
5405 ListScope
Group(W
, "DynamicSymbols");
5406 this->dumper()->printSymbolsHelper(true);
5409 template <class ELFT
> void LLVMStyle
<ELFT
>::printDynamic(const ELFFile
<ELFT
> *Obj
) {
5410 Elf_Dyn_Range Table
= this->dumper()->dynamic_table();
5414 raw_ostream
&OS
= W
.getOStream();
5415 W
.startLine() << "DynamicSection [ (" << Table
.size() << " entries)\n";
5417 bool Is64
= ELFT::Is64Bits
;
5419 W
.startLine() << " Tag Type Name/Value\n";
5421 W
.startLine() << " Tag Type Name/Value\n";
5422 for (auto Entry
: Table
) {
5423 uintX_t Tag
= Entry
.getTag();
5424 W
.startLine() << " " << format_hex(Tag
, Is64
? 18 : 10, true) << " "
5426 getTypeString(Obj
->getHeader()->e_machine
, Tag
));
5427 this->dumper()->printDynamicEntry(OS
, Tag
, Entry
.getVal());
5431 W
.startLine() << "]\n";
5434 template <class ELFT
>
5435 void LLVMStyle
<ELFT
>::printDynamicRelocations(const ELFO
*Obj
) {
5436 const DynRegionInfo
&DynRelRegion
= this->dumper()->getDynRelRegion();
5437 const DynRegionInfo
&DynRelaRegion
= this->dumper()->getDynRelaRegion();
5438 const DynRegionInfo
&DynRelrRegion
= this->dumper()->getDynRelrRegion();
5439 const DynRegionInfo
&DynPLTRelRegion
= this->dumper()->getDynPLTRelRegion();
5440 if (DynRelRegion
.Size
&& DynRelaRegion
.Size
)
5441 report_fatal_error("There are both REL and RELA dynamic relocations");
5442 W
.startLine() << "Dynamic Relocations {\n";
5444 if (DynRelaRegion
.Size
> 0)
5445 for (const Elf_Rela
&Rela
: this->dumper()->dyn_relas())
5446 printDynamicRelocation(Obj
, Rela
);
5448 for (const Elf_Rel
&Rel
: this->dumper()->dyn_rels()) {
5450 Rela
.r_offset
= Rel
.r_offset
;
5451 Rela
.r_info
= Rel
.r_info
;
5453 printDynamicRelocation(Obj
, Rela
);
5455 if (DynRelrRegion
.Size
> 0) {
5456 Elf_Relr_Range Relrs
= this->dumper()->dyn_relrs();
5457 std::vector
<Elf_Rela
> RelrRelas
=
5458 unwrapOrError(this->FileName
, Obj
->decode_relrs(Relrs
));
5459 for (const Elf_Rela
&Rela
: RelrRelas
)
5460 printDynamicRelocation(Obj
, Rela
);
5462 if (DynPLTRelRegion
.EntSize
== sizeof(Elf_Rela
))
5463 for (const Elf_Rela
&Rela
: DynPLTRelRegion
.getAsArrayRef
<Elf_Rela
>())
5464 printDynamicRelocation(Obj
, Rela
);
5466 for (const Elf_Rel
&Rel
: DynPLTRelRegion
.getAsArrayRef
<Elf_Rel
>()) {
5468 Rela
.r_offset
= Rel
.r_offset
;
5469 Rela
.r_info
= Rel
.r_info
;
5471 printDynamicRelocation(Obj
, Rela
);
5474 W
.startLine() << "}\n";
5477 template <class ELFT
>
5478 void LLVMStyle
<ELFT
>::printDynamicRelocation(const ELFO
*Obj
, Elf_Rela Rel
) {
5479 SmallString
<32> RelocName
;
5480 Obj
->getRelocationTypeName(Rel
.getType(Obj
->isMips64EL()), RelocName
);
5481 std::string SymbolName
=
5482 getSymbolForReloc(Obj
, this->FileName
, this->dumper(), Rel
).Name
;
5484 if (opts::ExpandRelocs
) {
5485 DictScope
Group(W
, "Relocation");
5486 W
.printHex("Offset", Rel
.r_offset
);
5487 W
.printNumber("Type", RelocName
, (int)Rel
.getType(Obj
->isMips64EL()));
5488 W
.printString("Symbol", !SymbolName
.empty() ? SymbolName
: "-");
5489 W
.printHex("Addend", Rel
.r_addend
);
5491 raw_ostream
&OS
= W
.startLine();
5492 OS
<< W
.hex(Rel
.r_offset
) << " " << RelocName
<< " "
5493 << (!SymbolName
.empty() ? SymbolName
: "-") << " " << W
.hex(Rel
.r_addend
)
5498 template <class ELFT
>
5499 void LLVMStyle
<ELFT
>::printProgramHeaders(
5500 const ELFO
*Obj
, bool PrintProgramHeaders
,
5501 cl::boolOrDefault PrintSectionMapping
) {
5502 if (PrintProgramHeaders
)
5503 printProgramHeaders(Obj
);
5504 if (PrintSectionMapping
== cl::BOU_TRUE
)
5505 printSectionMapping(Obj
);
5508 template <class ELFT
>
5509 void LLVMStyle
<ELFT
>::printProgramHeaders(const ELFO
*Obj
) {
5510 ListScope
L(W
, "ProgramHeaders");
5512 for (const Elf_Phdr
&Phdr
:
5513 unwrapOrError(this->FileName
, Obj
->program_headers())) {
5514 DictScope
P(W
, "ProgramHeader");
5516 getElfSegmentType(Obj
->getHeader()->e_machine
, Phdr
.p_type
),
5518 W
.printHex("Offset", Phdr
.p_offset
);
5519 W
.printHex("VirtualAddress", Phdr
.p_vaddr
);
5520 W
.printHex("PhysicalAddress", Phdr
.p_paddr
);
5521 W
.printNumber("FileSize", Phdr
.p_filesz
);
5522 W
.printNumber("MemSize", Phdr
.p_memsz
);
5523 W
.printFlags("Flags", Phdr
.p_flags
, makeArrayRef(ElfSegmentFlags
));
5524 W
.printNumber("Alignment", Phdr
.p_align
);
5528 template <class ELFT
>
5529 void LLVMStyle
<ELFT
>::printVersionSymbolSection(const ELFFile
<ELFT
> *Obj
,
5530 const Elf_Shdr
*Sec
) {
5531 DictScope
SS(W
, "Version symbols");
5535 StringRef SecName
= unwrapOrError(this->FileName
, Obj
->getSectionName(Sec
));
5536 W
.printNumber("Section Name", SecName
, Sec
->sh_name
);
5537 W
.printHex("Address", Sec
->sh_addr
);
5538 W
.printHex("Offset", Sec
->sh_offset
);
5539 W
.printNumber("Link", Sec
->sh_link
);
5541 const uint8_t *VersymBuf
=
5542 reinterpret_cast<const uint8_t *>(Obj
->base() + Sec
->sh_offset
);
5543 const ELFDumper
<ELFT
> *Dumper
= this->dumper();
5544 StringRef StrTable
= Dumper
->getDynamicStringTable();
5546 // Same number of entries in the dynamic symbol table (DT_SYMTAB).
5547 ListScope
Syms(W
, "Symbols");
5548 for (const Elf_Sym
&Sym
: Dumper
->dynamic_symbols()) {
5549 DictScope
S(W
, "Symbol");
5550 const Elf_Versym
*Versym
= reinterpret_cast<const Elf_Versym
*>(VersymBuf
);
5551 std::string FullSymbolName
=
5552 Dumper
->getFullSymbolName(&Sym
, StrTable
, true /* IsDynamic */);
5553 W
.printNumber("Version", Versym
->vs_index
& VERSYM_VERSION
);
5554 W
.printString("Name", FullSymbolName
);
5555 VersymBuf
+= sizeof(Elf_Versym
);
5559 template <class ELFT
>
5560 void LLVMStyle
<ELFT
>::printVersionDefinitionSection(const ELFFile
<ELFT
> *Obj
,
5561 const Elf_Shdr
*Sec
) {
5562 DictScope
SD(W
, "SHT_GNU_verdef");
5566 const uint8_t *SecStartAddress
=
5567 reinterpret_cast<const uint8_t *>(Obj
->base() + Sec
->sh_offset
);
5568 const uint8_t *SecEndAddress
= SecStartAddress
+ Sec
->sh_size
;
5569 const uint8_t *VerdefBuf
= SecStartAddress
;
5570 const Elf_Shdr
*StrTab
=
5571 unwrapOrError(this->FileName
, Obj
->getSection(Sec
->sh_link
));
5573 unsigned VerDefsNum
= Sec
->sh_info
;
5574 while (VerDefsNum
--) {
5575 if (VerdefBuf
+ sizeof(Elf_Verdef
) > SecEndAddress
)
5576 // FIXME: report_fatal_error is not a good way to report error. We should
5577 // emit a parsing error here and below.
5578 report_fatal_error("invalid offset in the section");
5580 const Elf_Verdef
*Verdef
= reinterpret_cast<const Elf_Verdef
*>(VerdefBuf
);
5581 DictScope
Def(W
, "Definition");
5582 W
.printNumber("Version", Verdef
->vd_version
);
5583 W
.printEnum("Flags", Verdef
->vd_flags
, makeArrayRef(SymVersionFlags
));
5584 W
.printNumber("Index", Verdef
->vd_ndx
);
5585 W
.printNumber("Hash", Verdef
->vd_hash
);
5586 W
.printString("Name", StringRef(reinterpret_cast<const char *>(
5587 Obj
->base() + StrTab
->sh_offset
+
5588 Verdef
->getAux()->vda_name
)));
5589 if (!Verdef
->vd_cnt
)
5590 report_fatal_error("at least one definition string must exist");
5591 if (Verdef
->vd_cnt
> 2)
5592 report_fatal_error("more than one predecessor is not expected");
5594 if (Verdef
->vd_cnt
== 2) {
5595 const uint8_t *VerdauxBuf
=
5596 VerdefBuf
+ Verdef
->vd_aux
+ Verdef
->getAux()->vda_next
;
5597 const Elf_Verdaux
*Verdaux
=
5598 reinterpret_cast<const Elf_Verdaux
*>(VerdauxBuf
);
5599 W
.printString("Predecessor",
5600 StringRef(reinterpret_cast<const char *>(
5601 Obj
->base() + StrTab
->sh_offset
+ Verdaux
->vda_name
)));
5603 VerdefBuf
+= Verdef
->vd_next
;
5607 template <class ELFT
>
5608 void LLVMStyle
<ELFT
>::printVersionDependencySection(const ELFFile
<ELFT
> *Obj
,
5609 const Elf_Shdr
*Sec
) {
5610 DictScope
SD(W
, "SHT_GNU_verneed");
5614 const uint8_t *SecData
=
5615 reinterpret_cast<const uint8_t *>(Obj
->base() + Sec
->sh_offset
);
5616 const Elf_Shdr
*StrTab
=
5617 unwrapOrError(this->FileName
, Obj
->getSection(Sec
->sh_link
));
5619 const uint8_t *VerneedBuf
= SecData
;
5620 unsigned VerneedNum
= Sec
->sh_info
;
5621 for (unsigned I
= 0; I
< VerneedNum
; ++I
) {
5622 const Elf_Verneed
*Verneed
=
5623 reinterpret_cast<const Elf_Verneed
*>(VerneedBuf
);
5624 DictScope
Entry(W
, "Dependency");
5625 W
.printNumber("Version", Verneed
->vn_version
);
5626 W
.printNumber("Count", Verneed
->vn_cnt
);
5627 W
.printString("FileName",
5628 StringRef(reinterpret_cast<const char *>(
5629 Obj
->base() + StrTab
->sh_offset
+ Verneed
->vn_file
)));
5631 const uint8_t *VernauxBuf
= VerneedBuf
+ Verneed
->vn_aux
;
5632 ListScope
L(W
, "Entries");
5633 for (unsigned J
= 0; J
< Verneed
->vn_cnt
; ++J
) {
5634 const Elf_Vernaux
*Vernaux
=
5635 reinterpret_cast<const Elf_Vernaux
*>(VernauxBuf
);
5636 DictScope
Entry(W
, "Entry");
5637 W
.printNumber("Hash", Vernaux
->vna_hash
);
5638 W
.printEnum("Flags", Vernaux
->vna_flags
, makeArrayRef(SymVersionFlags
));
5639 W
.printNumber("Index", Vernaux
->vna_other
);
5640 W
.printString("Name",
5641 StringRef(reinterpret_cast<const char *>(
5642 Obj
->base() + StrTab
->sh_offset
+ Vernaux
->vna_name
)));
5643 VernauxBuf
+= Vernaux
->vna_next
;
5645 VerneedBuf
+= Verneed
->vn_next
;
5649 template <class ELFT
>
5650 void LLVMStyle
<ELFT
>::printHashHistogram(const ELFFile
<ELFT
> *Obj
) {
5651 W
.startLine() << "Hash Histogram not implemented!\n";
5654 template <class ELFT
>
5655 void LLVMStyle
<ELFT
>::printCGProfile(const ELFFile
<ELFT
> *Obj
) {
5656 ListScope
L(W
, "CGProfile");
5657 if (!this->dumper()->getDotCGProfileSec())
5659 auto CGProfile
= unwrapOrError(
5660 this->FileName
, Obj
->template getSectionContentsAsArray
<Elf_CGProfile
>(
5661 this->dumper()->getDotCGProfileSec()));
5662 for (const Elf_CGProfile
&CGPE
: CGProfile
) {
5663 DictScope
D(W
, "CGProfileEntry");
5664 W
.printNumber("From", this->dumper()->getStaticSymbolName(CGPE
.cgp_from
),
5666 W
.printNumber("To", this->dumper()->getStaticSymbolName(CGPE
.cgp_to
),
5668 W
.printNumber("Weight", CGPE
.cgp_weight
);
5672 template <class ELFT
>
5673 void LLVMStyle
<ELFT
>::printAddrsig(const ELFFile
<ELFT
> *Obj
) {
5674 ListScope
L(W
, "Addrsig");
5675 if (!this->dumper()->getDotAddrsigSec())
5677 ArrayRef
<uint8_t> Contents
= unwrapOrError(
5679 Obj
->getSectionContents(this->dumper()->getDotAddrsigSec()));
5680 const uint8_t *Cur
= Contents
.begin();
5681 const uint8_t *End
= Contents
.end();
5682 while (Cur
!= End
) {
5685 uint64_t SymIndex
= decodeULEB128(Cur
, &Size
, End
, &Err
);
5687 reportError(createError(Err
), this->FileName
);
5689 W
.printNumber("Sym", this->dumper()->getStaticSymbolName(SymIndex
),
5695 template <typename ELFT
>
5696 static void printGNUNoteLLVMStyle(uint32_t NoteType
, ArrayRef
<uint8_t> Desc
,
5701 case ELF::NT_GNU_ABI_TAG
: {
5702 const GNUAbiTag
&AbiTag
= getGNUAbiTag
<ELFT
>(Desc
);
5703 if (!AbiTag
.IsValid
) {
5704 W
.printString("ABI", "<corrupt GNU_ABI_TAG>");
5706 W
.printString("OS", AbiTag
.OSName
);
5707 W
.printString("ABI", AbiTag
.ABI
);
5711 case ELF::NT_GNU_BUILD_ID
: {
5712 W
.printString("Build ID", getGNUBuildId(Desc
));
5715 case ELF::NT_GNU_GOLD_VERSION
:
5716 W
.printString("Version", getGNUGoldVersion(Desc
));
5718 case ELF::NT_GNU_PROPERTY_TYPE_0
:
5719 ListScope
D(W
, "Property");
5720 for (const auto &Property
: getGNUPropertyList
<ELFT
>(Desc
))
5721 W
.printString(Property
);
5726 static void printCoreNoteLLVMStyle(const CoreNote
&Note
, ScopedPrinter
&W
) {
5727 W
.printNumber("Page Size", Note
.PageSize
);
5728 for (const CoreFileMapping
&Mapping
: Note
.Mappings
) {
5729 ListScope
D(W
, "Mapping");
5730 W
.printHex("Start", Mapping
.Start
);
5731 W
.printHex("End", Mapping
.End
);
5732 W
.printHex("Offset", Mapping
.Offset
);
5733 W
.printString("Filename", Mapping
.Filename
);
5737 template <class ELFT
>
5738 void LLVMStyle
<ELFT
>::printNotes(const ELFFile
<ELFT
> *Obj
) {
5739 ListScope
L(W
, "Notes");
5741 auto PrintHeader
= [&](const typename
ELFT::Off Offset
,
5742 const typename
ELFT::Addr Size
) {
5743 W
.printHex("Offset", Offset
);
5744 W
.printHex("Size", Size
);
5747 auto ProcessNote
= [&](const Elf_Note
&Note
) {
5748 DictScope
D2(W
, "Note");
5749 StringRef Name
= Note
.getName();
5750 ArrayRef
<uint8_t> Descriptor
= Note
.getDesc();
5751 Elf_Word Type
= Note
.getType();
5753 // Print the note owner/type.
5754 W
.printString("Owner", Name
);
5755 W
.printHex("Data size", Descriptor
.size());
5756 if (Name
== "GNU") {
5757 W
.printString("Type", getGNUNoteTypeName(Type
));
5758 } else if (Name
== "FreeBSD") {
5759 W
.printString("Type", getFreeBSDNoteTypeName(Type
));
5760 } else if (Name
== "AMD") {
5761 W
.printString("Type", getAMDNoteTypeName(Type
));
5762 } else if (Name
== "AMDGPU") {
5763 W
.printString("Type", getAMDGPUNoteTypeName(Type
));
5765 StringRef NoteType
= Obj
->getHeader()->e_type
== ELF::ET_CORE
5766 ? getCoreNoteTypeName(Type
)
5767 : getGenericNoteTypeName(Type
);
5768 if (!NoteType
.empty())
5769 W
.printString("Type", NoteType
);
5771 W
.printString("Type",
5772 "Unknown (" + to_string(format_hex(Type
, 10)) + ")");
5775 // Print the description, or fallback to printing raw bytes for unknown
5777 if (Name
== "GNU") {
5778 printGNUNoteLLVMStyle
<ELFT
>(Type
, Descriptor
, W
);
5779 } else if (Name
== "AMD") {
5780 const AMDNote N
= getAMDNote
<ELFT
>(Type
, Descriptor
);
5781 if (!N
.Type
.empty())
5782 W
.printString(N
.Type
, N
.Value
);
5783 } else if (Name
== "AMDGPU") {
5784 const AMDGPUNote N
= getAMDGPUNote
<ELFT
>(Type
, Descriptor
);
5785 if (!N
.Type
.empty())
5786 W
.printString(N
.Type
, N
.Value
);
5787 } else if (Name
== "CORE") {
5788 if (Type
== ELF::NT_FILE
) {
5789 DataExtractor
DescExtractor(
5790 StringRef(reinterpret_cast<const char *>(Descriptor
.data()),
5792 ELFT::TargetEndianness
== support::little
, sizeof(Elf_Addr
));
5793 Expected
<CoreNote
> Note
= readCoreNote(DescExtractor
);
5795 printCoreNoteLLVMStyle(*Note
, W
);
5797 reportWarning(Note
.takeError(), this->FileName
);
5799 } else if (!Descriptor
.empty()) {
5800 W
.printBinaryBlock("Description data", Descriptor
);
5804 ArrayRef
<Elf_Shdr
> Sections
= unwrapOrError(this->FileName
, Obj
->sections());
5805 if (Obj
->getHeader()->e_type
!= ELF::ET_CORE
&& !Sections
.empty()) {
5806 for (const auto &S
: Sections
) {
5807 if (S
.sh_type
!= SHT_NOTE
)
5809 DictScope
D(W
, "NoteSection");
5810 PrintHeader(S
.sh_offset
, S
.sh_size
);
5811 Error Err
= Error::success();
5812 for (const auto &Note
: Obj
->notes(S
, Err
))
5815 reportError(std::move(Err
), this->FileName
);
5818 for (const auto &P
:
5819 unwrapOrError(this->FileName
, Obj
->program_headers())) {
5820 if (P
.p_type
!= PT_NOTE
)
5822 DictScope
D(W
, "NoteSection");
5823 PrintHeader(P
.p_offset
, P
.p_filesz
);
5824 Error Err
= Error::success();
5825 for (const auto &Note
: Obj
->notes(P
, Err
))
5828 reportError(std::move(Err
), this->FileName
);
5833 template <class ELFT
>
5834 void LLVMStyle
<ELFT
>::printELFLinkerOptions(const ELFFile
<ELFT
> *Obj
) {
5835 ListScope
L(W
, "LinkerOptions");
5837 for (const Elf_Shdr
&Shdr
: unwrapOrError(this->FileName
, Obj
->sections())) {
5838 if (Shdr
.sh_type
!= ELF::SHT_LLVM_LINKER_OPTIONS
)
5841 ArrayRef
<uint8_t> Contents
=
5842 unwrapOrError(this->FileName
, Obj
->getSectionContents(&Shdr
));
5843 for (const uint8_t *P
= Contents
.begin(), *E
= Contents
.end(); P
< E
; ) {
5844 StringRef Key
= StringRef(reinterpret_cast<const char *>(P
));
5846 StringRef(reinterpret_cast<const char *>(P
) + Key
.size() + 1);
5848 W
.printString(Key
, Value
);
5850 P
= P
+ Key
.size() + Value
.size() + 2;
5855 template <class ELFT
>
5856 void LLVMStyle
<ELFT
>::printStackSizes(const ELFObjectFile
<ELFT
> *Obj
) {
5858 "Dumping of stack sizes in LLVM style is not implemented yet\n");
5861 template <class ELFT
>
5862 void LLVMStyle
<ELFT
>::printStackSizeEntry(uint64_t Size
, StringRef FuncName
) {
5863 // FIXME: Implement this function for LLVM-style dumping.
5866 template <class ELFT
>
5867 void LLVMStyle
<ELFT
>::printMipsGOT(const MipsGOTParser
<ELFT
> &Parser
) {
5868 auto PrintEntry
= [&](const Elf_Addr
*E
) {
5869 W
.printHex("Address", Parser
.getGotAddress(E
));
5870 W
.printNumber("Access", Parser
.getGotOffset(E
));
5871 W
.printHex("Initial", *E
);
5874 DictScope
GS(W
, Parser
.IsStatic
? "Static GOT" : "Primary GOT");
5876 W
.printHex("Canonical gp value", Parser
.getGp());
5878 ListScope
RS(W
, "Reserved entries");
5880 DictScope
D(W
, "Entry");
5881 PrintEntry(Parser
.getGotLazyResolver());
5882 W
.printString("Purpose", StringRef("Lazy resolver"));
5885 if (Parser
.getGotModulePointer()) {
5886 DictScope
D(W
, "Entry");
5887 PrintEntry(Parser
.getGotModulePointer());
5888 W
.printString("Purpose", StringRef("Module pointer (GNU extension)"));
5892 ListScope
LS(W
, "Local entries");
5893 for (auto &E
: Parser
.getLocalEntries()) {
5894 DictScope
D(W
, "Entry");
5899 if (Parser
.IsStatic
)
5903 ListScope
GS(W
, "Global entries");
5904 for (auto &E
: Parser
.getGlobalEntries()) {
5905 DictScope
D(W
, "Entry");
5909 const Elf_Sym
*Sym
= Parser
.getGotSym(&E
);
5910 W
.printHex("Value", Sym
->st_value
);
5911 W
.printEnum("Type", Sym
->getType(), makeArrayRef(ElfSymbolTypes
));
5913 unsigned SectionIndex
= 0;
5914 StringRef SectionName
;
5915 this->dumper()->getSectionNameIndex(
5916 Sym
, this->dumper()->dynamic_symbols().begin(), SectionName
,
5918 W
.printHex("Section", SectionName
, SectionIndex
);
5920 std::string SymName
= this->dumper()->getFullSymbolName(
5921 Sym
, this->dumper()->getDynamicStringTable(), true);
5922 W
.printNumber("Name", SymName
, Sym
->st_name
);
5926 W
.printNumber("Number of TLS and multi-GOT entries",
5927 uint64_t(Parser
.getOtherEntries().size()));
5930 template <class ELFT
>
5931 void LLVMStyle
<ELFT
>::printMipsPLT(const MipsGOTParser
<ELFT
> &Parser
) {
5932 auto PrintEntry
= [&](const Elf_Addr
*E
) {
5933 W
.printHex("Address", Parser
.getPltAddress(E
));
5934 W
.printHex("Initial", *E
);
5937 DictScope
GS(W
, "PLT GOT");
5940 ListScope
RS(W
, "Reserved entries");
5942 DictScope
D(W
, "Entry");
5943 PrintEntry(Parser
.getPltLazyResolver());
5944 W
.printString("Purpose", StringRef("PLT lazy resolver"));
5947 if (auto E
= Parser
.getPltModulePointer()) {
5948 DictScope
D(W
, "Entry");
5950 W
.printString("Purpose", StringRef("Module pointer"));
5954 ListScope
LS(W
, "Entries");
5955 for (auto &E
: Parser
.getPltEntries()) {
5956 DictScope
D(W
, "Entry");
5959 const Elf_Sym
*Sym
= Parser
.getPltSym(&E
);
5960 W
.printHex("Value", Sym
->st_value
);
5961 W
.printEnum("Type", Sym
->getType(), makeArrayRef(ElfSymbolTypes
));
5963 unsigned SectionIndex
= 0;
5964 StringRef SectionName
;
5965 this->dumper()->getSectionNameIndex(
5966 Sym
, this->dumper()->dynamic_symbols().begin(), SectionName
,
5968 W
.printHex("Section", SectionName
, SectionIndex
);
5970 std::string SymName
=
5971 this->dumper()->getFullSymbolName(Sym
, Parser
.getPltStrTable(), true);
5972 W
.printNumber("Name", SymName
, Sym
->st_name
);