llvm.org GIT mirror llvm / 2448e9f
Move llvm-readobj/StreamWriter to Support. We wish to re-use this from llvm-pdbdump, and it provides a nice way to print structured data in scoped format that could prove useful for many other dumping tools as well. Moving to support and changing name to ScopedPrinter to better reflect its purpose. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268342 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 4 years ago
17 changed file(s) with 465 addition(s) and 485 deletion(s). Raw diff Collapse all Expand all
0 //===-- ScopedPrinter.h ---------------------------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_SCOPEDPRINTER_H
10 #define LLVM_SUPPORT_SCOPEDPRINTER_H
11
12 #include "llvm/ADT/APSInt.h"
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Support/DataTypes.h"
17 #include "llvm/Support/Endian.h"
18 #include "llvm/Support/raw_ostream.h"
19 #include
20
21 using namespace llvm;
22
23 namespace llvm {
24
25 template struct EnumEntry {
26 StringRef Name;
27 // While Name suffices in most of the cases, in certain cases
28 // GNU style and LLVM style of ELFDumper do not
29 // display same string for same enum. The AltName if initialized appropriately
30 // will hold the string that GNU style emits.
31 // Example:
32 // "EM_X86_64" string on LLVM style for Elf_Ehdr->e_machine corresponds to
33 // "Advanced Micro Devices X86-64" on GNU style
34 StringRef AltName;
35 T Value;
36 EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {}
37 EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {}
38 };
39
40 struct HexNumber {
41 // To avoid sign-extension we have to explicitly cast to the appropriate
42 // unsigned type. The overloads are here so that every type that is implicitly
43 // convertible to an integer (including enums and endian helpers) can be used
44 // without requiring type traits or call-site changes.
45 HexNumber(char Value) : Value(static_cast(Value)) {}
46 HexNumber(signed char Value) : Value(static_cast(Value)) {}
47 HexNumber(signed short Value) : Value(static_cast(Value)) {}
48 HexNumber(signed int Value) : Value(static_cast(Value)) {}
49 HexNumber(signed long Value) : Value(static_cast(Value)) {}
50 HexNumber(signed long long Value)
51 : Value(static_cast(Value)) {}
52 HexNumber(unsigned char Value) : Value(Value) {}
53 HexNumber(unsigned short Value) : Value(Value) {}
54 HexNumber(unsigned int Value) : Value(Value) {}
55 HexNumber(unsigned long Value) : Value(Value) {}
56 HexNumber(unsigned long long Value) : Value(Value) {}
57 uint64_t Value;
58 };
59
60 raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value);
61 const std::string to_hexString(uint64_t Value, bool UpperCase = true);
62
63 template const std::string to_string(const T &Value) {
64 std::string number;
65 llvm::raw_string_ostream stream(number);
66 stream << Value;
67 return stream.str();
68 }
69
70 class ScopedPrinter {
71 public:
72 ScopedPrinter(raw_ostream &OS) : OS(OS), IndentLevel(0) {}
73
74 void flush() { OS.flush(); }
75
76 void indent(int Levels = 1) { IndentLevel += Levels; }
77
78 void unindent(int Levels = 1) {
79 IndentLevel = std::max(0, IndentLevel - Levels);
80 }
81
82 void printIndent() {
83 for (int i = 0; i < IndentLevel; ++i)
84 OS << " ";
85 }
86
87 template HexNumber hex(T Value) { return HexNumber(Value); }
88
89 template
90 void printEnum(StringRef Label, T Value,
91 ArrayRef> EnumValues) {
92 StringRef Name;
93 bool Found = false;
94 for (const auto &EnumItem : EnumValues) {
95 if (EnumItem.Value == Value) {
96 Name = EnumItem.Name;
97 Found = true;
98 break;
99 }
100 }
101
102 if (Found) {
103 startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
104 } else {
105 startLine() << Label << ": " << hex(Value) << "\n";
106 }
107 }
108
109 template
110 void printFlags(StringRef Label, T Value, ArrayRef> Flags,
111 TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
112 TFlag EnumMask3 = {}) {
113 typedef EnumEntry FlagEntry;
114 typedef SmallVector FlagVector;
115 FlagVector SetFlags;
116
117 for (const auto &Flag : Flags) {
118 if (Flag.Value == 0)
119 continue;
120
121 TFlag EnumMask{};
122 if (Flag.Value & EnumMask1)
123 EnumMask = EnumMask1;
124 else if (Flag.Value & EnumMask2)
125 EnumMask = EnumMask2;
126 else if (Flag.Value & EnumMask3)
127 EnumMask = EnumMask3;
128 bool IsEnum = (Flag.Value & EnumMask) != 0;
129 if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
130 (IsEnum && (Value & EnumMask) == Flag.Value)) {
131 SetFlags.push_back(Flag);
132 }
133 }
134
135 std::sort(SetFlags.begin(), SetFlags.end(), &flagName);
136
137 startLine() << Label << " [ (" << hex(Value) << ")\n";
138 for (const auto &Flag : SetFlags) {
139 startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
140 }
141 startLine() << "]\n";
142 }
143
144 template void printFlags(StringRef Label, T Value) {
145 startLine() << Label << " [ (" << hex(Value) << ")\n";
146 uint64_t Flag = 1;
147 uint64_t Curr = Value;
148 while (Curr > 0) {
149 if (Curr & 1)
150 startLine() << " " << hex(Flag) << "\n";
151 Curr >>= 1;
152 Flag <<= 1;
153 }
154 startLine() << "]\n";
155 }
156
157 void printNumber(StringRef Label, uint64_t Value) {
158 startLine() << Label << ": " << Value << "\n";
159 }
160
161 void printNumber(StringRef Label, uint32_t Value) {
162 startLine() << Label << ": " << Value << "\n";
163 }
164
165 void printNumber(StringRef Label, uint16_t Value) {
166 startLine() << Label << ": " << Value << "\n";
167 }
168
169 void printNumber(StringRef Label, uint8_t Value) {
170 startLine() << Label << ": " << unsigned(Value) << "\n";
171 }
172
173 void printNumber(StringRef Label, int64_t Value) {
174 startLine() << Label << ": " << Value << "\n";
175 }
176
177 void printNumber(StringRef Label, int32_t Value) {
178 startLine() << Label << ": " << Value << "\n";
179 }
180
181 void printNumber(StringRef Label, int16_t Value) {
182 startLine() << Label << ": " << Value << "\n";
183 }
184
185 void printNumber(StringRef Label, int8_t Value) {
186 startLine() << Label << ": " << int(Value) << "\n";
187 }
188
189 void printNumber(StringRef Label, APSInt Value) {
190 startLine() << Label << ": " << Value << "\n";
191 }
192
193 void printBoolean(StringRef Label, bool Value) {
194 startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
195 }
196
197 template void printList(StringRef Label, const T &List) {
198 startLine() << Label << ": [";
199 bool Comma = false;
200 for (const auto &Item : List) {
201 if (Comma)
202 OS << ", ";
203 OS << Item;
204 Comma = true;
205 }
206 OS << "]\n";
207 }
208
209 template void printHexList(StringRef Label, const T &List) {
210 startLine() << Label << ": [";
211 bool Comma = false;
212 for (const auto &Item : List) {
213 if (Comma)
214 OS << ", ";
215 OS << hex(Item);
216 Comma = true;
217 }
218 OS << "]\n";
219 }
220
221 template void printHex(StringRef Label, T Value) {
222 startLine() << Label << ": " << hex(Value) << "\n";
223 }
224
225 template void printHex(StringRef Label, StringRef Str, T Value) {
226 startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
227 }
228
229 template
230 void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
231 startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
232 }
233
234 void printString(StringRef Label, StringRef Value) {
235 startLine() << Label << ": " << Value << "\n";
236 }
237
238 void printString(StringRef Label, const std::string &Value) {
239 startLine() << Label << ": " << Value << "\n";
240 }
241
242 template
243 void printNumber(StringRef Label, StringRef Str, T Value) {
244 startLine() << Label << ": " << Str << " (" << Value << ")\n";
245 }
246
247 void printBinary(StringRef Label, StringRef Str, ArrayRef Value) {
248 printBinaryImpl(Label, Str, Value, false);
249 }
250
251 void printBinary(StringRef Label, StringRef Str, ArrayRef Value) {
252 auto V = makeArrayRef(reinterpret_cast(Value.data()),
253 Value.size());
254 printBinaryImpl(Label, Str, V, false);
255 }
256
257 void printBinary(StringRef Label, ArrayRef Value) {
258 printBinaryImpl(Label, StringRef(), Value, false);
259 }
260
261 void printBinary(StringRef Label, ArrayRef Value) {
262 auto V = makeArrayRef(reinterpret_cast(Value.data()),
263 Value.size());
264 printBinaryImpl(Label, StringRef(), V, false);
265 }
266
267 void printBinary(StringRef Label, StringRef Value) {
268 auto V = makeArrayRef(reinterpret_cast(Value.data()),
269 Value.size());
270 printBinaryImpl(Label, StringRef(), V, false);
271 }
272
273 void printBinaryBlock(StringRef Label, StringRef Value) {
274 auto V = makeArrayRef(reinterpret_cast(Value.data()),
275 Value.size());
276 printBinaryImpl(Label, StringRef(), V, true);
277 }
278
279 raw_ostream &startLine() {
280 printIndent();
281 return OS;
282 }
283
284 raw_ostream &getOStream() { return OS; }
285
286 private:
287 template
288 static bool flagName(const EnumEntry &lhs, const EnumEntry &rhs) {
289 return lhs.Name < rhs.Name;
290 }
291
292 void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef Value,
293 bool Block);
294
295 raw_ostream &OS;
296 int IndentLevel;
297 };
298
299 template <>
300 inline void
301 ScopedPrinter::printHex(StringRef Label,
302 support::ulittle16_t Value) {
303 startLine() << Label << ": " << hex(Value) << "\n";
304 }
305
306 struct DictScope {
307 DictScope(ScopedPrinter &W, StringRef N) : W(W) {
308 W.startLine() << N << " {\n";
309 W.indent();
310 }
311
312 ~DictScope() {
313 W.unindent();
314 W.startLine() << "}\n";
315 }
316
317 ScopedPrinter &W;
318 };
319
320 struct ListScope {
321 ListScope(ScopedPrinter &W, StringRef N) : W(W) {
322 W.startLine() << N << " [\n";
323 W.indent();
324 }
325
326 ~ListScope() {
327 W.unindent();
328 W.startLine() << "]\n";
329 }
330
331 ScopedPrinter &W;
332 };
333
334 } // namespace llvm
335
336 #endif
7575 RandomNumberGenerator.cpp
7676 Regex.cpp
7777 ScaledNumber.cpp
78 ScopedPrinter.cpp
7879 SHA1.cpp
7980 SmallPtrSet.cpp
8081 SmallVector.cpp
0 #include "llvm/Support/ScopedPrinter.h"
1
2 #include "llvm/ADT/StringExtras.h"
3 #include "llvm/Support/Format.h"
4 #include
5
6 using namespace llvm::support;
7
8 namespace llvm {
9
10 raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value) {
11 OS << "0x" << to_hexString(Value.Value);
12 return OS;
13 }
14
15 const std::string to_hexString(uint64_t Value, bool UpperCase) {
16 std::string number;
17 llvm::raw_string_ostream stream(number);
18 stream << format_hex_no_prefix(Value, 1, UpperCase);
19 return stream.str();
20 }
21
22 void ScopedPrinter::printBinaryImpl(StringRef Label, StringRef Str,
23 ArrayRef Data, bool Block) {
24 if (Data.size() > 16)
25 Block = true;
26
27 if (Block) {
28 startLine() << Label;
29 if (Str.size() > 0)
30 OS << ": " << Str;
31 OS << " (\n";
32 for (size_t addr = 0, end = Data.size(); addr < end; addr += 16) {
33 startLine() << format(" %04" PRIX64 ": ", uint64_t(addr));
34 // Dump line of hex.
35 for (size_t i = 0; i < 16; ++i) {
36 if (i != 0 && i % 4 == 0)
37 OS << ' ';
38 if (addr + i < end)
39 OS << hexdigit((Data[addr + i] >> 4) & 0xF, false)
40 << hexdigit(Data[addr + i] & 0xF, false);
41 else
42 OS << " ";
43 }
44 // Print ascii.
45 OS << " |";
46 for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
47 if (std::isprint(Data[addr + i] & 0xFF))
48 OS << Data[addr + i];
49 else
50 OS << ".";
51 }
52 OS << "|\n";
53 }
54
55 startLine() << ")\n";
56 } else {
57 startLine() << Label << ":";
58 if (Str.size() > 0)
59 OS << " " << Str;
60 OS << " (";
61 for (size_t i = 0; i < Data.size(); ++i) {
62 if (i > 0)
63 OS << " ";
64
65 OS << format("%02X", static_cast(Data[i]));
66 }
67 OS << ")\n";
68 }
69 }
70
71 } // namespace llvm
77 //===----------------------------------------------------------------------===//
88
99 #include "ARMAttributeParser.h"
10 #include "StreamWriter.h"
1110 #include "llvm/ADT/STLExtras.h"
1211 #include "llvm/ADT/StringExtras.h"
1312 #include "llvm/Support/LEB128.h"
13 #include "llvm/Support/ScopedPrinter.h"
1414
1515 using namespace llvm;
1616 using namespace llvm::ARMBuildAttrs;
99 #ifndef LLVM_TOOLS_LLVM_READOBJ_ARMATTRIBUTEPARSER_H
1010 #define LLVM_TOOLS_LLVM_READOBJ_ARMATTRIBUTEPARSER_H
1111
12 #include "StreamWriter.h"
1312 #include "llvm/Support/ARMBuildAttributes.h"
13 #include "llvm/Support/ScopedPrinter.h"
1414
1515 namespace llvm {
1616 class StringRef;
1717
1818 class ARMAttributeParser {
19 StreamWriter &SW;
19 ScopedPrinter &SW;
2020
2121 struct DisplayHandler {
2222 ARMBuildAttrs::AttrType Attribute;
114114 SmallVectorImpl &IndexList);
115115 void ParseSubsection(const uint8_t *Data, uint32_t Length);
116116 public:
117 ARMAttributeParser(StreamWriter &SW) : SW(SW) {}
117 ARMAttributeParser(ScopedPrinter &SW) : SW(SW) {}
118118
119119 void Parse(ArrayRef Section);
120120 };
1010 #define LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
1111
1212 #include "Error.h"
13 #include "StreamWriter.h"
1413 #include "llvm-readobj.h"
1514 #include "llvm/ADT/STLExtras.h"
1615 #include "llvm/Object/ELF.h"
1918 #include "llvm/Support/Debug.h"
2019 #include "llvm/Support/Endian.h"
2120 #include "llvm/Support/Format.h"
21 #include "llvm/Support/ScopedPrinter.h"
2222 #include "llvm/Support/type_traits.h"
2323
2424 namespace llvm {
2626 namespace EHABI {
2727
2828 class OpcodeDecoder {
29 StreamWriter &SW;
29 ScopedPrinter &SW;
3030 raw_ostream &OS;
3131
3232 struct RingEntry {
6363 void PrintRegisters(uint32_t Mask, StringRef Prefix);
6464
6565 public:
66 OpcodeDecoder(StreamWriter &SW) : SW(SW), OS(SW.getOStream()) {}
66 OpcodeDecoder(ScopedPrinter &SW) : SW(SW), OS(SW.getOStream()) {}
6767 void Decode(const uint8_t *Opcodes, off_t Offset, size_t Length);
6868 };
6969
310310 typedef typename object::ELFFile::Elf_Rel Elf_Rel;
311311 typedef typename object::ELFFile::Elf_Word Elf_Word;
312312
313 StreamWriter &SW;
313 ScopedPrinter &SW;
314314 const object::ELFFile *ELF;
315315 const Elf_Shdr *Symtab;
316316 ArrayRef ShndxTable;
334334 void PrintOpcodes(const uint8_t *Entry, size_t Length, off_t Offset) const;
335335
336336 public:
337 PrinterContext(StreamWriter &SW, const object::ELFFile *ELF,
337 PrinterContext(ScopedPrinter &SW, const object::ELFFile *ELF,
338338 const Elf_Shdr *Symtab)
339339 : SW(SW), ELF(ELF), Symtab(Symtab) {}
340340
99 #ifndef LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
1010 #define LLVM_TOOLS_LLVM_READOBJ_ARMWINEHPRINTER_H
1111
12 #include "StreamWriter.h"
1312 #include "llvm/Object/COFF.h"
1413 #include "llvm/Support/ErrorOr.h"
14 #include "llvm/Support/ScopedPrinter.h"
1515
1616 namespace llvm {
1717 namespace ARM {
2121 class Decoder {
2222 static const size_t PDataEntrySize;
2323
24 StreamWriter &SW;
24 ScopedPrinter &SW;
2525 raw_ostream &OS;
2626
2727 struct RingEntry {
106106 const object::SectionRef Section);
107107
108108 public:
109 Decoder(StreamWriter &SW) : SW(SW), OS(SW.getOStream()) {}
109 Decoder(ScopedPrinter &SW) : SW(SW), OS(SW.getOStream()) {}
110110 std::error_code dumpProcedureData(const object::COFFObjectFile &COFF);
111111 };
112112 }
1212 llvm-readobj.cpp
1313 MachODumper.cpp
1414 ObjDumper.cpp
15 StreamWriter.cpp
1615 Win64EHDumper.cpp
1716 )
1111 ///
1212 //===----------------------------------------------------------------------===//
1313
14 #include "llvm-readobj.h"
1514 #include "ARMWinEHPrinter.h"
1615 #include "CodeView.h"
1716 #include "Error.h"
1817 #include "ObjDumper.h"
1918 #include "StackMapPrinter.h"
20 #include "StreamWriter.h"
2119 #include "Win64EHDumper.h"
20 #include "llvm-readobj.h"
2221 #include "llvm/ADT/DenseMap.h"
2322 #include "llvm/ADT/SmallString.h"
2423 #include "llvm/ADT/StringExtras.h"
2524 #include "llvm/ADT/StringSet.h"
2625 #include "llvm/DebugInfo/CodeView/CodeView.h"
2726 #include "llvm/DebugInfo/CodeView/Line.h"
27 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
2828 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
2929 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
30 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
3130 #include "llvm/Object/COFF.h"
3231 #include "llvm/Object/ObjectFile.h"
3332 #include "llvm/Support/COFF.h"
3534 #include "llvm/Support/Compiler.h"
3635 #include "llvm/Support/DataExtractor.h"
3736 #include "llvm/Support/Format.h"
37 #include "llvm/Support/ScopedPrinter.h"
3838 #include "llvm/Support/SourceMgr.h"
3939 #include "llvm/Support/Win64EH.h"
4040 #include "llvm/Support/raw_ostream.h"
5353
5454 class CVTypeDumper {
5555 public:
56 CVTypeDumper(StreamWriter &W) : W(W) {}
56 CVTypeDumper(ScopedPrinter &W) : W(W) {}
5757
5858 StringRef getTypeName(TypeIndex TI);
5959 void printTypeIndex(StringRef FieldName, TypeIndex TI);
6464 void printCodeViewFieldList(StringRef FieldData);
6565 void printMemberAttributes(MemberAttributes Attrs);
6666
67 StreamWriter &W;
67 ScopedPrinter &W;
6868
6969 /// All user defined type records in .debug$T live in here. Type indices
7070 /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
7676
7777 class COFFDumper : public ObjDumper {
7878 public:
79 COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter &Writer)
79 COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer)
8080 : ObjDumper(Writer), Obj(Obj), CVTD(Writer) {}
8181
8282 void printFileHeaders() override;
165165 namespace llvm {
166166
167167 std::error_code createCOFFDumper(const object::ObjectFile *Obj,
168 StreamWriter &Writer,
168 ScopedPrinter &Writer,
169169 std::unique_ptr &Result) {
170170 const COFFObjectFile *COFFObj = dyn_cast(Obj);
171171 if (!COFFObj)
1111 ///
1212 //===----------------------------------------------------------------------===//
1313
14 #include "llvm-readobj.h"
1514 #include "ARMAttributeParser.h"
1615 #include "ARMEHABIPrinter.h"
1716 #include "Error.h"
1817 #include "ObjDumper.h"
1918 #include "StackMapPrinter.h"
20 #include "StreamWriter.h"
19 #include "llvm-readobj.h"
2120 #include "llvm/ADT/Optional.h"
2221 #include "llvm/ADT/SmallString.h"
2322 #include "llvm/ADT/StringExtras.h"
2524 #include "llvm/Support/ARMBuildAttributes.h"
2625 #include "llvm/Support/Compiler.h"
2726 #include "llvm/Support/Format.h"
27 #include "llvm/Support/FormattedStream.h"
2828 #include "llvm/Support/MathExtras.h"
2929 #include "llvm/Support/MipsABIFlags.h"
30 #include "llvm/Support/ScopedPrinter.h"
3031 #include "llvm/Support/raw_ostream.h"
31 #include "llvm/Support/FormattedStream.h"
3232
3333 using namespace llvm;
3434 using namespace llvm::object;
9696 template
9797 class ELFDumper : public ObjDumper {
9898 public:
99 ELFDumper(const ELFFile *Obj, StreamWriter &Writer);
99 ELFDumper(const ELFFile *Obj, ScopedPrinter &Writer);
100100
101101 void printFileHeaders() override;
102102 void printSections() override;
299299 formatted_raw_ostream OS;
300300 public:
301301 TYPEDEF_ELF_TYPES(ELFT)
302 GNUStyle(StreamWriter &W, ELFDumper *Dumper)
302 GNUStyle(ScopedPrinter &W, ELFDumper *Dumper)
303303 : DumpStyle(Dumper), OS(W.getOStream()) {}
304304 void printFileHeaders(const ELFO *Obj) override;
305305 void printGroupSections(const ELFFile *Obj) override;
352352 template class LLVMStyle : public DumpStyle {
353353 public:
354354 TYPEDEF_ELF_TYPES(ELFT)
355 LLVMStyle(StreamWriter &W, ELFDumper *Dumper)
355 LLVMStyle(ScopedPrinter &W, ELFDumper *Dumper)
356356 : DumpStyle(Dumper), W(W) {}
357357
358358 void printFileHeaders(const ELFO *Obj) override;
371371 void printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel);
372372 void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
373373 StringRef StrTable, bool IsDynamic) override;
374 StreamWriter &W;
374 ScopedPrinter &W;
375375 };
376376
377377 } // namespace
380380
381381 template
382382 static std::error_code createELFDumper(const ELFFile *Obj,
383 StreamWriter &Writer,
383 ScopedPrinter &Writer,
384384 std::unique_ptr &Result) {
385385 Result.reset(new ELFDumper(Obj, Writer));
386386 return readobj_error::success;
387387 }
388388
389389 std::error_code createELFDumper(const object::ObjectFile *Obj,
390 StreamWriter &Writer,
390 ScopedPrinter &Writer,
391391 std::unique_ptr &Result) {
392392 // Little-endian 32-bit
393393 if (const ELF32LEObjectFile *ELFObj = dyn_cast(Obj))
490490 LoadVersionNeeds(dot_gnu_version_r_sec);
491491 }
492492
493
494493 template
495 static void printVersionSymbolSection(ELFDumper *Dumper,
496 const ELFO *Obj,
494 static void printVersionSymbolSection(ELFDumper *Dumper, const ELFO *Obj,
497495 const typename ELFO::Elf_Shdr *Sec,
498 StreamWriter &W) {
496 ScopedPrinter &W) {
499497 DictScope SS(W, "Version symbols");
500498 if (!Sec)
501499 return;
524522 static void printVersionDefinitionSection(ELFDumper *Dumper,
525523 const ELFO *Obj,
526524 const typename ELFO::Elf_Shdr *Sec,
527 StreamWriter &W) {
525 ScopedPrinter &W) {
528526 DictScope SD(W, "Version definition");
529527 if (!Sec)
530528 return;
12161214 };
12171215
12181216 template
1219 ELFDumper::ELFDumper(const ELFFile *Obj, StreamWriter &Writer)
1217 ELFDumper::ELFDumper(const ELFFile *Obj, ScopedPrinter &Writer)
12201218 : ObjDumper(Writer), Obj(Obj) {
12211219
12221220 SmallVector LoadSegments;
17941792 typedef typename ELFO::Elf_Rela Elf_Rela;
17951793
17961794 MipsGOTParser(ELFDumper *Dumper, const ELFO *Obj,
1797 Elf_Dyn_Range DynTable, StreamWriter &W);
1795 Elf_Dyn_Range DynTable, ScopedPrinter &W);
17981796
17991797 void parseGOT();
18001798 void parsePLT();
18021800 private:
18031801 ELFDumper *Dumper;
18041802 const ELFO *Obj;
1805 StreamWriter &W;
1803 ScopedPrinter &W;
18061804 llvm::Optional DtPltGot;
18071805 llvm::Optional DtLocalGotNum;
18081806 llvm::Optional DtGotSym;
18271825
18281826 template
18291827 MipsGOTParser::MipsGOTParser(ELFDumper *Dumper, const ELFO *Obj,
1830 Elf_Dyn_Range DynTable, StreamWriter &W)
1828 Elf_Dyn_Range DynTable, ScopedPrinter &W)
18311829 : Dumper(Dumper), Obj(Obj), W(W) {
18321830 for (const auto &Entry : DynTable) {
18331831 switch (Entry.getTag()) {
1010 //
1111 //===----------------------------------------------------------------------===//
1212
13 #include "llvm-readobj.h"
1413 #include "Error.h"
1514 #include "ObjDumper.h"
1615 #include "StackMapPrinter.h"
17 #include "StreamWriter.h"
16 #include "llvm-readobj.h"
1817 #include "llvm/ADT/SmallString.h"
1918 #include "llvm/ADT/StringExtras.h"
2019 #include "llvm/Object/MachO.h"
2120 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/ScopedPrinter.h"
2222
2323 using namespace llvm;
2424 using namespace object;
2727
2828 class MachODumper : public ObjDumper {
2929 public:
30 MachODumper(const MachOObjectFile *Obj, StreamWriter& Writer)
31 : ObjDumper(Writer)
32 , Obj(Obj) { }
30 MachODumper(const MachOObjectFile *Obj, ScopedPrinter &Writer)
31 : ObjDumper(Writer), Obj(Obj) {}
3332
3433 void printFileHeaders() override;
3534 void printSections() override;
6867 namespace llvm {
6968
7069 std::error_code createMachODumper(const object::ObjectFile *Obj,
71 StreamWriter &Writer,
70 ScopedPrinter &Writer,
7271 std::unique_ptr &Result) {
7372 const MachOObjectFile *MachOObj = dyn_cast(Obj);
7473 if (!MachOObj)
1313
1414 #include "ObjDumper.h"
1515 #include "Error.h"
16 #include "StreamWriter.h"
1716 #include "llvm/Object/ObjectFile.h"
17 #include "llvm/Support/ScopedPrinter.h"
1818 #include "llvm/Support/raw_ostream.h"
1919
2020 namespace llvm {
2121
22 ObjDumper::ObjDumper(StreamWriter& Writer)
23 : W(Writer) {
24 }
22 ObjDumper::ObjDumper(ScopedPrinter &Writer) : W(Writer) {}
2523
2624 ObjDumper::~ObjDumper() {
2725 }
1818 class ObjectFile;
1919 }
2020
21 class StreamWriter;
21 class ScopedPrinter;
2222
2323 class ObjDumper {
2424 public:
25 ObjDumper(StreamWriter& Writer);
25 ObjDumper(ScopedPrinter &Writer);
2626 virtual ~ObjDumper();
2727
2828 virtual void printFileHeaders() = 0;
7070 virtual void printStackMap() const = 0;
7171
7272 protected:
73 StreamWriter& W;
73 ScopedPrinter &W;
7474 };
7575
7676 std::error_code createCOFFDumper(const object::ObjectFile *Obj,
77 StreamWriter &Writer,
77 ScopedPrinter &Writer,
7878 std::unique_ptr &Result);
7979
8080 std::error_code createELFDumper(const object::ObjectFile *Obj,
81 StreamWriter &Writer,
81 ScopedPrinter &Writer,
8282 std::unique_ptr &Result);
8383
8484 std::error_code createMachODumper(const object::ObjectFile *Obj,
85 StreamWriter &Writer,
85 ScopedPrinter &Writer,
8686 std::unique_ptr &Result);
8787
8888 void dumpCOFFImportFile(const object::COFFImportFile *File);
+0
-71
tools/llvm-readobj/StreamWriter.cpp less more
None #include "StreamWriter.h"
1 #include "llvm/ADT/StringExtras.h"
2 #include "llvm/Support/Format.h"
3 #include
4
5 using namespace llvm::support;
6
7 namespace llvm {
8
9 raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value) {
10 OS << "0x" << to_hexString(Value.Value);
11 return OS;
12 }
13
14 const std::string to_hexString(uint64_t Value, bool UpperCase) {
15 std::string number;
16 llvm::raw_string_ostream stream(number);
17 stream << format_hex_no_prefix(Value, 1, UpperCase);
18 return stream.str();
19 }
20
21 void StreamWriter::printBinaryImpl(StringRef Label, StringRef Str,
22 ArrayRef Data, bool Block) {
23 if (Data.size() > 16)
24 Block = true;
25
26 if (Block) {
27 startLine() << Label;
28 if (Str.size() > 0)
29 OS << ": " << Str;
30 OS << " (\n";
31 for (size_t addr = 0, end = Data.size(); addr < end; addr += 16) {
32 startLine() << format(" %04" PRIX64 ": ", uint64_t(addr));
33 // Dump line of hex.
34 for (size_t i = 0; i < 16; ++i) {
35 if (i != 0 && i % 4 == 0)
36 OS << ' ';
37 if (addr + i < end)
38 OS << hexdigit((Data[addr + i] >> 4) & 0xF, false)
39 << hexdigit(Data[addr + i] & 0xF, false);
40 else
41 OS << " ";
42 }
43 // Print ascii.
44 OS << " |";
45 for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
46 if (std::isprint(Data[addr + i] & 0xFF))
47 OS << Data[addr + i];
48 else
49 OS << ".";
50 }
51 OS << "|\n";
52 }
53
54 startLine() << ")\n";
55 } else {
56 startLine() << Label << ":";
57 if (Str.size() > 0)
58 OS << " " << Str;
59 OS << " (";
60 for (size_t i = 0; i < Data.size(); ++i) {
61 if (i > 0)
62 OS << " ";
63
64 OS << format("%02X", static_cast(Data[i]));
65 }
66 OS << ")\n";
67 }
68 }
69
70 } // namespace llvm
+0
-354
tools/llvm-readobj/StreamWriter.h less more
None //===-- StreamWriter.h ----------------------------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_TOOLS_LLVM_READOBJ_STREAMWRITER_H
10 #define LLVM_TOOLS_LLVM_READOBJ_STREAMWRITER_H
11
12 #include "llvm/ADT/APSInt.h"
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Support/DataTypes.h"
17 #include "llvm/Support/Endian.h"
18 #include "llvm/Support/raw_ostream.h"
19 #include
20
21 using namespace llvm;
22
23 namespace llvm {
24
25 template
26 struct EnumEntry {
27 StringRef Name;
28 // While Name suffices in most of the cases, in certain cases
29 // GNU style and LLVM style of ELFDumper do not
30 // display same string for same enum. The AltName if initialized appropriately
31 // will hold the string that GNU style emits.
32 // Example:
33 // "EM_X86_64" string on LLVM style for Elf_Ehdr->e_machine corresponds to
34 // "Advanced Micro Devices X86-64" on GNU style
35 StringRef AltName;
36 T Value;
37 EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {}
38 EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {}
39 };
40
41 struct HexNumber {
42 // To avoid sign-extension we have to explicitly cast to the appropriate
43 // unsigned type. The overloads are here so that every type that is implicitly
44 // convertible to an integer (including enums and endian helpers) can be used
45 // without requiring type traits or call-site changes.
46 HexNumber(char Value) : Value(static_cast(Value)) { }
47 HexNumber(signed char Value) : Value(static_cast(Value)) { }
48 HexNumber(signed short Value) : Value(static_cast(Value)) { }
49 HexNumber(signed int Value) : Value(static_cast(Value)) { }
50 HexNumber(signed long Value) : Value(static_cast(Value)) { }
51 HexNumber(signed long long Value) : Value(static_cast(Value)) { }
52 HexNumber(unsigned char Value) : Value(Value) { }
53 HexNumber(unsigned short Value) : Value(Value) { }
54 HexNumber(unsigned int Value) : Value(Value) { }
55 HexNumber(unsigned long Value) : Value(Value) { }
56 HexNumber(unsigned long long Value) : Value(Value) { }
57 uint64_t Value;
58 };
59
60 raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value);
61 const std::string to_hexString(uint64_t Value, bool UpperCase = true);
62
63 template const std::string to_string(const T &Value) {
64 std::string number;
65 llvm::raw_string_ostream stream(number);
66 stream << Value;
67 return stream.str();
68 }
69
70 class StreamWriter {
71 public:
72 StreamWriter(raw_ostream &OS)
73 : OS(OS)
74 , IndentLevel(0) {
75 }
76
77 void flush() {
78 OS.flush();
79 }
80
81 void indent(int Levels = 1) {
82 IndentLevel += Levels;
83 }
84
85 void unindent(int Levels = 1) {
86 IndentLevel = std::max(0, IndentLevel - Levels);
87 }
88
89 void printIndent() {
90 for (int i = 0; i < IndentLevel; ++i)
91 OS << " ";
92 }
93
94 template
95 HexNumber hex(T Value) {
96 return HexNumber(Value);
97 }
98
99 template
100 void printEnum(StringRef Label, T Value,
101 ArrayRef > EnumValues) {
102 StringRef Name;
103 bool Found = false;
104 for (const auto &EnumItem : EnumValues) {
105 if (EnumItem.Value == Value) {
106 Name = EnumItem.Name;
107 Found = true;
108 break;
109 }
110 }
111
112 if (Found) {
113 startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
114 } else {
115 startLine() << Label << ": " << hex(Value) << "\n";
116 }
117 }
118
119 template
120 void printFlags(StringRef Label, T Value, ArrayRef> Flags,
121 TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
122 TFlag EnumMask3 = {}) {
123 typedef EnumEntry FlagEntry;
124 typedef SmallVector FlagVector;
125 FlagVector SetFlags;
126
127 for (const auto &Flag : Flags) {
128 if (Flag.Value == 0)
129 continue;
130
131 TFlag EnumMask{};
132 if (Flag.Value & EnumMask1)
133 EnumMask = EnumMask1;
134 else if (Flag.Value & EnumMask2)
135 EnumMask = EnumMask2;
136 else if (Flag.Value & EnumMask3)
137 EnumMask = EnumMask3;
138 bool IsEnum = (Flag.Value & EnumMask) != 0;
139 if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
140 (IsEnum && (Value & EnumMask) == Flag.Value)) {
141 SetFlags.push_back(Flag);
142 }
143 }
144
145 std::sort(SetFlags.begin(), SetFlags.end(), &flagName);
146
147 startLine() << Label << " [ (" << hex(Value) << ")\n";
148 for (const auto &Flag : SetFlags) {
149 startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
150 }
151 startLine() << "]\n";
152 }
153
154 template
155 void printFlags(StringRef Label, T Value) {
156 startLine() << Label << " [ (" << hex(Value) << ")\n";
157 uint64_t Flag = 1;
158 uint64_t Curr = Value;
159 while (Curr > 0) {
160 if (Curr & 1)
161 startLine() << " " << hex(Flag) << "\n";
162 Curr >>= 1;
163 Flag <<= 1;
164 }
165 startLine() << "]\n";
166 }
167
168 void printNumber(StringRef Label, uint64_t Value) {
169 startLine() << Label << ": " << Value << "\n";
170 }
171
172 void printNumber(StringRef Label, uint32_t Value) {
173 startLine() << Label << ": " << Value << "\n";
174 }
175
176 void printNumber(StringRef Label, uint16_t Value) {
177 startLine() << Label << ": " << Value << "\n";
178 }
179
180 void printNumber(StringRef Label, uint8_t Value) {
181 startLine() << Label << ": " << unsigned(Value) << "\n";
182 }
183
184 void printNumber(StringRef Label, int64_t Value) {
185 startLine() << Label << ": " << Value << "\n";
186 }
187
188 void printNumber(StringRef Label, int32_t Value) {
189 startLine() << Label << ": " << Value << "\n";
190 }
191
192 void printNumber(StringRef Label, int16_t Value) {
193 startLine() << Label << ": " << Value << "\n";
194 }
195
196 void printNumber(StringRef Label, int8_t Value) {
197 startLine() << Label << ": " << int(Value) << "\n";
198 }
199
200 void printNumber(StringRef Label, APSInt Value) {
201 startLine() << Label << ": " << Value << "\n";
202 }
203
204 void printBoolean(StringRef Label, bool Value) {
205 startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
206 }
207
208 template
209 void printList(StringRef Label, const T &List) {
210 startLine() << Label << ": [";
211 bool Comma = false;
212 for (const auto &Item : List) {
213 if (Comma)
214 OS << ", ";
215 OS << Item;
216 Comma = true;
217 }
218 OS << "]\n";
219 }
220
221 template
222 void printHexList(StringRef Label, const T &List) {
223 startLine() << Label << ": [";
224 bool Comma = false;
225 for (const auto &Item : List) {
226 if (Comma)
227 OS << ", ";
228 OS << hex(Item);
229 Comma = true;
230 }
231 OS << "]\n";
232 }
233
234 template
235 void printHex(StringRef Label, T Value) {
236 startLine() << Label << ": " << hex(Value) << "\n";
237 }
238
239 template
240 void printHex(StringRef Label, StringRef Str, T Value) {
241 startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
242 }
243
244 template
245 void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
246 startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
247 }
248
249 void printString(StringRef Label, StringRef Value) {
250 startLine() << Label << ": " << Value << "\n";
251 }
252
253 void printString(StringRef Label, const std::string &Value) {
254 startLine() << Label << ": " << Value << "\n";
255 }
256
257 template
258 void printNumber(StringRef Label, StringRef Str, T Value) {
259 startLine() << Label << ": " << Str << " (" << Value << ")\n";
260 }
261
262 void printBinary(StringRef Label, StringRef Str, ArrayRef Value) {
263 printBinaryImpl(Label, Str, Value, false);
264 }
265
266 void printBinary(StringRef Label, StringRef Str, ArrayRef Value) {
267 auto V = makeArrayRef(reinterpret_cast(Value.data()),
268 Value.size());
269 printBinaryImpl(Label, Str, V, false);
270 }
271
272 void printBinary(StringRef Label, ArrayRef Value) {
273 printBinaryImpl(Label, StringRef(), Value, false);
274 }
275
276 void printBinary(StringRef Label, ArrayRef Value) {
277 auto V = makeArrayRef(reinterpret_cast(Value.data()),
278 Value.size());
279 printBinaryImpl(Label, StringRef(), V, false);
280 }
281
282 void printBinary(StringRef Label, StringRef Value) {
283 auto V = makeArrayRef(reinterpret_cast(Value.data()),
284 Value.size());
285 printBinaryImpl(Label, StringRef(), V, false);
286 }
287
288 void printBinaryBlock(StringRef Label, StringRef Value) {
289 auto V = makeArrayRef(reinterpret_cast(Value.data()),
290 Value.size());
291 printBinaryImpl(Label, StringRef(), V, true);
292 }
293
294 raw_ostream& startLine() {
295 printIndent();
296 return OS;
297 }
298
299 raw_ostream& getOStream() {
300 return OS;
301 }
302
303 private:
304 template
305 static bool flagName(const EnumEntry& lhs, const EnumEntry& rhs) {
306 return lhs.Name < rhs.Name;
307 }
308
309 void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef Value,
310 bool Block);
311
312 raw_ostream &OS;
313 int IndentLevel;
314 };
315
316 template <>
317 inline void
318 StreamWriter::printHex(StringRef Label,
319 support::ulittle16_t Value) {
320 startLine() << Label << ": " << hex(Value) << "\n";
321 }
322
323 struct DictScope {
324 DictScope(StreamWriter& W, StringRef N) : W(W) {
325 W.startLine() << N << " {\n";
326 W.indent();
327 }
328
329 ~DictScope() {
330 W.unindent();
331 W.startLine() << "}\n";
332 }
333
334 StreamWriter& W;
335 };
336
337 struct ListScope {
338 ListScope(StreamWriter& W, StringRef N) : W(W) {
339 W.startLine() << N << " [\n";
340 W.indent();
341 }
342
343 ~ListScope() {
344 W.unindent();
345 W.startLine() << "]\n";
346 }
347
348 StreamWriter& W;
349 };
350
351 } // namespace llvm
352
353 #endif
99 #ifndef LLVM_TOOLS_LLVM_READOBJ_WIN64EHDUMPER_H
1010 #define LLVM_TOOLS_LLVM_READOBJ_WIN64EHDUMPER_H
1111
12 #include "StreamWriter.h"
12 #include "llvm/Support/ScopedPrinter.h"
1313 #include "llvm/Support/Win64EH.h"
1414
1515 namespace llvm {
2121
2222 namespace Win64EH {
2323 class Dumper {
24 StreamWriter &SW;
24 ScopedPrinter &SW;
2525 raw_ostream &OS;
2626
2727 public:
5252 uint64_t SectionOffset, const RuntimeFunction &RF);
5353
5454 public:
55 Dumper(StreamWriter &SW) : SW(SW), OS(SW.getOStream()) {}
55 Dumper(ScopedPrinter &SW) : SW(SW), OS(SW.getOStream()) {}
5656
5757 void printData(const Context &Ctx);
5858 };
2121 #include "llvm-readobj.h"
2222 #include "Error.h"
2323 #include "ObjDumper.h"
24 #include "StreamWriter.h"
2524 #include "llvm/Object/Archive.h"
2625 #include "llvm/Object/COFFImportFile.h"
2726 #include "llvm/Object/ELFObjectFile.h"
3433 #include "llvm/Support/FileSystem.h"
3534 #include "llvm/Support/ManagedStatic.h"
3635 #include "llvm/Support/PrettyStackTrace.h"
36 #include "llvm/Support/ScopedPrinter.h"
3737 #include "llvm/Support/Signals.h"
3838 #include "llvm/Support/TargetRegistry.h"
3939 #include "llvm/Support/TargetSelect.h"
292292 }
293293
294294 /// @brief Creates an format-specific object file dumper.
295 static std::error_code createDumper(const ObjectFile *Obj, StreamWriter &Writer,
295 static std::error_code createDumper(const ObjectFile *Obj,
296 ScopedPrinter &Writer,
296297 std::unique_ptr &Result) {
297298 if (!Obj)
298299 return readobj_error::unsupported_file_format;
309310
310311 /// @brief Dumps the specified object file.
311312 static void dumpObject(const ObjectFile *Obj) {
312 StreamWriter Writer(outs());
313 ScopedPrinter Writer(outs());
313314 std::unique_ptr Dumper;
314315 if (std::error_code EC = createDumper(Obj, Writer, Dumper))
315316 reportError(Obj->getFileName(), EC);