From patchwork Fri Jun 20 15:57:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 1609 Received: (qmail 1819 invoked by alias); 20 Jun 2014 16:32:14 -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 1800 invoked by uid 89); 20 Jun 2014 16:32:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 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; Fri, 20 Jun 2014 16:32:08 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s5KFwApA006306 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 20 Jun 2014 11:58:10 -0400 Received: from barimba.redhat.com (ovpn-113-103.phx2.redhat.com [10.3.113.103]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s5KFw53L015561; Fri, 20 Jun 2014 11:58:09 -0400 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH v2 07/14] add gnu_triplet_regexp gdbarch method Date: Fri, 20 Jun 2014 09:57:47 -0600 Message-Id: <1403279874-23781-8-git-send-email-tromey@redhat.com> In-Reply-To: <1403279874-23781-1-git-send-email-tromey@redhat.com> References: <1403279874-23781-1-git-send-email-tromey@redhat.com> 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-06-20 Tom Tromey * 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. * amd64-tdep.c (amd64_gnu_triplet_regexp): New function. (amd64_init_abi): Call set_gdbarch_gnu_triplet_regexp. --- gdb/ChangeLog | 19 ++++++++++++ gdb/amd64-tdep.c | 10 +++++++ 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 | 16 ++++++++++ gdb/osabi.c | 90 +++++++++++++++++++++++++++++++++++--------------------- gdb/osabi.h | 4 +++ 10 files changed, 155 insertions(+), 33 deletions(-) diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 45ed97b..efeddc8 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -2957,6 +2957,14 @@ static const int amd64_record_regmap[] = AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM }; +/* gdbarch gnu_triplet_regexp method. */ + +static const char * +amd64_gnu_triplet_regexp (struct gdbarch *gdbarch) +{ + return "x86_64"; +} + void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -3110,6 +3118,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_insn_is_call (gdbarch, amd64_insn_is_call); set_gdbarch_insn_is_ret (gdbarch, amd64_insn_is_ret); set_gdbarch_insn_is_jump (gdbarch, amd64_insn_is_jump); + + set_gdbarch_gnu_triplet_regexp (gdbarch, amd64_gnu_triplet_regexp); } diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 2c67546..d45dc83 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -833,6 +833,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 */ diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index d4bf353..73f85cf 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -177,5 +177,6 @@ extern int default_insn_is_jump (struct gdbarch *, CORE_ADDR); 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 553fbcc..914d54c 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -321,6 +321,7 @@ struct gdbarch gdbarch_auxv_parse_ftype *auxv_parse; 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 @@ -415,6 +416,7 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->insn_is_jump = default_insn_is_jump; 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; @@ -636,6 +638,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of auxv_parse, has predicate. */ /* 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) @@ -942,6 +945,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, @@ -4452,6 +4458,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 6f03fe5..18e8ef5 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1334,6 +1334,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 b0b57c8..6daa4c3 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -1041,6 +1041,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 5e3cc79..dbaaf35 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -4342,6 +4342,16 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch, +/* gdbarch gnu_triplet_regexp method. */ + +static const char * +i386_gnu_triplet_regexp (struct gdbarch *gdbarch) +{ + return "i.86"; +} + + + /* Generic ELF. */ void @@ -4368,6 +4378,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). */ @@ -4415,6 +4427,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); } @@ -8449,6 +8463,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 5b69eeb..741121f 100644 --- a/gdb/osabi.c +++ b/gdb/osabi.c @@ -44,47 +44,71 @@ 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", - "OSF/1", - "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 }, + { "OSF/1", 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 @@ -96,7 +120,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. */ @@ -649,7 +673,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. */