From patchwork Sun Nov 23 19:28:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 3867 Received: (qmail 18765 invoked by alias); 23 Nov 2014 19:28:18 -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 18746 invoked by uid 89); 23 Nov 2014 19:28:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.0 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sun, 23 Nov 2014 19:28:14 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id sANJSDE8014244 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Sun, 23 Nov 2014 14:28:13 -0500 Received: from host1.jankratochvil.net (ovpn-116-31.ams2.redhat.com [10.36.116.31]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id sANJSB9W005658 for ; Sun, 23 Nov 2014 14:28:12 -0500 Subject: [PATCH v4 07/14] add gnu_triplet_regexp gdbarch method From: Jan Kratochvil To: gdb-patches@sourceware.org Date: Sun, 23 Nov 2014 20:28:11 +0100 Message-ID: <20141123192810.32193.48269.stgit@host1.jankratochvil.net> In-Reply-To: <20141123192713.32193.57150.stgit@host1.jankratochvil.net> References: <20141123192713.32193.57150.stgit@host1.jankratochvil.net> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-IsSubscribed: yes From: Tom Tromey gdb has to inform libcc1.so of the target being used, so that the correct compiler can be invoked. The compiler is invoked using the GNU configury triplet prefix, e.g., "x86_64-unknown-linux-gnu-gcc". In order for this to work we need to map the gdbarch to the GNU configury triplet arch. In most cases these are identical; however, the x86 family poses some problems, as the BFD arch names are quite different from the GNU triplet names. So, we introduce a new gdbarch method for this. A regular expression is used because there are various valid values for the arch prefix in the triplet. This patch also updates the osabi code to associate a regular expression with the OS ABI. I have only added a concrete value for Linux. Note that the "-gnu" part is optional, at least on Fedora it is omitted from the installed GCC executable's name. 2014-10-07 Tom Tromey Jan Kratochvil * osabi.h (osabi_triplet_regexp): Declare. * osabi.c (struct osabi_names): New. (gdb_osabi_names): Change type to struct osabi_names. Update values. (gdbarch_osabi_name): Update. (osabi_triplet_regexp): New function. (osabi_from_tdesc_string, _initialize_gdb_osabi): Update. * i386-tdep.c (i386_gnu_triplet_regexp): New method. (i386_elf_init_abi, i386_go32_init_abi, i386_gdbarch_init): Call set_gdbarch_gnu_triplet_regexp. * gdbarch.sh (gnu_triplet_regexp): New method. * gdbarch.c, gdbarch.h: Rebuild. * arch-utils.h (default_gnu_triplet_regexp): Declare. * arch-utils.c (default_gnu_triplet_regexp): New function. --- gdb/ChangeLog | 18 +++++++++++ gdb/arch-utils.c | 8 +++++ gdb/arch-utils.h | 1 + gdb/gdbarch.c | 23 ++++++++++++++ gdb/gdbarch.h | 10 ++++++ gdb/gdbarch.sh | 7 ++++ gdb/i386-tdep.c | 17 ++++++++++ gdb/osabi.c | 88 ++++++++++++++++++++++++++++++++++-------------------- gdb/osabi.h | 4 ++ 9 files changed, 144 insertions(+), 32 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d62748a..9222c54 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,21 @@ +2014-10-07 Tom Tromey + Jan Kratochvil + + * osabi.h (osabi_triplet_regexp): Declare. + * osabi.c (struct osabi_names): New. + (gdb_osabi_names): Change type to struct osabi_names. Update + values. + (gdbarch_osabi_name): Update. + (osabi_triplet_regexp): New function. + (osabi_from_tdesc_string, _initialize_gdb_osabi): Update. + * i386-tdep.c (i386_gnu_triplet_regexp): New method. + (i386_elf_init_abi, i386_go32_init_abi, i386_gdbarch_init): Call + set_gdbarch_gnu_triplet_regexp. + * gdbarch.sh (gnu_triplet_regexp): New method. + * gdbarch.c, gdbarch.h: Rebuild. + * arch-utils.h (default_gnu_triplet_regexp): Declare. + * arch-utils.c (default_gnu_triplet_regexp): New function. + 2014-10-07 Jan Kratochvil * arch-utils.c (default_infcall_mmap) diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 950912d..ad4d90d 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -855,6 +855,14 @@ default_gcc_target_options (struct gdbarch *gdbarch) gdbarch_ptr_bit (gdbarch) == 64 ? " -mcmodel=large" : ""); } +/* gdbarch gnu_triplet_regexp method. */ + +const char * +default_gnu_triplet_regexp (struct gdbarch *gdbarch) +{ + return gdbarch_bfd_arch_info (gdbarch)->arch_name; +} + /* -Wmissing-prototypes */ extern initialize_file_ftype _initialize_gdbarch_utils; diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 1ccb56a..cb78907 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -194,5 +194,6 @@ extern void default_skip_permanent_breakpoint (struct regcache *regcache); extern CORE_ADDR default_infcall_mmap (CORE_ADDR size, unsigned prot); extern char *default_gcc_target_options (struct gdbarch *gdbarch); +extern const char *default_gnu_triplet_regexp (struct gdbarch *gdbarch); #endif diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 7eb1e6b..4cb9fcb 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -320,6 +320,7 @@ struct gdbarch gdbarch_vsyscall_range_ftype *vsyscall_range; gdbarch_infcall_mmap_ftype *infcall_mmap; gdbarch_gcc_target_options_ftype *gcc_target_options; + gdbarch_gnu_triplet_regexp_ftype *gnu_triplet_regexp; }; /* Create a new ``struct gdbarch'' based on information provided by @@ -416,6 +417,7 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->vsyscall_range = default_vsyscall_range; gdbarch->infcall_mmap = default_infcall_mmap; gdbarch->gcc_target_options = default_gcc_target_options; + gdbarch->gnu_triplet_regexp = default_gnu_triplet_regexp; /* gdbarch_alloc() */ return gdbarch; @@ -640,6 +642,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of vsyscall_range, invalid_p == 0 */ /* Skip verify of infcall_mmap, invalid_p == 0 */ /* Skip verify of gcc_target_options, invalid_p == 0 */ + /* Skip verify of gnu_triplet_regexp, invalid_p == 0 */ buf = ui_file_xstrdup (log, &length); make_cleanup (xfree, buf); if (length > 0) @@ -943,6 +946,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: get_syscall_number = <%s>\n", host_address_to_string (gdbarch->get_syscall_number)); fprintf_unfiltered (file, + "gdbarch_dump: gnu_triplet_regexp = <%s>\n", + host_address_to_string (gdbarch->gnu_triplet_regexp)); + fprintf_unfiltered (file, "gdbarch_dump: half_bit = %s\n", plongest (gdbarch->half_bit)); fprintf_unfiltered (file, @@ -4487,6 +4493,23 @@ set_gdbarch_gcc_target_options (struct gdbarch *gdbarch, gdbarch->gcc_target_options = gcc_target_options; } +const char * +gdbarch_gnu_triplet_regexp (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->gnu_triplet_regexp != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_gnu_triplet_regexp called\n"); + return gdbarch->gnu_triplet_regexp (gdbarch); +} + +void +set_gdbarch_gnu_triplet_regexp (struct gdbarch *gdbarch, + gdbarch_gnu_triplet_regexp_ftype gnu_triplet_regexp) +{ + gdbarch->gnu_triplet_regexp = gnu_triplet_regexp; +} + /* Keep a registry of per-architecture data-pointers required by GDB modules. */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 304d136..962ef9a 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1356,6 +1356,16 @@ typedef char * (gdbarch_gcc_target_options_ftype) (struct gdbarch *gdbarch); extern char * gdbarch_gcc_target_options (struct gdbarch *gdbarch); extern void set_gdbarch_gcc_target_options (struct gdbarch *gdbarch, gdbarch_gcc_target_options_ftype *gcc_target_options); +/* Return a regular expression that matches names used by this + architecture in GNU configury triplets. The result is statically + allocated and must not be freed. The default implementation simply + returns the BFD architecture name, which is correct in nearly every + case. */ + +typedef const char * (gdbarch_gnu_triplet_regexp_ftype) (struct gdbarch *gdbarch); +extern const char * gdbarch_gnu_triplet_regexp (struct gdbarch *gdbarch); +extern void set_gdbarch_gnu_triplet_regexp (struct gdbarch *gdbarch, gdbarch_gnu_triplet_regexp_ftype *gnu_triplet_regexp); + /* Definition for an unknown syscall, used basically in error-cases. */ #define UNKNOWN_SYSCALL (-1) diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index d3d4e57..f049efc 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -1053,6 +1053,13 @@ f:CORE_ADDR:infcall_mmap:CORE_ADDR size, unsigned prot:size, prot::default_infca # These options are put before CU's DW_AT_producer compilation options so that # they can override it. Method may also return NULL. m:char *:gcc_target_options:void:::default_gcc_target_options::0 + +# Return a regular expression that matches names used by this +# architecture in GNU configury triplets. The result is statically +# allocated and must not be freed. The default implementation simply +# returns the BFD architecture name, which is correct in nearly every +# case. +m:const char *:gnu_triplet_regexp:void:::default_gnu_triplet_regexp::0 EOF } diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 6c4ef17..0750506 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -4306,6 +4306,17 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch, +/* gdbarch gnu_triplet_regexp method. Both arches are acceptable as GDB always + also supplies -m64 or -m32 by gdbarch_gcc_target_options. */ + +static const char * +i386_gnu_triplet_regexp (struct gdbarch *gdbarch) +{ + return "(x86_64|i.86)"; +} + + + /* Generic ELF. */ void @@ -4332,6 +4343,8 @@ i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) i386_stap_is_single_operand); set_gdbarch_stap_parse_special_token (gdbarch, i386_stap_parse_special_token); + + set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp); } /* System V Release 4 (SVR4). */ @@ -4379,6 +4392,8 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum); set_gdbarch_has_dos_based_file_system (gdbarch, 1); + + set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp); } @@ -8402,6 +8417,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) gap for the upper AVX, MPX and AVX512 registers. */ set_gdbarch_num_regs (gdbarch, I386_AVX512_NUM_REGS); + set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp); + /* Get the x86 target description from INFO. */ tdesc = info.target_desc; if (! tdesc_has_registers (tdesc)) diff --git a/gdb/osabi.c b/gdb/osabi.c index d33ef9c..50d391a 100644 --- a/gdb/osabi.c +++ b/gdb/osabi.c @@ -41,46 +41,70 @@ static const char *gdb_osabi_available_names[GDB_OSABI_INVALID + 3] = { }; static const char *set_osabi_string; +/* Names associated with each osabi. */ + +struct osabi_names +{ + /* The "pretty" name. */ + + const char *pretty; + + /* The triplet regexp, or NULL if not known. */ + + const char *regexp; +}; + /* This table matches the indices assigned to enum gdb_osabi. Keep them in sync. */ -static const char * const gdb_osabi_names[] = +static const struct osabi_names gdb_osabi_names[] = { - "none", - - "SVR4", - "GNU/Hurd", - "Solaris", - "GNU/Linux", - "FreeBSD a.out", - "FreeBSD ELF", - "NetBSD a.out", - "NetBSD ELF", - "OpenBSD ELF", - "Windows CE", - "DJGPP", - "Irix", - "HP/UX ELF", - "HP/UX SOM", - "QNX Neutrino", - "Cygwin", - "AIX", - "DICOS", - "Darwin", - "Symbian", - "OpenVMS", - "LynxOS178", - "Newlib", - - "" + { "none", NULL }, + + { "SVR4", NULL }, + { "GNU/Hurd", NULL }, + { "Solaris", NULL }, + { "GNU/Linux", "linux(-gnu)?" }, + { "FreeBSD a.out", NULL }, + { "FreeBSD ELF", NULL }, + { "NetBSD a.out", NULL }, + { "NetBSD ELF", NULL }, + { "OpenBSD ELF", NULL }, + { "Windows CE", NULL }, + { "DJGPP", NULL }, + { "Irix", NULL }, + { "HP/UX ELF", NULL }, + { "HP/UX SOM", NULL }, + { "QNX Neutrino", NULL }, + { "Cygwin", NULL }, + { "AIX", NULL }, + { "DICOS", NULL }, + { "Darwin", NULL }, + { "Symbian", NULL }, + { "OpenVMS", NULL }, + { "LynxOS178", NULL }, + { "Newlib", NULL }, + + { "", NULL } }; const char * gdbarch_osabi_name (enum gdb_osabi osabi) { if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID) - return gdb_osabi_names[osabi]; + return gdb_osabi_names[osabi].pretty; + + return gdb_osabi_names[GDB_OSABI_INVALID].pretty; +} + +/* See osabi.h. */ + +const char * +osabi_triplet_regexp (enum gdb_osabi osabi) +{ + if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID) + return gdb_osabi_names[osabi].regexp; - return gdb_osabi_names[GDB_OSABI_INVALID]; + return gdb_osabi_names[GDB_OSABI_INVALID].regexp; } /* Lookup the OS ABI corresponding to the specified target description @@ -92,7 +116,7 @@ osabi_from_tdesc_string (const char *name) int i; for (i = 0; i < ARRAY_SIZE (gdb_osabi_names); i++) - if (strcmp (name, gdb_osabi_names[i]) == 0) + if (strcmp (name, gdb_osabi_names[i].pretty) == 0) { /* See note above: the name table matches the indices assigned to enum gdb_osabi. */ @@ -645,7 +669,7 @@ extern initialize_file_ftype _initialize_gdb_osabi; /* -Wmissing-prototype */ void _initialize_gdb_osabi (void) { - if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID], "") != 0) + if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID].pretty, "") != 0) internal_error (__FILE__, __LINE__, _("_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent")); diff --git a/gdb/osabi.h b/gdb/osabi.h index 4c03790..8408f0a 100644 --- a/gdb/osabi.h +++ b/gdb/osabi.h @@ -49,6 +49,10 @@ void gdbarch_init_osabi (struct gdbarch_info, struct gdbarch *); /* Return the name of the specified OS ABI. */ const char *gdbarch_osabi_name (enum gdb_osabi); +/* Return a regular expression that matches the OS part of a GNU + configury triplet for the given OSABI. */ +const char *osabi_triplet_regexp (enum gdb_osabi osabi); + /* Helper routine for ELF file sniffers. This looks at ABI tag note sections to determine the OS ABI from the note. It should be called via bfd_map_over_sections. */