diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-08-26 16:07:22 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-08-26 16:07:22 +0000 |
commit | 49b75da26ac7c23305d18a4e5c1e0c43265fa0af (patch) | |
tree | 6b43a446ce30f6afa366ebff572856da6536d701 | |
parent | db7a6fe44e18f382d05ea543ed3aa15cfd0cf086 (diff) | |
download | gdb-49b75da26ac7c23305d18a4e5c1e0c43265fa0af.zip gdb-49b75da26ac7c23305d18a4e5c1e0c43265fa0af.tar.gz gdb-49b75da26ac7c23305d18a4e5c1e0c43265fa0af.tar.bz2 |
2003-08-21 Andrew Cagney <cagney@redhat.com>cagney_x86i386-20030821-branch
* x86-64-linux-nat.c (ps_get_thread_area): When architecture is
i386 use PTRACE_GET_THREAD_AREA. Suggested by Roland McGrath.
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/x86-64-linux-nat.c | 76 |
2 files changed, 63 insertions, 18 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 05da66d..d6f39a9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,10 @@ 2003-08-21 Andrew Cagney <cagney@redhat.com> + * x86-64-linux-nat.c (ps_get_thread_area): When architecture is + i386 use PTRACE_GET_THREAD_AREA. Suggested by Roland McGrath. + +2003-08-21 Andrew Cagney <cagney@redhat.com> + * thread-db.c (verbose_dlsym): New function. (thread_db_load): Use verbose_dlsym (thread_db_new_objfile): Print that libthread_db was loaded, and diff --git a/gdb/x86-64-linux-nat.c b/gdb/x86-64-linux-nat.c index f589463..efe0f91 100644 --- a/gdb/x86-64-linux-nat.c +++ b/gdb/x86-64-linux-nat.c @@ -314,34 +314,74 @@ x86_64_linux_dr_get_status (void) return x86_64_linux_dr_get (DR_STATUS); } +/* This function is called by libthread_db as part of its handling of + a request for a thread's local storage address. */ + extern ps_err_e ps_get_thread_area (const struct ps_prochandle *ph, lwpid_t lwpid, int idx, void **base) { -/* This definition comes from prctl.h, but some kernels may not have it. */ + switch (TARGET_ARCHITECTURE->mach) + { + case bfd_mach_i386_i386: + case bfd_mach_i386_i386_intel_syntax: + { + /* 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; + } + + case bfd_mach_x86_64: + case bfd_mach_x86_64_intel_syntax: + + /* This definition comes from prctl.h, but some kernels may not + have it. */ #ifndef PTRACE_ARCH_PRCTL #define PTRACE_ARCH_PRCTL 30 #endif - /* FIXME: ezannoni-2003-07-09 see comment above about include file order. - We could be getting bogus values for these two. */ - gdb_assert (FS < ELF_NGREG); - gdb_assert (GS < ELF_NGREG); - switch (idx) - { - case FS: - if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0) - return PS_OK; - break; - case GS: - if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0) - return PS_OK; - break; - default: /* Should not happen. */ - return PS_BADADDR; + /* FIXME: ezannoni-2003-07-09 see comment above about include + file order. We could be getting bogus values for these two. */ + gdb_assert (FS < ELF_NGREG); + gdb_assert (GS < ELF_NGREG); + switch (idx) + { + case FS: + if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0) + return PS_OK; + break; + case GS: + if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0) + return PS_OK; + break; + default: /* Should not happen. */ + return PS_BADADDR; + } + return PS_ERR; /* ptrace failed. */ + + case bfd_mach_i386_i8086: + internal_error (__FILE__, __LINE__, "bad i8086 machine"); + default: + internal_error (__FILE__, __LINE__, "bad_switch"); } - return PS_ERR; /* ptrace failed. */ } void |