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 }