aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Prus <vladimir@codesourcery.com>2008-05-04 09:28:27 +0000
committerVladimir Prus <vladimir@codesourcery.com>2008-05-04 09:28:27 +0000
commitc47ffbe3b159da69fcc66cb7ad3a69077641b384 (patch)
tree2b2787dd5be1f1afca6ee3cb7c9ad40950507445
parent55cd6f92dce132108458c2b1bcdba08fc7feb5da (diff)
downloadgdb-c47ffbe3b159da69fcc66cb7ad3a69077641b384.zip
gdb-c47ffbe3b159da69fcc66cb7ad3a69077641b384.tar.gz
gdb-c47ffbe3b159da69fcc66cb7ad3a69077641b384.tar.bz2
Fix auxv data parsing on 64-bit solaris
* target.h (struct target_ops): New field to_auxv_parse. * auxv.c (default_auxv_parse): New, renamed from previous target_auxv_parse. (target_auxv_parse): Try to call target method. Fallback to default_auxv_parse if not found. * procfs.c (procfs_auxv_parse): New. (init_procfs_ops): On Solaris, in 64-bit mode, install procfs_auxv_parse.
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/auxv.c18
-rw-r--r--gdb/procfs.c34
-rw-r--r--gdb/target.h7
4 files changed, 69 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5a002a7..a41bf87 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2008-05-04 Vladimir Prus <vladimir@codesourcery.com>
+
+ * target.h (struct target_ops): New field to_auxv_parse.
+ * auxv.c (default_auxv_parse): New, renamed from previous
+ target_auxv_parse.
+ (target_auxv_parse): Try to call target method. Fallback to
+ default_auxv_parse if not found.
+ * procfs.c (procfs_auxv_parse): New.
+ (init_procfs_ops): On Solaris, in 64-bit mode, install
+ procfs_auxv_parse.
+
2008-05-03 Adam Nemet <anemet@caviumnetworks.com>
* symfile.c (add_symbol_file_command): Use paddress rather than
diff --git a/gdb/auxv.c b/gdb/auxv.c
index d1d93e7..292a0d6 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -79,7 +79,7 @@ procfs_xfer_auxv (struct target_ops *ops,
Return -1 if there is insufficient buffer for a whole entry.
Return 1 if an entry was read into *TYPEP and *VALP. */
int
-target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
+default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
{
const int sizeof_auxv_field = TYPE_LENGTH (builtin_type_void_data_ptr);
@@ -100,6 +100,22 @@ target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
return 1;
}
+/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
+ Return 0 if *READPTR is already at the end of the buffer.
+ Return -1 if there is insufficient buffer for a whole entry.
+ Return 1 if an entry was read into *TYPEP and *VALP. */
+int
+target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+{
+ struct target_ops *t;
+ for (t = ops; t != NULL; t = t->beneath)
+ if (t->to_auxv_parse != NULL)
+ return t->to_auxv_parse (t, readptr, endptr, typep, valp);
+
+ return default_auxv_parse (ops, readptr, endptr, typep, valp);
+}
+
/* Extract the auxiliary vector entry with a_type matching MATCH.
Return zero if no such entry was found, or -1 if there was
an error getting the information. On success, return 1 after
diff --git a/gdb/procfs.c b/gdb/procfs.c
index f40b388..da9fd4c 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -152,6 +152,35 @@ static int procfs_can_use_hw_breakpoint (int, int, int);
struct target_ops procfs_ops; /* the target vector */
+#if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+/* When GDB is built as 64-bit application on Solaris, the auxv data is
+ presented in 64-bit format. We need to provide a custom parser to handle
+ that. */
+static int
+procfs_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+{
+ const int pointer_size = TYPE_LENGTH (builtin_type_void_data_ptr);
+ gdb_byte *ptr = *readptr;
+
+ if (endptr == ptr)
+ return 0;
+
+ if (endptr - ptr < 8 * 2)
+ return -1;
+
+ *typep = extract_unsigned_integer (ptr, 4);
+ ptr += 8;
+ /* The size of data is always 64-bit. If the application is 32-bit,
+ it will be zero extended, as expected. */
+ *valp = extract_unsigned_integer (ptr, 8);
+ ptr += 8;
+
+ *readptr = ptr;
+ return 1;
+}
+#endif
+
static void
init_procfs_ops (void)
{
@@ -200,6 +229,11 @@ init_procfs_ops (void)
procfs_ops.to_find_memory_regions = proc_find_memory_regions;
procfs_ops.to_make_corefile_notes = procfs_make_note_section;
procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
+
+#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+ procfs_ops.to_auxv_parse = procfs_auxv_parse;
+#endif
+
procfs_ops.to_magic = OPS_MAGIC;
}
diff --git a/gdb/target.h b/gdb/target.h
index 3b424ba..8822a40 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -498,6 +498,13 @@ struct target_ops
was available. */
const struct target_desc *(*to_read_description) (struct target_ops *ops);
+ /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
+ Return 0 if *READPTR is already at the end of the buffer.
+ Return -1 if there is insufficient buffer for a whole entry.
+ Return 1 if an entry was read into *TYPEP and *VALP. */
+ int (*to_auxv_parse) (struct target_ops *ops, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp);
+
int to_magic;
/* Need sub-structure for target machine related rather than comm related?
*/