From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 41144 invoked by alias); 6 Oct 2016 03:00:54 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 41126 invoked by uid 89); 6 Oct 2016 03:00:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=unavailable version=3.3.2 spammy=2811, wishes, 12810, private_data 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; Thu, 06 Oct 2016 03:00:52 +0000 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u962xPie091037 for ; Wed, 5 Oct 2016 23:00:50 -0400 Received: from e18.ny.us.ibm.com (e18.ny.us.ibm.com [129.33.205.208]) by mx0a-001b2d01.pphosted.com with ESMTP id 25w9qs9g3a-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 05 Oct 2016 23:00:50 -0400 Received: from localhost by e18.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 5 Oct 2016 23:00:49 -0400 Received: from d01dlp03.pok.ibm.com (9.56.250.168) by e18.ny.us.ibm.com (146.89.104.205) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 5 Oct 2016 23:00:46 -0400 Received: from b01cxnp23032.gho.pok.ibm.com (b01cxnp23032.gho.pok.ibm.com [9.57.198.27]) by d01dlp03.pok.ibm.com (Postfix) with ESMTP id B4FD0C90043; Wed, 5 Oct 2016 23:00:32 -0400 (EDT) Received: from b01ledav004.gho.pok.ibm.com (b01ledav004.gho.pok.ibm.com [9.57.199.109]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u9630kFJ15008212; Thu, 6 Oct 2016 03:00:46 GMT Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 56AB3112034; Wed, 5 Oct 2016 23:00:46 -0400 (EDT) Received: from otta.local (unknown [9.85.144.178]) by b01ledav004.gho.pok.ibm.com (Postfix) with ESMTP id D867911204B; Wed, 5 Oct 2016 23:00:45 -0400 (EDT) Subject: Re: [PATCH, RFC] Add support for choosing disassembler cpu in GDB for POWER. To: Alan Modra References: <20160930161908.6A43511C24D@oc8523832656.ibm.com> <20161003222527.GO4877@bubble.grove.modra.org> Cc: Ulrich Weigand , gdb-patches@sourceware.org, binutils From: Peter Bergner Date: Thu, 06 Oct 2016 03:00:00 -0000 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 In-Reply-To: <20161003222527.GO4877@bubble.grove.modra.org> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16100603-0044-0000-0000-00000162B055 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00005860; HX=3.00000240; KW=3.00000007; PH=3.00000004; SC=3.00000186; SDB=6.00764844; UDB=6.00365376; IPR=6.00540693; BA=6.00004789; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00012890; XFM=3.00000011; UTC=2016-10-06 03:00:48 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16100603-0045-0000-0000-0000058FBB49 Message-Id: <5a66aca9-dfe9-7c44-21f9-27774a07d143@vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2016-10-06_01:,, 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-1609300000 definitions=main-1610060053 X-IsSubscribed: yes X-SW-Source: 2016-10/txt/msg00104.txt.bz2 On 10/3/16 5:25 PM, Alan Modra wrote: > Somewhere in gdb you must be calling disassemble_init_for_target. > Why can't you call that again after setting the cpu (in struct > disassemble_info disassembler_options)? We (rs6000-tdep.c) don't call disassemble_init_for_target(). That is done by architecture independent gdb code before gdb_print_insn_powerpc() is ever called. We could call it from there, but as I mentioned in one of my previous notes, we'd be doing that before every insn we emit, which would be very expensive. The problem is, currently there is no way for the target to catch the disassembly initialization process to modify the struct disassemble_info disassembler_options value before we start emitting insns. That said, how about the following patch which adds that ability? Peter include/ * dis-asm.h (ppc_verify_disassembler_options): New prototype. * opcode/ppc.h (PPC_DEFAULT_CPU): New define. opcodes/ * ppc-dis.c (parse_ppc_dis_option): New function. (ppc_verify_disassembler_options): Likewise. (powerpc_init_dialect): Use parse_ppc_dis_option() and PPC_DEFAULT_CPU. gdb/ * target.h (target_init_disassembly): New prototype. * disasm.c (target_init_disassembly): New global function pointer. (gdb_disassemble_info): Use it. * rs6000-tdep.c: Include "opcode/ppc.h". (gdb_disassembler_cpu): New static declaration. (prospective_cpu): Likewise. (set_disassembler_cpu): New function. (show_disassembler_cpu): Likewise. (rs6000_init_disassembly): Likewise. (_initialize_rs6000_tdep): Initialize gdb_disassembler_cpu and target_init_disassembly. Setup callbacks for set_disassembler_cpu() and show_disassembler_cpu(). diff --git a/gdb/disasm.c b/gdb/disasm.c index 07c3abe..03fbd70 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -27,6 +27,8 @@ #include "source.h" #include +void (*target_init_disassembly)(struct disassemble_info *); + /* 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. */ @@ -785,6 +787,9 @@ gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file) di.endian = gdbarch_byte_order (gdbarch); di.endian_code = gdbarch_byte_order_for_code (gdbarch); di.application_data = gdbarch; + /* Allow the target to set disassembly options if it wishes. */ + if (target_init_disassembly) + target_init_disassembly (&di); disassemble_init_for_target (&di); return di; } diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index ca4d668..774b94b 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -57,6 +57,7 @@ #include "ppc-ravenscar-thread.h" #include "dis-asm.h" +#include "opcode/ppc.h" #include "trad-frame.h" #include "frame-unwind.h" @@ -127,6 +128,10 @@ static const char *const powerpc_vector_strings[] = static enum powerpc_vector_abi powerpc_vector_abi_global = POWERPC_VEC_AUTO; static const char *powerpc_vector_abi_string = "auto"; +/* This is the variable that is set with "set disassembler-cpu". */ +static char *gdb_disassembler_cpu; +static char *prospective_cpu; + /* To be used by skip_prologue. */ struct rs6000_framedata @@ -6676,6 +6681,30 @@ show_powerpc_exact_watchpoints (struct ui_file *file, int from_tty, fprintf_filtered (file, _("Use of exact watchpoints is %s.\n"), value); } +static void +set_disassembler_cpu (char *args, int from_tty, struct cmd_list_element *c) +{ + char *opt; + if ((opt = ppc_verify_disassembler_options (prospective_cpu)) != NULL) + { + fprintf_filtered (gdb_stdlog, + _("Invalid disasembler-cpu value: '%s'.\n"), opt); + return; + } + free (gdb_disassembler_cpu); + gdb_disassembler_cpu = strdup (prospective_cpu); +} + +static void +show_disassembler_cpu (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("\ +The current disassembler cpu is '%s'\n\n\ +See objdump's -M option for the list of supported PPC specific\n\ +disassembler options.\n"), gdb_disassembler_cpu); +} + /* Read a PPC instruction from memory. */ static unsigned int @@ -6747,6 +6776,12 @@ ppc_insn_ds_field (unsigned int insn) /* Initialization code. */ +void +rs6000_init_disassembly (disassemble_info *info) +{ + info->disassembler_options = gdb_disassembler_cpu; +} + /* -Wmissing-prototypes */ extern initialize_file_ftype _initialize_rs6000_tdep; @@ -6777,6 +6812,9 @@ _initialize_rs6000_tdep (void) initialize_tdesc_powerpc_e500 (); initialize_tdesc_rs6000 (); + gdb_disassembler_cpu = strdup (PPC_DEFAULT_CPU",any"); + target_init_disassembly = rs6000_init_disassembly; + /* Add root prefix command for all "set powerpc"/"show powerpc" commands. */ add_prefix_cmd ("powerpc", no_class, set_powerpc_command, @@ -6796,6 +6834,18 @@ _initialize_rs6000_tdep (void) powerpc_set_soft_float, NULL, &setpowerpccmdlist, &showpowerpccmdlist); + /* Add the command that controls the disassembler cpu. */ + add_setshow_string_cmd ("disassembler-cpu", no_class, + &prospective_cpu, _("\ +Set the disassembler cpu.\n\ +Usage: set disassembler-cpu [,]*\n\ +See 'show disassembler-cpu' for the valid names."), _("\ +Show the disassembler cpu."), _("\ +The default value is '" PPC_DEFAULT_CPU ",any'."), + set_disassembler_cpu, + show_disassembler_cpu, + &setlist, &showlist); + add_setshow_enum_cmd ("vector-abi", class_support, powerpc_vector_strings, &powerpc_vector_abi_string, _("Set the vector ABI."), diff --git a/gdb/target.h b/gdb/target.h index b458970..507b7ec 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -2515,4 +2515,6 @@ extern void target_prepare_to_generate_core (void); /* See to_done_generating_core. */ extern void target_done_generating_core (void); +extern void (*target_init_disassembly)(struct disassemble_info *); + #endif /* !defined (TARGET_H) */ diff --git a/include/dis-asm.h b/include/dis-asm.h index 05bfa37..15573d9 100644 --- a/include/dis-asm.h +++ b/include/dis-asm.h @@ -337,6 +337,7 @@ extern int get_arm_regnames (int, const char **, const char **, const char *con 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 char *ppc_verify_disassembler_options (char *); /* Fetch the disassembler for a given BFD, if that support is available. */ extern disassembler_ftype disassembler (bfd *); diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h index 66d2ceb..f97c652 100644 --- a/include/opcode/ppc.h +++ b/include/opcode/ppc.h @@ -28,6 +28,11 @@ extern "C" { #endif +/* The default cpu type the assembler/disassembler will use if there + is no explcit use of -m or -M. */ + +#define PPC_DEFAULT_CPU "power9" + typedef uint64_t ppc_cpu_t; /* The opcode table is an array of struct powerpc_opcode. */ diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c index da1301e..fcbb4c8 100644 --- a/opcodes/ppc-dis.c +++ b/opcodes/ppc-dis.c @@ -271,6 +271,50 @@ ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg) return ppc_cpu; } +/* Parse the OPTIONS argument looking for ',' seperated cpu names. + The first cpu name is copied into CPU and a pointer to the + next name is returned or NULL if there are no more cpu names. + CPU must contain enough space to hold the cpu name. */ + +static char * +parse_ppc_dis_option (char *cpu, const char *options) +{ + char *next = strchr (options, ','); + + if (next != NULL) + { + strncpy (cpu, options, (size_t) (next - options)); + cpu[(size_t) (next - options)] = 0; + next++; + } + else + strcpy (cpu, options); + + return next; +} + +/* Parse OPTIONS looking for ',' seperated cpu names and verify each name + is valid. Return NULL if all names are valid. Otherwise, return a + pointer to the first invalid cpu name. */ + +char * +ppc_verify_disassembler_options (char *options) +{ + static char opt[32]; + while (options != NULL) + { + unsigned int i; + options = parse_ppc_dis_option (opt, options); + + for (i = 0; ppc_opts[i].opt; i++) + if (strcmp (ppc_opts[i].opt, opt) == 0) + break; + if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0])) + return opt; + } + return NULL; +} + /* Determine which set of machines to disassemble for. */ static void @@ -323,30 +367,26 @@ powerpc_init_dialect (struct disassemble_info *info) dialect = ppc_parse_cpu (dialect, &sticky, "vle"); break; default: - dialect = ppc_parse_cpu (dialect, &sticky, "power9") | PPC_OPCODE_ANY; + dialect = ppc_parse_cpu (dialect, &sticky, PPC_DEFAULT_CPU) + | PPC_OPCODE_ANY; + break; } arg = info->disassembler_options; while (arg != NULL) { ppc_cpu_t new_cpu = 0; - char *end = strchr (arg, ','); + char opt[64]; + arg = parse_ppc_dis_option (opt, arg); - if (end != NULL) - *end = 0; - - if ((new_cpu = ppc_parse_cpu (dialect, &sticky, arg)) != 0) + if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0) dialect = new_cpu; - else if (strcmp (arg, "32") == 0) + else if (strcmp (opt, "32") == 0) dialect &= ~(ppc_cpu_t) PPC_OPCODE_64; - else if (strcmp (arg, "64") == 0) + else if (strcmp (opt, "64") == 0) dialect |= PPC_OPCODE_64; 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;