/* Target-dependent code for GNU/Linux, architecture independent.
- Copyright (C) 2009-2021 Free Software Foundation, Inc.
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
This file is part of GDB.
#include "inferior.h"
#include "cli/cli-utils.h"
#include "arch-utils.h"
-#include "gdb_obstack.h"
+#include "gdbsupport/gdb_obstack.h"
#include "observable.h"
#include "objfiles.h"
#include "infcall.h"
#include "gdbcmd.h"
-#include "gdb_regex.h"
+#include "gdbsupport/gdb_regex.h"
#include "gdbsupport/enum-flags.h"
#include "gdbsupport/gdb_optional.h"
#include "gcore.h"
#include "gcore-elf.h"
+#include "solib-svr4.h"
#include <ctype.h>
append_composite_type_field (type, "si_fd", int_type);
append_composite_type_field (sifields_type, "_sigpoll", type);
+ /* _sigsys */
+ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (type, "_call_addr", void_ptr_type);
+ append_composite_type_field (type, "_syscall", int_type);
+ append_composite_type_field (type, "_arch", uint_type);
+ append_composite_type_field (sifields_type, "_sigsys", type);
+
/* struct siginfo */
siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
siginfo_type->set_name (xstrdup ("siginfo"));
linux_is_uclinux (void)
{
CORE_ADDR dummy;
+ target_ops *target = current_inferior ()->top_target ();
- return (target_auxv_search (current_top_target (), AT_NULL, &dummy) > 0
- && target_auxv_search (current_top_target (), AT_PAGESZ, &dummy) == 0);
+ return (target_auxv_search (target, AT_NULL, &dummy) > 0
+ && target_auxv_search (target, AT_PAGESZ, &dummy) == 0);
}
static int
for each mapping. */
static void
-linux_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)>
- loop_cb)
+linux_read_core_file_mappings
+ (struct gdbarch *gdbarch,
+ struct bfd *cbfd,
+ read_core_file_mappings_pre_loop_ftype pre_loop_cb,
+ read_core_file_mappings_loop_ftype loop_cb)
{
/* Ensure that ULONGEST is big enough for reading 64-bit core files. */
gdb_static_assert (sizeof (ULONGEST) >= 8);
char * filename = filenames;
filenames += strlen ((char *) filenames) + 1;
- loop_cb (i, start, end, file_ofs, filename);
+ loop_cb (i, start, end, file_ofs, filename, nullptr);
}
}
}
},
[=] (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs,
- const char *filename)
+ const char *filename, const bfd_build_id *build_id)
{
if (gdbarch_addr_bit (gdbarch) == 32)
printf_filtered ("\t%10s %10s %10s %10s %s\n",
gdb::byte_vector buf (TYPE_LENGTH (siginfo_type));
- bytes_read = target_read (current_top_target (), TARGET_OBJECT_SIGNAL_INFO, NULL,
+ bytes_read = target_read (current_inferior ()->top_target (),
+ TARGET_OBJECT_SIGNAL_INFO, NULL,
buf.data (), 0, TYPE_LENGTH (siginfo_type));
if (bytes_read != TYPE_LENGTH (siginfo_type))
buf.clear ();
char filename[100];
/* The basename of the executable. */
const char *basename;
- const char *infargs;
/* Temporary buffer. */
char *tmpstr;
/* The valid states of a process, according to the Linux kernel. */
strncpy (p->pr_fname, basename, sizeof (p->pr_fname) - 1);
p->pr_fname[sizeof (p->pr_fname) - 1] = '\0';
- infargs = get_inferior_args ();
+ const std::string &infargs = current_inferior ()->args ();
/* The arguments of the program. */
std::string psargs = fname.get ();
- if (infargs != NULL)
- psargs = psargs + " " + infargs;
+ if (!infargs.empty ())
+ psargs += ' ' + infargs;
strncpy (p->pr_psargs, psargs.c_str (), sizeof (p->pr_psargs) - 1);
p->pr_psargs[sizeof (p->pr_psargs) - 1] = '\0';
thread_info *signalled_thr = gcore_find_signalled_thread ();
gdb_signal stop_signal;
if (signalled_thr != nullptr)
- stop_signal = signalled_thr->suspend.stop_signal;
+ stop_signal = signalled_thr->stop_signal ();
else
stop_signal = GDB_SIGNAL_0;
/* Auxillary vector. */
gdb::optional<gdb::byte_vector> auxv =
- target_read_alloc (current_top_target (), TARGET_OBJECT_AUXV, NULL);
+ target_read_alloc (current_inferior ()->top_target (),
+ TARGET_OBJECT_AUXV, NULL);
if (auxv && !auxv->empty ())
{
note_data.reset (elfcore_write_note (obfd, note_data.release (),
char filename[100];
long pid;
- if (target_auxv_search (current_top_target (), AT_SYSINFO_EHDR, &range->start) <= 0)
+ if (target_auxv_search (current_inferior ()->top_target (),
+ AT_SYSINFO_EHDR, &range->start) <= 0)
return 0;
/* It doesn't make sense to access the host's /proc when debugging a
local-store address and is thus not usable as displaced stepping
location. The auxiliary vector gets us the PowerPC-side entry
point address instead. */
- if (target_auxv_search (current_top_target (), AT_ENTRY, &addr) <= 0)
+ if (target_auxv_search (current_inferior ()->top_target (),
+ AT_ENTRY, &addr) <= 0)
throw_error (NOT_SUPPORTED_ERROR,
_("Cannot find AT_ENTRY auxiliary vector entry."));
/* Make certain that the address points at real code, and not a
function descriptor. */
- addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
- current_top_target ());
+ addr = gdbarch_convert_from_func_ptr_addr
+ (gdbarch, addr, current_inferior ()->top_target ());
/* Inferior calls also use the entry point as a breakpoint location.
We don't want displaced stepping to interfere with those
gdbarch_data_register_pre_init (init_linux_gdbarch_data);
/* Observers used to invalidate the cache when needed. */
- gdb::observers::inferior_exit.attach (invalidate_linux_cache_inf);
- gdb::observers::inferior_appeared.attach (invalidate_linux_cache_inf);
- gdb::observers::inferior_execd.attach (invalidate_linux_cache_inf);
+ gdb::observers::inferior_exit.attach (invalidate_linux_cache_inf,
+ "linux-tdep");
+ gdb::observers::inferior_appeared.attach (invalidate_linux_cache_inf,
+ "linux-tdep");
+ gdb::observers::inferior_execd.attach (invalidate_linux_cache_inf,
+ "linux-tdep");
add_setshow_boolean_cmd ("use-coredump-filter", class_files,
&use_coredump_filter, _("\
NULL, show_dump_excluded_mappings,
&setlist, &showlist);
}
+
+/* Fetch (and possibly build) an appropriate `link_map_offsets' for
+ ILP32/LP64 Linux systems which don't have the r_ldsomap field. */
+
+link_map_offsets *
+linux_ilp32_fetch_link_map_offsets ()
+{
+ static link_map_offsets lmo;
+ static link_map_offsets *lmp = nullptr;
+
+ if (lmp == nullptr)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 4;
+ lmo.r_brk_offset = 8;
+ lmo.r_ldsomap_offset = -1;
+
+ /* Everything we need is in the first 20 bytes. */
+ lmo.link_map_size = 20;
+ lmo.l_addr_offset = 0;
+ lmo.l_name_offset = 4;
+ lmo.l_ld_offset = 8;
+ lmo.l_next_offset = 12;
+ lmo.l_prev_offset = 16;
+ }
+
+ return lmp;
+}
+
+link_map_offsets *
+linux_lp64_fetch_link_map_offsets ()
+{
+ static link_map_offsets lmo;
+ static link_map_offsets *lmp = nullptr;
+
+ if (lmp == nullptr)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 8;
+ lmo.r_brk_offset = 16;
+ lmo.r_ldsomap_offset = -1;
+
+ /* Everything we need is in the first 40 bytes. */
+ lmo.link_map_size = 40;
+ lmo.l_addr_offset = 0;
+ lmo.l_name_offset = 8;
+ lmo.l_ld_offset = 16;
+ lmo.l_next_offset = 24;
+ lmo.l_prev_offset = 32;
+ }
+
+ return lmp;
+}