+2020-04-09 Kamil Rytarowski <n54@gmx.com>
+
+ * auxv.h (svr4_auxv_parse): New.
+ * auxv.c (default_auxv_parse): Split into default_auxv_parse
+ and generic_auxv_parse.
+ (svr4_auxv_parse): Add.
+ * obsd-tdep.c: Include "auxv.h".
+ (obsd_auxv_parse): Remove.
+ (obsd_init_abi): Remove comment.
+ (obsd_init_abi): Change set_gdbarch_auxv_parse passed argument
+ from `obsd_auxv_parse' to `svr4_auxv_parse'.
+ * nbsd-tdep.c: Include "auxv.h".
+ (nbsd_init_abi): Call set_gdbarch_auxv_parse.
+
2020-04-08 Tom Tromey <tromey@adacore.com>
* nat/windows-nat.h (last_wait_event): Don't declare.
return procfs_xfer_auxv (readbuf, writebuf, offset, len, xfered_len);
}
-/* 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
-default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
- gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+/* This function compared to other auxv_parse functions: it takes the size of
+ the auxv type field as a parameter. */
+
+static int
+generic_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp,
+ int sizeof_auxv_type)
{
- const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch ())
- / TARGET_CHAR_BIT;
- const enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+ struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+ const int sizeof_auxv_val = TYPE_LENGTH (ptr_type);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte *ptr = *readptr;
if (endptr == ptr)
return 0;
- if (endptr - ptr < sizeof_auxv_field * 2)
+ if (endptr - ptr < 2 * sizeof_auxv_val)
return -1;
- *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
- ptr += sizeof_auxv_field;
- *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
- ptr += sizeof_auxv_field;
+ *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order);
+ /* Even if the auxv type takes less space than an auxv value, there is
+ padding after the type such that the value is aligned on a multiple of
+ its size (and this is why we advance by `sizeof_auxv_val` and not
+ `sizeof_auxv_type`). */
+ ptr += sizeof_auxv_val;
+ *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order);
+ ptr += sizeof_auxv_val;
*readptr = ptr;
return 1;
}
+/* See auxv.h. */
+
+int
+default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+{
+ struct gdbarch *gdbarch = target_gdbarch ();
+ struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+ const int sizeof_auxv_type = TYPE_LENGTH (ptr_type);
+
+ return generic_auxv_parse (gdbarch, readptr, endptr, typep, valp,
+ sizeof_auxv_type);
+}
+
+/* See auxv.h. */
+
+int
+svr4_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+{
+ struct type *int_type = builtin_type (gdbarch)->builtin_int;
+ const int sizeof_auxv_type = TYPE_LENGTH (int_type);
+
+ return generic_auxv_parse (gdbarch, readptr, endptr, typep, valp,
+ sizeof_auxv_type);
+}
+
/* 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.
/* See "include/elf/common.h" for the definition of valid AT_* values. */
/* The default implementation of to_auxv_parse, used by the target
- stack. */
+ stack.
+ 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. */
extern int default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
gdb_byte *endptr, CORE_ADDR *typep,
CORE_ADDR *valp);
+/* The SVR4 psABI implementation of to_auxv_parse, that uses an int to
+ store the type rather than long as assumed by the default parser.
+
+ 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. */
+extern int svr4_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep,
+ CORE_ADDR *valp);
+
/* 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.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
+#include "auxv.h"
#include "solib-svr4.h"
#include "nbsd-tdep.h"
#include "gdbarch.h"
set_gdbarch_gdb_signal_from_target (gdbarch, nbsd_gdb_signal_from_target);
set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target);
set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
+ set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse);
}
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
+#include "auxv.h"
#include "frame.h"
#include "symtab.h"
#include "objfiles.h"
return -1;
}
-static int
-obsd_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr,
- gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
-{
- struct type *int_type = builtin_type (gdbarch)->builtin_int;
- struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
- const int sizeof_auxv_type = TYPE_LENGTH (int_type);
- const int sizeof_auxv_val = TYPE_LENGTH (ptr_type);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte *ptr = *readptr;
-
- if (endptr == ptr)
- return 0;
-
- if (endptr - ptr < 2 * sizeof_auxv_val)
- return -1;
-
- *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order);
- ptr += sizeof_auxv_val; /* Alignment. */
- *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order);
- ptr += sizeof_auxv_val;
-
- *readptr = ptr;
- return 1;
-}
-
void
obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
set_gdbarch_gdb_signal_to_target (gdbarch,
obsd_gdb_signal_to_target);
- /* Unlike Linux, OpenBSD actually follows the ELF standard. */
- set_gdbarch_auxv_parse (gdbarch, obsd_auxv_parse);
+ set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse);
}