2004-02-28 Andrew Cagney <cagney@redhat.com>

* amd64-linux-nat.c (ps_get_thread_area): When architecture is
	i386 use PTRACE_GET_THREAD_AREA.  Suggested by Roland McGrath.
This commit is contained in:
Andrew Cagney 2004-02-28 19:38:21 +00:00
parent b6d42148e9
commit 50d71875b9
2 changed files with 52 additions and 18 deletions

View file

@ -1,3 +1,8 @@
2004-02-28 Andrew Cagney <cagney@redhat.com>
* amd64-linux-nat.c (ps_get_thread_area): When architecture is
i386 use PTRACE_GET_THREAD_AREA. Suggested by Roland McGrath.
2004-02-28 Mark Kettenis <kettenis@gnu.org> 2004-02-28 Mark Kettenis <kettenis@gnu.org>
* amd64-tdep.c (amd64_frame_cache): Fix comment. * amd64-tdep.c (amd64_frame_cache): Fix comment.

View file

@ -350,31 +350,60 @@ amd64_linux_dr_get_status (void)
} }
/* This function is called by libthread_db as part of its handling of
a request for a thread's local storage address. */
ps_err_e ps_err_e
ps_get_thread_area (const struct ps_prochandle *ph, ps_get_thread_area (const struct ps_prochandle *ph,
lwpid_t lwpid, int idx, void **base) lwpid_t lwpid, int idx, void **base)
{ {
/* This definition comes from prctl.h, but some kernels may not have it. */ if (gdbarch_ptr_bit (current_gdbarch) == 32)
{
/* The full structure is found in <asm-i386/ldt.h>. 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;
}
else
{
/* This definition comes from prctl.h, but some kernels may not
have it. */
#ifndef PTRACE_ARCH_PRCTL #ifndef PTRACE_ARCH_PRCTL
#define PTRACE_ARCH_PRCTL 30 #define PTRACE_ARCH_PRCTL 30
#endif #endif
/* FIXME: ezannoni-2003-07-09 see comment above about include
/* FIXME: ezannoni-2003-07-09 see comment above about include file order. file order. We could be getting bogus values for these two. */
We could be getting bogus values for these two. */ gdb_assert (FS < ELF_NGREG);
gdb_assert (FS < ELF_NGREG); gdb_assert (GS < ELF_NGREG);
gdb_assert (GS < ELF_NGREG); switch (idx)
switch (idx) {
{ case FS:
case FS: if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0) return PS_OK;
return PS_OK; break;
break; case GS:
case GS: if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0) return PS_OK;
return PS_OK; break;
break; default: /* Should not happen. */
default: /* Should not happen. */ return PS_BADADDR;
return PS_BADADDR; }
} }
return PS_ERR; /* ptrace failed. */ return PS_ERR; /* ptrace failed. */
} }