This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[rfc] Fix word-size detection in PowerPC Linux native target
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 21 Jan 2009 23:56:47 +0100 (CET)
- Subject: [rfc] Fix word-size detection in PowerPC Linux native target
Hello,
the ppc-linux-nat.c:ppc_linux_read_description routine carefully attempts
to detect whether the current inferior is a 32-bit or 64-bit process.
However, before it does so, the code has already make implicit assumptions
on the wordsize:
if (ppc_linux_get_hwcap () & PPC_FEATURE_ARCH_2_05)
isa205 = 1;
as the ppc_linux_get_hwcap routine calls target_auxv_search, which uses
the target wordsize as the size of auxillary vector entries ...
Now, in most scenarios, this doesn't matter, because at that point the
currently active architecture will be used, which will usually already
have the correct wordsize, as it was determined from the exec file.
However, there are some scenarios where determining the wordsize
actually matters (e.g. because the exec file cannot be determined).
In those cases, the attempts in ppc_linux_read_description would be
somewhat futile ...
The following patch overrides the target's to_auxv_parse callback
as well, so that it can use the same mechanism currently used in
ppc_linux_read_description in order to find the size of auxillary
vector entries. This fixed the problem above.
Tested on powerpc64-linux (64-bit / 32-bit).
Any comment? If there are objections, I'm planning to commit
this in a couple of days ...
Bye,
Ulrich
ChangeLog:
* ppc-linux-nat.c (ppc_linux_target_wordsize): New function.
(ppc_linux_auxv_parse): New function.
(ppc_linux_read_description): Use ppc_linux_target_wordsize.
(_initialize_ppc_linux_nat): Install ppc_linux_auxv_parse.
Index: src/gdb/ppc-linux-nat.c
===================================================================
--- src.orig/gdb/ppc-linux-nat.c
+++ src/gdb/ppc-linux-nat.c
@@ -1238,6 +1238,51 @@ fill_fpregset (const struct regcache *re
fpregsetp, sizeof (*fpregsetp));
}
+static int
+ppc_linux_target_wordsize (void)
+{
+ int wordsize = 4;
+
+ /* Check for 64-bit inferior process. This is the case when the host is
+ 64-bit, and in addition the top bit of the MSR register is set. */
+#ifdef __powerpc64__
+ long msr;
+
+ int tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid);
+
+ errno = 0;
+ msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0);
+ if (errno == 0 && msr < 0)
+ wordsize = 8;
+#endif
+
+ return wordsize;
+}
+
+static int
+ppc_linux_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+{
+ int sizeof_auxv_field = ppc_linux_target_wordsize ();
+ gdb_byte *ptr = *readptr;
+
+ if (endptr == ptr)
+ return 0;
+
+ if (endptr - ptr < sizeof_auxv_field * 2)
+ return -1;
+
+ *typep = extract_unsigned_integer (ptr, sizeof_auxv_field);
+ ptr += sizeof_auxv_field;
+ *valp = extract_unsigned_integer (ptr, sizeof_auxv_field);
+ ptr += sizeof_auxv_field;
+
+ *readptr = ptr;
+ return 1;
+}
+
static const struct target_desc *
ppc_linux_read_description (struct target_ops *ops)
{
@@ -1291,24 +1336,15 @@ ppc_linux_read_description (struct targe
if (ppc_linux_get_hwcap () & PPC_FEATURE_ARCH_2_05)
isa205 = 1;
- /* Check for 64-bit inferior process. This is the case when the host is
- 64-bit, and in addition the top bit of the MSR register is set. */
-#ifdef __powerpc64__
- {
- long msr;
- errno = 0;
- msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0);
- if (errno == 0 && msr < 0)
- {
- if (vsx)
- return isa205? tdesc_powerpc_isa205_vsx64l : tdesc_powerpc_vsx64l;
- else if (altivec)
- return isa205? tdesc_powerpc_isa205_altivec64l : tdesc_powerpc_altivec64l;
-
- return isa205? tdesc_powerpc_isa205_64l : tdesc_powerpc_64l;
- }
- }
-#endif
+ if (ppc_linux_target_wordsize () == 8)
+ {
+ if (vsx)
+ return isa205? tdesc_powerpc_isa205_vsx64l : tdesc_powerpc_vsx64l;
+ else if (altivec)
+ return isa205? tdesc_powerpc_isa205_altivec64l : tdesc_powerpc_altivec64l;
+
+ return isa205? tdesc_powerpc_isa205_64l : tdesc_powerpc_64l;
+ }
if (vsx)
return isa205? tdesc_powerpc_isa205_vsx32l : tdesc_powerpc_vsx32l;
@@ -1342,6 +1378,7 @@ _initialize_ppc_linux_nat (void)
t->to_watchpoint_addr_within_range = ppc_linux_watchpoint_addr_within_range;
t->to_read_description = ppc_linux_read_description;
+ t->to_auxv_parse = ppc_linux_auxv_parse;
/* Register the target. */
linux_nat_add_target (t);
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com