1 //===-- ObjDumper.cpp - Base dumper class -----------------------*- C++ -*-===//
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 ObjDumper.
12 //===----------------------------------------------------------------------===//
14 #include "ObjDumper.h"
16 #include "llvm-readobj.h"
17 #include "llvm/Object/ObjectFile.h"
18 #include "llvm/Support/Error.h"
19 #include "llvm/Support/ScopedPrinter.h"
20 #include "llvm/Support/raw_ostream.h"
24 ObjDumper::ObjDumper(ScopedPrinter
&Writer
) : W(Writer
) {}
26 ObjDumper::~ObjDumper() {
29 static void printAsPrintable(raw_ostream
&W
, const uint8_t *Start
, size_t Len
) {
30 for (size_t i
= 0; i
< Len
; i
++)
31 W
<< (isPrint(Start
[i
]) ? static_cast<char>(Start
[i
]) : '.');
34 static Expected
<object::SectionRef
>
35 getSecNameOrIndexAsSecRef(const object::ObjectFile
*Obj
, StringRef SecName
) {
37 long SectionIndex
= strtol(SecName
.data(), &StrPtr
, 10);
38 object::SectionRef Section
;
44 for (object::SectionRef SecRef
: Obj
->sections()) {
46 StringRef SectionName
;
48 if (std::error_code E
= SecRef
.getName(SectionName
))
49 return errorCodeToError(E
);
51 if (SectionName
== SecName
)
53 } else if (SecIndex
== SectionIndex
)
58 return make_error
<StringError
>("invalid section reference",
59 object::object_error::parse_failed
);
62 void ObjDumper::printSectionAsString(const object::ObjectFile
*Obj
,
64 Expected
<object::SectionRef
> SectionRefOrError
=
65 getSecNameOrIndexAsSecRef(Obj
, SecName
);
66 if (!SectionRefOrError
)
67 error(std::move(SectionRefOrError
));
68 object::SectionRef Section
= *SectionRefOrError
;
69 StringRef SectionName
;
71 if (std::error_code E
= Section
.getName(SectionName
))
73 W
.startLine() << "String dump of section '" << SectionName
<< "':\n";
75 StringRef SectionContent
;
76 Section
.getContents(SectionContent
);
78 const uint8_t *SecContent
= SectionContent
.bytes_begin();
79 const uint8_t *CurrentWord
= SecContent
;
80 const uint8_t *SecEnd
= SectionContent
.bytes_end();
82 while (CurrentWord
<= SecEnd
) {
83 size_t WordSize
= strnlen(reinterpret_cast<const char *>(CurrentWord
),
84 SecEnd
- CurrentWord
);
89 W
.startLine() << format("[%6tx] ", CurrentWord
- SecContent
);
90 printAsPrintable(W
.startLine(), CurrentWord
, WordSize
);
91 W
.startLine() << '\n';
92 CurrentWord
+= WordSize
+ 1;
96 void ObjDumper::printSectionAsHex(const object::ObjectFile
*Obj
,
98 Expected
<object::SectionRef
> SectionRefOrError
=
99 getSecNameOrIndexAsSecRef(Obj
, SecName
);
100 if (!SectionRefOrError
)
101 error(std::move(SectionRefOrError
));
102 object::SectionRef Section
= *SectionRefOrError
;
103 StringRef SectionName
;
105 if (std::error_code E
= Section
.getName(SectionName
))
107 W
.startLine() << "Hex dump of section '" << SectionName
<< "':\n";
109 StringRef SectionContent
;
110 Section
.getContents(SectionContent
);
111 const uint8_t *SecContent
= SectionContent
.bytes_begin();
112 const uint8_t *SecEnd
= SecContent
+ SectionContent
.size();
114 for (const uint8_t *SecPtr
= SecContent
; SecPtr
< SecEnd
; SecPtr
+= 16) {
115 const uint8_t *TmpSecPtr
= SecPtr
;
119 W
.startLine() << format_hex(Section
.getAddress() + (SecPtr
- SecContent
),
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';