summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2022-04-28 13:31:07 +0100
committerAndrew Burgess <aburgess@redhat.com>2022-07-29 13:58:32 +0100
commit76a4c1e063fabb45d15597a6dd17813e92875a43 (patch)
tree6ffa0f49d408e3c15031aa5dc9c99573d492c05d /include
parentb44cfc5de139d7e2410e91846df0f0164d663d0b (diff)
libopcodes/aarch64: add support for disassembler styling
This commit enables disassembler styling for AArch64. After this commit it is possible to have objdump style AArch64 disassembler output (using --disassembler-color option). Once the required GDB patches are merged, GDB will also style the disassembler output. The changes to support styling are mostly split between two files opcodes/aarch64-dis.c and opcodes/aarch64-opc.c. The entry point for the AArch64 disassembler can be found in aarch64-dis.c, this file handles printing the instruction mnemonics, and assembler directives (e.g. '.byte', '.word', etc). Some operands, mostly relating to assembler directives are also printed from this file. This commit changes all of this to pass through suitable styling information. However, for most "normal" instructions, the instruction operands are printed using a two step process. From aarch64-dis.c, in the print_operands function, the function aarch64_print_operand is called, this function is in aarch64-opc.c, and converts an instruction operand into a string. Then, back in print_operands (aarch64-dis.c), the operand string is printed. Unfortunately, the string returned by aarch64_print_operand can be quite complex, it will include syntax elements, like '[' and ']', in addition to register names and immediate values. In some cases, a single operand will expand into what will appear (to the user) as multiple operands separated with a ','. This makes the task of styling more complex, all these different components need to by styled differently, so we need to get the styling information out of aarch64_print_operand in some way. The solution that I propose here is similar to the solution that I used for the i386 disassembler. Currently, aarch64_print_operand uses snprintf to write the operand text into a buffer provided by the caller. What I propose is that we pass an extra argument to the aarch64_print_operand function, this argument will be a structure, the structure contains a callback function and some state. When aarch64_print_operand needs to format part of its output this can be done by using the callback function within the new structure, this callback returns a string with special embedded markers that indicate which mode should be used for each piece of text. Back in aarch64-dis.c we can spot these special style markers and use this to split the disassembler output up and apply the correct style to each piece. To make aarch64-opc.c clearer a series of new static functions have been added, e.g. 'style_reg', 'style_imm', etc. Each of these functions formats a piece of text in a different style, 'register' and 'immediate' in this case. Here's an example taken from aarch64-opc.c of the new functions in use: snprintf (buf, size, "[%s, %s]!", style_reg (styler, base), style_imm (styler, "#%d", opnd->addr.offset.imm)); The aarch64_print_operand function is also called from the assembler to aid in printing diagnostic messages. Right now I have no plans to add styling to the assembler output, and so, the callback function used in the assembler ignores the styling information and just returns an plain string. I've used the source files in gas/testsuite/gas/aarch64/ for testing, and have manually gone through and checked that the styling looks reasonable, however, I'm not an AArch64 expert, so it is possible that the odd piece is styled incorrectly. Please point out any mistakes I've made. With objdump disassembler color turned off, there should be no change in the output after this commit.
Diffstat (limited to 'include')
-rw-r--r--include/opcode/aarch64.h28
1 files changed, 27 insertions, 1 deletions
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 186ba9a480..9477ac98f3 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -27,6 +27,8 @@
#include <assert.h>
#include <stdlib.h>
+#include "dis-asm.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -1367,12 +1369,36 @@ aarch64_replace_opcode (struct aarch64_inst *,
extern const aarch64_opcode *
aarch64_get_opcode (enum aarch64_op);
+/* An instance of this structure is passed to aarch64_print_operand, and
+ the callback within this structure is used to apply styling to the
+ disassembler output. This structure encapsulates the callback and a
+ state pointer. */
+
+struct aarch64_styler
+{
+ /* The callback used to apply styling. Returns a string created from FMT
+ and ARGS with STYLE applied to the string. STYLER is a pointer back
+ to this object so that the callback can access the state member.
+
+ The string returned from this callback must remain valid until the
+ call to aarch64_print_operand has completed. */
+ const char *(*apply_style) (struct aarch64_styler *styler,
+ enum disassembler_style style,
+ const char *fmt,
+ va_list args);
+
+ /* A pointer to a state object which can be used by the apply_style
+ callback function. */
+ void *state;
+};
+
/* Generate the string representation of an operand. */
extern void
aarch64_print_operand (char *, size_t, bfd_vma, const aarch64_opcode *,
const aarch64_opnd_info *, int, int *, bfd_vma *,
char **, char *, size_t,
- aarch64_feature_set features);
+ aarch64_feature_set features,
+ struct aarch64_styler *styler);
/* Miscellaneous interface. */