Mercurial > hg > CbC > CbC_llvm
comparison tools/llvm-mc/llvm-mc.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===-- llvm-mc.cpp - Machine Code Hacking Driver ---------------*- C++ -*-===// | 1 //===-- llvm-mc.cpp - Machine Code Hacking Driver ---------------*- C++ -*-===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 // | 8 // |
10 // This utility is a simple driver that allows command line hacking on machine | 9 // This utility is a simple driver that allows command line hacking on machine |
11 // code. | 10 // code. |
18 #include "llvm/MC/MCCodeEmitter.h" | 17 #include "llvm/MC/MCCodeEmitter.h" |
19 #include "llvm/MC/MCContext.h" | 18 #include "llvm/MC/MCContext.h" |
20 #include "llvm/MC/MCInstPrinter.h" | 19 #include "llvm/MC/MCInstPrinter.h" |
21 #include "llvm/MC/MCInstrInfo.h" | 20 #include "llvm/MC/MCInstrInfo.h" |
22 #include "llvm/MC/MCObjectFileInfo.h" | 21 #include "llvm/MC/MCObjectFileInfo.h" |
22 #include "llvm/MC/MCObjectWriter.h" | |
23 #include "llvm/MC/MCParser/AsmLexer.h" | 23 #include "llvm/MC/MCParser/AsmLexer.h" |
24 #include "llvm/MC/MCParser/MCTargetAsmParser.h" | 24 #include "llvm/MC/MCParser/MCTargetAsmParser.h" |
25 #include "llvm/MC/MCRegisterInfo.h" | 25 #include "llvm/MC/MCRegisterInfo.h" |
26 #include "llvm/MC/MCStreamer.h" | 26 #include "llvm/MC/MCStreamer.h" |
27 #include "llvm/MC/MCSubtargetInfo.h" | 27 #include "llvm/MC/MCSubtargetInfo.h" |
28 #include "llvm/MC/MCTargetOptionsCommandFlags.def" | 28 #include "llvm/MC/MCTargetOptionsCommandFlags.inc" |
29 #include "llvm/Support/CommandLine.h" | 29 #include "llvm/Support/CommandLine.h" |
30 #include "llvm/Support/Compression.h" | 30 #include "llvm/Support/Compression.h" |
31 #include "llvm/Support/FileUtilities.h" | 31 #include "llvm/Support/FileUtilities.h" |
32 #include "llvm/Support/FormattedStream.h" | 32 #include "llvm/Support/FormattedStream.h" |
33 #include "llvm/Support/Host.h" | 33 #include "llvm/Support/Host.h" |
34 #include "llvm/Support/ManagedStatic.h" | 34 #include "llvm/Support/InitLLVM.h" |
35 #include "llvm/Support/MemoryBuffer.h" | 35 #include "llvm/Support/MemoryBuffer.h" |
36 #include "llvm/Support/PrettyStackTrace.h" | |
37 #include "llvm/Support/Signals.h" | |
38 #include "llvm/Support/SourceMgr.h" | 36 #include "llvm/Support/SourceMgr.h" |
39 #include "llvm/Support/TargetRegistry.h" | 37 #include "llvm/Support/TargetRegistry.h" |
40 #include "llvm/Support/TargetSelect.h" | 38 #include "llvm/Support/TargetSelect.h" |
41 #include "llvm/Support/ToolOutputFile.h" | 39 #include "llvm/Support/ToolOutputFile.h" |
40 #include "llvm/Support/WithColor.h" | |
42 | 41 |
43 using namespace llvm; | 42 using namespace llvm; |
44 | 43 |
45 static cl::opt<std::string> | 44 static cl::opt<std::string> |
46 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); | 45 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); |
47 | 46 |
48 static cl::opt<std::string> | 47 static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"), |
49 OutputFilename("o", cl::desc("Output filename"), | 48 cl::value_desc("filename"), |
50 cl::value_desc("filename")); | 49 cl::init("-")); |
50 | |
51 static cl::opt<std::string> SplitDwarfFile("split-dwarf-file", | |
52 cl::desc("DWO output filename"), | |
53 cl::value_desc("filename")); | |
51 | 54 |
52 static cl::opt<bool> | 55 static cl::opt<bool> |
53 ShowEncoding("show-encoding", cl::desc("Show instruction encodings")); | 56 ShowEncoding("show-encoding", cl::desc("Show instruction encodings")); |
54 | 57 |
55 static cl::opt<bool> RelaxELFRel( | 58 static cl::opt<bool> RelaxELFRel( |
146 | 149 |
147 static cl::opt<std::string> | 150 static cl::opt<std::string> |
148 DebugCompilationDir("fdebug-compilation-dir", | 151 DebugCompilationDir("fdebug-compilation-dir", |
149 cl::desc("Specifies the debug info's compilation dir")); | 152 cl::desc("Specifies the debug info's compilation dir")); |
150 | 153 |
154 static cl::list<std::string> | |
155 DebugPrefixMap("fdebug-prefix-map", | |
156 cl::desc("Map file source paths in debug info"), | |
157 cl::value_desc("= separated key-value pairs")); | |
158 | |
151 static cl::opt<std::string> | 159 static cl::opt<std::string> |
152 MainFileName("main-file-name", | 160 MainFileName("main-file-name", |
153 cl::desc("Specifies the name we should consider the input file")); | 161 cl::desc("Specifies the name we should consider the input file")); |
154 | 162 |
155 static cl::opt<bool> SaveTempLabels("save-temp-labels", | 163 static cl::opt<bool> SaveTempLabels("save-temp-labels", |
156 cl::desc("Don't discard temporary labels")); | 164 cl::desc("Don't discard temporary labels")); |
165 | |
166 static cl::opt<bool> LexMasmIntegers( | |
167 "masm-integers", | |
168 cl::desc("Enable binary and hex masm integers (0b110 and 0ABCh)")); | |
157 | 169 |
158 static cl::opt<bool> NoExecStack("no-exec-stack", | 170 static cl::opt<bool> NoExecStack("no-exec-stack", |
159 cl::desc("File doesn't need an exec stack")); | 171 cl::desc("File doesn't need an exec stack")); |
160 | 172 |
161 enum ActionType { | 173 enum ActionType { |
186 // Get the target specific parser. | 198 // Get the target specific parser. |
187 std::string Error; | 199 std::string Error; |
188 const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple, | 200 const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple, |
189 Error); | 201 Error); |
190 if (!TheTarget) { | 202 if (!TheTarget) { |
191 errs() << ProgName << ": " << Error; | 203 WithColor::error(errs(), ProgName) << Error; |
192 return nullptr; | 204 return nullptr; |
193 } | 205 } |
194 | 206 |
195 // Update the triple name and return the found target. | 207 // Update the triple name and return the found target. |
196 TripleName = TheTriple.getTriple(); | 208 TripleName = TheTriple.getTriple(); |
197 return TheTarget; | 209 return TheTarget; |
198 } | 210 } |
199 | 211 |
200 static std::unique_ptr<ToolOutputFile> GetOutputStream() { | 212 static std::unique_ptr<ToolOutputFile> GetOutputStream(StringRef Path) { |
201 if (OutputFilename == "") | |
202 OutputFilename = "-"; | |
203 | |
204 std::error_code EC; | 213 std::error_code EC; |
205 auto Out = | 214 auto Out = llvm::make_unique<ToolOutputFile>(Path, EC, sys::fs::OF_None); |
206 llvm::make_unique<ToolOutputFile>(OutputFilename, EC, sys::fs::F_None); | |
207 if (EC) { | 215 if (EC) { |
208 errs() << EC.message() << '\n'; | 216 WithColor::error() << EC.message() << '\n'; |
209 return nullptr; | 217 return nullptr; |
210 } | 218 } |
211 | 219 |
212 return Out; | 220 return Out; |
213 } | 221 } |
236 AsmLexer Lexer(MAI); | 244 AsmLexer Lexer(MAI); |
237 Lexer.setBuffer(SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer()); | 245 Lexer.setBuffer(SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer()); |
238 | 246 |
239 bool Error = false; | 247 bool Error = false; |
240 while (Lexer.Lex().isNot(AsmToken::Eof)) { | 248 while (Lexer.Lex().isNot(AsmToken::Eof)) { |
241 const AsmToken &Tok = Lexer.getTok(); | 249 Lexer.getTok().dump(OS); |
242 | 250 OS << "\n"; |
243 switch (Tok.getKind()) { | 251 if (Lexer.getTok().getKind() == AsmToken::Error) |
244 default: | |
245 SrcMgr.PrintMessage(Lexer.getLoc(), SourceMgr::DK_Warning, | |
246 "unknown token"); | |
247 Error = true; | 252 Error = true; |
248 break; | |
249 case AsmToken::Error: | |
250 Error = true; // error already printed. | |
251 break; | |
252 case AsmToken::Identifier: | |
253 OS << "identifier: " << Lexer.getTok().getString(); | |
254 break; | |
255 case AsmToken::Integer: | |
256 OS << "int: " << Lexer.getTok().getString(); | |
257 break; | |
258 case AsmToken::Real: | |
259 OS << "real: " << Lexer.getTok().getString(); | |
260 break; | |
261 case AsmToken::String: | |
262 OS << "string: " << Lexer.getTok().getString(); | |
263 break; | |
264 | |
265 case AsmToken::Amp: OS << "Amp"; break; | |
266 case AsmToken::AmpAmp: OS << "AmpAmp"; break; | |
267 case AsmToken::At: OS << "At"; break; | |
268 case AsmToken::Caret: OS << "Caret"; break; | |
269 case AsmToken::Colon: OS << "Colon"; break; | |
270 case AsmToken::Comma: OS << "Comma"; break; | |
271 case AsmToken::Dollar: OS << "Dollar"; break; | |
272 case AsmToken::Dot: OS << "Dot"; break; | |
273 case AsmToken::EndOfStatement: OS << "EndOfStatement"; break; | |
274 case AsmToken::Eof: OS << "Eof"; break; | |
275 case AsmToken::Equal: OS << "Equal"; break; | |
276 case AsmToken::EqualEqual: OS << "EqualEqual"; break; | |
277 case AsmToken::Exclaim: OS << "Exclaim"; break; | |
278 case AsmToken::ExclaimEqual: OS << "ExclaimEqual"; break; | |
279 case AsmToken::Greater: OS << "Greater"; break; | |
280 case AsmToken::GreaterEqual: OS << "GreaterEqual"; break; | |
281 case AsmToken::GreaterGreater: OS << "GreaterGreater"; break; | |
282 case AsmToken::Hash: OS << "Hash"; break; | |
283 case AsmToken::LBrac: OS << "LBrac"; break; | |
284 case AsmToken::LCurly: OS << "LCurly"; break; | |
285 case AsmToken::LParen: OS << "LParen"; break; | |
286 case AsmToken::Less: OS << "Less"; break; | |
287 case AsmToken::LessEqual: OS << "LessEqual"; break; | |
288 case AsmToken::LessGreater: OS << "LessGreater"; break; | |
289 case AsmToken::LessLess: OS << "LessLess"; break; | |
290 case AsmToken::Minus: OS << "Minus"; break; | |
291 case AsmToken::Percent: OS << "Percent"; break; | |
292 case AsmToken::Pipe: OS << "Pipe"; break; | |
293 case AsmToken::PipePipe: OS << "PipePipe"; break; | |
294 case AsmToken::Plus: OS << "Plus"; break; | |
295 case AsmToken::RBrac: OS << "RBrac"; break; | |
296 case AsmToken::RCurly: OS << "RCurly"; break; | |
297 case AsmToken::RParen: OS << "RParen"; break; | |
298 case AsmToken::Slash: OS << "Slash"; break; | |
299 case AsmToken::Star: OS << "Star"; break; | |
300 case AsmToken::Tilde: OS << "Tilde"; break; | |
301 case AsmToken::PercentCall16: | |
302 OS << "PercentCall16"; | |
303 break; | |
304 case AsmToken::PercentCall_Hi: | |
305 OS << "PercentCall_Hi"; | |
306 break; | |
307 case AsmToken::PercentCall_Lo: | |
308 OS << "PercentCall_Lo"; | |
309 break; | |
310 case AsmToken::PercentDtprel_Hi: | |
311 OS << "PercentDtprel_Hi"; | |
312 break; | |
313 case AsmToken::PercentDtprel_Lo: | |
314 OS << "PercentDtprel_Lo"; | |
315 break; | |
316 case AsmToken::PercentGot: | |
317 OS << "PercentGot"; | |
318 break; | |
319 case AsmToken::PercentGot_Disp: | |
320 OS << "PercentGot_Disp"; | |
321 break; | |
322 case AsmToken::PercentGot_Hi: | |
323 OS << "PercentGot_Hi"; | |
324 break; | |
325 case AsmToken::PercentGot_Lo: | |
326 OS << "PercentGot_Lo"; | |
327 break; | |
328 case AsmToken::PercentGot_Ofst: | |
329 OS << "PercentGot_Ofst"; | |
330 break; | |
331 case AsmToken::PercentGot_Page: | |
332 OS << "PercentGot_Page"; | |
333 break; | |
334 case AsmToken::PercentGottprel: | |
335 OS << "PercentGottprel"; | |
336 break; | |
337 case AsmToken::PercentGp_Rel: | |
338 OS << "PercentGp_Rel"; | |
339 break; | |
340 case AsmToken::PercentHi: | |
341 OS << "PercentHi"; | |
342 break; | |
343 case AsmToken::PercentHigher: | |
344 OS << "PercentHigher"; | |
345 break; | |
346 case AsmToken::PercentHighest: | |
347 OS << "PercentHighest"; | |
348 break; | |
349 case AsmToken::PercentLo: | |
350 OS << "PercentLo"; | |
351 break; | |
352 case AsmToken::PercentNeg: | |
353 OS << "PercentNeg"; | |
354 break; | |
355 case AsmToken::PercentPcrel_Hi: | |
356 OS << "PercentPcrel_Hi"; | |
357 break; | |
358 case AsmToken::PercentPcrel_Lo: | |
359 OS << "PercentPcrel_Lo"; | |
360 break; | |
361 case AsmToken::PercentTlsgd: | |
362 OS << "PercentTlsgd"; | |
363 break; | |
364 case AsmToken::PercentTlsldm: | |
365 OS << "PercentTlsldm"; | |
366 break; | |
367 case AsmToken::PercentTprel_Hi: | |
368 OS << "PercentTprel_Hi"; | |
369 break; | |
370 case AsmToken::PercentTprel_Lo: | |
371 OS << "PercentTprel_Lo"; | |
372 break; | |
373 } | |
374 | |
375 // Print the token string. | |
376 OS << " (\""; | |
377 OS.write_escaped(Tok.getString()); | |
378 OS << "\")\n"; | |
379 } | 253 } |
380 | 254 |
381 return Error; | 255 return Error; |
382 } | 256 } |
383 | 257 |
386 auto Pair = StringRef(I).split('='); | 260 auto Pair = StringRef(I).split('='); |
387 auto Sym = Pair.first; | 261 auto Sym = Pair.first; |
388 auto Val = Pair.second; | 262 auto Val = Pair.second; |
389 | 263 |
390 if (Sym.empty() || Val.empty()) { | 264 if (Sym.empty() || Val.empty()) { |
391 errs() << "error: defsym must be of the form: sym=value: " << I << "\n"; | 265 WithColor::error() << "defsym must be of the form: sym=value: " << I |
266 << "\n"; | |
392 return 1; | 267 return 1; |
393 } | 268 } |
394 int64_t Value; | 269 int64_t Value; |
395 if (Val.getAsInteger(0, Value)) { | 270 if (Val.getAsInteger(0, Value)) { |
396 errs() << "error: Value is not an integer: " << Val << "\n"; | 271 WithColor::error() << "value is not an integer: " << Val << "\n"; |
397 return 1; | 272 return 1; |
398 } | 273 } |
399 Parser.getContext().setSymbolValue(Parser.getStreamer(), Sym, Value); | 274 Parser.getContext().setSymbolValue(Parser.getStreamer(), Sym, Value); |
400 } | 275 } |
401 return 0; | 276 return 0; |
402 } | 277 } |
403 | 278 |
404 static int AssembleInput(const char *ProgName, const Target *TheTarget, | 279 static int AssembleInput(const char *ProgName, const Target *TheTarget, |
405 SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str, | 280 SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str, |
406 MCAsmInfo &MAI, MCSubtargetInfo &STI, | 281 MCAsmInfo &MAI, MCSubtargetInfo &STI, |
407 MCInstrInfo &MCII, MCTargetOptions &MCOptions) { | 282 MCInstrInfo &MCII, MCTargetOptions const &MCOptions) { |
408 std::unique_ptr<MCAsmParser> Parser( | 283 std::unique_ptr<MCAsmParser> Parser( |
409 createMCAsmParser(SrcMgr, Ctx, Str, MAI)); | 284 createMCAsmParser(SrcMgr, Ctx, Str, MAI)); |
410 std::unique_ptr<MCTargetAsmParser> TAP( | 285 std::unique_ptr<MCTargetAsmParser> TAP( |
411 TheTarget->createMCAsmParser(STI, *Parser, MCII, MCOptions)); | 286 TheTarget->createMCAsmParser(STI, *Parser, MCII, MCOptions)); |
412 | 287 |
413 if (!TAP) { | 288 if (!TAP) { |
414 errs() << ProgName | 289 WithColor::error(errs(), ProgName) |
415 << ": error: this target does not support assembly parsing.\n"; | 290 << "this target does not support assembly parsing.\n"; |
416 return 1; | 291 return 1; |
417 } | 292 } |
418 | 293 |
419 int SymbolResult = fillCommandLineSymbols(*Parser); | 294 int SymbolResult = fillCommandLineSymbols(*Parser); |
420 if(SymbolResult) | 295 if(SymbolResult) |
421 return SymbolResult; | 296 return SymbolResult; |
422 Parser->setShowParsedOperands(ShowInstOperands); | 297 Parser->setShowParsedOperands(ShowInstOperands); |
423 Parser->setTargetParser(*TAP); | 298 Parser->setTargetParser(*TAP); |
299 Parser->getLexer().setLexMasmIntegers(LexMasmIntegers); | |
424 | 300 |
425 int Res = Parser->Run(NoInitialTextSection); | 301 int Res = Parser->Run(NoInitialTextSection); |
426 | 302 |
427 return Res; | 303 return Res; |
428 } | 304 } |
429 | 305 |
430 int main(int argc, char **argv) { | 306 int main(int argc, char **argv) { |
431 // Print a stack trace if we signal out. | 307 InitLLVM X(argc, argv); |
432 sys::PrintStackTraceOnErrorSignal(argv[0]); | |
433 PrettyStackTraceProgram X(argc, argv); | |
434 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. | |
435 | 308 |
436 // Initialize targets and assembly printers/parsers. | 309 // Initialize targets and assembly printers/parsers. |
437 llvm::InitializeAllTargetInfos(); | 310 llvm::InitializeAllTargetInfos(); |
438 llvm::InitializeAllTargetMCs(); | 311 llvm::InitializeAllTargetMCs(); |
439 llvm::InitializeAllAsmParsers(); | 312 llvm::InitializeAllAsmParsers(); |
441 | 314 |
442 // Register the target printer for --version. | 315 // Register the target printer for --version. |
443 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); | 316 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); |
444 | 317 |
445 cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); | 318 cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); |
446 MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); | 319 const MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); |
447 TripleName = Triple::normalize(TripleName); | |
448 setDwarfDebugFlags(argc, argv); | 320 setDwarfDebugFlags(argc, argv); |
449 | 321 |
450 setDwarfDebugProducer(); | 322 setDwarfDebugProducer(); |
451 | 323 |
452 const char *ProgName = argv[0]; | 324 const char *ProgName = argv[0]; |
458 Triple TheTriple(TripleName); | 330 Triple TheTriple(TripleName); |
459 | 331 |
460 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr = | 332 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr = |
461 MemoryBuffer::getFileOrSTDIN(InputFilename); | 333 MemoryBuffer::getFileOrSTDIN(InputFilename); |
462 if (std::error_code EC = BufferPtr.getError()) { | 334 if (std::error_code EC = BufferPtr.getError()) { |
463 errs() << InputFilename << ": " << EC.message() << '\n'; | 335 WithColor::error(errs(), ProgName) |
336 << InputFilename << ": " << EC.message() << '\n'; | |
464 return 1; | 337 return 1; |
465 } | 338 } |
466 MemoryBuffer *Buffer = BufferPtr->get(); | 339 MemoryBuffer *Buffer = BufferPtr->get(); |
467 | 340 |
468 SourceMgr SrcMgr; | 341 SourceMgr SrcMgr; |
482 | 355 |
483 MAI->setRelaxELFRelocations(RelaxELFRel); | 356 MAI->setRelaxELFRelocations(RelaxELFRel); |
484 | 357 |
485 if (CompressDebugSections != DebugCompressionType::None) { | 358 if (CompressDebugSections != DebugCompressionType::None) { |
486 if (!zlib::isAvailable()) { | 359 if (!zlib::isAvailable()) { |
487 errs() << ProgName | 360 WithColor::error(errs(), ProgName) |
488 << ": build tools with zlib to enable -compress-debug-sections"; | 361 << "build tools with zlib to enable -compress-debug-sections"; |
489 return 1; | 362 return 1; |
490 } | 363 } |
491 MAI->setCompressDebugSections(CompressDebugSections); | 364 MAI->setCompressDebugSections(CompressDebugSections); |
492 } | 365 } |
493 MAI->setPreserveAsmComments(PreserveComments); | 366 MAI->setPreserveAsmComments(PreserveComments); |
494 | 367 |
495 // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and | 368 // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and |
496 // MCObjectFileInfo needs a MCContext reference in order to initialize itself. | 369 // MCObjectFileInfo needs a MCContext reference in order to initialize itself. |
497 MCObjectFileInfo MOFI; | 370 MCObjectFileInfo MOFI; |
498 MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr); | 371 MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr, &MCOptions); |
499 MOFI.InitMCObjectFileInfo(TheTriple, PIC, Ctx, LargeCodeModel); | 372 MOFI.InitMCObjectFileInfo(TheTriple, PIC, Ctx, LargeCodeModel); |
500 | 373 |
501 if (SaveTempLabels) | 374 if (SaveTempLabels) |
502 Ctx.setAllowTemporaryLabels(false); | 375 Ctx.setAllowTemporaryLabels(false); |
503 | 376 |
520 // If no compilation dir is set, try to use the current directory. | 393 // If no compilation dir is set, try to use the current directory. |
521 SmallString<128> CWD; | 394 SmallString<128> CWD; |
522 if (!sys::fs::current_path(CWD)) | 395 if (!sys::fs::current_path(CWD)) |
523 Ctx.setCompilationDir(CWD); | 396 Ctx.setCompilationDir(CWD); |
524 } | 397 } |
398 for (const auto &Arg : DebugPrefixMap) { | |
399 const auto &KV = StringRef(Arg).split('='); | |
400 Ctx.addDebugPrefixMapEntry(KV.first, KV.second); | |
401 } | |
525 if (!MainFileName.empty()) | 402 if (!MainFileName.empty()) |
526 Ctx.setMainFileName(MainFileName); | 403 Ctx.setMainFileName(MainFileName); |
404 if (GenDwarfForAssembly) | |
405 Ctx.setGenDwarfRootFile(InputFilename, Buffer->getBuffer()); | |
527 | 406 |
528 // Package up features to be passed to target/subtarget | 407 // Package up features to be passed to target/subtarget |
529 std::string FeaturesStr; | 408 std::string FeaturesStr; |
530 if (MAttrs.size()) { | 409 if (MAttrs.size()) { |
531 SubtargetFeatures Features; | 410 SubtargetFeatures Features; |
532 for (unsigned i = 0; i != MAttrs.size(); ++i) | 411 for (unsigned i = 0; i != MAttrs.size(); ++i) |
533 Features.AddFeature(MAttrs[i]); | 412 Features.AddFeature(MAttrs[i]); |
534 FeaturesStr = Features.getString(); | 413 FeaturesStr = Features.getString(); |
535 } | 414 } |
536 | 415 |
537 std::unique_ptr<ToolOutputFile> Out = GetOutputStream(); | 416 std::unique_ptr<ToolOutputFile> Out = GetOutputStream(OutputFilename); |
538 if (!Out) | 417 if (!Out) |
539 return 1; | 418 return 1; |
419 | |
420 std::unique_ptr<ToolOutputFile> DwoOut; | |
421 if (!SplitDwarfFile.empty()) { | |
422 if (FileType != OFT_ObjectFile) { | |
423 WithColor::error() << "dwo output only supported with object files\n"; | |
424 return 1; | |
425 } | |
426 DwoOut = GetOutputStream(SplitDwarfFile); | |
427 if (!DwoOut) | |
428 return 1; | |
429 } | |
540 | 430 |
541 std::unique_ptr<buffer_ostream> BOS; | 431 std::unique_ptr<buffer_ostream> BOS; |
542 raw_pwrite_stream *OS = &Out->os(); | 432 raw_pwrite_stream *OS = &Out->os(); |
543 std::unique_ptr<MCStreamer> Str; | 433 std::unique_ptr<MCStreamer> Str; |
544 | 434 |
550 if (FileType == OFT_AssemblyFile) { | 440 if (FileType == OFT_AssemblyFile) { |
551 IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant, | 441 IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant, |
552 *MAI, *MCII, *MRI); | 442 *MAI, *MCII, *MRI); |
553 | 443 |
554 if (!IP) { | 444 if (!IP) { |
555 errs() | 445 WithColor::error() |
556 << "error: unable to create instruction printer for target triple '" | 446 << "unable to create instruction printer for target triple '" |
557 << TheTriple.normalize() << "' with assembly variant " | 447 << TheTriple.normalize() << "' with assembly variant " |
558 << OutputAsmVariant << ".\n"; | 448 << OutputAsmVariant << ".\n"; |
559 return 1; | 449 return 1; |
560 } | 450 } |
561 | 451 |
562 // Set the display preference for hex vs. decimal immediates. | 452 // Set the display preference for hex vs. decimal immediates. |
563 IP->setPrintImmHex(PrintImmHex); | 453 IP->setPrintImmHex(PrintImmHex); |
564 | 454 |
565 // Set up the AsmStreamer. | 455 // Set up the AsmStreamer. |
566 MCCodeEmitter *CE = nullptr; | 456 std::unique_ptr<MCCodeEmitter> CE; |
567 MCAsmBackend *MAB = nullptr; | 457 if (ShowEncoding) |
568 if (ShowEncoding) { | 458 CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx)); |
569 CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); | 459 |
570 MAB = TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions); | 460 std::unique_ptr<MCAsmBackend> MAB( |
571 } | 461 TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions)); |
572 auto FOut = llvm::make_unique<formatted_raw_ostream>(*OS); | 462 auto FOut = llvm::make_unique<formatted_raw_ostream>(*OS); |
573 Str.reset(TheTarget->createAsmStreamer( | 463 Str.reset( |
574 Ctx, std::move(FOut), /*asmverbose*/ true, | 464 TheTarget->createAsmStreamer(Ctx, std::move(FOut), /*asmverbose*/ true, |
575 /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst)); | 465 /*useDwarfDirectory*/ true, IP, |
466 std::move(CE), std::move(MAB), ShowInst)); | |
576 | 467 |
577 } else if (FileType == OFT_Null) { | 468 } else if (FileType == OFT_Null) { |
578 Str.reset(TheTarget->createNullStreamer(Ctx)); | 469 Str.reset(TheTarget->createNullStreamer(Ctx)); |
579 } else { | 470 } else { |
580 assert(FileType == OFT_ObjectFile && "Invalid file type!"); | 471 assert(FileType == OFT_ObjectFile && "Invalid file type!"); |
588 } | 479 } |
589 | 480 |
590 MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); | 481 MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); |
591 MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions); | 482 MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions); |
592 Str.reset(TheTarget->createMCObjectStreamer( | 483 Str.reset(TheTarget->createMCObjectStreamer( |
593 TheTriple, Ctx, std::unique_ptr<MCAsmBackend>(MAB), *OS, | 484 TheTriple, Ctx, std::unique_ptr<MCAsmBackend>(MAB), |
485 DwoOut ? MAB->createDwoObjectWriter(*OS, DwoOut->os()) | |
486 : MAB->createObjectWriter(*OS), | |
594 std::unique_ptr<MCCodeEmitter>(CE), *STI, MCOptions.MCRelaxAll, | 487 std::unique_ptr<MCCodeEmitter>(CE), *STI, MCOptions.MCRelaxAll, |
595 MCOptions.MCIncrementalLinkerCompatible, | 488 MCOptions.MCIncrementalLinkerCompatible, |
596 /*DWARFMustBeAtTheEnd*/ false)); | 489 /*DWARFMustBeAtTheEnd*/ false)); |
597 if (NoExecStack) | 490 if (NoExecStack) |
598 Str->InitSections(true); | 491 Str->InitSections(true); |
599 } | 492 } |
493 | |
494 // Use Assembler information for parsing. | |
495 Str->setUseAssemblerInfoForParsing(true); | |
600 | 496 |
601 int Res = 1; | 497 int Res = 1; |
602 bool disassemble = false; | 498 bool disassemble = false; |
603 switch (Action) { | 499 switch (Action) { |
604 case AC_AsLex: | 500 case AC_AsLex: |
608 Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, | 504 Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, |
609 *MCII, MCOptions); | 505 *MCII, MCOptions); |
610 break; | 506 break; |
611 case AC_MDisassemble: | 507 case AC_MDisassemble: |
612 assert(IP && "Expected assembly output"); | 508 assert(IP && "Expected assembly output"); |
613 IP->setUseMarkup(1); | 509 IP->setUseMarkup(true); |
614 disassemble = true; | 510 disassemble = true; |
615 break; | 511 break; |
616 case AC_Disassemble: | 512 case AC_Disassemble: |
617 disassemble = true; | 513 disassemble = true; |
618 break; | 514 break; |
620 if (disassemble) | 516 if (disassemble) |
621 Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, | 517 Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, |
622 *Buffer, SrcMgr, Out->os()); | 518 *Buffer, SrcMgr, Out->os()); |
623 | 519 |
624 // Keep output if no errors. | 520 // Keep output if no errors. |
625 if (Res == 0) Out->keep(); | 521 if (Res == 0) { |
522 Out->keep(); | |
523 if (DwoOut) | |
524 DwoOut->keep(); | |
525 } | |
626 return Res; | 526 return Res; |
627 } | 527 } |