17
17
//
18
18
// ===----------------------------------------------------------------------===//
19
19
20
- #include " FileAnalysis.h"
21
-
22
- #include " llvm/BinaryFormat/ELF.h"
20
+ #include " llvm/MC/MCAsmInfo.h"
21
+ #include " llvm/MC/MCContext.h"
22
+ #include " llvm/MC/MCDisassembler/MCDisassembler.h"
23
+ #include " llvm/MC/MCInst.h"
24
+ #include " llvm/MC/MCInstPrinter.h"
25
+ #include " llvm/MC/MCInstrAnalysis.h"
26
+ #include " llvm/MC/MCInstrDesc.h"
27
+ #include " llvm/MC/MCInstrInfo.h"
28
+ #include " llvm/MC/MCObjectFileInfo.h"
29
+ #include " llvm/MC/MCRegisterInfo.h"
30
+ #include " llvm/MC/MCSubtargetInfo.h"
31
+ #include " llvm/Object/Binary.h"
32
+ #include " llvm/Object/COFF.h"
33
+ #include " llvm/Object/ObjectFile.h"
34
+ #include " llvm/Support/Casting.h"
23
35
#include " llvm/Support/CommandLine.h"
24
- #include " llvm/Support/Error.h"
36
+ #include " llvm/Support/MemoryBuffer.h"
37
+ #include " llvm/Support/TargetRegistry.h"
38
+ #include " llvm/Support/TargetSelect.h"
39
+ #include " llvm/Support/raw_ostream.h"
25
40
41
+ #include < cassert>
26
42
#include < cstdlib>
27
43
28
44
using namespace llvm ;
29
45
using namespace llvm ::object;
30
- using namespace llvm ::cfi_verify;
31
46
47
+ cl::opt<bool > ArgDumpSymbols (" sym" , cl::desc(" Dump the symbol table." ));
32
48
cl::opt<std::string> InputFilename (cl::Positional, cl::desc(" <input file>" ),
33
49
cl::Required);
34
50
35
- ExitOnError ExitOnErr;
51
+ static void printSymbols (const ObjectFile *Object) {
52
+ for (const SymbolRef &Symbol : Object->symbols ()) {
53
+ outs () << " Symbol [" << format_hex_no_prefix (Symbol.getValue (), 2 )
54
+ << " ] = " ;
55
+
56
+ auto SymbolName = Symbol.getName ();
57
+ if (SymbolName)
58
+ outs () << *SymbolName;
59
+ else
60
+ outs () << " UNKNOWN" ;
61
+
62
+ if (Symbol.getFlags () & SymbolRef::SF_Hidden)
63
+ outs () << " .hidden" ;
64
+
65
+ outs () << " (Section = " ;
66
+
67
+ auto SymbolSection = Symbol.getSection ();
68
+ if (SymbolSection) {
69
+ StringRef SymbolSectionName;
70
+ if ((*SymbolSection)->getName (SymbolSectionName))
71
+ outs () << " UNKNOWN)" ;
72
+ else
73
+ outs () << SymbolSectionName << " )" ;
74
+ } else {
75
+ outs () << " N/A)" ;
76
+ }
36
77
37
- void printIndirectCFInstructions (const FileAnalysis &Verifier) {
38
- for (uint64_t Address : Verifier.getIndirectInstructions ()) {
39
- const auto &InstrMeta = Verifier.getInstructionOrDie (Address);
40
- outs () << format_hex (Address, 2 ) << " |"
41
- << Verifier.getMCInstrInfo ()->getName (
42
- InstrMeta.Instruction .getOpcode ())
43
- << " " ;
44
- InstrMeta.Instruction .print (outs ());
45
78
outs () << " \n " ;
46
79
}
47
80
}
@@ -54,8 +87,155 @@ int main(int argc, char **argv) {
54
87
InitializeAllAsmParsers ();
55
88
InitializeAllDisassemblers ();
56
89
57
- FileAnalysis Verifier = ExitOnErr (FileAnalysis::Create (InputFilename));
58
- printIndirectCFInstructions (Verifier);
90
+ Expected<OwningBinary<Binary>> BinaryOrErr = createBinary (InputFilename);
91
+ if (!BinaryOrErr) {
92
+ errs () << " Failed to open file.\n " ;
93
+ return EXIT_FAILURE;
94
+ }
95
+
96
+ Binary &Binary = *BinaryOrErr.get ().getBinary ();
97
+ ObjectFile *Object = dyn_cast<ObjectFile>(&Binary);
98
+ if (!Object) {
99
+ errs () << " Disassembling of non-objects not currently supported.\n " ;
100
+ return EXIT_FAILURE;
101
+ }
102
+
103
+ Triple TheTriple = Object->makeTriple ();
104
+ std::string TripleName = TheTriple.getTriple ();
105
+ std::string ArchName = " " ;
106
+ std::string ErrorString;
107
+
108
+ const Target *TheTarget =
109
+ TargetRegistry::lookupTarget (ArchName, TheTriple, ErrorString);
110
+
111
+ if (!TheTarget) {
112
+ errs () << " Couldn't find target \" " << TheTriple.getTriple ()
113
+ << " \" , failed with error: " << ErrorString << " .\n " ;
114
+ return EXIT_FAILURE;
115
+ }
116
+
117
+ SubtargetFeatures Features = Object->getFeatures ();
118
+
119
+ std::unique_ptr<const MCRegisterInfo> RegisterInfo (
120
+ TheTarget->createMCRegInfo (TripleName));
121
+ if (!RegisterInfo) {
122
+ errs () << " Failed to initialise RegisterInfo.\n " ;
123
+ return EXIT_FAILURE;
124
+ }
125
+
126
+ std::unique_ptr<const MCAsmInfo> AsmInfo (
127
+ TheTarget->createMCAsmInfo (*RegisterInfo, TripleName));
128
+ if (!AsmInfo) {
129
+ errs () << " Failed to initialise AsmInfo.\n " ;
130
+ return EXIT_FAILURE;
131
+ }
132
+
133
+ std::string MCPU = " " ;
134
+ std::unique_ptr<MCSubtargetInfo> SubtargetInfo (
135
+ TheTarget->createMCSubtargetInfo (TripleName, MCPU, Features.getString ()));
136
+ if (!SubtargetInfo) {
137
+ errs () << " Failed to initialise SubtargetInfo.\n " ;
138
+ return EXIT_FAILURE;
139
+ }
140
+
141
+ std::unique_ptr<const MCInstrInfo> MII (TheTarget->createMCInstrInfo ());
142
+ if (!MII) {
143
+ errs () << " Failed to initialise MII.\n " ;
144
+ return EXIT_FAILURE;
145
+ }
146
+
147
+ MCObjectFileInfo MOFI;
148
+ MCContext Context (AsmInfo.get (), RegisterInfo.get (), &MOFI);
149
+
150
+ std::unique_ptr<const MCDisassembler> Disassembler (
151
+ TheTarget->createMCDisassembler (*SubtargetInfo, Context));
152
+
153
+ if (!Disassembler) {
154
+ errs () << " No disassembler available for target." ;
155
+ return EXIT_FAILURE;
156
+ }
157
+
158
+ std::unique_ptr<const MCInstrAnalysis> MIA (
159
+ TheTarget->createMCInstrAnalysis (MII.get ()));
160
+
161
+ std::unique_ptr<MCInstPrinter> Printer (
162
+ TheTarget->createMCInstPrinter (TheTriple, AsmInfo->getAssemblerDialect (),
163
+ *AsmInfo, *MII, *RegisterInfo));
164
+
165
+ if (ArgDumpSymbols)
166
+ printSymbols (Object);
167
+
168
+ for (const SectionRef &Section : Object->sections ()) {
169
+ outs () << " Section [" << format_hex_no_prefix (Section.getAddress (), 2 )
170
+ << " ] = " ;
171
+ StringRef SectionName;
172
+
173
+ if (Section.getName (SectionName))
174
+ outs () << " UNKNOWN.\n " ;
175
+ else
176
+ outs () << SectionName << " \n " ;
177
+
178
+ StringRef SectionContents;
179
+ if (Section.getContents (SectionContents)) {
180
+ errs () << " Failed to retrieve section contents.\n " ;
181
+ return EXIT_FAILURE;
182
+ }
183
+
184
+ MCInst Instruction;
185
+ uint64_t InstructionSize;
186
+
187
+ ArrayRef<uint8_t > SectionBytes ((const uint8_t *)SectionContents.data (),
188
+ Section.getSize ());
189
+
190
+ for (uint64_t Byte = 0 ; Byte < Section.getSize ();) {
191
+ bool BadInstruction = false ;
192
+
193
+ // Disassemble the instruction.
194
+ if (Disassembler->getInstruction (
195
+ Instruction, InstructionSize, SectionBytes.drop_front (Byte ), 0 ,
196
+ nulls (), outs ()) != MCDisassembler::Success) {
197
+ BadInstruction = true ;
198
+ }
199
+
200
+ Byte += InstructionSize;
201
+
202
+ if (BadInstruction)
203
+ continue ;
204
+
205
+ // Skip instructions that do not affect the control flow.
206
+ const auto &InstrDesc = MII->get (Instruction.getOpcode ());
207
+ if (!InstrDesc.mayAffectControlFlow (Instruction, *RegisterInfo))
208
+ continue ;
209
+
210
+ // Skip instructions that do not operate on register operands.
211
+ bool UsesRegisterOperand = false ;
212
+ for (const auto &Operand : Instruction) {
213
+ if (Operand.isReg ())
214
+ UsesRegisterOperand = true ;
215
+ }
216
+
217
+ if (!UsesRegisterOperand)
218
+ continue ;
219
+
220
+ // Print the instruction address.
221
+ outs () << " "
222
+ << format_hex (Section.getAddress () + Byte - InstructionSize, 2 )
223
+ << " : " ;
224
+
225
+ // Print the instruction bytes.
226
+ for (uint64_t i = 0 ; i < InstructionSize; ++i) {
227
+ outs () << format_hex_no_prefix (SectionBytes[Byte - InstructionSize + i],
228
+ 2 )
229
+ << " " ;
230
+ }
231
+
232
+ // Print the instruction.
233
+ outs () << " | " << MII->getName (Instruction.getOpcode ()) << " " ;
234
+ Instruction.dump_pretty (outs (), Printer.get ());
235
+
236
+ outs () << " \n " ;
237
+ }
238
+ }
59
239
60
240
return EXIT_SUCCESS;
61
241
}
0 commit comments