annotate tools/llvm-readobj/DwarfCFIEHPrinter.h @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 //===--- DwarfCFIEHPrinter.h - DWARF-based Unwind Information Printer -----===//
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 #ifndef LLVM_TOOLS_LLVM_READOBJ_DWARFCFIEHPRINTER_H
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 #define LLVM_TOOLS_LLVM_READOBJ_DWARFCFIEHPRINTER_H
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 #include "Error.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 #include "llvm-readobj.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 #include "llvm/ADT/STLExtras.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 #include "llvm/BinaryFormat/Dwarf.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 #include "llvm/Object/ELF.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 #include "llvm/Object/ELFTypes.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 #include "llvm/Object/ELFObjectFile.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 #include "llvm/Support/Casting.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 #include "llvm/Support/ScopedPrinter.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "llvm/Support/Debug.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 #include "llvm/Support/Endian.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "llvm/Support/Format.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 #include "llvm/Support/type_traits.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 namespace llvm {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 namespace DwarfCFIEH {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 template <typename ELFT>
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 class PrinterContext {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 ScopedPrinter &W;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 const object::ELFObjectFile<ELFT> *ObjF;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 void printEHFrameHdr(uint64_t Offset, uint64_t Address, uint64_t Size) const;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 void printEHFrame(const typename ELFT::Shdr *EHFrameShdr) const;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 public:
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 PrinterContext(ScopedPrinter &W, const object::ELFObjectFile<ELFT> *ObjF)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 : W(W), ObjF(ObjF) {}
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 void printUnwindInformation() const;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 };
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 template <class ELFO>
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 static const typename ELFO::Elf_Shdr *findSectionByAddress(const ELFO *Obj,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 uint64_t Addr) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 auto Sections = Obj->sections();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 if (Error E = Sections.takeError())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 reportError(toString(std::move(E)));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 for (const auto &Shdr : *Sections)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 if (Shdr.sh_addr == Addr)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 return &Shdr;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 return nullptr;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 template <typename ELFT>
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 void PrinterContext<ELFT>::printUnwindInformation() const {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 const typename ELFT::Phdr *EHFramePhdr = nullptr;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 auto PHs = Obj->program_headers();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 if (Error E = PHs.takeError())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 reportError(toString(std::move(E)));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 for (const auto &Phdr : *PHs) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 if (Phdr.p_type == ELF::PT_GNU_EH_FRAME) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 EHFramePhdr = &Phdr;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 if (Phdr.p_memsz != Phdr.p_filesz)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 reportError("p_memsz does not match p_filesz for GNU_EH_FRAME");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 break;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 if (EHFramePhdr)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 printEHFrameHdr(EHFramePhdr->p_offset, EHFramePhdr->p_vaddr,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 EHFramePhdr->p_memsz);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 auto Sections = Obj->sections();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 if (Error E = Sections.takeError())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 reportError(toString(std::move(E)));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 for (const auto &Shdr : *Sections) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 auto SectionName = Obj->getSectionName(&Shdr);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 if (Error E = SectionName.takeError())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 reportError(toString(std::move(E)));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 if (*SectionName == ".eh_frame")
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 printEHFrame(&Shdr);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 template <typename ELFT>
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 void PrinterContext<ELFT>::printEHFrameHdr(uint64_t EHFrameHdrOffset,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 uint64_t EHFrameHdrAddress,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 uint64_t EHFrameHdrSize) const {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 ListScope L(W, "EH_FRAME Header");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 W.startLine() << format("Address: 0x%" PRIx64 "\n", EHFrameHdrAddress);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 W.startLine() << format("Offset: 0x%" PRIx64 "\n", EHFrameHdrOffset);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 W.startLine() << format("Size: 0x%" PRIx64 "\n", EHFrameHdrSize);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 const auto *EHFrameHdrShdr = findSectionByAddress(Obj, EHFrameHdrAddress);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 if (EHFrameHdrShdr) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 auto SectionName = Obj->getSectionName(EHFrameHdrShdr);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 if (Error E = SectionName.takeError())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 reportError(toString(std::move(E)));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 W.printString("Corresponding Section", *SectionName);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 DataExtractor DE(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 StringRef(reinterpret_cast<const char *>(Obj->base()) + EHFrameHdrOffset,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 EHFrameHdrSize),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 ELFT::TargetEndianness == support::endianness::little,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 ELFT::Is64Bits ? 8 : 4);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 DictScope D(W, "Header");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 uint64_t Offset = 0;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 auto Version = DE.getU8(&Offset);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 W.printNumber("version", Version);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 if (Version != 1)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 reportError("only version 1 of .eh_frame_hdr is supported");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 uint64_t EHFramePtrEnc = DE.getU8(&Offset);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 W.startLine() << format("eh_frame_ptr_enc: 0x%" PRIx64 "\n", EHFramePtrEnc);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 if (EHFramePtrEnc != (dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 reportError("unexpected encoding eh_frame_ptr_enc");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 uint64_t FDECountEnc = DE.getU8(&Offset);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 W.startLine() << format("fde_count_enc: 0x%" PRIx64 "\n", FDECountEnc);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 if (FDECountEnc != dwarf::DW_EH_PE_udata4)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 reportError("unexpected encoding fde_count_enc");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 uint64_t TableEnc = DE.getU8(&Offset);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 W.startLine() << format("table_enc: 0x%" PRIx64 "\n", TableEnc);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 if (TableEnc != (dwarf::DW_EH_PE_datarel | dwarf::DW_EH_PE_sdata4))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 reportError("unexpected encoding table_enc");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
143
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 auto EHFramePtr = DE.getSigned(&Offset, 4) + EHFrameHdrAddress + 4;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 W.startLine() << format("eh_frame_ptr: 0x%" PRIx64 "\n", EHFramePtr);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 auto FDECount = DE.getUnsigned(&Offset, 4);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 W.printNumber("fde_count", FDECount);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 unsigned NumEntries = 0;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 uint64_t PrevPC = 0;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 while (Offset + 8 <= EHFrameHdrSize && NumEntries < FDECount) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 DictScope D(W, std::string("entry ") + std::to_string(NumEntries));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 auto InitialPC = DE.getSigned(&Offset, 4) + EHFrameHdrAddress;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 W.startLine() << format("initial_location: 0x%" PRIx64 "\n", InitialPC);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 auto Address = DE.getSigned(&Offset, 4) + EHFrameHdrAddress;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 W.startLine() << format("address: 0x%" PRIx64 "\n", Address);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 if (InitialPC < PrevPC)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 reportError("initial_location is out of order");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 PrevPC = InitialPC;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 ++NumEntries;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
167
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 template <typename ELFT>
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 void PrinterContext<ELFT>::printEHFrame(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 const typename ELFT::Shdr *EHFrameShdr) const {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 uint64_t Address = EHFrameShdr->sh_addr;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 uint64_t ShOffset = EHFrameShdr->sh_offset;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 W.startLine() << format(".eh_frame section at offset 0x%" PRIx64
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 " address 0x%" PRIx64 ":\n",
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 ShOffset, Address);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 W.indent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 auto Result = Obj->getSectionContents(EHFrameShdr);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 if (Error E = Result.takeError())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 reportError(toString(std::move(E)));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
182
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 auto Contents = Result.get();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 DWARFDataExtractor DE(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 StringRef(reinterpret_cast<const char *>(Contents.data()),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 Contents.size()),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 ELFT::TargetEndianness == support::endianness::little,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 ELFT::Is64Bits ? 8 : 4);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 DWARFDebugFrame EHFrame(Triple::ArchType(ObjF->getArch()), /*IsEH=*/true,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 /*EHFrameAddress=*/Address);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 EHFrame.parse(DE);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
192
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 for (const auto &Entry : EHFrame) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 if (const auto *CIE = dyn_cast<dwarf::CIE>(&Entry)) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 W.startLine() << format("[0x%" PRIx64 "] CIE length=%" PRIu64 "\n",
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 Address + CIE->getOffset(),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 CIE->getLength());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 W.indent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
199
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 W.printNumber("version", CIE->getVersion());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 W.printString("augmentation", CIE->getAugmentationString());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 W.printNumber("code_alignment_factor", CIE->getCodeAlignmentFactor());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 W.printNumber("data_alignment_factor", CIE->getDataAlignmentFactor());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 W.printNumber("return_address_register", CIE->getReturnAddressRegister());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
205
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 W.getOStream() << "\n";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 W.startLine() << "Program:\n";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 W.indent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 CIE->cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 W.unindent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
211
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 W.unindent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 W.getOStream() << "\n";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
214
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 } else if (const auto *FDE = dyn_cast<dwarf::FDE>(&Entry)) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 W.startLine() << format("[0x%" PRIx64 "] FDE length=%" PRIu64
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 " cie=[0x%" PRIx64 "]\n",
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 Address + FDE->getOffset(),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 FDE->getLength(),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 Address + FDE->getLinkedCIE()->getOffset());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 W.indent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
222
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 W.startLine() << format("initial_location: 0x%" PRIx64 "\n",
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 FDE->getInitialLocation());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 W.startLine()
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
226 << format("address_range: 0x%" PRIx64 " (end : 0x%" PRIx64 ")\n",
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 FDE->getAddressRange(),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 FDE->getInitialLocation() + FDE->getAddressRange());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
229
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 W.getOStream() << "\n";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 W.startLine() << "Program:\n";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 W.indent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 FDE->cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 W.unindent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
235
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 W.unindent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 W.getOStream() << "\n";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 } else {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 llvm_unreachable("unexpected DWARF frame kind");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
242
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 W.unindent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
245
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
248
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 #endif