forked from Imagelibrary/binutils-gdb
Compare commits
1 Commits
gdb-16-bra
...
users/sima
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bc35691f1 |
@@ -721,6 +721,7 @@ ALL_TARGET_OBS = \
|
|||||||
arm-fbsd-tdep.o \
|
arm-fbsd-tdep.o \
|
||||||
arm-linux-tdep.o \
|
arm-linux-tdep.o \
|
||||||
arm-netbsd-tdep.o \
|
arm-netbsd-tdep.o \
|
||||||
|
arm-none-tdep.o \
|
||||||
arm-obsd-tdep.o \
|
arm-obsd-tdep.o \
|
||||||
arm-pikeos-tdep.o \
|
arm-pikeos-tdep.o \
|
||||||
arm-symbian-tdep.o \
|
arm-symbian-tdep.o \
|
||||||
@@ -788,6 +789,7 @@ ALL_TARGET_OBS = \
|
|||||||
nds32-tdep.o \
|
nds32-tdep.o \
|
||||||
nios2-linux-tdep.o \
|
nios2-linux-tdep.o \
|
||||||
nios2-tdep.o \
|
nios2-tdep.o \
|
||||||
|
none-tdep.o \
|
||||||
nto-tdep.o \
|
nto-tdep.o \
|
||||||
obsd-tdep.o \
|
obsd-tdep.o \
|
||||||
or1k-linux-tdep.o \
|
or1k-linux-tdep.o \
|
||||||
@@ -1225,6 +1227,7 @@ HFILES_NO_SRCDIR = \
|
|||||||
arch-utils.h \
|
arch-utils.h \
|
||||||
arm-linux-tdep.h \
|
arm-linux-tdep.h \
|
||||||
arm-netbsd-tdep.h \
|
arm-netbsd-tdep.h \
|
||||||
|
arm-none-tdep.h \
|
||||||
arm-tdep.h \
|
arm-tdep.h \
|
||||||
async-event.h \
|
async-event.h \
|
||||||
auto-load.h \
|
auto-load.h \
|
||||||
@@ -1350,6 +1353,7 @@ HFILES_NO_SRCDIR = \
|
|||||||
netbsd-tdep.h \
|
netbsd-tdep.h \
|
||||||
nds32-tdep.h \
|
nds32-tdep.h \
|
||||||
nios2-tdep.h \
|
nios2-tdep.h \
|
||||||
|
none-tdep.h \
|
||||||
nto-tdep.h \
|
nto-tdep.h \
|
||||||
objc-lang.h \
|
objc-lang.h \
|
||||||
objfiles.h \
|
objfiles.h \
|
||||||
@@ -2152,6 +2156,7 @@ ALLDEPFILES = \
|
|||||||
arm-linux-tdep.c \
|
arm-linux-tdep.c \
|
||||||
arm-netbsd-nat.c \
|
arm-netbsd-nat.c \
|
||||||
arm-netbsd-tdep.c \
|
arm-netbsd-tdep.c \
|
||||||
|
arm-none-tdep.c \
|
||||||
arm-obsd-tdep.c \
|
arm-obsd-tdep.c \
|
||||||
arm-symbian-tdep.c \
|
arm-symbian-tdep.c \
|
||||||
arm-tdep.c \
|
arm-tdep.c \
|
||||||
@@ -2238,6 +2243,7 @@ ALLDEPFILES = \
|
|||||||
nds32-tdep.c \
|
nds32-tdep.c \
|
||||||
nios2-linux-tdep.c \
|
nios2-linux-tdep.c \
|
||||||
nios2-tdep.c \
|
nios2-tdep.c \
|
||||||
|
none-tdep.c \
|
||||||
obsd-nat.c \
|
obsd-nat.c \
|
||||||
obsd-tdep.c \
|
obsd-tdep.c \
|
||||||
posix-hdep.c \
|
posix-hdep.c \
|
||||||
|
|||||||
184
gdb/arm-none-tdep.c
Normal file
184
gdb/arm-none-tdep.c
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/* none on ARM target support.
|
||||||
|
|
||||||
|
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "target.h"
|
||||||
|
#include "value.h"
|
||||||
|
#include "gdbtypes.h"
|
||||||
|
#include "gdbcore.h"
|
||||||
|
#include "frame.h"
|
||||||
|
#include "regcache.h"
|
||||||
|
#include "solib-svr4.h"
|
||||||
|
#include "osabi.h"
|
||||||
|
#include "regset.h"
|
||||||
|
#include "trad-frame.h"
|
||||||
|
#include "tramp-frame.h"
|
||||||
|
#include "breakpoint.h"
|
||||||
|
#include "auxv.h"
|
||||||
|
|
||||||
|
#include "aarch32-tdep.h"
|
||||||
|
#include "arch/arm.h"
|
||||||
|
#include "arm-tdep.h"
|
||||||
|
#include "arm-none-tdep.h"
|
||||||
|
#include "glibc-tdep.h"
|
||||||
|
#include "arch-utils.h"
|
||||||
|
#include "inferior.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
#include "symfile.h"
|
||||||
|
|
||||||
|
#include "cli/cli-utils.h"
|
||||||
|
#include "stap-probe.h"
|
||||||
|
#include "parser-defs.h"
|
||||||
|
#include "user-regs.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "elf-bfd.h"
|
||||||
|
#include "coff/internal.h"
|
||||||
|
#include "elf/arm.h"
|
||||||
|
#include "elf/common.h"
|
||||||
|
|
||||||
|
/* The ARM none register setup is based on the ARM GNU/Linux design. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
arm_none_supply_gregset (const struct regset *regset,
|
||||||
|
struct regcache *regcache,
|
||||||
|
int regnum, const void *gregs_buf, size_t len)
|
||||||
|
{
|
||||||
|
struct gdbarch *gdbarch = regcache->arch ();
|
||||||
|
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||||
|
const gdb_byte *gregs = (const gdb_byte *) gregs_buf;
|
||||||
|
int regno;
|
||||||
|
CORE_ADDR reg_pc;
|
||||||
|
gdb_byte pc_buf[ARM_INT_REGISTER_SIZE];
|
||||||
|
|
||||||
|
for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
|
||||||
|
if (regnum == -1 || regnum == regno)
|
||||||
|
regcache->raw_supply (regno, gregs + ARM_INT_REGISTER_SIZE * regno);
|
||||||
|
|
||||||
|
if (regnum == ARM_PS_REGNUM || regnum == -1)
|
||||||
|
{
|
||||||
|
if (arm_apcs_32)
|
||||||
|
regcache->raw_supply (ARM_PS_REGNUM,
|
||||||
|
gregs + ARM_INT_REGISTER_SIZE * ARM_NONE_CPSR_GREGNUM);
|
||||||
|
else
|
||||||
|
regcache->raw_supply (ARM_PS_REGNUM,
|
||||||
|
gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regnum == ARM_PC_REGNUM || regnum == -1)
|
||||||
|
{
|
||||||
|
reg_pc = extract_unsigned_integer (
|
||||||
|
gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM,
|
||||||
|
ARM_INT_REGISTER_SIZE, byte_order);
|
||||||
|
reg_pc = gdbarch_addr_bits_remove (gdbarch, reg_pc);
|
||||||
|
store_unsigned_integer (pc_buf, ARM_INT_REGISTER_SIZE, byte_order,
|
||||||
|
reg_pc);
|
||||||
|
regcache->raw_supply (ARM_PC_REGNUM, pc_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
arm_none_collect_gregset (const struct regset *regset,
|
||||||
|
const struct regcache *regcache,
|
||||||
|
int regnum, void *gregs_buf, size_t len)
|
||||||
|
{
|
||||||
|
gdb_byte *gregs = (gdb_byte *) gregs_buf;
|
||||||
|
int regno;
|
||||||
|
|
||||||
|
for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
|
||||||
|
if (regnum == -1 || regnum == regno)
|
||||||
|
regcache->raw_collect (regno,
|
||||||
|
gregs + ARM_INT_REGISTER_SIZE * regno);
|
||||||
|
|
||||||
|
if (regnum == ARM_PS_REGNUM || regnum == -1)
|
||||||
|
{
|
||||||
|
if (arm_apcs_32)
|
||||||
|
regcache->raw_collect (ARM_PS_REGNUM,
|
||||||
|
gregs + ARM_INT_REGISTER_SIZE * ARM_NONE_CPSR_GREGNUM);
|
||||||
|
else
|
||||||
|
regcache->raw_collect (ARM_PS_REGNUM,
|
||||||
|
gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regnum == ARM_PC_REGNUM || regnum == -1)
|
||||||
|
regcache->raw_collect (ARM_PC_REGNUM,
|
||||||
|
gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Support VFP register format. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
arm_none_supply_vfp (const struct regset *regset,
|
||||||
|
struct regcache *regcache,
|
||||||
|
int regnum, const void *regs_buf, size_t len)
|
||||||
|
{
|
||||||
|
const gdb_byte *regs = (const gdb_byte *) regs_buf;
|
||||||
|
int regno;
|
||||||
|
|
||||||
|
if (regnum == ARM_FPSCR_REGNUM || regnum == -1)
|
||||||
|
regcache->raw_supply (ARM_FPSCR_REGNUM, regs + 32 * 8);
|
||||||
|
|
||||||
|
for (regno = ARM_D0_REGNUM; regno <= ARM_D31_REGNUM; regno++)
|
||||||
|
if (regnum == -1 || regnum == regno)
|
||||||
|
regcache->raw_supply (regno, regs + (regno - ARM_D0_REGNUM) * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
arm_none_collect_vfp (const struct regset *regset,
|
||||||
|
const struct regcache *regcache,
|
||||||
|
int regnum, void *regs_buf, size_t len)
|
||||||
|
{
|
||||||
|
gdb_byte *regs = (gdb_byte *) regs_buf;
|
||||||
|
int regno;
|
||||||
|
|
||||||
|
if (regnum == ARM_FPSCR_REGNUM || regnum == -1)
|
||||||
|
regcache->raw_collect (ARM_FPSCR_REGNUM, regs + 32 * 8);
|
||||||
|
|
||||||
|
for (regno = ARM_D0_REGNUM; regno <= ARM_D31_REGNUM; regno++)
|
||||||
|
if (regnum == -1 || regnum == regno)
|
||||||
|
regcache->raw_collect (regno, regs + (regno - ARM_D0_REGNUM) * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct regset arm_none_gregset =
|
||||||
|
{
|
||||||
|
nullptr, arm_none_supply_gregset, arm_none_collect_gregset
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regset arm_none_vfpregset =
|
||||||
|
{
|
||||||
|
nullptr, arm_none_supply_vfp, arm_none_collect_vfp
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Iterate over core file register note sections. */
|
||||||
|
|
||||||
|
void
|
||||||
|
arm_none_iterate_over_regset_sections (struct gdbarch *gdbarch,
|
||||||
|
iterate_over_regset_sections_cb *cb,
|
||||||
|
void *cb_data,
|
||||||
|
const struct regcache *regcache)
|
||||||
|
{
|
||||||
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
|
||||||
|
cb (".reg", ARM_NONE_SIZEOF_GREGSET, ARM_NONE_SIZEOF_GREGSET,
|
||||||
|
&arm_none_gregset, nullptr, cb_data);
|
||||||
|
|
||||||
|
if (tdep->vfp_register_count > 0)
|
||||||
|
cb (".reg-arm-vfp", ARM_NONE_SIZEOF_VFP, ARM_NONE_SIZEOF_VFP,
|
||||||
|
&arm_none_vfpregset, "VFP floating-point", cb_data);
|
||||||
|
}
|
||||||
42
gdb/arm-none-tdep.h
Normal file
42
gdb/arm-none-tdep.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/* none on ARM target support, prototypes.
|
||||||
|
|
||||||
|
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef ARM_NONE_TDEP_H
|
||||||
|
#define ARM_NONE_TDEP_H
|
||||||
|
|
||||||
|
#include "bfd.h"
|
||||||
|
#include "regset.h"
|
||||||
|
|
||||||
|
struct regcache;
|
||||||
|
|
||||||
|
/* Core file and register set support. */
|
||||||
|
#define ARM_NONE_SIZEOF_GREGSET (18 * ARM_INT_REGISTER_SIZE)
|
||||||
|
|
||||||
|
/* Support VFP register format. */
|
||||||
|
#define ARM_NONE_SIZEOF_VFP (32 * 8 + 4)
|
||||||
|
|
||||||
|
/* The index to access CSPR in user_regs as defined in GLIBC. */
|
||||||
|
#define ARM_NONE_CPSR_GREGNUM 16
|
||||||
|
|
||||||
|
void
|
||||||
|
arm_none_iterate_over_regset_sections (struct gdbarch *gdbarch,
|
||||||
|
iterate_over_regset_sections_cb *cb,
|
||||||
|
void *cb_data,
|
||||||
|
const struct regcache *regcache);
|
||||||
|
#endif /* ARM_NONE_TDEP_H */
|
||||||
@@ -50,6 +50,8 @@
|
|||||||
#include "arch/arm.h"
|
#include "arch/arm.h"
|
||||||
#include "arch/arm-get-next-pcs.h"
|
#include "arch/arm-get-next-pcs.h"
|
||||||
#include "arm-tdep.h"
|
#include "arm-tdep.h"
|
||||||
|
#include "none-tdep.h"
|
||||||
|
#include "arm-none-tdep.h"
|
||||||
#include "gdb/sim-arm.h"
|
#include "gdb/sim-arm.h"
|
||||||
|
|
||||||
#include "elf-bfd.h"
|
#include "elf-bfd.h"
|
||||||
@@ -9453,6 +9455,11 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||||||
/* Virtual tables. */
|
/* Virtual tables. */
|
||||||
set_gdbarch_vbit_in_delta (gdbarch, 1);
|
set_gdbarch_vbit_in_delta (gdbarch, 1);
|
||||||
|
|
||||||
|
/* Default none core file support, can be overridden by osabi. */
|
||||||
|
none_init_corefile (info, gdbarch);
|
||||||
|
set_gdbarch_iterate_over_regset_sections (gdbarch,
|
||||||
|
arm_none_iterate_over_regset_sections);
|
||||||
|
|
||||||
/* Hook in the ABI-specific overrides, if they have been registered. */
|
/* Hook in the ABI-specific overrides, if they have been registered. */
|
||||||
gdbarch_init_osabi (info, gdbarch);
|
gdbarch_init_osabi (info, gdbarch);
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ arc*-*-*)
|
|||||||
|
|
||||||
arm*-*-*)
|
arm*-*-*)
|
||||||
cpu_obs="aarch32-tdep.o arch/aarch32.o arch/arm.o \
|
cpu_obs="aarch32-tdep.o arch/aarch32.o arch/arm.o \
|
||||||
arch/arm-get-next-pcs.o arm-tdep.o";;
|
arch/arm-get-next-pcs.o arm-tdep.o \
|
||||||
|
none-tdep.o arm-none-tdep.o";;
|
||||||
|
|
||||||
hppa*-*-*)
|
hppa*-*-*)
|
||||||
# Target: HP PA-RISC
|
# Target: HP PA-RISC
|
||||||
|
|||||||
290
gdb/none-tdep.c
Normal file
290
gdb/none-tdep.c
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
/* Target-dependent code for none, architecture independent.
|
||||||
|
|
||||||
|
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "gdbtypes.h"
|
||||||
|
#include "none-tdep.h"
|
||||||
|
#include "target.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
#include "gdbcore.h"
|
||||||
|
#include "regcache.h"
|
||||||
|
#include "regset.h"
|
||||||
|
#include "elf/common.h"
|
||||||
|
#include "elf-bfd.h" /* for elfcore_write_* */
|
||||||
|
#include "inferior.h"
|
||||||
|
#include "cli/cli-utils.h"
|
||||||
|
#include "arch-utils.h"
|
||||||
|
#include "gdb_obstack.h"
|
||||||
|
#include "observable.h"
|
||||||
|
#include "objfiles.h"
|
||||||
|
#include "infcall.h"
|
||||||
|
#include "gdbcmd.h"
|
||||||
|
#include "gdb_regex.h"
|
||||||
|
#include "gdbsupport/enum-flags.h"
|
||||||
|
#include "gdbsupport/gdb_optional.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
using none_collect_thread_registers_ftype
|
||||||
|
= void (const struct regcache *, ptid_t, bfd *,
|
||||||
|
gdb::unique_xmalloc_ptr<char> &, int *, enum gdb_signal);
|
||||||
|
|
||||||
|
/* The ARM none corefile setup is based on the ARM GNU/Linux design. */
|
||||||
|
|
||||||
|
/* Structure for passing information from
|
||||||
|
none_collect_thread_registers via an iterator to
|
||||||
|
none_collect_regset_section_cb. */
|
||||||
|
|
||||||
|
struct none_collect_regset_section_cb_data
|
||||||
|
{
|
||||||
|
none_collect_regset_section_cb_data (struct gdbarch *gdbarch,
|
||||||
|
const struct regcache *regcache,
|
||||||
|
bfd *obfd,
|
||||||
|
gdb::unique_xmalloc_ptr<char> ¬e_data,
|
||||||
|
int *note_size,
|
||||||
|
unsigned long lwp,
|
||||||
|
enum gdb_signal stop_signal)
|
||||||
|
: gdbarch (gdbarch), regcache (regcache), obfd (obfd),
|
||||||
|
note_data (note_data), note_size (note_size),
|
||||||
|
lwp (lwp), stop_signal (stop_signal)
|
||||||
|
{}
|
||||||
|
|
||||||
|
struct gdbarch *gdbarch;
|
||||||
|
const struct regcache *regcache;
|
||||||
|
bfd *obfd;
|
||||||
|
gdb::unique_xmalloc_ptr<char> ¬e_data;
|
||||||
|
int *note_size;
|
||||||
|
unsigned long lwp;
|
||||||
|
enum gdb_signal stop_signal;
|
||||||
|
bool abort_iteration = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Callback for iterate_over_regset_sections that records a single
|
||||||
|
regset in the corefile note section. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
none_collect_regset_section_cb (const char *sect_name, int supply_size,
|
||||||
|
int collect_size, const struct regset *regset,
|
||||||
|
const char *human_name, void *cb_data)
|
||||||
|
{
|
||||||
|
struct none_collect_regset_section_cb_data *data
|
||||||
|
= (struct none_collect_regset_section_cb_data *) cb_data;
|
||||||
|
bool variable_size_section = (regset != nullptr
|
||||||
|
&& regset->flags & REGSET_VARIABLE_SIZE);
|
||||||
|
|
||||||
|
if (!variable_size_section)
|
||||||
|
gdb_assert (supply_size == collect_size);
|
||||||
|
|
||||||
|
if (data->abort_iteration)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gdb_assert (regset && regset->collect_regset);
|
||||||
|
|
||||||
|
/* This is intentionally zero-initialized by using std::vector, so
|
||||||
|
that any padding bytes in the core file will show as 0. */
|
||||||
|
std::vector<gdb_byte> buf (collect_size);
|
||||||
|
|
||||||
|
regset->collect_regset (regset, data->regcache, -1, buf.data (),
|
||||||
|
collect_size);
|
||||||
|
|
||||||
|
/* PRSTATUS still needs to be treated specially. */
|
||||||
|
if (strcmp (sect_name, ".reg") == 0)
|
||||||
|
data->note_data.reset (elfcore_write_prstatus
|
||||||
|
(data->obfd, data->note_data.release (),
|
||||||
|
data->note_size, data->lwp,
|
||||||
|
gdb_signal_to_host (data->stop_signal),
|
||||||
|
buf.data ()));
|
||||||
|
else
|
||||||
|
data->note_data.reset (elfcore_write_register_note
|
||||||
|
(data->obfd, data->note_data.release (),
|
||||||
|
data->note_size, sect_name, buf.data (),
|
||||||
|
collect_size));
|
||||||
|
|
||||||
|
if (data->note_data == nullptr)
|
||||||
|
data->abort_iteration = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Records the thread's register state for the corefile note
|
||||||
|
section. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
none_collect_thread_registers (const struct regcache *regcache,
|
||||||
|
ptid_t ptid, bfd *obfd,
|
||||||
|
gdb::unique_xmalloc_ptr<char> ¬e_data,
|
||||||
|
int *note_size, enum gdb_signal stop_signal)
|
||||||
|
{
|
||||||
|
struct gdbarch *gdbarch = regcache->arch ();
|
||||||
|
unsigned long lwp;
|
||||||
|
|
||||||
|
/* For remote targets the LWP may not be available, so use the TID. */
|
||||||
|
lwp = ptid.lwp ();
|
||||||
|
if (lwp == 0)
|
||||||
|
lwp = ptid.tid ();
|
||||||
|
|
||||||
|
none_collect_regset_section_cb_data data (gdbarch, regcache, obfd, note_data,
|
||||||
|
note_size, lwp, stop_signal);
|
||||||
|
|
||||||
|
gdbarch_iterate_over_regset_sections (gdbarch,
|
||||||
|
none_collect_regset_section_cb,
|
||||||
|
&data, regcache);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct none_corefile_thread_data
|
||||||
|
{
|
||||||
|
none_corefile_thread_data (struct gdbarch *gdbarch,
|
||||||
|
bfd *obfd,
|
||||||
|
gdb::unique_xmalloc_ptr<char> ¬e_data,
|
||||||
|
int *note_size,
|
||||||
|
enum gdb_signal stop_signal)
|
||||||
|
: gdbarch (gdbarch), obfd (obfd), note_data (note_data),
|
||||||
|
note_size (note_size), stop_signal (stop_signal)
|
||||||
|
{}
|
||||||
|
|
||||||
|
struct gdbarch *gdbarch;
|
||||||
|
bfd *obfd;
|
||||||
|
gdb::unique_xmalloc_ptr<char> ¬e_data;
|
||||||
|
int *note_size;
|
||||||
|
enum gdb_signal stop_signal;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Records the thread's register state for the corefile note
|
||||||
|
section. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
none_corefile_thread (struct thread_info *info,
|
||||||
|
struct none_corefile_thread_data *args)
|
||||||
|
{
|
||||||
|
struct regcache *regcache;
|
||||||
|
|
||||||
|
regcache = get_thread_arch_regcache (info->inf->process_target (),
|
||||||
|
info->ptid, args->gdbarch);
|
||||||
|
|
||||||
|
target_fetch_registers (regcache, -1);
|
||||||
|
none_collect_thread_registers
|
||||||
|
(regcache, info->ptid, args->obfd, args->note_data,
|
||||||
|
args->note_size, args->stop_signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the signalled thread. In case there's more than one signalled
|
||||||
|
thread, prefer the current thread, if it is signalled. If no
|
||||||
|
thread was signalled, default to the current thread, unless it has
|
||||||
|
exited, in which case return nullptr. */
|
||||||
|
|
||||||
|
static thread_info *
|
||||||
|
find_signalled_thread ()
|
||||||
|
{
|
||||||
|
thread_info *curr_thr = inferior_thread ();
|
||||||
|
if (curr_thr->state != THREAD_EXITED
|
||||||
|
&& curr_thr->suspend.stop_signal != GDB_SIGNAL_0)
|
||||||
|
return curr_thr;
|
||||||
|
|
||||||
|
for (thread_info *thr : current_inferior ()->non_exited_threads ())
|
||||||
|
if (thr->suspend.stop_signal != GDB_SIGNAL_0)
|
||||||
|
return thr;
|
||||||
|
|
||||||
|
/* Default to the current thread, unless it has exited. */
|
||||||
|
if (curr_thr->state != THREAD_EXITED)
|
||||||
|
return curr_thr;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fills the "to_make_corefile_note" target vector. Builds the note
|
||||||
|
section for a corefile, and returns it in a malloc buffer. */
|
||||||
|
|
||||||
|
static gdb::unique_xmalloc_ptr<char>
|
||||||
|
none_make_corefile_notes_1 (struct gdbarch *gdbarch, bfd *obfd, int *note_size,
|
||||||
|
none_collect_thread_registers_ftype collect)
|
||||||
|
{
|
||||||
|
gdb::unique_xmalloc_ptr<char> note_data;
|
||||||
|
|
||||||
|
/* Process information. */
|
||||||
|
if (get_exec_file (0))
|
||||||
|
{
|
||||||
|
const char *fname = lbasename (get_exec_file (0));
|
||||||
|
std::string psargs = fname;
|
||||||
|
|
||||||
|
if (get_inferior_args ())
|
||||||
|
{
|
||||||
|
psargs += " ";
|
||||||
|
psargs += get_inferior_args ();
|
||||||
|
}
|
||||||
|
|
||||||
|
note_data.reset (elfcore_write_prpsinfo (obfd, note_data.release (),
|
||||||
|
note_size, fname,
|
||||||
|
psargs.c_str ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!note_data)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
/* Thread register information. */
|
||||||
|
try
|
||||||
|
{
|
||||||
|
update_thread_list ();
|
||||||
|
}
|
||||||
|
catch (const gdb_exception_error &e)
|
||||||
|
{
|
||||||
|
exception_print (gdb_stderr, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like the kernel, prefer dumping the signalled thread first.
|
||||||
|
"First thread" is what tools use to infer the signalled
|
||||||
|
thread. */
|
||||||
|
thread_info *signalled_thr = find_signalled_thread ();
|
||||||
|
gdb_signal stop_signal;
|
||||||
|
|
||||||
|
if (signalled_thr != nullptr)
|
||||||
|
stop_signal = signalled_thr->suspend.stop_signal;
|
||||||
|
else
|
||||||
|
stop_signal = GDB_SIGNAL_0;
|
||||||
|
|
||||||
|
none_corefile_thread_data thread_args (gdbarch, obfd, note_data, note_size,
|
||||||
|
stop_signal);
|
||||||
|
|
||||||
|
if (signalled_thr != nullptr)
|
||||||
|
none_corefile_thread (signalled_thr, &thread_args);
|
||||||
|
for (thread_info *thr : current_inferior ()->non_exited_threads ())
|
||||||
|
{
|
||||||
|
if (thr == signalled_thr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
none_corefile_thread (thr, &thread_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return note_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gdb::unique_xmalloc_ptr<char>
|
||||||
|
none_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
|
||||||
|
{
|
||||||
|
return none_make_corefile_notes_1 (gdbarch, obfd, note_size,
|
||||||
|
none_collect_thread_registers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup default core file support for none targets.
|
||||||
|
Can be overridden later by OSABI. */
|
||||||
|
|
||||||
|
void
|
||||||
|
none_init_corefile (struct gdbarch_info info,
|
||||||
|
struct gdbarch *gdbarch)
|
||||||
|
{
|
||||||
|
/* Default core file support. */
|
||||||
|
set_gdbarch_make_corefile_notes (gdbarch, none_make_corefile_notes);
|
||||||
|
}
|
||||||
30
gdb/none-tdep.h
Normal file
30
gdb/none-tdep.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* Target-dependent code for none, architecture independent.
|
||||||
|
|
||||||
|
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef NONE_TDEP_H
|
||||||
|
#define NONE_TDEP_H
|
||||||
|
|
||||||
|
#include "bfd.h"
|
||||||
|
|
||||||
|
struct regcache;
|
||||||
|
|
||||||
|
void none_init_corefile (struct gdbarch_info info,
|
||||||
|
struct gdbarch *gdbarch);
|
||||||
|
|
||||||
|
#endif /* none-tdep.h */
|
||||||
Reference in New Issue
Block a user