From patchwork Fri Jun 27 14:12:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gary Benson X-Patchwork-Id: 1793 Received: (qmail 11081 invoked by alias); 27 Jun 2014 14:12:48 -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 11059 invoked by uid 89); 27 Jun 2014 14:12:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.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; Fri, 27 Jun 2014 14:12:46 +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 s5RECioc022172 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 27 Jun 2014 10:12:44 -0400 Received: from blade.nx (ovpn-116-77.ams2.redhat.com [10.36.116.77]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s5RECh8k015538; Fri, 27 Jun 2014 10:12:43 -0400 Received: from blade.nx (localhost [127.0.0.1]) by blade.nx (Postfix) with ESMTP id CA93F2640BE; Fri, 27 Jun 2014 15:12:42 +0100 (BST) From: Gary Benson To: gdb-patches@sourceware.org Cc: Mark Kettenis , Pedro Alves Subject: [PATCH 3/7 v2] Merge ps_get_thread_area Date: Fri, 27 Jun 2014 15:12:27 +0100 Message-Id: <1403878351-22974-4-git-send-email-gbenson@redhat.com> In-Reply-To: <1403878351-22974-1-git-send-email-gbenson@redhat.com> References: <1403878351-22974-1-git-send-email-gbenson@redhat.com> X-IsSubscribed: yes This commit adds a new helper, x86_linux_get_thread_area, to hold the common parts of the ps_get_thread_area functions in i386-linux-nat.c and amd64-linux-nat.c. This patch is unchanged from the original version in this series. gdb/ 2014-06-27 Gary Benson * amd64-linux-nat.c (x86_linux_get_thread_area): New function. (ps_get_thread_area): Delegate to the above in 32-bit mode. * i386-linux-nat.c (x86_linux_get_thread_area): New function. (ps_get_thread_area): Delegate to the above. --- gdb/ChangeLog | 7 +++++ gdb/amd64-linux-nat.c | 73 +++++++++++++++++++++++++++++++++++------------- gdb/i386-linux-nat.c | 36 +++++++++++++++++++----- 3 files changed, 88 insertions(+), 28 deletions(-) diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index c442878..57e5c51 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -490,6 +490,47 @@ x86_linux_new_fork (struct lwp_info *parent, pid_t child_pid) +/* Helper for ps_get_thread_area. Sets BASE_ADDR to a pointer to + the thread local storage (or its descriptor) and returns PS_OK + on success. Returns PS_ERR on failure. */ + +static ps_err_e +x86_linux_get_thread_area (pid_t pid, void *addr, unsigned int *base_addr) +{ + /* NOTE: cagney/2003-08-26: The definition of this buffer is found + in the kernel header . It, after padding, is 4 x + 4 byte integers in size: `entry_number', `base_addr', `limit', + and a bunch of status bits. + + The values returned by this ptrace call should be part of the + regcache buffer, and ps_get_thread_area should channel its + request through the regcache. That way remote targets could + provide the value using the remote protocol and not this direct + call. + + Is this function needed? I'm guessing that the `base' is the + address of a descriptor that libthread_db uses to find the + thread local address base that GDB needs. Perhaps that + descriptor is defined by the ABI. Anyway, given that + libthread_db calls this function without prompting (gdb + requesting tls base) I guess it needs info in there anyway. */ + unsigned int desc[4]; + + /* This code assumes that "int" is 32 bits and that + GET_THREAD_AREA returns no more than 4 int values. */ + gdb_assert (sizeof (int) == 4); + +#ifndef PTRACE_GET_THREAD_AREA +#define PTRACE_GET_THREAD_AREA 25 +#endif + + if (ptrace (PTRACE_GET_THREAD_AREA, pid, addr, &desc) < 0) + return PS_ERR; + + *base_addr = desc[1]; + return PS_OK; +} + /* This function is called by libthread_db as part of its handling of a request for a thread's local storage address. */ @@ -499,26 +540,18 @@ ps_get_thread_area (const struct ps_prochandle *ph, { if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32) { - /* The full structure is found in . The second - integer is the LDT's base_address and that is used to locate - the thread's local storage. See i386-linux-nat.c more - info. */ - unsigned int desc[4]; - - /* This code assumes that "int" is 32 bits and that - GET_THREAD_AREA returns no more than 4 int values. */ - gdb_assert (sizeof (int) == 4); -#ifndef PTRACE_GET_THREAD_AREA -#define PTRACE_GET_THREAD_AREA 25 -#endif - if (ptrace (PTRACE_GET_THREAD_AREA, - lwpid, (void *) (long) idx, (unsigned long) &desc) < 0) - return PS_ERR; - - /* Extend the value to 64 bits. Here it's assumed that a "long" - and a "void *" are the same. */ - (*base) = (void *) (long) desc[1]; - return PS_OK; + unsigned int base_addr; + ps_err_e result; + + result = x86_linux_get_thread_area (lwpid, (void *) (long) idx, + &base_addr); + if (result == PS_OK) + { + /* Extend the value to 64 bits. Here it's assumed that + a "long" and a "void *" are the same. */ + (*base) = (void *) (long) base_addr; + } + return result; } else { diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index 62ad29f..d647c3d 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -848,12 +848,12 @@ x86_linux_new_fork (struct lwp_info *parent, pid_t child_pid) -/* Called by libthread_db. Returns a pointer to the thread local - storage (or its descriptor). */ +/* Helper for ps_get_thread_area. Sets BASE_ADDR to a pointer to + the thread local storage (or its descriptor) and returns PS_OK + on success. Returns PS_ERR on failure. */ -ps_err_e -ps_get_thread_area (const struct ps_prochandle *ph, - lwpid_t lwpid, int idx, void **base) +static ps_err_e +x86_linux_get_thread_area (pid_t pid, void *addr, unsigned int *base_addr) { /* NOTE: cagney/2003-08-26: The definition of this buffer is found in the kernel header . It, after padding, is 4 x @@ -873,19 +873,39 @@ ps_get_thread_area (const struct ps_prochandle *ph, libthread_db calls this function without prompting (gdb requesting tls base) I guess it needs info in there anyway. */ unsigned int desc[4]; + + /* This code assumes that "int" is 32 bits and that + GET_THREAD_AREA returns no more than 4 int values. */ gdb_assert (sizeof (int) == 4); #ifndef PTRACE_GET_THREAD_AREA #define PTRACE_GET_THREAD_AREA 25 #endif - if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, - (void *) idx, (unsigned long) &desc) < 0) + if (ptrace (PTRACE_GET_THREAD_AREA, pid, addr, &desc) < 0) return PS_ERR; - *(int *)base = desc[1]; + *base_addr = desc[1]; return PS_OK; } + +/* Called by libthread_db. Returns a pointer to the thread local + storage (or its descriptor). */ + +ps_err_e +ps_get_thread_area (const struct ps_prochandle *ph, + lwpid_t lwpid, int idx, void **base) +{ + unsigned int base_addr; + ps_err_e result; + + result = x86_linux_get_thread_area (lwpid, (void *) idx, &base_addr); + + if (result == PS_OK) + *(int *) base = base_addr; + + return result; +} /* The instruction for a GNU/Linux system call is: