diff --git a/llvm/docs/CommandGuide/llvm-objdump.rst b/llvm/docs/CommandGuide/llvm-objdump.rst --- a/llvm/docs/CommandGuide/llvm-objdump.rst +++ b/llvm/docs/CommandGuide/llvm-objdump.rst @@ -179,6 +179,15 @@ * ``att``: x86 only (default). Print in the AT&T syntax. * ``intel``: x86 only. Print in the intel syntax. + +.. option:: --disassembler-color= + + Enable or disable disassembler color output. + + * ``off``: Disable disassembler color output. + * ``on``: Enable disassembler color output. + * ``terminal``: Enable disassembler color output if the terminal supports it (default). + .. option:: --mcpu= Target a specific CPU type for disassembly. Specify ``--mcpu=help`` to display diff --git a/llvm/llvm/llvm/test/tools/llvm-objdump/MachO/arm64-disassembly-color.s b/llvm/llvm/llvm/test/tools/llvm-objdump/MachO/arm64-disassembly-color.s new file mode 100644 --- /dev/null +++ b/llvm/llvm/llvm/test/tools/llvm-objdump/MachO/arm64-disassembly-color.s @@ -0,0 +1,25 @@ +// RUN: llvm-mc -triple arm64-apple-macosx %s -filetype=obj -o %t +// RUN: llvm-objdump --disassembler-color=on --disassemble %t | FileCheck %s --check-prefix=COLOR +// RUN: llvm-objdump --disassembler-color=off --disassemble %t | FileCheck %s --check-prefix=NOCOLOR +// RUN: llvm-objdump --disassembler-color=terminal --disassemble %t | FileCheck %s --check-prefix=NOCOLOR + +sub sp, sp, #16 +str w0, [sp, #12] +ldr w8, [sp, #12] +ldr w9, [sp, #12] +mul w0, w8, w9 +add sp, sp, #16 + +// NOCOLOR: sub sp, sp, #0x10 +// NOCOLOR: str w0, [sp, #0xc] +// NOCOLOR: ldr w8, [sp, #0xc] +// NOCOLOR: ldr w9, [sp, #0xc] +// NOCOLOR: mul w0, w8, w9 +// NOCOLOR: add sp, sp, #0x10 + +// COLOR: sub sp, sp, #0x10 +// COLOR: str w0, [sp, #0xc] +// COLOR: ldr w8, [sp, #0xc] +// COLOR: ldr w9, [sp, #0xc] +// COLOR: mul w0, w8, w9 +// COLOR: add sp, sp, #0x10 diff --git a/llvm/llvm/test/tools/llvm-objdump/MachO/arm64-disassembly-color.s b/llvm/llvm/test/tools/llvm-objdump/MachO/arm64-disassembly-color.s new file mode 100644 --- /dev/null +++ b/llvm/llvm/test/tools/llvm-objdump/MachO/arm64-disassembly-color.s @@ -0,0 +1,25 @@ +// RUN: llvm-mc -triple arm64-apple-macosx %s -filetype=obj -o %t +// RUN: llvm-objdump --disassembler-color=on --disassemble %t | FileCheck %s --check-prefix=COLOR +// RUN: llvm-objdump --disassembler-color=off --disassemble %t | FileCheck %s --check-prefix=NOCOLOR +// RUN: llvm-objdump --disassembler-color=terminal --disassemble %t | FileCheck %s --check-prefix=NOCOLOR + +sub sp, sp, #16 +str w0, [sp, #12] +ldr w8, [sp, #12] +ldr w9, [sp, #12] +mul w0, w8, w9 +add sp, sp, #16 + +// NOCOLOR: sub sp, sp, #0x10 +// NOCOLOR: str w0, [sp, #0xc] +// NOCOLOR: ldr w8, [sp, #0xc] +// NOCOLOR: ldr w9, [sp, #0xc] +// NOCOLOR: mul w0, w8, w9 +// NOCOLOR: add sp, sp, #0x10 + +// COLOR: sub sp, sp, #0x10 +// COLOR: str w0, [sp, #0xc] +// COLOR: ldr w8, [sp, #0xc] +// COLOR: ldr w9, [sp, #0xc] +// COLOR: mul w0, w8, w9 +// COLOR: add sp, sp, #0x10 diff --git a/llvm/test/tools/llvm-objdump/MachO/arm64-disassembly-color.s b/llvm/test/tools/llvm-objdump/MachO/arm64-disassembly-color.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/MachO/arm64-disassembly-color.s @@ -0,0 +1,25 @@ +// RUN: llvm-mc -triple arm64-apple-macosx %s -filetype=obj -o %t +// RUN: llvm-objdump --disassembler-color=on --disassemble %t | FileCheck %s --check-prefix=COLOR +// RUN: llvm-objdump --disassembler-color=off --disassemble %t | FileCheck %s --check-prefix=NOCOLOR +// RUN: llvm-objdump --disassembler-color=terminal --disassemble %t | FileCheck %s --check-prefix=NOCOLOR + +sub sp, sp, #16 +str w0, [sp, #12] +ldr w8, [sp, #12] +ldr w9, [sp, #12] +mul w0, w8, w9 +add sp, sp, #16 + +// NOCOLOR: sub sp, sp, #0x10 +// NOCOLOR: str w0, [sp, #0xc] +// NOCOLOR: ldr w8, [sp, #0xc] +// NOCOLOR: ldr w9, [sp, #0xc] +// NOCOLOR: mul w0, w8, w9 +// NOCOLOR: add sp, sp, #0x10 + +// COLOR: sub sp, sp, #0x10 +// COLOR: str w0, [sp, #0xc] +// COLOR: ldr w8, [sp, #0xc] +// COLOR: ldr w9, [sp, #0xc] +// COLOR: mul w0, w8, w9 +// COLOR: add sp, sp, #0x10 diff --git a/llvm/tools/llvm-objdump/ObjdumpOpts.td b/llvm/tools/llvm-objdump/ObjdumpOpts.td --- a/llvm/tools/llvm-objdump/ObjdumpOpts.td +++ b/llvm/tools/llvm-objdump/ObjdumpOpts.td @@ -87,6 +87,11 @@ def : JoinedOrSeparate<["-"], "M">, Alias, HelpText<"Alias for --disassembler-options=">; +def disassembler_color_EQ : Joined<["--"], "disassembler-color=">, + MetaVarName<"mode">, + HelpText<"Enable or disable disassembler color output. " + "Valid options are \"on\", \"off\" and \"terminal\" (default)">; + def dynamic_reloc : Flag<["--"], "dynamic-reloc">, HelpText<"Display the dynamic relocation entries in the file">; def : Flag<["-"], "R">, Alias, diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -177,6 +177,13 @@ #define DEBUG_TYPE "objdump" +enum class ColorOutput { + Auto, + Enable, + Disable, + Invalid, +}; + static uint64_t AdjustVMA; static bool AllHeaders; static std::string ArchName; @@ -189,6 +196,7 @@ static std::vector DisassembleSymbols; static bool DisassembleZeroes; static std::vector DisassemblerOptions; +static ColorOutput DisassemblyColor; DIDumpType objdump::DwarfDumpType; static bool DynamicRelocations; static bool FaultMapSection; @@ -900,6 +908,19 @@ InstPrinter->setPrintBranchImmAsAddress(true); InstPrinter->setSymbolizeOperands(SymbolizeOperands); InstPrinter->setMCInstrAnalysis(InstrAnalysis.get()); + + switch (DisassemblyColor) { + case ColorOutput::Enable: + InstPrinter->setUseColor(true); + break; + case ColorOutput::Auto: + InstPrinter->setUseColor(outs().has_colors()); + break; + case ColorOutput::Disable: + case ColorOutput::Invalid: + InstPrinter->setUseColor(false); + break; + }; } DisassemblerTarget::DisassemblerTarget(DisassemblerTarget &Other, @@ -1900,6 +1921,13 @@ formatted_raw_ostream FOS(outs()); + // FIXME: Workaround for bug in formatted_raw_ostream. Color escape codes + // are (incorrectly) written directly to the unbuffered raw_ostream + // wrapped by the formatted_raw_ostream. + if (DisassemblyColor == ColorOutput::Enable || + DisassemblyColor == ColorOutput::Auto) + FOS.SetUnbuffered(); + std::unordered_map AllLabels; std::unordered_map> BBAddrMapLabels; if (SymbolizeOperands) { @@ -3193,6 +3221,16 @@ if (DbgVariables == DVInvalid) invalidArgValue(A); } + if (const opt::Arg *A = InputArgs.getLastArg(OBJDUMP_disassembler_color_EQ)) { + DisassemblyColor = StringSwitch(A->getValue()) + .Case("on", ColorOutput::Enable) + .Case("off", ColorOutput::Disable) + .Case("terminal", ColorOutput::Auto) + .Default(ColorOutput::Invalid); + if (DisassemblyColor == ColorOutput::Invalid) + invalidArgValue(A); + } + parseIntArg(InputArgs, OBJDUMP_debug_vars_indent_EQ, DbgIndent); parseMachOOptions(InputArgs);