|
|
0c1cd1 |
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
|
|
0c1cd1 |
From: Keith Seitz <keiths@redhat.com>
|
|
|
0c1cd1 |
Date: Mon, 27 Jul 2020 18:01:32 -0400
|
|
|
0c1cd1 |
Subject: gdb-rhbz1842691-corefile-mem-access-7of15.patch
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
;; Add new gdbarch method, read_core_file_mappings
|
|
|
0c1cd1 |
;; Kevin Buettner, RH BZ 1842961
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
Author: Kevin Buettner <kevinb@redhat.com>
|
|
|
0c1cd1 |
Date: Fri Jul 3 13:32:08 2020 -0700
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
Add new gdbarch method, read_core_file_mappings
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
The new gdbarch method, read_core_file_mappings, will be used for
|
|
|
0c1cd1 |
reading file-backed mappings from a core file. It'll be used
|
|
|
0c1cd1 |
for two purposes: 1) to construct a table of file-backed mappings
|
|
|
0c1cd1 |
in corelow.c, and 2) for display of core file mappings.
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
For Linux, I tried a different approach in which knowledge of the note
|
|
|
0c1cd1 |
format was placed directly in corelow.c. This seemed okay at first;
|
|
|
0c1cd1 |
it was only one note format and the note format was fairly simple.
|
|
|
0c1cd1 |
After looking at FreeBSD's note/mapping reading code, I concluded
|
|
|
0c1cd1 |
that it's best to leave architecture specific details for decoding
|
|
|
0c1cd1 |
the note in (architecture specific) tdep files.
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
With regard to display of core file mappings, I experimented with
|
|
|
0c1cd1 |
placing the mappings display code in corelow.c. It has access to the
|
|
|
0c1cd1 |
file-backed mappings which were read in when the core file was loaded.
|
|
|
0c1cd1 |
And, better, still common code could be used for all architectures.
|
|
|
0c1cd1 |
But, again, the FreeBSD mapping code convinced me that this was not
|
|
|
0c1cd1 |
the best approach since it has even more mapping info than Linux.
|
|
|
0c1cd1 |
Display code which would work well for Linux will leave out mappings
|
|
|
0c1cd1 |
as well as protection info for mappings.
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
So, for these reasons, I'm introducing a new gdbarch method for
|
|
|
0c1cd1 |
reading core file mappings.
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
gdb/ChangeLog:
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
* arch-utils.c (default_read_core_file_mappings): New function.
|
|
|
0c1cd1 |
* arch-utils.c (default_read_core_file_mappings): Declare.
|
|
|
0c1cd1 |
* gdbarch.sh (read_core_file_mappings): New gdbarch method.
|
|
|
0c1cd1 |
* gdbarch.h, gdbarch.c: Regenerate.
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
|
|
|
0c1cd1 |
--- a/gdb/arch-utils.c
|
|
|
0c1cd1 |
+++ b/gdb/arch-utils.c
|
|
|
0c1cd1 |
@@ -997,6 +997,22 @@ default_type_align (struct gdbarch *gdbarch, struct type *type)
|
|
|
0c1cd1 |
return type_length_units (check_typedef (type));
|
|
|
0c1cd1 |
}
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
+/* See arch-utils.h. */
|
|
|
0c1cd1 |
+void
|
|
|
0c1cd1 |
+default_read_core_file_mappings (struct gdbarch *gdbarch,
|
|
|
0c1cd1 |
+ struct bfd *cbfd,
|
|
|
0c1cd1 |
+ gdb::function_view<void (ULONGEST count)>
|
|
|
0c1cd1 |
+ pre_loop_cb,
|
|
|
0c1cd1 |
+ gdb::function_view
|
|
|
0c1cd1 |
+ ULONGEST start,
|
|
|
0c1cd1 |
+ ULONGEST end,
|
|
|
0c1cd1 |
+ ULONGEST file_ofs,
|
|
|
0c1cd1 |
+ const char *filename,
|
|
|
0c1cd1 |
+ const void *other)>
|
|
|
0c1cd1 |
+ loop_cb)
|
|
|
0c1cd1 |
+{
|
|
|
0c1cd1 |
+}
|
|
|
0c1cd1 |
+
|
|
|
0c1cd1 |
void
|
|
|
0c1cd1 |
_initialize_gdbarch_utils (void)
|
|
|
0c1cd1 |
{
|
|
|
0c1cd1 |
diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h
|
|
|
0c1cd1 |
--- a/gdb/arch-utils.h
|
|
|
0c1cd1 |
+++ b/gdb/arch-utils.h
|
|
|
0c1cd1 |
@@ -271,4 +271,16 @@ extern bool default_in_indirect_branch_thunk (gdbarch *gdbarch,
|
|
|
0c1cd1 |
extern ULONGEST default_type_align (struct gdbarch *gdbarch,
|
|
|
0c1cd1 |
struct type *type);
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
+/* Default implementation of gdbarch read_core_file_mappings method. */
|
|
|
0c1cd1 |
+extern void default_read_core_file_mappings (struct gdbarch *gdbarch,
|
|
|
0c1cd1 |
+ struct bfd *cbfd,
|
|
|
0c1cd1 |
+ gdb::function_view<void (ULONGEST count)>
|
|
|
0c1cd1 |
+ pre_loop_cb,
|
|
|
0c1cd1 |
+ gdb::function_view
|
|
|
0c1cd1 |
+ ULONGEST start,
|
|
|
0c1cd1 |
+ ULONGEST end,
|
|
|
0c1cd1 |
+ ULONGEST file_ofs,
|
|
|
0c1cd1 |
+ const char *filename,
|
|
|
0c1cd1 |
+ const void *other)>
|
|
|
0c1cd1 |
+ loop_cb);
|
|
|
0c1cd1 |
#endif
|
|
|
0c1cd1 |
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
|
|
|
0c1cd1 |
--- a/gdb/gdbarch.c
|
|
|
0c1cd1 |
+++ b/gdb/gdbarch.c
|
|
|
0c1cd1 |
@@ -354,6 +354,7 @@ struct gdbarch
|
|
|
0c1cd1 |
char ** disassembler_options;
|
|
|
0c1cd1 |
const disasm_options_and_args_t * valid_disassembler_options;
|
|
|
0c1cd1 |
gdbarch_type_align_ftype *type_align;
|
|
|
0c1cd1 |
+ gdbarch_read_core_file_mappings_ftype *read_core_file_mappings;
|
|
|
0c1cd1 |
};
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
/* Create a new ``struct gdbarch'' based on information provided by
|
|
|
0c1cd1 |
@@ -466,6 +467,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
|
|
|
0c1cd1 |
gdbarch->gnu_triplet_regexp = default_gnu_triplet_regexp;
|
|
|
0c1cd1 |
gdbarch->addressable_memory_unit_size = default_addressable_memory_unit_size;
|
|
|
0c1cd1 |
gdbarch->type_align = default_type_align;
|
|
|
0c1cd1 |
+ gdbarch->read_core_file_mappings = default_read_core_file_mappings;
|
|
|
0c1cd1 |
/* gdbarch_alloc() */
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
return gdbarch;
|
|
|
0c1cd1 |
@@ -712,6 +714,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
|
|
0c1cd1 |
/* Skip verify of disassembler_options, invalid_p == 0 */
|
|
|
0c1cd1 |
/* Skip verify of valid_disassembler_options, invalid_p == 0 */
|
|
|
0c1cd1 |
/* Skip verify of type_align, invalid_p == 0 */
|
|
|
0c1cd1 |
+ /* Skip verify of read_core_file_mappings, invalid_p == 0 */
|
|
|
0c1cd1 |
if (!log.empty ())
|
|
|
0c1cd1 |
internal_error (__FILE__, __LINE__,
|
|
|
0c1cd1 |
_("verify_gdbarch: the following are invalid ...%s"),
|
|
|
0c1cd1 |
@@ -1275,6 +1278,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
|
|
0c1cd1 |
fprintf_unfiltered (file,
|
|
|
0c1cd1 |
"gdbarch_dump: ravenscar_ops = %s\n",
|
|
|
0c1cd1 |
host_address_to_string (gdbarch->ravenscar_ops));
|
|
|
0c1cd1 |
+ fprintf_unfiltered (file,
|
|
|
0c1cd1 |
+ "gdbarch_dump: read_core_file_mappings = <%s>\n",
|
|
|
0c1cd1 |
+ host_address_to_string (gdbarch->read_core_file_mappings));
|
|
|
0c1cd1 |
fprintf_unfiltered (file,
|
|
|
0c1cd1 |
"gdbarch_dump: gdbarch_read_pc_p() = %d\n",
|
|
|
0c1cd1 |
gdbarch_read_pc_p (gdbarch));
|
|
|
0c1cd1 |
@@ -5117,6 +5123,23 @@ set_gdbarch_type_align (struct gdbarch *gdbarch,
|
|
|
0c1cd1 |
gdbarch->type_align = type_align;
|
|
|
0c1cd1 |
}
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
+void
|
|
|
0c1cd1 |
+gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, struct bfd *cbfd,gdb::function_view<void (ULONGEST count)> pre_loop_cb,gdb::function_view<void (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, const char *filename, const void *other)> loop_cb)
|
|
|
0c1cd1 |
+{
|
|
|
0c1cd1 |
+ gdb_assert (gdbarch != NULL);
|
|
|
0c1cd1 |
+ gdb_assert (gdbarch->read_core_file_mappings != NULL);
|
|
|
0c1cd1 |
+ if (gdbarch_debug >= 2)
|
|
|
0c1cd1 |
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_read_core_file_mappings called\n");
|
|
|
0c1cd1 |
+ gdbarch->read_core_file_mappings (gdbarch, cbfd, pre_loop_cb, loop_cb);
|
|
|
0c1cd1 |
+}
|
|
|
0c1cd1 |
+
|
|
|
0c1cd1 |
+void
|
|
|
0c1cd1 |
+set_gdbarch_read_core_file_mappings (struct gdbarch *gdbarch,
|
|
|
0c1cd1 |
+ gdbarch_read_core_file_mappings_ftype read_core_file_mappings)
|
|
|
0c1cd1 |
+{
|
|
|
0c1cd1 |
+ gdbarch->read_core_file_mappings = read_core_file_mappings;
|
|
|
0c1cd1 |
+}
|
|
|
0c1cd1 |
+
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
/* Keep a registry of per-architecture data-pointers required by GDB
|
|
|
0c1cd1 |
modules. */
|
|
|
0c1cd1 |
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
|
|
|
0c1cd1 |
--- a/gdb/gdbarch.h
|
|
|
0c1cd1 |
+++ b/gdb/gdbarch.h
|
|
|
0c1cd1 |
@@ -1566,6 +1566,12 @@ typedef ULONGEST (gdbarch_type_align_ftype) (struct gdbarch *gdbarch, struct typ
|
|
|
0c1cd1 |
extern ULONGEST gdbarch_type_align (struct gdbarch *gdbarch, struct type *type);
|
|
|
0c1cd1 |
extern void set_gdbarch_type_align (struct gdbarch *gdbarch, gdbarch_type_align_ftype *type_align);
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
+/* Read core file mappings */
|
|
|
0c1cd1 |
+
|
|
|
0c1cd1 |
+typedef void (gdbarch_read_core_file_mappings_ftype) (struct gdbarch *gdbarch, struct bfd *cbfd,gdb::function_view<void (ULONGEST count)> pre_loop_cb,gdb::function_view<void (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, const char *filename, const void *other)> loop_cb);
|
|
|
0c1cd1 |
+extern void gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, struct bfd *cbfd,gdb::function_view<void (ULONGEST count)> pre_loop_cb,gdb::function_view<void (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, const char *filename, const void *other)> loop_cb);
|
|
|
0c1cd1 |
+extern void set_gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, gdbarch_read_core_file_mappings_ftype *read_core_file_mappings);
|
|
|
0c1cd1 |
+
|
|
|
0c1cd1 |
/* Definition for an unknown syscall, used basically in error-cases. */
|
|
|
0c1cd1 |
#define UNKNOWN_SYSCALL (-1)
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
|
|
|
0c1cd1 |
--- a/gdb/gdbarch.sh
|
|
|
0c1cd1 |
+++ b/gdb/gdbarch.sh
|
|
|
0c1cd1 |
@@ -1164,6 +1164,9 @@ v;const disasm_options_and_args_t *;valid_disassembler_options;;;0;0;;0;host_add
|
|
|
0c1cd1 |
# Type alignment.
|
|
|
0c1cd1 |
m;ULONGEST;type_align;struct type *type;type;;default_type_align;;0
|
|
|
0c1cd1 |
|
|
|
0c1cd1 |
+# Read core file mappings
|
|
|
0c1cd1 |
+m;void;read_core_file_mappings;struct bfd *cbfd,gdb::function_view<void (ULONGEST count)> pre_loop_cb,gdb::function_view<void (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, const char *filename, const void *other)> loop_cb;cbfd, pre_loop_cb, loop_cb;;default_read_core_file_mappings;;0
|
|
|
0c1cd1 |
+
|
|
|
0c1cd1 |
EOF
|
|
|
0c1cd1 |
}
|
|
|
0c1cd1 |
|