diff options
author | Maciej W. Rozycki <macro@mips.com> | 2018-07-02 23:57:21 +0100 |
---|---|---|
committer | Maciej W. Rozycki <macro@mips.com> | 2018-07-02 23:57:21 +0100 |
commit | 471b9d15076fffb738f1bc6fcea41d0dcb59c947 (patch) | |
tree | 2d57149ea32d39c1e8922e2644641e55aa672b8b /opcodes | |
parent | b638b5d57fafc84a8dc0ff91d7579a3c24aad90c (diff) | |
download | gdb-471b9d15076fffb738f1bc6fcea41d0dcb59c947.zip gdb-471b9d15076fffb738f1bc6fcea41d0dcb59c947.tar.gz gdb-471b9d15076fffb738f1bc6fcea41d0dcb59c947.tar.bz2 |
GDB PR tdep/8282: MIPS: Wire in `set disassembler-options'
Implement MIPS target support for passing options to the disassembler,
complementing commit 65b48a81404c ("GDB: Add support for the new
set/show disassembler-options commands.").
This includes options that expect an argument, so adjust the generic
code and data structures used so as to handle such options. So as to
give backends syntax flexibility no specific delimiter has been defined
to separate options from their respective arguments, so it has to be
included as the last character of the option name. Completion code
however has not been adjusted and consequently option arguments cannot
be completed at this time.
Also the MIPS target has non-empty defaults for the options, so that ABI
names for the general-purpose registers respect our `set mips abi ...'
setting rather than always being determined from the ELF headers of the
binary file selected. Handle these defaults as implicit options, never
shown to the user and always prepended to the user-specified options, so
that the latters can override the defaults.
The resulting output for the MIPS target is as follows:
(gdb) show disassembler-options
The current disassembler options are ''
The following disassembler options are supported for use with the
'set disassembler-options <option>[,<option>...]' command:
no-aliases Use canonical instruction forms.
msa Recognize MSA instructions.
virt Recognize the virtualization ASE instructions.
xpa Recognize the eXtended Physical Address (XPA) ASE
instructions.
ginv Recognize the Global INValidate (GINV) ASE instructions.
gpr-names=ABI Print GPR names according to specified ABI.
Default: based on binary being disassembled.
fpr-names=ABI Print FPR names according to specified ABI.
Default: numeric.
cp0-names=ARCH Print CP0 register names according to specified architecture.
Default: based on binary being disassembled.
hwr-names=ARCH Print HWR names according to specified architecture.
Default: based on binary being disassembled.
reg-names=ABI Print GPR and FPR names according to specified ABI.
reg-names=ARCH Print CP0 register and HWR names according to specified
architecture.
For the options above, the following values are supported for "ABI":
numeric 32 n32 64
For the options above, the following values are supported for "ARCH":
numeric r3000 r3900 r4000 r4010 vr4100 vr4111 vr4120 r4300 r4400 r4600
r4650 r5000 vr5400 vr5500 r5900 r6000 rm7000 rm9000 r8000 r10000 r12000
r14000 r16000 mips5 mips32 mips32r2 mips32r3 mips32r5 mips32r6 mips64
mips64r2 mips64r3 mips64r5 mips64r6 interaptiv-mr2 sb1 loongson2e
loongson2f loongson3a octeon octeon+ octeon2 octeon3 xlr xlp
(gdb)
which corresponds to what `objdump --help' used to print for the MIPS
target, with minor formatting changes, most notably option argument
lists being wrapped, but also the amount of white space separating
options from the respective descriptions. The relevant part the new
code is now also used by `objdump --help', which means these formatting
changes apply to both outputs, except for argument list wrapping, which
is GDB-specific.
This also adds a separating new line between the heading and option
lists where descriptions are provided, hence:
(gdb) set architecture s390:31-bit
(gdb) show disassembler-options
The current disassembler options are ''
The following disassembler options are supported for use with the
'set disassembler-options <option>[,<option>...]' command:
esa Disassemble in ESA architecture mode
zarch Disassemble in z/Architecture mode
insnlength Print unknown instructions according to length from first two bits
(gdb)
but:
(gdb) set architecture powerpc:common
(gdb) show disassembler-options
The current disassembler options are ''
The following disassembler options are supported for use with the
'set disassembler-options <option>[,<option>...]' command:
403, 405, 440, 464, 476, 601, 603, 604, 620, 7400, 7410, 7450, 7455, 750cl,
821, 850, 860, a2, altivec, any, booke, booke32, cell, com, e200z4, e300,
e500, e500mc, e500mc64, e5500, e6500, e500x2, efs, efs2, power4, power5,
power6, power7, power8, power9, ppc, ppc32, 32, ppc64, 64, ppc64bridge,
ppcps, pwr, pwr2, pwr4, pwr5, pwr5x, pwr6, pwr7, pwr8, pwr9, pwrx, raw, spe,
spe2, titan, vle, vsx
(gdb)
Existing affected target backends have been adjusted accordingly.
This has been verified manually with:
(gdb) set architecture arm
(gdb) set architecture powerpc:common
(gdb) set architecture s390:31-bit
to cause no issues with the `show disassembler-options' and `set
disassembler-options' commands. A test case for the MIPS target has
also been provided, covering the default settings with ABI overrides as
well as disassembler option overrides.
2018-07-02 Maciej W. Rozycki <macro@mips.com>
Simon Marchi <simon.marchi@polymtl.ca>
include/
PR tdep/8282
* dis-asm.h (disasm_option_arg_t): New typedef.
(disasm_options_and_args_t): Likewise.
(disasm_options_t): Add `arg' member, document members.
(disassembler_options_mips): New prototype.
(disassembler_options_arm, disassembler_options_powerpc)
(disassembler_options_s390): Update prototypes.
opcodes/
PR tdep/8282
* mips-dis.c (mips_option_arg_t): New enumeration.
(mips_options): New variable.
(disassembler_options_mips): New function.
(print_mips_disassembler_options): Reimplement in terms of
`disassembler_options_mips'.
* arm-dis.c (disassembler_options_arm): Adapt to using the
`disasm_options_and_args_t' structure.
* ppc-dis.c (disassembler_options_powerpc): Likewise.
* s390-dis.c (disassembler_options_s390): Likewise.
gdb/
PR tdep/8282
* disasm.h (gdb_disassembler): Add
`m_disassembler_options_holder'. member
* disasm.c (get_all_disassembler_options): New function.
(gdb_disassembler::gdb_disassembler): Use it.
(gdb_buffered_insn_length_init_dis): Likewise.
(gdb_buffered_insn_length): Adjust accordingly.
(set_disassembler_options): Handle options with arguments.
(show_disassembler_options_sfunc): Likewise. Add a leading new
line if showing options with descriptions.
(disassembler_options_completer): Adapt to using the
`disasm_options_and_args_t' structure.
* mips-tdep.c (mips_disassembler_options): New variable.
(mips_disassembler_options_o32): Likewise.
(mips_disassembler_options_n32): Likewise.
(mips_disassembler_options_n64): Likewise.
(gdb_print_insn_mips): Don't set `disassembler_options'.
(gdb_print_insn_mips_n32, gdb_print_insn_mips_n64): Remove
functions.
(mips_gdbarch_init): Always set `gdbarch_print_insn' to
`gdb_print_insn_mips'. Set `gdbarch_disassembler_options',
`gdbarch_disassembler_options_implicit' and
`gdbarch_valid_disassembler_options'.
* arm-tdep.c (_initialize_arm_tdep): Adapt to using the
`disasm_options_and_args_t' structure.
* gdbarch.sh (disassembler_options_implicit): New `gdbarch'
method.
(valid_disassembler_options): Switch from `disasm_options_t' to
the `disasm_options_and_args_t' structure.
* NEWS: Document `set disassembler-options' support for the MIPS
target.
* gdbarch.h: Regenerate.
* gdbarch.c: Regenerate.
gdb/doc/
PR tdep/8282
* gdb.texinfo (Source and Machine Code): Document `set
disassembler-options' support for the MIPS target.
gdb/testsuite/
PR tdep/8282
* gdb.arch/mips-disassembler-options.exp: New test.
* gdb.arch/mips-disassembler-options.s: New test source.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 13 | ||||
-rw-r--r-- | opcodes/arm-dis.c | 16 | ||||
-rw-r--r-- | opcodes/mips-dis.c | 210 | ||||
-rw-r--r-- | opcodes/ppc-dis.c | 18 | ||||
-rw-r--r-- | opcodes/s390-dis.c | 16 |
5 files changed, 205 insertions, 68 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index fdc0e44..149737e 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,16 @@ +2018-07-02 Maciej W. Rozycki <macro@mips.com> + + PR tdep/8282 + * mips-dis.c (mips_option_arg_t): New enumeration. + (mips_options): New variable. + (disassembler_options_mips): New function. + (print_mips_disassembler_options): Reimplement in terms of + `disassembler_options_mips'. + * arm-dis.c (disassembler_options_arm): Adapt to using the + `disasm_options_and_args_t' structure. + * ppc-dis.c (disassembler_options_powerpc): Likewise. + * s390-dis.c (disassembler_options_s390): Likewise. + 2018-07-02 Thomas Preud'homme <thomas.preudhomme@arm.com> * testsuite/ld-arm/tls-descrelax-be8.d: Add architecture version in diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index da28837..8bcec13 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -6850,17 +6850,23 @@ print_insn_little_arm (bfd_vma pc, struct disassemble_info *info) return print_insn (pc, info, TRUE); } -const disasm_options_t * +const disasm_options_and_args_t * disassembler_options_arm (void) { - static disasm_options_t *opts = NULL; + static disasm_options_and_args_t *opts_and_args; - if (opts == NULL) + if (opts_and_args == NULL) { + disasm_options_t *opts; unsigned int i; - opts = XNEW (disasm_options_t); + + opts_and_args = XNEW (disasm_options_and_args_t); + opts_and_args->args = NULL; + + opts = &opts_and_args->options; opts->name = XNEWVEC (const char *, NUM_ARM_OPTIONS + 1); opts->description = XNEWVEC (const char *, NUM_ARM_OPTIONS + 1); + opts->arg = NULL; for (i = 0; i < NUM_ARM_OPTIONS; i++) { opts->name[i] = regnames[i].name; @@ -6874,7 +6880,7 @@ disassembler_options_arm (void) opts->description[i] = NULL; } - return opts; + return opts_and_args; } void diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c index 4938f90..bbf2132 100644 --- a/opcodes/mips-dis.c +++ b/opcodes/mips-dis.c @@ -2552,72 +2552,178 @@ print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info) return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE); } -void -print_mips_disassembler_options (FILE *stream) +/* Indices into option argument vector for options accepting an argument. + Use MIPS_OPTION_ARG_NONE for options accepting no argument. */ +typedef enum { - unsigned int i; - - fprintf (stream, _("\n\ -The following MIPS specific disassembler options are supported for use\n\ -with the -M switch (multiple options should be separated by commas):\n")); - - fprintf (stream, _("\n\ - no-aliases Use canonical instruction forms.\n")); + MIPS_OPTION_ARG_NONE = -1, + MIPS_OPTION_ARG_ABI, + MIPS_OPTION_ARG_ARCH, + MIPS_OPTION_ARG_SIZE +} mips_option_arg_t; + +/* Valid MIPS disassembler options. */ +static struct +{ + const char *name; + const char *description; + mips_option_arg_t arg; +} mips_options[] = +{ + { "no-aliases", N_("Use canonical instruction forms.\n"), + MIPS_OPTION_ARG_NONE }, + { "msa", N_("Recognize MSA instructions.\n"), + MIPS_OPTION_ARG_NONE }, + { "virt", N_("Recognize the virtualization ASE instructions.\n"), + MIPS_OPTION_ARG_NONE }, + { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\ + instructions.\n"), + MIPS_OPTION_ARG_NONE }, + { "ginv", N_("Recognize the Global INValidate (GINV) ASE " + "instructions.\n"), + MIPS_OPTION_ARG_NONE }, + { "gpr-names=", N_("Print GPR names according to specified ABI.\n\ + Default: based on binary being disassembled.\n"), + MIPS_OPTION_ARG_ABI }, + { "fpr-names=", N_("Print FPR names according to specified ABI.\n\ + Default: numeric.\n"), + MIPS_OPTION_ARG_ABI }, + { "cp0-names=", N_("Print CP0 register names according to specified " + "architecture.\n\ + Default: based on binary being disassembled.\n"), + MIPS_OPTION_ARG_ARCH }, + { "hwr-names=", N_("Print HWR names according to specified architecture.\n\ + Default: based on binary being disassembled.\n"), + MIPS_OPTION_ARG_ARCH }, + { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"), + MIPS_OPTION_ARG_ABI }, + { "reg-names=", N_("Print CP0 register and HWR names according to " + "specified\n\ + architecture."), + MIPS_OPTION_ARG_ARCH } +}; - fprintf (stream, _("\n\ - msa Recognize MSA instructions.\n")); +/* Build the structure representing valid MIPS disassembler options. + This is done dynamically for maintenance ease purpose; a static + initializer would be unreadable. */ - fprintf (stream, _("\n\ - virt Recognize the virtualization ASE instructions.\n")); +const disasm_options_and_args_t * +disassembler_options_mips (void) +{ + static disasm_options_and_args_t *opts_and_args; - fprintf (stream, _("\n\ - xpa Recognize the eXtended Physical Address (XPA)\n\ - ASE instructions.\n")); + if (opts_and_args == NULL) + { + size_t num_options = ARRAY_SIZE (mips_options); + size_t num_args = MIPS_OPTION_ARG_SIZE; + disasm_option_arg_t *args; + disasm_options_t *opts; + size_t i; + size_t j; + + args = XNEWVEC (disasm_option_arg_t, num_args + 1); + + args[MIPS_OPTION_ARG_ABI].name = "ABI"; + args[MIPS_OPTION_ARG_ABI].values + = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1); + for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++) + args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name; + /* The array we return must be NULL terminated. */ + args[MIPS_OPTION_ARG_ABI].values[i] = NULL; + + args[MIPS_OPTION_ARG_ARCH].name = "ARCH"; + args[MIPS_OPTION_ARG_ARCH].values + = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1); + for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++) + if (*mips_arch_choices[i].name != '\0') + args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name; + /* The array we return must be NULL terminated. */ + args[MIPS_OPTION_ARG_ARCH].values[j] = NULL; + + /* The array we return must be NULL terminated. */ + args[MIPS_OPTION_ARG_SIZE].name = NULL; + args[MIPS_OPTION_ARG_SIZE].values = NULL; + + opts_and_args = XNEW (disasm_options_and_args_t); + opts_and_args->args = args; + + opts = &opts_and_args->options; + opts->name = XNEWVEC (const char *, num_options + 1); + opts->description = XNEWVEC (const char *, num_options + 1); + opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1); + for (i = 0; i < num_options; i++) + { + opts->name[i] = mips_options[i].name; + opts->description[i] = _(mips_options[i].description); + if (mips_options[i].arg != MIPS_OPTION_ARG_NONE) + opts->arg[i] = &args[mips_options[i].arg]; + else + opts->arg[i] = NULL; + } + /* The array we return must be NULL terminated. */ + opts->name[i] = NULL; + opts->description[i] = NULL; + opts->arg[i] = NULL; + } - fprintf (stream, _("\n\ - ginv Recognize the Global INValidate (GINV) ASE\n\ - instructions.\n")); + return opts_and_args; +} - fprintf (stream, _("\n\ - gpr-names=ABI Print GPR names according to specified ABI.\n\ - Default: based on binary being disassembled.\n")); +void +print_mips_disassembler_options (FILE *stream) +{ + const disasm_options_and_args_t *opts_and_args; + const disasm_option_arg_t *args; + const disasm_options_t *opts; + size_t max_len = 0; + size_t i; + size_t j; - fprintf (stream, _("\n\ - fpr-names=ABI Print FPR names according to specified ABI.\n\ - Default: numeric.\n")); + opts_and_args = disassembler_options_mips (); + opts = &opts_and_args->options; + args = opts_and_args->args; fprintf (stream, _("\n\ - cp0-names=ARCH Print CP0 register names according to\n\ - specified architecture.\n\ - Default: based on binary being disassembled.\n")); +The following MIPS specific disassembler options are supported for use\n\ +with the -M switch (multiple options should be separated by commas):\n\n")); - fprintf (stream, _("\n\ - hwr-names=ARCH Print HWR names according to specified \n\ - architecture.\n\ - Default: based on binary being disassembled.\n")); + /* Compute the length of the longest option name. */ + for (i = 0; opts->name[i] != NULL; i++) + { + size_t len = strlen (opts->name[i]); - fprintf (stream, _("\n\ - reg-names=ABI Print GPR and FPR names according to\n\ - specified ABI.\n")); + if (opts->arg[i] != NULL) + len += strlen (opts->arg[i]->name); + if (max_len < len) + max_len = len; + } - fprintf (stream, _("\n\ - reg-names=ARCH Print CP0 register and HWR names according to\n\ - specified architecture.\n")); + for (i = 0, max_len++; opts->name[i] != NULL; i++) + { + fprintf (stream, " %s", opts->name[i]); + if (opts->arg[i] != NULL) + fprintf (stream, "%s", opts->arg[i]->name); + if (opts->description[i] != NULL) + { + size_t len = strlen (opts->name[i]); - fprintf (stream, _("\n\ - For the options above, the following values are supported for \"ABI\":\n\ - ")); - for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++) - fprintf (stream, " %s", mips_abi_choices[i].name); - fprintf (stream, _("\n")); + if (opts->arg[i] != NULL) + len += strlen (opts->arg[i]->name); + fprintf (stream, + "%*c %s", (int) (max_len - len), ' ', opts->description[i]); + } + fprintf (stream, _("\n")); + } - fprintf (stream, _("\n\ - For the options above, The following values are supported for \"ARCH\":\n\ - ")); - for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++) - if (*mips_arch_choices[i].name != '\0') - fprintf (stream, " %s", mips_arch_choices[i].name); - fprintf (stream, _("\n")); + for (i = 0; args[i].name != NULL; i++) + { + fprintf (stream, _("\n\ + For the options above, the following values are supported for \"%s\":\n "), + args[i].name); + for (j = 0; args[i].values[j] != NULL; j++) + fprintf (stream, " %s", args[i].values[j]); + fprintf (stream, _("\n")); + } fprintf (stream, _("\n")); } diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c index 43f4ce8..bd6072e 100644 --- a/opcodes/ppc-dis.c +++ b/opcodes/ppc-dis.c @@ -810,24 +810,30 @@ print_insn_powerpc (bfd_vma memaddr, return 4; } -const disasm_options_t * +const disasm_options_and_args_t * disassembler_options_powerpc (void) { - static disasm_options_t *opts = NULL; + static disasm_options_and_args_t *opts_and_args; - if (opts == NULL) + if (opts_and_args == NULL) { size_t i, num_options = ARRAY_SIZE (ppc_opts); - opts = XNEW (disasm_options_t); + disasm_options_t *opts; + + opts_and_args = XNEW (disasm_options_and_args_t); + opts_and_args->args = NULL; + + opts = &opts_and_args->options; opts->name = XNEWVEC (const char *, num_options + 1); + opts->description = NULL; + opts->arg = NULL; for (i = 0; i < num_options; i++) opts->name[i] = ppc_opts[i].opt; /* The array we return must be NULL terminated. */ opts->name[i] = NULL; - opts->description = NULL; } - return opts; + return opts_and_args; } void diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c index 6763d9f..79d9f53 100644 --- a/opcodes/s390-dis.c +++ b/opcodes/s390-dis.c @@ -379,17 +379,23 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info) return 0; } -const disasm_options_t * +const disasm_options_and_args_t * disassembler_options_s390 (void) { - static disasm_options_t *opts = NULL; + static disasm_options_and_args_t *opts_and_args; - if (opts == NULL) + if (opts_and_args == NULL) { size_t i, num_options = ARRAY_SIZE (options); - opts = XNEW (disasm_options_t); + disasm_options_t *opts; + + opts_and_args = XNEW (disasm_options_and_args_t); + opts_and_args->args = NULL; + + opts = &opts_and_args->options; opts->name = XNEWVEC (const char *, num_options + 1); opts->description = XNEWVEC (const char *, num_options + 1); + opts->arg = NULL; for (i = 0; i < num_options; i++) { opts->name[i] = options[i].name; @@ -400,7 +406,7 @@ disassembler_options_s390 (void) opts->description[i] = NULL; } - return opts; + return opts_and_args; } void |