From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4139 invoked by alias); 14 Jan 2015 02:54:12 -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 4107 invoked by uid 89); 14 Jan 2015 02:54:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 14 Jan 2015 02:54:05 +0000 Received: from svr-orw-fem-02x.mgc.mentorg.com ([147.34.96.206] helo=SVR-ORW-FEM-02.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1YBE5p-0002wv-QW from Yao_Qi@mentor.com ; Tue, 13 Jan 2015 18:54:01 -0800 Received: from GreenOnly (147.34.91.1) by svr-orw-fem-02.mgc.mentorg.com (147.34.96.168) with Microsoft SMTP Server id 14.3.224.2; Tue, 13 Jan 2015 18:54:00 -0800 From: Yao Qi To: Ulrich Weigand CC: Subject: Re: [PATCH 2/2] Detect 64-bit-ness in PowerPC Book III-E References: <201501131700.t0DH0eDu014515@d03av02.boulder.ibm.com> Date: Wed, 14 Jan 2015 02:54:00 -0000 In-Reply-To: <201501131700.t0DH0eDu014515@d03av02.boulder.ibm.com> (Ulrich Weigand's message of "Tue, 13 Jan 2015 18:00:30 +0100") Message-ID: <87egqyrs13.fsf@codesourcery.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2015-01/txt/msg00360.txt.bz2 Ulrich Weigand writes: > All this can be done using "getauxval (AT_HWCAP)", which is faster and wo= rks > even if /proc is not mounted. However, getauxval was only introduced with > glibc 2.16, so we'll probably still need the fallback ... In the updated patch below, I add configure check to function getauxval. If it exists, we use getauxval, otherwise fallback to parsing /proc/self/auxv. Manually test gdbserver and it works well. My target glibc is >=3D 2.16, so getauxval path is tested. Is the patch OK? --=20 Yao (=E9=BD=90=E5=B0=A7) Subject: [PATCH] Detect 64-bit-ness in PowerPC Book III-E This patch is to teach both GDB and GDBServer to detect 64-bit inferior correctly. We find a problem that GDBServer is unable to detect on a e5500 core processor. Current GDBServer assumes that MSR is a 64-bit register, but MSR is a 32-bit register in Book III-E. This patch is to fix this problem by checking the right bit in MSR, in order to handle both Book III-S and Book III-E. In order to detect Book III-S and Book III-E, we check the PPC_FEATURE_BOOKE from the host's HWCAP (by getauxval on glibc >=3D 2.16. If getauxval doesn't exist, we implement the fallback by parsing /proc/self/auxv), because it should an invariant on the same machine cross different processes. In order to share code, I add nat/ppc-linux.c for both GDB and GDBserver side. gdb: 2015-01-14 Yao Qi * Makefile.in (ppc-linux.o): New rule. * config/powerpc/ppc64-linux.mh (NATDEPFILES): Add ppc-linux.o. * configure.ac: AC_CHECK_FUNCS(getauxval). * config.in: Re-generated. * configure: Re-generated. * nat/ppc-linux.h [__powerpc64__] (ppc64_64bit_inferior_p): Declare. * nat/ppc-linux.c: New file. * ppc-linux-nat.c (ppc_linux_target_wordsize) [__powerpc64__]: Call ppc64_64bit_inferior_p. gdb/gdbserver: 2015-01-14 Yao Qi * Makefile.in (SFILES): Add nat/ppc-linux.c. (ppc-linux.o): New rule. * configure.srv (powerpc*-*-linux*): Add ppc-linux.o. * configure.ac: AC_CHECK_FUNCS(getauxval). * config.in: Re-generated. * configure: Re-generated. * linux-ppc-low.c (ppc_arch_setup) [__powerpc64__]: Call ppc64_64bit_inferior_p diff --git a/gdb/Makefile.in b/gdb/Makefile.in index f519f0a..fc1c7fa 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2271,6 +2271,10 @@ mips-linux-watch.o: ${srcdir}/nat/mips-linux-watch.c $(COMPILE) $(srcdir)/nat/mips-linux-watch.c $(POSTCOMPILE) =20 +ppc-linux.o: ${srcdir}/nat/ppc-linux.c + $(COMPILE) $(srcdir)/nat/ppc-linux.c + $(POSTCOMPILE) + # # gdb/tui/ dependencies # diff --git a/gdb/config.in b/gdb/config.in index 9d3f32d..806cbac 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -138,6 +138,9 @@ /* Define if has fpregset_t. */ #undef HAVE_FPREGSET_T =20 +/* Define to 1 if you have the `getauxval' function. */ +#undef HAVE_GETAUXVAL + /* Define to 1 if you have the `getgid' function. */ #undef HAVE_GETGID =20 diff --git a/gdb/config/powerpc/ppc64-linux.mh b/gdb/config/powerpc/ppc64-l= inux.mh index 4b91408..1b3fbc7 100644 --- a/gdb/config/powerpc/ppc64-linux.mh +++ b/gdb/config/powerpc/ppc64-linux.mh @@ -6,7 +6,7 @@ NAT_FILE=3D config/nm-linux.h NATDEPFILES=3D inf-ptrace.o fork-child.o \ ppc-linux-nat.o proc-service.o linux-thread-db.o \ linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \ - linux-waitpid.o + linux-waitpid.o ppc-linux.o NAT_CDEPS =3D $(srcdir)/proc-service.list =20 # The PowerPC has severe limitations on TOC size, and uses them even diff --git a/gdb/configure b/gdb/configure index 7ff74ba..661d8a7 100755 --- a/gdb/configure +++ b/gdb/configure @@ -10509,6 +10509,19 @@ _ACEOF fi done =20 +# glibc >=3D 2.16 provides getauxval(). +for ac_func in getauxval +do : + ac_fn_c_check_func "$LINENO" "getauxval" "ac_cv_func_getauxval" +if test "x$ac_cv_func_getauxval" =3D x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETAUXVAL 1 +_ACEOF + +fi +done + + =20 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CO= DESET" >&5 $as_echo_n "checking for nl_langinfo and CODESET... " >&6; } diff --git a/gdb/configure.ac b/gdb/configure.ac index ec776d7..dadaf76 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -1318,6 +1318,9 @@ AC_CHECK_FUNCS([getrusage getuid getgid \ ttrace wborder wresize setlocale iconvlist libiconvlist btowc \ setrlimit getrlimit posix_madvise waitpid \ ptrace64 sigaltstack mkdtemp]) +# glibc >=3D 2.16 provides getauxval(). +AC_CHECK_FUNCS(getauxval) + AM_LANGINFO_CODESET GDB_AC_COMMON =20 diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 1ed2ec8..0e442fc 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -155,7 +155,7 @@ SFILES=3D $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $= (srcdir)/dll.c \ $(srcdir)/linux-m32r-low.c \ $(srcdir)/linux-m68k-low.c $(srcdir)/linux-mips-low.c \ $(srcdir)/linux-nios2-low.c \ - $(srcdir)/linux-ppc-low.c \ + $(srcdir)/linux-ppc-low.c $(srcdir)/nat/ppc-linux.c \ $(srcdir)/linux-s390-low.c \ $(srcdir)/linux-sh-low.c $(srcdir)/linux-sparc-low.c \ $(srcdir)/linux-x86-low.c \ @@ -581,6 +581,9 @@ linux-waitpid.o: ../nat/linux-waitpid.c mips-linux-watch.o: ../nat/mips-linux-watch.c $(COMPILE) $< $(POSTCOMPILE) +ppc-linux.o: ../nat/ppc-linux.c + $(COMPILE) $< + $(POSTCOMPILE) =20 aarch64.c : $(srcdir)/../regformats/aarch64.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/aarch64.dat aarch64.c diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in index fd80adc..8f68ed2 100644 --- a/gdb/gdbserver/config.in +++ b/gdb/gdbserver/config.in @@ -60,6 +60,9 @@ /* Define to 1 if you have the `fdwalk' function. */ #undef HAVE_FDWALK =20 +/* Define to 1 if you have the `getauxval' function. */ +#undef HAVE_GETAUXVAL + /* Define to 1 if you have the `getrlimit' function. */ #undef HAVE_GETRLIMIT =20 diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure index 45efc51..14594ec 100755 --- a/gdb/gdbserver/configure +++ b/gdb/gdbserver/configure @@ -4758,6 +4758,18 @@ _ACEOF fi done =20 +# glibc >=3D 2.16 provides getauxval(). +for ac_func in getauxval +do : + ac_fn_c_check_func "$LINENO" "getauxval" "ac_cv_func_getauxval" +if test "x$ac_cv_func_getauxval" =3D x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETAUXVAL 1 +_ACEOF + +fi +done + =20 =20 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header file= s" >&5 diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac index 02082cc..93a5ed1 100644 --- a/gdb/gdbserver/configure.ac +++ b/gdb/gdbserver/configure.ac @@ -91,6 +91,8 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h str= ing.h dnl sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl netinet/tcp.h arpa/inet.h) AC_CHECK_FUNCS(pread pwrite pread64) +# glibc >=3D 2.16 provides getauxval(). +AC_CHECK_FUNCS(getauxval) =20 GDB_AC_COMMON =20 diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index 679fc9f..f52aee2 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -217,7 +217,7 @@ case "${target}" in srv_regobj=3D"${srv_regobj} powerpc-isa205-64l.o" srv_regobj=3D"${srv_regobj} powerpc-isa205-altivec64l.o" srv_regobj=3D"${srv_regobj} powerpc-isa205-vsx64l.o" - srv_tgtobj=3D"$srv_linux_obj linux-ppc-low.o" + srv_tgtobj=3D"$srv_linux_obj linux-ppc-low.o ppc-linux.o" srv_xmlfiles=3D"rs6000/powerpc-32l.xml" srv_xmlfiles=3D"${srv_xmlfiles} rs6000/powerpc-altivec32l.xml" srv_xmlfiles=3D"${srv_xmlfiles} rs6000/powerpc-cell32l.xml" diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c index 6e880c1..188fac0 100644 --- a/gdb/gdbserver/linux-ppc-low.c +++ b/gdb/gdbserver/linux-ppc-low.c @@ -398,13 +398,11 @@ ppc_arch_setup (void) current_process ()->tdesc =3D tdesc; ppc_hwcap =3D 0; =20 - /* Only if the high bit of the MSR is set, we actually have - a 64-bit inferior. */ regcache =3D new_register_cache (tdesc); fetch_inferior_registers (regcache, find_regno (tdesc, "msr")); collect_register_by_name (regcache, "msr", &msr); free_register_cache (regcache); - if (msr < 0) + if (ppc64_64bit_inferior_p (msr)) { ppc_get_hwcap (&ppc_hwcap); if (ppc_hwcap & PPC_FEATURE_CELL) diff --git a/gdb/nat/ppc-linux.c b/gdb/nat/ppc-linux.c new file mode 100644 index 0000000..a29c9bd --- /dev/null +++ b/gdb/nat/ppc-linux.c @@ -0,0 +1,77 @@ +/*Copyright (C) 2015 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . = */ + +#include "common-defs.h" +#include "ppc-linux.h" +#include + +#ifdef HAVE_GETAUXVAL +#include +#endif + +#ifdef __powerpc64__ + +/* Get the HWCAP from the process of GDB or GDBserver. If success, + save it in *VALP. */ + +static void +ppc64_host_hwcap (unsigned long *valp) +{ +#ifdef HAVE_GETAUXVAL + *valp =3D getauxval (AT_HWCAP); +#else + unsigned char data[2 * 8]; + FILE *f =3D fopen ("/proc/self/auxv", "r"); + + if (f =3D=3D NULL) + return; + + while (fread (data, sizeof (data), 1, f) > 0) + { + unsigned long *data_p =3D (unsigned long *) data; + + if (data_p[0] =3D=3D AT_HWCAP) + { + *valp =3D data_p[1]; + break; + } + } + + fclose (f); +#endif /* HAVE_GETAUXVAL */ +} + +int +ppc64_64bit_inferior_p (long msr) +{ + unsigned long ppc_host_hwcap =3D 0; + + /* Get host's HWCAP to check whether the machine is Book E. */ + ppc64_host_hwcap (&ppc_host_hwcap); + + /* We actually have a 64-bit inferior only if the certain bit of the + MSR is set. The PowerISA Book III-S MSR is different from the + PowerISA Book III-E MSR. The Book III-S MSR is 64 bits wide, and + its MSR[SF] is the bit 0 of a 64-bit value. Book III-E MSR is 32 + bits wide, and its MSR[CM] is the bit 0 of a 32-bit value. */ + if (ppc_host_hwcap & PPC_FEATURE_BOOKE) + return msr & 0x80000000; + else + return msr < 0; +} + +#endif diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h index 30d936f..0ff2223 100644 --- a/gdb/nat/ppc-linux.h +++ b/gdb/nat/ppc-linux.h @@ -82,4 +82,10 @@ #define PTRACE_SETEVRREGS 21 #endif =20 +#ifdef __powerpc64__ +/* Return whether the inferior is 64bit or not by checking certain bit + in MSR. */ +int ppc64_64bit_inferior_p (long msr); +#endif + #endif diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index c5a286b..88ca49e 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -2367,7 +2367,7 @@ ppc_linux_target_wordsize (void) =20 errno =3D 0; msr =3D (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0); - if (errno =3D=3D 0 && msr < 0) + if (errno =3D=3D 0 && ppc64_64bit_inferior_p (msr)) wordsize =3D 8; #endif =20