1 //===-- ObjDumper.cpp - Base dumper class -----------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file implements ObjDumper.
13 //===----------------------------------------------------------------------===//
15 #include "ObjDumper.h"
17 #include "llvm-readobj.h"
18 #include "llvm/Object/ObjectFile.h"
19 #include "llvm/Support/Error.h"
20 #include "llvm/Support/ScopedPrinter.h"
21 #include "llvm/Support/raw_ostream.h"
25 ObjDumper::ObjDumper(ScopedPrinter
&Writer
) : W(Writer
) {}
27 ObjDumper::~ObjDumper() {
30 static void printAsPrintable(raw_ostream
&W
, const uint8_t *Start
, size_t Len
) {
31 for (size_t i
= 0; i
< Len
; i
++)
32 W
<< (isPrint(Start
[i
]) ? static_cast<char>(Start
[i
]) : '.');
35 static Expected
<object::SectionRef
>
36 getSecNameOrIndexAsSecRef(const object::ObjectFile
*Obj
, StringRef SecName
) {
38 long SectionIndex
= strtol(SecName
.data(), &StrPtr
, 10);
39 object::SectionRef Section
;
45 for (object::SectionRef SecRef
: Obj
->sections()) {
47 StringRef SectionName
;
49 if (std::error_code E
= SecRef
.getName(SectionName
))
50 return errorCodeToError(E
);
52 if (SectionName
== SecName
)
54 } else if (SecIndex
== SectionIndex
)
59 return make_error
<StringError
>("invalid section reference",
60 object::object_error::parse_failed
);
63 void ObjDumper::printSectionAsString(const object::ObjectFile
*Obj
,
65 Expected
<object::SectionRef
> SectionRefOrError
=
66 getSecNameOrIndexAsSecRef(Obj
, SecName
);
67 if (!SectionRefOrError
)
68 error(std::move(SectionRefOrError
));
69 object::SectionRef Section
= *SectionRefOrError
;
70 StringRef SectionName
;
72 if (std::error_code E
= Section
.getName(SectionName
))
74 W
.startLine() << "String dump of section '" << SectionName
<< "':\n";
76 StringRef SectionContent
;
77 Section
.getContents(SectionContent
);
79 const uint8_t *SecContent
= SectionContent
.bytes_begin();
80 const uint8_t *CurrentWord
= SecContent
;
81 const uint8_t *SecEnd
= SectionContent
.bytes_end();
83 while (CurrentWord
<= SecEnd
) {
84 size_t WordSize
= strnlen(reinterpret_cast<const char *>(CurrentWord
),
85 SecEnd
- CurrentWord
);
90 W
.startLine() << format("[%6tx] ", CurrentWord
- SecContent
);
91 printAsPrintable(W
.startLine(), CurrentWord
, WordSize
);
92 W
.startLine() << '\n';
93 CurrentWord
+= WordSize
+ 1;
97 void ObjDumper::printSectionAsHex(const object::ObjectFile
*Obj
,
99 Expected
<object::SectionRef
> SectionRefOrError
=
100 getSecNameOrIndexAsSecRef(Obj
, SecName
);
101 if (!SectionRefOrError
)
102 error(std::move(SectionRefOrError
));
103 object::SectionRef Section
= *SectionRefOrError
;
104 StringRef SectionName
;
106 if (std::error_code E
= Section
.getName(SectionName
))
108 W
.startLine() << "Hex dump of section '" << SectionName
<< "':\n";
110 StringRef SectionContent
;
111 Section
.getContents(SectionContent
);
112 const uint8_t *SecContent
= SectionContent
.bytes_begin();
113 const uint8_t *SecEnd
= SecContent
+ SectionContent
.size();
115 for (const uint8_t *SecPtr
= SecContent
; SecPtr
< SecEnd
; SecPtr
+= 16) {
116 const uint8_t *TmpSecPtr
= SecPtr
;
120 W
.startLine() << format_hex(SecPtr
- SecContent
, 10);
121 W
.startLine() << ' ';
122 for (i
= 0; TmpSecPtr
< SecEnd
&& i
< 4; ++i
) {
123 for (k
= 0; TmpSecPtr
< SecEnd
&& k
< 4; k
++, TmpSecPtr
++) {
124 uint8_t Val
= *(reinterpret_cast<const uint8_t *>(TmpSecPtr
));
125 W
.startLine() << format_hex_no_prefix(Val
, 2);
127 W
.startLine() << ' ';
130 // We need to print the correct amount of spaces to match the format.
131 // We are adding the (4 - i) last rows that are 8 characters each.
132 // Then, the (4 - i) spaces that are in between the rows.
133 // Least, if we cut in a middle of a row, we add the remaining characters,
134 // which is (8 - (k * 2))
136 W
.startLine() << format("%*c", (4 - i
) * 8 + (4 - i
) + (8 - (k
* 2)),
140 for (i
= 0; TmpSecPtr
+ i
< SecEnd
&& i
< 16; ++i
)
141 W
.startLine() << (isPrint(TmpSecPtr
[i
]) ? static_cast<char>(TmpSecPtr
[i
])
144 W
.startLine() << '\n';