From patchwork Fri Feb 24 05:02:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Bergner X-Patchwork-Id: 19363 Received: (qmail 112167 invoked by alias); 24 Feb 2017 05:02:50 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 112127 invoked by uid 89); 24 Feb 2017 05:02:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS, UNSUBSCRIBE_BODY autolearn=unavailable version=3.3.2 spammy= X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 24 Feb 2017 05:02:17 +0000 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v1O514Xf013753 for ; Fri, 24 Feb 2017 00:02:16 -0500 Received: from e35.co.us.ibm.com (e35.co.us.ibm.com [32.97.110.153]) by mx0a-001b2d01.pphosted.com with ESMTP id 28t61rj7en-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 24 Feb 2017 00:02:12 -0500 Received: from localhost by e35.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 23 Feb 2017 22:02:11 -0700 Received: from d03dlp01.boulder.ibm.com (9.17.202.177) by e35.co.us.ibm.com (192.168.1.135) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 23 Feb 2017 22:02:08 -0700 Received: from b03cxnp07028.gho.boulder.ibm.com (b03cxnp07028.gho.boulder.ibm.com [9.17.130.15]) by d03dlp01.boulder.ibm.com (Postfix) with ESMTP id 233911FF0029; Thu, 23 Feb 2017 22:01:45 -0700 (MST) Received: from b03ledav004.gho.boulder.ibm.com (b03ledav004.gho.boulder.ibm.com [9.17.130.235]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v1O51sKN12452322; Thu, 23 Feb 2017 22:02:07 -0700 Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AA07978037; Thu, 23 Feb 2017 22:02:07 -0700 (MST) Received: from otta.local (unknown [9.85.168.217]) by b03ledav004.gho.boulder.ibm.com (Postfix) with ESMTP id A6C6B78038; Thu, 23 Feb 2017 22:02:05 -0700 (MST) To: gdb-patches@sourceware.org, Pedro Alves Cc: binutils , Alan Modra , Yao Qi , Ulrich Weigand From: Peter Bergner Subject: [PATCH, v18] Add support for setting disassembler-options in GDB for POWER, ARM and S390 Date: Thu, 23 Feb 2017 23:02:05 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:45.0) Gecko/20100101 Thunderbird/45.7.1 MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 17022405-0012-0000-0000-000013C244B1 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00006672; HX=3.00000240; KW=3.00000007; PH=3.00000004; SC=3.00000204; SDB=6.00826293; UDB=6.00404678; IPR=6.00603744; BA=6.00005168; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00014420; XFM=3.00000011; UTC=2017-02-24 05:02:10 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17022405-0013-0000-0000-00004BB3ED12 Message-Id: <3b452b44-43a9-75fe-2d4a-e32f17d86fa9@vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-02-24_03:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1702240051 X-IsSubscribed: yes Here is the 18th version of the patch that fixes the issues that Pedro found in v17. Pedro, how does this look now? Peter include/ * dis-asm.h (disasm_options_t): New typedef. (parse_arm_disassembler_option): Remove prototype. (set_arm_regname_option): Likewise. (get_arm_regnames): Likewise. (get_arm_regname_num_options): Likewise. (disassemble_init_s390): New prototype. (disassembler_options_powerpc): Likewise. (disassembler_options_arm): Likewise. (disassembler_options_s390): Likewise. (remove_whitespace_and_extra_commas): Likewise. (disassembler_options_cmp): Likewise. (next_disassembler_option): New inline function. (FOR_EACH_DISASSEMBLER_OPTION): New macro. opcodes/ * disassemble.c Include "safe-ctype.h". (disassemble_init_for_target): Handle s390 init. (remove_whitespace_and_extra_commas): New function. (disassembler_options_cmp): Likewise. * arm-dis.c: Include "libiberty.h". (NUM_ELEM): Delete. (regnames): Use long disassembler style names. Add force-thumb and no-force-thumb options. (NUM_ARM_REGNAMES): Rename from this... (NUM_ARM_OPTIONS): ...to this. Use ARRAY_SIZE. (get_arm_regname_num_options): Delete. (set_arm_regname_option): Likewise. (get_arm_regnames): Likewise. (parse_disassembler_options): Likewise. (parse_arm_disassembler_option): Rename from this... (parse_arm_disassembler_options): ...to this. Make static. Use new FOR_EACH_DISASSEMBLER_OPTION macro to scan over options. (print_insn): Use parse_arm_disassembler_options. (disassembler_options_arm): New function. (print_arm_disassembler_options): Handle updated regnames. * ppc-dis.c: Include "libiberty.h". (ppc_opts): Add "32" and "64" entries. (ppc_parse_cpu): Use ARRAY_SIZE and disassembler_options_cmp. (powerpc_init_dialect): Add break to switch statement. Use new FOR_EACH_DISASSEMBLER_OPTION macro. (disassembler_options_powerpc): New function. (print_ppc_disassembler_options): Use ARRAY_SIZE. Remove printing of "32" and "64". * s390-dis.c: Include "libiberty.h". (init_flag): Remove unneeded variable. (struct s390_options_t): New structure type. (options): New structure. (init_disasm): Rename from this... (disassemble_init_s390): ...to this. Add initializations for current_arch_mask and option_use_insn_len_bits_p. Remove init_flag. (print_insn_s390): Delete call to init_disasm. (disassembler_options_s390): New function. (print_s390_disassembler_options): Print using information from struct 'options'. * po/opcodes.pot: Regenerate. binutils/ * objdump.c (main): Use remove_whitespace_and_extra_commas. gdb/ * NEWS: Mention new set/show disassembler-options commands. * doc/gdb.texinfo: Document new set/show disassembler-options commands. * disasm.c: Include "arch-utils.h", "gdbcmd.h" and "safe-ctype.h". (prospective_options): New static variable. (gdb_disassembler::gdb_disassembler): Initialize m_di.disassembler_options. (gdb_buffered_insn_length_init_dis): Initilize di->disassembler_options. (get_disassembler_options): New function. (set_disassembler_options): Likewise. (set_disassembler_options_sfunc): Likewise. (show_disassembler_options_sfunc): Likewise. (disassembler_options_completer): Likewise. (_initialize_disasm): Likewise. * disasm.h (get_disassembler_options): New prototype. (set_disassembler_options): Likewise. * gdbarch.sh (gdbarch_disassembler_options): New variable. (gdbarch_verify_disassembler_options): Likewise. * gdbarch.c: Regenerate. * gdbarch.h: Likewise. * arm-tdep.c (num_disassembly_options): Delete. (set_disassembly_style): Likewise. (arm_disassembler_options): New static variable. (set_disassembly_style_sfunc): Convert short style name into long option name. Call set_disassembler_options. (show_disassembly_style_sfunc): New function. (arm_gdbarch_init): Call set_gdbarch_disassembler_options and set_gdbarch_verify_disassembler_options. (_initialize_arm_tdep): Delete regnames variable and update callers. (arm_disassembler_options): Initialize. (disasm_options): New variable. (num_disassembly_options): Rename from this... (num_disassembly_styles): ...to this. Compute by scanning through disasm_options. (valid_disassembly_styles): Initialize using disasm_options. Remove calls to parse_arm_disassembler_option, get_arm_regnames and set_arm_regname_option. Pass show_disassembly_style_sfunc to the "disassembler" setshow command. * rs6000-tdep.c (powerpc_disassembler_options): New static variable. (rs6000_gdbarch_init): Call set_gdbarch_disassembler_options and set_gdbarch_verify_disassembler_options. * s390-tdep.c (s390_disassembler_options): New static variable. (s390_gdbarch_init):all set_gdbarch_disassembler_options and set_gdbarch_verify_disassembler_options. gdb/testsuite/ * gdb.arch/powerpc-power.exp: Delete test. * gdb.arch/powerpc-power.s: Likewise. * gdb.disasm/disassembler-options.exp: New test. * gdb.arch/powerpc-altivec.exp: Likewise. * gdb.arch/powerpc-altivec.s: Likewise. * gdb.arch/powerpc-altivec2.exp: Likewise. * gdb.arch/powerpc-altivec2.s: Likewise. * gdb.arch/powerpc-altivec3.exp: Likewise. * gdb.arch/powerpc-altivec3.s: Likewise. * gdb.arch/powerpc-power7.exp: Likewise. * gdb.arch/powerpc-power7.s: Likewise. * gdb.arch/powerpc-power8.exp: Likewise. * gdb.arch/powerpc-power8.s: Likewise. * gdb.arch/powerpc-power9.exp: Likewise. * gdb.arch/powerpc-power9.s: Likewise. * gdb.arch/powerpc-vsx.exp: Likewise. * gdb.arch/powerpc-vsx.s: Likewise. * gdb.arch/powerpc-vsx2.exp: Likewise. * gdb.arch/powerpc-vsx2.s: Likewise. * gdb.arch/powerpc-vsx3.exp: Likewise. * gdb.arch/powerpc-vsx3.s: Likewise. * gdb.arch/arm-disassembler-options.exp: Likewise. * gdb.arch/powerpc-disassembler-options.exp: Likewise. * gdb.arch/s390-disassembler-options.exp: Likewise. diff --git a/include/dis-asm.h b/include/dis-asm.h index 4872920..f054450 100644 --- a/include/dis-asm.h +++ b/include/dis-asm.h @@ -222,6 +222,16 @@ typedef struct disassemble_info } disassemble_info; +/* This struct is used to pass information about valid disassembler options + and their descriptions from the target to the generic GDB functions that + set and display them. */ + +typedef struct +{ + const char **name; + const char **description; +} disasm_options_t; + /* Standard disassemblers. Disassemble one instruction at the given target address. Return number of octets processed. */ @@ -332,14 +342,14 @@ extern void print_ppc_disassembler_options (FILE *); extern void print_riscv_disassembler_options (FILE *); extern void print_arm_disassembler_options (FILE *); extern void print_arc_disassembler_options (FILE *); -extern void parse_arm_disassembler_option (char *); extern void print_s390_disassembler_options (FILE *); -extern int get_arm_regname_num_options (void); -extern int set_arm_regname_option (int); -extern int get_arm_regnames (int, const char **, const char **, const char *const **); extern bfd_boolean aarch64_symbol_is_valid (asymbol *, struct disassemble_info *); extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *); extern void disassemble_init_powerpc (struct disassemble_info *); +extern void disassemble_init_s390 (struct disassemble_info *); +extern const disasm_options_t *disassembler_options_powerpc (void); +extern const disasm_options_t *disassembler_options_arm (void); +extern const disasm_options_t *disassembler_options_s390 (void); /* Fetch the disassembler for a given BFD, if that support is available. */ extern disassembler_ftype disassembler (bfd *); @@ -351,6 +361,29 @@ extern void disassemble_init_for_target (struct disassemble_info * dinfo); /* Document any target specific options available from the disassembler. */ extern void disassembler_usage (FILE *); +/* Remove whitespace and consecutive commas. */ +extern char *remove_whitespace_and_extra_commas (char *); + +/* Like STRCMP, but treat ',' the same as '\0' so that we match + strings like "foobar" against "foobar,xxyyzz,...". */ +extern int disassembler_options_cmp (const char *, const char *); + +/* A helper function for FOR_EACH_DISASSEMBLER_OPTION. */ +static inline char * +next_disassembler_option (char *options) +{ + char *opt = strchr (options, ','); + if (opt != NULL) + opt++; + return opt; +} + +/* A macro for iterating over each comma separated option in OPTIONS. */ +#define FOR_EACH_DISASSEMBLER_OPTION(OPT, OPTIONS) \ + for ((OPT) = (OPTIONS); \ + (OPT) != NULL; \ + (OPT) = next_disassembler_option (OPT)) + /* This block of definitions is for particular callers who read instructions into a buffer before calling the instruction decoder. */ diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c index 1b15242..eef0658 100644 --- a/opcodes/disassemble.c +++ b/opcodes/disassemble.c @@ -20,6 +20,7 @@ #include "sysdep.h" #include "dis-asm.h" +#include "safe-ctype.h" #ifdef ARCH_all #define ARCH_aarch64 @@ -649,7 +650,76 @@ disassemble_init_for_target (struct disassemble_info * info) disassemble_init_powerpc (info); break; #endif +#ifdef ARCH_s390 + case bfd_arch_s390: + disassemble_init_s390 (info); + break; +#endif default: break; } } + +/* Remove whitespace and consecutive commas from OPTIONS. */ + +char * +remove_whitespace_and_extra_commas (char *options) +{ + char *str; + size_t i, len; + + if (options == NULL) + return NULL; + + /* Strip off all trailing whitespace and commas. */ + for (len = strlen (options); len > 0; len--) + { + if (!ISSPACE (options[len - 1]) && options[len - 1] != ',') + break; + options[len - 1] = '\0'; + } + + /* Convert all remaining whitespace to commas. */ + for (i = 0; options[i] != '\0'; i++) + if (ISSPACE (options[i])) + options[i] = ','; + + /* Remove consecutive commas. */ + for (str = options; *str != '\0'; str++) + if (*str == ',' && (*(str + 1) == ',' || str == options)) + { + char *next = str + 1; + while (*next == ',') + next++; + len = strlen (next); + if (str != options) + str++; + memmove (str, next, len); + next[len - (size_t)(next - str)] = '\0'; + } + return (strlen (options) != 0) ? options : NULL; +} + +/* Like STRCMP, but treat ',' the same as '\0' so that we match + strings like "foobar" against "foobar,xxyyzz,...". */ + +int +disassembler_options_cmp (const char *s1, const char *s2) +{ + unsigned char c1, c2; + + do + { + c1 = (unsigned char) *s1++; + if (c1 == ',') + c1 = '\0'; + c2 = (unsigned char) *s2++; + if (c2 == ',') + c2 = '\0'; + if (c1 == '\0') + return c1 - c2; + } + while (c1 == c2); + + return c1 - c2; +} diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 2987403..e4f99b8 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -26,6 +26,7 @@ #include "opcode/arm.h" #include "opintl.h" #include "safe-ctype.h" +#include "libiberty.h" #include "floatformat.h" /* FIXME: This shouldn't be done here. */ @@ -41,10 +42,6 @@ #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) #endif -#ifndef NUM_ELEM -#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) -#endif - /* Cached mapping symbol state. */ enum map_type { @@ -3198,18 +3195,20 @@ arm_regname; static const arm_regname regnames[] = { - { "raw" , "Select raw register names", + { "reg-names-raw", N_("Select raw register names"), { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}, - { "gcc", "Select register names used by GCC", + { "reg-names-gcc", N_("Select register names used by GCC"), { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }}, - { "std", "Select register names used in ARM's ISA documentation", + { "reg-names-std", N_("Select register names used in ARM's ISA documentation"), { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }}, - { "apcs", "Select register names used in the APCS", + { "force-thumb", N_("Assume all insns are Thumb insns"), {NULL} }, + { "no-force-thumb", N_("Examine preceding label to determine an insn's type"), {NULL} }, + { "reg-names-apcs", N_("Select register names used in the APCS"), { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }}, - { "atpcs", "Select register names used in the ATPCS", + { "reg-names-atpcs", N_("Select register names used in the ATPCS"), { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }}, - { "special-atpcs", "Select special register names used in the ATPCS", - { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}, + { "reg-names-special-atpcs", N_("Select special register names used in the ATPCS"), + { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }} }; static const char *const iwmmxt_wwnames[] = @@ -3235,7 +3234,7 @@ static const char *const iwmmxt_cregnames[] = /* Default to GCC register name set. */ static unsigned int regname_selected = 1; -#define NUM_ARM_REGNAMES NUM_ELEM (regnames) +#define NUM_ARM_OPTIONS ARRAY_SIZE (regnames) #define arm_regnames regnames[regname_selected].reg_names static bfd_boolean force_thumb = FALSE; @@ -3254,31 +3253,6 @@ static bfd_vma ifthen_address; /* Functions. */ -int -get_arm_regname_num_options (void) -{ - return NUM_ARM_REGNAMES; -} - -int -set_arm_regname_option (int option) -{ - int old = regname_selected; - regname_selected = option; - return old; -} - -int -get_arm_regnames (int option, - const char **setname, - const char **setdescription, - const char *const **register_names) -{ - *setname = regnames[option].name; - *setdescription = regnames[option].description; - *register_names = regnames[option].reg_names; - return 16; -} /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?. Returns pointer to following character of the format string and @@ -6124,64 +6098,39 @@ arm_symbol_is_valid (asymbol * sym, return (name && *name != '$' && strncmp (name, "__tagsym$$", 10)); } -/* Parse an individual disassembler option. */ +/* Parse the string of disassembler options. */ -void -parse_arm_disassembler_option (char *option) +static void +parse_arm_disassembler_options (char *options) { - if (option == NULL) - return; + char *opt; - if (CONST_STRNEQ (option, "reg-names-")) + FOR_EACH_DISASSEMBLER_OPTION (opt, options) { - int i; - - option += 10; - - for (i = NUM_ARM_REGNAMES; i--;) - if (strneq (option, regnames[i].name, strlen (regnames[i].name))) - { - regname_selected = i; - break; - } + if (CONST_STRNEQ (opt, "reg-names-")) + { + unsigned int i; + for (i = 0; i < NUM_ARM_OPTIONS; i++) + if (disassembler_options_cmp (opt, regnames[i].name) == 0) + { + regname_selected = i; + break; + } - if (i < 0) - /* XXX - should break 'option' at following delimiter. */ - fprintf (stderr, _("Unrecognised register name set: %s\n"), option); + if (i >= NUM_ARM_OPTIONS) + fprintf (stderr, _("Unrecognised register name set: %s\n"), opt); + } + else if (CONST_STRNEQ (opt, "force-thumb")) + force_thumb = 1; + else if (CONST_STRNEQ (opt, "no-force-thumb")) + force_thumb = 0; + else + fprintf (stderr, _("Unrecognised disassembler option: %s\n"), opt); } - else if (CONST_STRNEQ (option, "force-thumb")) - force_thumb = 1; - else if (CONST_STRNEQ (option, "no-force-thumb")) - force_thumb = 0; - else - /* XXX - should break 'option' at following delimiter. */ - fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option); return; } -/* Parse the string of disassembler options, spliting it at whitespaces - or commas. (Whitespace separators supported for backwards compatibility). */ - -static void -parse_disassembler_options (char *options) -{ - if (options == NULL) - return; - - while (*options) - { - parse_arm_disassembler_option (options); - - /* Skip forward to next seperator. */ - while ((*options) && (! ISSPACE (*options)) && (*options != ',')) - ++ options; - /* Skip forward past seperators. */ - while (ISSPACE (*options) || (*options == ',')) - ++ options; - } -} - static bfd_boolean mapping_symbol_for_insn (bfd_vma pc, struct disassemble_info *info, enum map_type *map_symbol); @@ -6473,7 +6422,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little) if (info->disassembler_options) { - parse_disassembler_options (info->disassembler_options); + parse_arm_disassembler_options (info->disassembler_options); /* To avoid repeated parsing of these options, we remove them here. */ info->disassembler_options = NULL; @@ -6842,21 +6791,51 @@ print_insn_little_arm (bfd_vma pc, struct disassemble_info *info) return print_insn (pc, info, TRUE); } +const disasm_options_t * +disassembler_options_arm (void) +{ + static disasm_options_t *opts = NULL; + + if (opts == NULL) + { + unsigned int i; + opts = XNEW (disasm_options_t); + opts->name = XNEWVEC (const char *, NUM_ARM_OPTIONS + 1); + opts->description = XNEWVEC (const char *, NUM_ARM_OPTIONS + 1); + for (i = 0; i < NUM_ARM_OPTIONS; i++) + { + opts->name[i] = regnames[i].name; + if (regnames[i].description != NULL) + opts->description[i] = _(regnames[i].description); + else + opts->description[i] = NULL; + } + /* The array we return must be NULL terminated. */ + opts->name[i] = NULL; + opts->description[i] = NULL; + } + + return opts; +} + void print_arm_disassembler_options (FILE *stream) { - int i; - + unsigned int i, max_len = 0; fprintf (stream, _("\n\ The following ARM specific disassembler options are supported for use with\n\ the -M switch:\n")); - for (i = NUM_ARM_REGNAMES; i--;) - fprintf (stream, " reg-names-%s %*c%s\n", - regnames[i].name, - (int)(14 - strlen (regnames[i].name)), ' ', - regnames[i].description); + for (i = 0; i < NUM_ARM_OPTIONS; i++) + { + unsigned int len = strlen (regnames[i].name); + if (max_len < len) + max_len = len; + } - fprintf (stream, " force-thumb Assume all insns are Thumb insns\n"); - fprintf (stream, " no-force-thumb Examine preceding label to determine an insn's type\n\n"); + for (i = 0, max_len++; i < NUM_ARM_OPTIONS; i++) + fprintf (stream, " %s%*c %s\n", + regnames[i].name, + (int)(max_len - strlen (regnames[i].name)), ' ', + _(regnames[i].description)); } diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c index e0eff7a..3f8aef8 100644 --- a/opcodes/ppc-dis.c +++ b/opcodes/ppc-dis.c @@ -26,6 +26,7 @@ #include "elf/ppc.h" #include "opintl.h" #include "opcode/ppc.h" +#include "libiberty.h" /* This file provides several disassembler functions, all of which use the disassembler interface defined in dis-asm.h. Several functions @@ -172,8 +173,12 @@ struct ppc_mopt ppc_opts[] = { 0 }, { "ppc32", PPC_OPCODE_PPC, 0 }, + { "32", PPC_OPCODE_PPC, + 0 }, { "ppc64", PPC_OPCODE_PPC | PPC_OPCODE_64, 0 }, + { "64", PPC_OPCODE_PPC | PPC_OPCODE_64, + 0 }, { "ppc64bridge", PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE, 0 }, { "ppcps", PPC_OPCODE_PPC | PPC_OPCODE_PPCPS, @@ -252,8 +257,8 @@ ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg) { unsigned int i; - for (i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++) - if (strcmp (ppc_opts[i].opt, arg) == 0) + for (i = 0; i < ARRAY_SIZE (ppc_opts); i++) + if (disassembler_options_cmp (ppc_opts[i].opt, arg) == 0) { if (ppc_opts[i].sticky) { @@ -264,7 +269,7 @@ ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg) ppc_cpu = ppc_opts[i].cpu; break; } - if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0])) + if (i >= ARRAY_SIZE (ppc_opts)) return 0; ppc_cpu |= *sticky; @@ -278,7 +283,6 @@ powerpc_init_dialect (struct disassemble_info *info) { ppc_cpu_t dialect = 0; ppc_cpu_t sticky = 0; - char *arg; struct dis_private *priv = calloc (sizeof (*priv), 1); if (priv == NULL) @@ -324,29 +328,22 @@ powerpc_init_dialect (struct disassemble_info *info) break; default: dialect = ppc_parse_cpu (dialect, &sticky, "power9") | PPC_OPCODE_ANY; + break; } - arg = info->disassembler_options; - while (arg != NULL) + char *opt; + FOR_EACH_DISASSEMBLER_OPTION (opt, info->disassembler_options) { ppc_cpu_t new_cpu = 0; - char *end = strchr (arg, ','); - - if (end != NULL) - *end = 0; - if ((new_cpu = ppc_parse_cpu (dialect, &sticky, arg)) != 0) - dialect = new_cpu; - else if (strcmp (arg, "32") == 0) + if (disassembler_options_cmp (opt, "32") == 0) dialect &= ~(ppc_cpu_t) PPC_OPCODE_64; - else if (strcmp (arg, "64") == 0) + else if (disassembler_options_cmp (opt, "64") == 0) dialect |= PPC_OPCODE_64; + else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0) + dialect = new_cpu; else - fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), arg); - - if (end != NULL) - *end++ = ','; - arg = end; + fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), opt); } info->private_data = priv; @@ -767,6 +764,26 @@ print_insn_powerpc (bfd_vma memaddr, return 4; } +const disasm_options_t * +disassembler_options_powerpc (void) +{ + static disasm_options_t *opts = NULL; + + if (opts == NULL) + { + size_t i, num_options = ARRAY_SIZE (ppc_opts); + opts = XNEW (disasm_options_t); + opts->name = XNEWVEC (const char *, num_options + 1); + 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; +} + void print_ppc_disassembler_options (FILE *stream) { @@ -776,7 +793,7 @@ print_ppc_disassembler_options (FILE *stream) The following PPC specific disassembler options are supported for use with\n\ the -M switch:\n")); - for (col = 0, i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++) + for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++) { col += fprintf (stream, " %s,", ppc_opts[i].opt); if (col > 66) @@ -785,5 +802,5 @@ the -M switch:\n")); col = 0; } } - fprintf (stream, " 32, 64\n"); + fprintf (stream, "\n"); } diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c index 328ba2d..2d97a2a 100644 --- a/opcodes/s390-dis.c +++ b/opcodes/s390-dis.c @@ -25,16 +25,30 @@ #include "dis-asm.h" #include "opintl.h" #include "opcode/s390.h" +#include "libiberty.h" -static int init_flag = 0; static int opc_index[256]; static int current_arch_mask = 0; static int option_use_insn_len_bits_p = 0; +typedef struct +{ + const char *name; + const char *description; +} s390_options_t; + +static const s390_options_t options[] = +{ + { "esa" , N_("Disassemble in ESA architecture mode") }, + { "zarch", N_("Disassemble in z/Architecture mode") }, + { "insnlength", N_("Print unknown instructions according to " + "length from first two bits") } +}; + /* Set up index table for first opcode byte. */ -static void -init_disasm (struct disassemble_info *info) +void +disassemble_init_s390 (struct disassemble_info *info) { int i; const char *p; @@ -46,6 +60,9 @@ init_disasm (struct disassemble_info *info) for (i = s390_num_opcodes; i--; ) opc_index[s390_opcodes[i].opcode[0]] = i; + current_arch_mask = 1 << S390_OPCODE_ZARCH; + option_use_insn_len_bits_p = 0; + for (p = info->disassembler_options; p != NULL; ) { if (CONST_STRNEQ (p, "esa")) @@ -61,11 +78,6 @@ init_disasm (struct disassemble_info *info) if (p != NULL) p++; } - - if (!current_arch_mask) - current_arch_mask = 1 << S390_OPCODE_ZARCH; - - init_flag = 1; } /* Derive the length of an instruction from its first byte. */ @@ -266,9 +278,6 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info) unsigned int value; int status, opsize, bufsize, bytes_to_dump, i; - if (init_flag == 0) - init_disasm (info); - /* The output looks better if we put 6 bytes on a line. */ info->bytes_per_line = 6; @@ -360,15 +369,48 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info) return 0; } +const disasm_options_t * +disassembler_options_s390 (void) +{ + static disasm_options_t *opts = NULL; + + if (opts == NULL) + { + size_t i, num_options = ARRAY_SIZE (options); + opts = XNEW (disasm_options_t); + opts->name = XNEWVEC (const char *, num_options + 1); + opts->description = XNEWVEC (const char *, num_options + 1); + for (i = 0; i < num_options; i++) + { + opts->name[i] = options[i].name; + opts->description[i] = _(options[i].description); + } + /* The array we return must be NULL terminated. */ + opts->name[i] = NULL; + opts->description[i] = NULL; + } + + return opts; +} + void print_s390_disassembler_options (FILE *stream) { + unsigned int i, max_len = 0; fprintf (stream, _("\n\ The following S/390 specific disassembler options are supported for use\n\ with the -M switch (multiple options should be separated by commas):\n")); - fprintf (stream, _(" esa Disassemble in ESA architecture mode\n")); - fprintf (stream, _(" zarch Disassemble in z/Architecture mode\n")); - fprintf (stream, _(" insnlength Print unknown instructions according " - "to length from first two bits\n")); + for (i = 0; i < ARRAY_SIZE (options); i++) + { + unsigned int len = strlen (options[i].name); + if (max_len < len) + max_len = len; + } + + for (i = 0, max_len++; i < ARRAY_SIZE (options); i++) + fprintf (stream, " %s%*c %s\n", + options[i].name, + (int)(max_len - strlen (options[i].name)), ' ', + _(options[i].description)); } diff --git a/opcodes/po/opcodes.pot b/opcodes/po/opcodes.pot index 56c7a23..e64a678 100644 --- a/opcodes/po/opcodes.pot +++ b/opcodes/po/opcodes.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: bug-binutils@gnu.org\n" -"POT-Creation-Date: 2016-12-23 09:23+0100\n" +"POT-Creation-Date: 2017-02-08 13:38-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,8 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. Invalid option. -#. XXX - should break 'option' at following delimiter. -#: aarch64-dis.c:81 arc-dis.c:699 arm-dis.c:6158 +#: aarch64-dis.c:81 arc-dis.c:769 arm-dis.c:6158 #, c-format msgid "Unrecognised disassembler option: %s\n" msgstr "" @@ -54,7 +53,7 @@ msgid "" msgstr "" #: aarch64-dis.c:3215 mips-dis.c:2477 mips-dis.c:2485 mips-dis.c:2487 -#: riscv-dis.c:505 +#: riscv-dis.c:506 #, c-format msgid "\n" msgstr "" @@ -262,7 +261,7 @@ msgstr "" msgid "jump hint unaligned" msgstr "" -#: arc-dis.c:323 +#: arc-dis.c:368 msgid "" "\n" "Warning: disassembly may be wrong due to guessed opcode class choice.\n" @@ -270,7 +269,7 @@ msgid "" "\t\t\t\t" msgstr "" -#: arc-dis.c:1182 +#: arc-dis.c:1267 #, c-format msgid "" "\n" @@ -278,37 +277,37 @@ msgid "" "with -M switch (multiple options should be separated by commas):\n" msgstr "" -#: arc-dis.c:1186 +#: arc-dis.c:1271 #, c-format msgid " dsp Recognize DSP instructions.\n" msgstr "" -#: arc-dis.c:1188 +#: arc-dis.c:1273 #, c-format msgid " spfp Recognize FPX SP instructions.\n" msgstr "" -#: arc-dis.c:1190 +#: arc-dis.c:1275 #, c-format msgid " dpfp Recognize FPX DP instructions.\n" msgstr "" -#: arc-dis.c:1192 +#: arc-dis.c:1277 #, c-format msgid " quarkse_em Recognize FPU QuarkSE-EM instructions.\n" msgstr "" -#: arc-dis.c:1194 +#: arc-dis.c:1279 #, c-format msgid " fpuda Recognize double assist FPU instructions.\n" msgstr "" -#: arc-dis.c:1196 +#: arc-dis.c:1281 #, c-format msgid " fpus Recognize single precision FPU instructions.\n" msgstr "" -#: arc-dis.c:1198 +#: arc-dis.c:1283 #, c-format msgid " fpud Recognize double precision FPU instructions.\n" msgstr "" @@ -454,17 +453,49 @@ msgstr "" msgid "Value must be in the range 0 to 31" msgstr "" -#: arm-dis.c:3634 +#: arm-dis.c:3202 +msgid "Select raw register names" +msgstr "" + +#: arm-dis.c:3204 +msgid "Select register names used by GCC" +msgstr "" + +#: arm-dis.c:3206 +msgid "Select register names used in ARM's ISA documentation" +msgstr "" + +#: arm-dis.c:3208 +msgid "Select register names used in the APCS" +msgstr "" + +#: arm-dis.c:3210 +msgid "Select register names used in the ATPCS" +msgstr "" + +#: arm-dis.c:3212 +msgid "Select special register names used in the ATPCS" +msgstr "" + +#. All non "reg-names-* options must be listed last. +#: arm-dis.c:3216 +msgid "Assume all insns are Thumb insns" +msgstr "" + +#: arm-dis.c:3217 +msgid "Examine preceding label to determine an insn's type" +msgstr "" + +#: arm-dis.c:3638 msgid "" msgstr "" -#. XXX - should break 'option' at following delimiter. -#: arm-dis.c:6150 +#: arm-dis.c:6151 #, c-format msgid "Unrecognised register name set: %s\n" msgstr "" -#: arm-dis.c:6850 +#: arm-dis.c:6855 #, c-format msgid "" "\n" @@ -472,17 +503,17 @@ msgid "" "the -M switch:\n" msgstr "" -#: avr-dis.c:114 avr-dis.c:135 +#: avr-dis.c:115 avr-dis.c:136 #, c-format msgid "undefined" msgstr "" -#: avr-dis.c:214 +#: avr-dis.c:215 #, c-format msgid "Internal disassembler error" msgstr "" -#: avr-dis.c:267 +#: avr-dis.c:268 #, c-format msgid "unknown constraint `%c'" msgstr "" @@ -573,12 +604,12 @@ msgstr "" #: ip2k-asm.c:789 ip2k-asm.c:896 iq2000-asm.c:644 iq2000-asm.c:648 #: iq2000-asm.c:737 iq2000-asm.c:844 lm32-asm.c:534 lm32-asm.c:538 #: lm32-asm.c:627 lm32-asm.c:734 m32c-asm.c:1769 m32c-asm.c:1773 -#: m32c-asm.c:1862 m32c-asm.c:1969 m32r-asm.c:513 m32r-asm.c:517 -#: m32r-asm.c:606 m32r-asm.c:713 mep-asm.c:1472 mep-asm.c:1476 mep-asm.c:1565 -#: mep-asm.c:1672 mt-asm.c:780 mt-asm.c:784 mt-asm.c:873 mt-asm.c:980 -#: or1k-asm.c:688 or1k-asm.c:692 or1k-asm.c:781 or1k-asm.c:888 xc16x-asm.c:561 -#: xc16x-asm.c:565 xc16x-asm.c:654 xc16x-asm.c:761 xstormy16-asm.c:461 -#: xstormy16-asm.c:465 xstormy16-asm.c:554 xstormy16-asm.c:661 +#: m32c-asm.c:1862 m32c-asm.c:1969 m32r-asm.c:513 m32r-asm.c:517 m32r-asm.c:606 +#: m32r-asm.c:713 mep-asm.c:1472 mep-asm.c:1476 mep-asm.c:1565 mep-asm.c:1672 +#: mt-asm.c:780 mt-asm.c:784 mt-asm.c:873 mt-asm.c:980 or1k-asm.c:688 +#: or1k-asm.c:692 or1k-asm.c:781 or1k-asm.c:888 xc16x-asm.c:561 xc16x-asm.c:565 +#: xc16x-asm.c:654 xc16x-asm.c:761 xstormy16-asm.c:461 xstormy16-asm.c:465 +#: xstormy16-asm.c:554 xstormy16-asm.c:661 msgid "unrecognized instruction" msgstr "" @@ -636,9 +667,8 @@ msgid "*unknown*" msgstr "" #: epiphany-dis.c:277 fr30-dis.c:298 frv-dis.c:395 ip2k-dis.c:287 -#: iq2000-dis.c:188 lm32-dis.c:146 m32c-dis.c:890 m32r-dis.c:278 -#: mep-dis.c:1186 mt-dis.c:289 or1k-dis.c:140 xc16x-dis.c:419 -#: xstormy16-dis.c:167 +#: iq2000-dis.c:188 lm32-dis.c:146 m32c-dis.c:890 m32r-dis.c:278 mep-dis.c:1186 +#: mt-dis.c:289 or1k-dis.c:140 xc16x-dis.c:419 xstormy16-dis.c:167 #, c-format msgid "Unrecognized field %d while printing insn.\n" msgstr "" @@ -760,11 +790,11 @@ msgstr "" msgid "%02x\t\t*unknown*" msgstr "" -#: i386-dis.c:12198 +#: i386-dis.c:12200 msgid "" msgstr "" -#: i386-dis.c:12490 +#: i386-dis.c:12492 #, c-format msgid "" "\n" @@ -773,145 +803,145 @@ msgid "" "with the -M switch (multiple options should be separated by commas):\n" msgstr "" -#: i386-dis.c:12494 +#: i386-dis.c:12496 #, c-format msgid " x86-64 Disassemble in 64bit mode\n" msgstr "" -#: i386-dis.c:12495 +#: i386-dis.c:12497 #, c-format msgid " i386 Disassemble in 32bit mode\n" msgstr "" -#: i386-dis.c:12496 +#: i386-dis.c:12498 #, c-format msgid " i8086 Disassemble in 16bit mode\n" msgstr "" -#: i386-dis.c:12497 +#: i386-dis.c:12499 #, c-format msgid " att Display instruction in AT&T syntax\n" msgstr "" -#: i386-dis.c:12498 +#: i386-dis.c:12500 #, c-format msgid " intel Display instruction in Intel syntax\n" msgstr "" -#: i386-dis.c:12499 +#: i386-dis.c:12501 #, c-format msgid "" " att-mnemonic\n" " Display instruction in AT&T mnemonic\n" msgstr "" -#: i386-dis.c:12501 +#: i386-dis.c:12503 #, c-format msgid "" " intel-mnemonic\n" " Display instruction in Intel mnemonic\n" msgstr "" -#: i386-dis.c:12503 +#: i386-dis.c:12505 #, c-format msgid " addr64 Assume 64bit address size\n" msgstr "" -#: i386-dis.c:12504 +#: i386-dis.c:12506 #, c-format msgid " addr32 Assume 32bit address size\n" msgstr "" -#: i386-dis.c:12505 +#: i386-dis.c:12507 #, c-format msgid " addr16 Assume 16bit address size\n" msgstr "" -#: i386-dis.c:12506 +#: i386-dis.c:12508 #, c-format msgid " data32 Assume 32bit data size\n" msgstr "" -#: i386-dis.c:12507 +#: i386-dis.c:12509 #, c-format msgid " data16 Assume 16bit data size\n" msgstr "" -#: i386-dis.c:12508 +#: i386-dis.c:12510 #, c-format msgid " suffix Always display instruction suffix in AT&T syntax\n" msgstr "" -#: i386-dis.c:12509 +#: i386-dis.c:12511 #, c-format msgid " amd64 Display instruction in AMD64 ISA\n" msgstr "" -#: i386-dis.c:12510 +#: i386-dis.c:12512 #, c-format msgid " intel64 Display instruction in Intel64 ISA\n" msgstr "" -#: i386-dis.c:13061 +#: i386-dis.c:13063 msgid "64-bit address is disabled" msgstr "" -#: i386-gen.c:674 ia64-gen.c:306 +#: i386-gen.c:679 ia64-gen.c:306 #, c-format msgid "%s: Error: " msgstr "" -#: i386-gen.c:838 +#: i386-gen.c:843 #, c-format msgid "%s: %d: Unknown bitfield: %s\n" msgstr "" -#: i386-gen.c:840 +#: i386-gen.c:845 #, c-format msgid "Unknown bitfield: %s\n" msgstr "" -#: i386-gen.c:899 +#: i386-gen.c:904 #, c-format msgid "%s: %d: Missing `)' in bitfield: %s\n" msgstr "" -#: i386-gen.c:1170 +#: i386-gen.c:1175 #, c-format msgid "can't find i386-opc.tbl for reading, errno = %s\n" msgstr "" -#: i386-gen.c:1301 +#: i386-gen.c:1306 #, c-format msgid "can't find i386-reg.tbl for reading, errno = %s\n" msgstr "" -#: i386-gen.c:1378 +#: i386-gen.c:1383 #, c-format msgid "can't create i386-init.h, errno = %s\n" msgstr "" -#: i386-gen.c:1468 ia64-gen.c:2829 +#: i386-gen.c:1473 ia64-gen.c:2829 #, c-format msgid "unable to change directory to \"%s\", errno = %s\n" msgstr "" -#: i386-gen.c:1480 i386-gen.c:1483 +#: i386-gen.c:1485 i386-gen.c:1488 #, c-format msgid "CpuMax != %d!\n" msgstr "" -#: i386-gen.c:1487 +#: i386-gen.c:1492 #, c-format msgid "%d unused bits in i386_cpu_flags.\n" msgstr "" -#: i386-gen.c:1494 +#: i386-gen.c:1499 #, c-format msgid "%d unused bits in i386_operand_type.\n" msgstr "" -#: i386-gen.c:1508 +#: i386-gen.c:1513 #, c-format msgid "can't create i386-tbl.h, errno = %s\n" msgstr "" @@ -1181,12 +1211,12 @@ msgstr "" msgid "Invalid size specifier" msgstr "" -#: m68k-dis.c:1278 +#: m68k-dis.c:1292 #, c-format msgid "" msgstr "" -#: m68k-dis.c:1437 +#: m68k-dis.c:1455 #, c-format msgid "\n" msgstr "" @@ -1229,7 +1259,7 @@ msgstr "" msgid "Value is not aligned enough" msgstr "" -#: mips-dis.c:1633 mips-dis.c:1844 +#: mips-dis.c:1634 mips-dis.c:1846 #, c-format msgid "# internal error, undefined operand in `%s %s'" msgstr "" @@ -1359,20 +1389,20 @@ msgstr "" msgid "Error: read from memory failed" msgstr "" -#: msp430-dis.c:485 +#: msp430-dis.c:499 msgid "Warning: illegal as emulation instr" msgstr "" #. R2/R3 are illegal as dest: may be data section. -#: msp430-dis.c:569 +#: msp430-dis.c:591 msgid "Warning: illegal as 2-op instr" msgstr "" -#: msp430-dis.c:950 +#: msp430-dis.c:1002 msgid "Warning: unrecognised CALLA addressing mode" msgstr "" -#: msp430-dis.c:1232 msp430-dis.c:1249 msp430-dis.c:1270 +#: msp430-dis.c:1303 msp430-dis.c:1324 msp430-dis.c:1345 #, c-format msgid "Warning: reserved use of A/L and B/W bits detected" msgstr "" @@ -1403,12 +1433,12 @@ msgstr "" msgid "$" msgstr "" -#: ppc-dis.c:345 +#: ppc-dis.c:347 #, c-format msgid "warning: ignoring unknown -M%s option\n" msgstr "" -#: ppc-dis.c:775 +#: ppc-dis.c:793 #, c-format msgid "" "\n" @@ -1490,12 +1520,12 @@ msgstr "" msgid "Unrecognized disassembler option: %s\n" msgstr "" -#: riscv-dis.c:342 +#: riscv-dis.c:343 #, c-format msgid "# internal error, undefined modifier (%c)" msgstr "" -#: riscv-dis.c:494 +#: riscv-dis.c:495 #, c-format msgid "" "\n" @@ -1503,14 +1533,14 @@ msgid "" "with the -M switch (multiple options should be separated by commas):\n" msgstr "" -#: riscv-dis.c:498 +#: riscv-dis.c:499 #, c-format msgid "" "\n" " numeric Print numeric reigster names, rather than ABI names.\n" msgstr "" -#: riscv-dis.c:501 +#: riscv-dis.c:502 #, c-format msgid "" "\n" @@ -1518,29 +1548,24 @@ msgid "" " than into pseudoinstructions.\n" msgstr "" -#: s390-dis.c:366 -#, c-format -msgid "" -"\n" -"The following S/390 specific disassembler options are supported for use\n" -"with the -M switch (multiple options should be separated by commas):\n" +#: s390-dis.c:42 +msgid "Disassemble in ESA architecture mode" msgstr "" -#: s390-dis.c:370 -#, c-format -msgid " esa Disassemble in ESA architecture mode\n" +#: s390-dis.c:43 +msgid "Disassemble in z/Architecture mode" msgstr "" -#: s390-dis.c:371 -#, c-format -msgid " zarch Disassemble in z/Architecture mode\n" +#: s390-dis.c:44 +msgid "Print unknown instructions according to length from first two bits" msgstr "" -#: s390-dis.c:372 +#: s390-dis.c:400 #, c-format msgid "" -" insnlength Print unknown instructions according to length from first two " -"bits\n" +"\n" +"The following S/390 specific disassembler options are supported for use\n" +"with the -M switch (multiple options should be separated by commas):\n" msgstr "" #: score-dis.c:662 score-dis.c:869 score-dis.c:1030 score-dis.c:1144 diff --git a/binutils/objdump.c b/binutils/objdump.c index b9fecef..4609858 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -3728,12 +3728,16 @@ main (int argc, char **argv) machine = optarg; break; case 'M': - if (disassembler_options) - /* Ignore potential memory leak for now. */ - disassembler_options = concat (disassembler_options, ",", - optarg, (const char *) NULL); - else - disassembler_options = optarg; + { + char *options; + if (disassembler_options) + /* Ignore potential memory leak for now. */ + options = concat (disassembler_options, ",", + optarg, (const char *) NULL); + else + options = optarg; + disassembler_options = remove_whitespace_and_extra_commas (options); + } break; case 'j': add_only (optarg); diff --git a/gdb/NEWS b/gdb/NEWS index 76de00e..cf58595 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -84,6 +84,16 @@ flash-erase Erases all the flash memory regions reported by the target. This is equivalent to the CLI command flash-erase. +* New commands + +set disassembler-options +show disassembler-options + Controls the passing of target specific information to the disassembler. + If it is necessary to specify more than one disassembler option then + multiple options can be placed together into a comma separated list. + The default value is the empty string. Currently, the only supported + targets are ARM, PowerPC and S/390. + *** Changes in GDB 7.12 * GDB and GDBserver now build with a C++ compiler by default. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 962325b..f19e80f 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -8520,6 +8520,27 @@ location of the relocation table. On some architectures, @value{GDBN} might be able to resolve these to actual function names. @table @code +@kindex set disassembler-options +@cindex disassembler options +@item set disassembler-options @var{option1}[,@var{option2}@dots{}] +This command controls the passing of target specific information to +the disassembler. For a list of valid options, please refer to the +@code{-M}/@code{--disassembler-options} section of the @samp{objdump} +manual and/or the output of @kbd{objdump --help} +(@pxref{objdump,,objdump,binutils.info,The GNU Binary Utilities}). +The default value is the empty string. + +If it is necessary to specify more than one disassembler option, then +multiple options can be placed together into a comma separated list. +Currently this command is only supported on targets ARM, PowerPC +and S/390. + +@kindex show disassembler-options +@item show disassembler-options +Show the current setting of the disassembler options. +@end table + +@table @code @kindex set disassembly-flavor @cindex Intel disassembly flavor @cindex AT&T disassembly flavor diff --git a/gdb/disasm.c b/gdb/disasm.c index 64d6684..7ac61ef 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -18,19 +18,26 @@ along with this program. If not, see . */ #include "defs.h" +#include "arch-utils.h" #include "target.h" #include "value.h" #include "ui-out.h" #include "disasm.h" #include "gdbcore.h" +#include "gdbcmd.h" #include "dis-asm.h" #include "source.h" +#include "safe-ctype.h" #include /* Disassemble functions. FIXME: We should get rid of all the duplicate code in gdb that does the same thing: disassemble_command() and the gdbtk variation. */ +/* This variable is used to hold the prospective disassembler_options value + which is set by the "set disassembler_options" command. */ +static char *prospective_options = NULL; + /* This structure is used to store line number information for the deprecated /m option. We need a different sort of line table from the normal one cuz we can't @@ -780,6 +787,7 @@ gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch, m_di.endian = gdbarch_byte_order (gdbarch); m_di.endian_code = gdbarch_byte_order_for_code (gdbarch); m_di.application_data = this; + m_di.disassembler_options = get_disassembler_options (gdbarch); disassemble_init_for_target (&m_di); } @@ -888,6 +896,7 @@ gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch, di->endian = gdbarch_byte_order (gdbarch); di->endian_code = gdbarch_byte_order_for_code (gdbarch); + di->disassembler_options = get_disassembler_options (gdbarch); disassemble_init_for_target (di); } @@ -904,3 +913,180 @@ gdb_buffered_insn_length (struct gdbarch *gdbarch, return gdbarch_print_insn (gdbarch, addr, &di); } + +char * +get_disassembler_options (struct gdbarch *gdbarch) +{ + char **disassembler_options = gdbarch_disassembler_options (gdbarch); + if (disassembler_options == NULL) + return NULL; + return *disassembler_options; +} + +void +set_disassembler_options (char *prospective_options) +{ + struct gdbarch *gdbarch = get_current_arch (); + char **disassembler_options = gdbarch_disassembler_options (gdbarch); + const disasm_options_t *valid_options; + char *options = remove_whitespace_and_extra_commas (prospective_options); + char *opt; + + /* Allow all architectures, even ones that do not support 'set disassembler', + to reset their disassembler options to NULL. */ + if (options == NULL) + { + if (disassembler_options != NULL) + { + free (*disassembler_options); + *disassembler_options = NULL; + } + return; + } + + valid_options = gdbarch_valid_disassembler_options (gdbarch); + if (valid_options == NULL) + { + fprintf_filtered (gdb_stdlog, _("\ +'set disassembler-options ...' is not supported on this architecture.\n")); + return; + } + + /* Verify we have valid disassembler options. */ + FOR_EACH_DISASSEMBLER_OPTION (opt, options) + { + size_t i; + for (i = 0; valid_options->name[i] != NULL; i++) + if (disassembler_options_cmp (opt, valid_options->name[i]) == 0) + break; + if (valid_options->name[i] == NULL) + { + fprintf_filtered (gdb_stdlog, + _("Invalid disassembler option value: '%s'.\n"), + opt); + return; + } + } + + free (*disassembler_options); + *disassembler_options = xstrdup (options); +} + +static void +set_disassembler_options_sfunc (char *args, int from_tty, + struct cmd_list_element *c) +{ + set_disassembler_options (prospective_options); +} + +static void +show_disassembler_options_sfunc (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + struct gdbarch *gdbarch = get_current_arch (); + const disasm_options_t *valid_options; + + const char *options = get_disassembler_options (gdbarch); + if (options == NULL) + options = ""; + + fprintf_filtered (file, _("The current disassembler options are '%s'\n"), + options); + + valid_options = gdbarch_valid_disassembler_options (gdbarch); + + if (valid_options == NULL) + return; + + fprintf_filtered (file, _("\n\ +The following disassembler options are supported for use with\n\ +the 'set disassembler-options