-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[llvm-objdump] Fix coloring with nested WithMarkup #113834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[llvm-objdump] Fix coloring with nested WithMarkup #113834
Conversation
Created using spr 1.3.5-bogner
|
@llvm/pr-subscribers-mc @llvm/pr-subscribers-llvm-binary-utilities Author: Fangrui Song (MaskRay) ChangesWithMarkup objects may nest, resulting in the To ensure that Full diff: https://github.com/llvm/llvm-project/pull/113834.diff 3 Files Affected:
diff --git a/llvm/include/llvm/MC/MCInstPrinter.h b/llvm/include/llvm/MC/MCInstPrinter.h
index 60a901e3d0deae..c296a6fe1c045d 100644
--- a/llvm/include/llvm/MC/MCInstPrinter.h
+++ b/llvm/include/llvm/MC/MCInstPrinter.h
@@ -9,8 +9,10 @@
#ifndef LLVM_MC_MCINSTPRINTER_H
#define LLVM_MC_MCINSTPRINTER_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
#include <cstdint>
namespace llvm {
@@ -24,7 +26,6 @@ class MCRegister;
class MCRegisterInfo;
class MCSubtargetInfo;
class StringRef;
-class raw_ostream;
/// Convert `Bytes' to a hex string and output to `OS'
void dumpBytes(ArrayRef<uint8_t> Bytes, raw_ostream &OS);
@@ -76,6 +77,8 @@ class MCInstPrinter {
/// If true, symbolize branch target and memory reference operands.
bool SymbolizeOperands = false;
+ SmallVector<raw_ostream::Colors, 4> ColorStack{raw_ostream::Colors::RESET};
+
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
@@ -98,8 +101,8 @@ class MCInstPrinter {
class WithMarkup {
public:
- LLVM_CTOR_NODISCARD WithMarkup(raw_ostream &OS, Markup M, bool EnableMarkup,
- bool EnableColor);
+ LLVM_CTOR_NODISCARD WithMarkup(MCInstPrinter &IP, raw_ostream &OS, Markup M,
+ bool EnableMarkup, bool EnableColor);
~WithMarkup();
template <typename T> WithMarkup &operator<<(T &O) {
@@ -113,6 +116,7 @@ class MCInstPrinter {
}
private:
+ MCInstPrinter &IP;
raw_ostream &OS;
bool EnableMarkup;
bool EnableColor;
diff --git a/llvm/lib/MC/MCInstPrinter.cpp b/llvm/lib/MC/MCInstPrinter.cpp
index e4faeba04a8fd7..a57f4e19c81c6b 100644
--- a/llvm/lib/MC/MCInstPrinter.cpp
+++ b/llvm/lib/MC/MCInstPrinter.cpp
@@ -226,27 +226,32 @@ format_object<uint64_t> MCInstPrinter::formatHex(uint64_t Value) const {
MCInstPrinter::WithMarkup MCInstPrinter::markup(raw_ostream &OS,
Markup S) const {
- return WithMarkup(OS, S, getUseMarkup(), getUseColor());
+ return WithMarkup(const_cast<MCInstPrinter &>(*this), OS, S, getUseMarkup(),
+ getUseColor());
}
-MCInstPrinter::WithMarkup::WithMarkup(raw_ostream &OS, Markup M,
- bool EnableMarkup, bool EnableColor)
- : OS(OS), EnableMarkup(EnableMarkup), EnableColor(EnableColor) {
+MCInstPrinter::WithMarkup::WithMarkup(MCInstPrinter &IP, raw_ostream &OS,
+ Markup M, bool EnableMarkup,
+ bool EnableColor)
+ : IP(IP), OS(OS), EnableMarkup(EnableMarkup), EnableColor(EnableColor) {
if (EnableColor) {
+ raw_ostream::Colors Color = raw_ostream::Colors::RESET;
switch (M) {
case Markup::Immediate:
- OS.changeColor(raw_ostream::RED);
+ Color = raw_ostream::RED;
break;
case Markup::Register:
- OS.changeColor(raw_ostream::CYAN);
+ Color = raw_ostream::CYAN;
break;
case Markup::Target:
- OS.changeColor(raw_ostream::YELLOW);
+ Color = raw_ostream::YELLOW;
break;
case Markup::Memory:
- OS.changeColor(raw_ostream::GREEN);
+ Color = raw_ostream::GREEN;
break;
}
+ IP.ColorStack.push_back(Color);
+ OS.changeColor(Color);
}
if (EnableMarkup) {
@@ -270,6 +275,8 @@ MCInstPrinter::WithMarkup::WithMarkup(raw_ostream &OS, Markup M,
MCInstPrinter::WithMarkup::~WithMarkup() {
if (EnableMarkup)
OS << '>';
- if (EnableColor)
- OS.resetColor();
+ if (!EnableColor)
+ return;
+ IP.ColorStack.pop_back();
+ OS << IP.ColorStack.back();
}
diff --git a/llvm/test/tools/llvm-objdump/X86/disassemble-color.s b/llvm/test/tools/llvm-objdump/X86/disassemble-color.s
new file mode 100644
index 00000000000000..4e1d82562fb546
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/X86/disassemble-color.s
@@ -0,0 +1,21 @@
+# UNSUPPORTED: system-windows
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t
+# RUN: llvm-objdump -d --no-show-raw-insn --disassembler-color=on %t | FileCheck %s --check-prefix=ATT
+# RUN: llvm-objdump -d --no-show-raw-insn --disassembler-color=on -M intel %t | FileCheck %s --check-prefix=INTEL
+
+# ATT: <.text>:
+# ATT-NEXT: leaq �[0;32m(�[0;36m%rdx�[0;32m,�[0;36m%rax�[0;32m,�[0;31m4�[0;32m)�[0m, �[0;36m%rbx�[0m
+# ATT-NEXT: movq �[0;32m(,�[0;36m%rax�[0;32m)�[0m, �[0;36m%rbx�[0m
+# ATT-NEXT: leaq �[0;32m0x3(�[0;36m%rdx�[0;32m,�[0;36m%rax�[0;32m)�[0m, �[0;36m%rbx�[0m
+# ATT-NEXT: movq �[0;31m$0x3�[0m, �[0;36m%rax�[0m
+
+# INTEL: <.text>:
+# INTEL-NEXT: lea �[0;36mrbx�[0m, �[0;32m[�[0;36mrdx�[0;32m + 4*�[0;36mrax�[0;32m]�[0m
+# INTEL-NEXT: mov �[0;36mrbx�[0m, qword ptr �[0;32m[1*�[0;36mrax�[0;32m]�[0m
+# INTEL-NEXT: lea �[0;36mrbx�[0m, �[0;32m[�[0;36mrdx�[0;32m + �[0;36mrax�[0;32m + �[0;31m0x3�[0;32m]�[0m
+# INTEL-NEXT: mov �[0;36mrax�[0m, �[0;31m0x3�[0m
+
+leaq (%rdx,%rax,4), %rbx
+movq (,%rax), %rbx
+leaq 3(%rdx,%rax), %rbx
+movq $3, %rax
|
llvm/lib/MC/MCInstPrinter.cpp
Outdated
| MCInstPrinter::WithMarkup MCInstPrinter::markup(raw_ostream &OS, | ||
| Markup S) const { | ||
| return WithMarkup(OS, S, getUseMarkup(), getUseColor()); | ||
| return WithMarkup(const_cast<MCInstPrinter &>(*this), OS, S, getUseMarkup(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall approach looks fine, but this does feel a bit like an abuse of const. Could const be dropped from the markup method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many const methods transitively call the const markup. If we want to drop const_cast here, many target functions printXXX will need be adjusted...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yuck, okay. I think that's probably still the "right" thing to do (after all you're modifying the state of the class when calling these methods in this manner). But I acknowledge that's probably a bit impractical too, so if you add a TODO comment here instead, I'd be happy with that.
I also considered making the ColorStack member mutable, but that doesn't really feel any better than the const_cast in this context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Migrated printRegName users. Dropped const_cast now.
llvm/lib/MC/MCInstPrinter.cpp
Outdated
| MCInstPrinter::WithMarkup MCInstPrinter::markup(raw_ostream &OS, | ||
| Markup S) const { | ||
| return WithMarkup(OS, S, getUseMarkup(), getUseColor()); | ||
| return WithMarkup(const_cast<MCInstPrinter &>(*this), OS, S, getUseMarkup(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yuck, okay. I think that's probably still the "right" thing to do (after all you're modifying the state of the class when calling these methods in this manner). But I acknowledge that's probably a bit impractical too, so if you add a TODO comment here instead, I'd be happy with that.
I also considered making the ColorStack member mutable, but that doesn't really feel any better than the const_cast in this context.
|
Thank you for fixing this |
Similar to printInst. printRegName may change states (e.g. #113834).
Created using spr 1.3.5-bogner
Similar to printInst. printRegName may change states (e.g. llvm#113834).
WithMarkup objects may nest, resulting in the `)` in `leaq
(%rdx,%rax), %rbx` to be green instead of the default color,
mismatching the color of `(`.
```
% llvm-mc -triple=x86_64 -mdis <<< '0x48 0x8d 0x1c 0x02'
.text
leaq <mem:(<reg:%rdx>,<reg:%rax>)>, <reg:%rbx>
```
To ensure that `(` and `)` get the same color, maintain a color stack
within MCInstPrinter.
Fix llvm#99661
Pull Request: llvm#113834
WithMarkup objects may nest, resulting in the
)inleaq (%rdx,%rax), %rbxto be green instead of the default color,mismatching the color of
(.To ensure that
(and)get the same color, maintain a color stackwithin MCInstPrinter.
Fix #99661