mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
69 Commits
binutils-2
...
gdb-10.1-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1510de4294 | ||
|
|
893aa14fb9 | ||
|
|
34718bcc22 | ||
|
|
7565d82a50 | ||
|
|
a9e3b91950 | ||
|
|
4c02be1198 | ||
|
|
9a312e4904 | ||
|
|
43b860e8c4 | ||
|
|
974fee813c | ||
|
|
a606acc8d2 | ||
|
|
aa873d8315 | ||
|
|
628b363a6a | ||
|
|
c94703dc45 | ||
|
|
b96b7cf31f | ||
|
|
2acc8db7ed | ||
|
|
2e052fd569 | ||
|
|
f9052d5c0e | ||
|
|
0241ddc77d | ||
|
|
5d09cf9879 | ||
|
|
e610101040 | ||
|
|
f7a8799115 | ||
|
|
dc37fea759 | ||
|
|
114f9fd9e9 | ||
|
|
223de168bb | ||
|
|
f39391b6f0 | ||
|
|
460fd13b5b | ||
|
|
94265abc20 | ||
|
|
b13599da1a | ||
|
|
e26d3e9b76 | ||
|
|
8f97e9b79d | ||
|
|
e68941ba17 | ||
|
|
7ba0e35baa | ||
|
|
522605be60 | ||
|
|
fdb72ad268 | ||
|
|
ea9cc728dc | ||
|
|
2378f62126 | ||
|
|
7e7e2357fc | ||
|
|
ccf7653413 | ||
|
|
f6c03ee4ad | ||
|
|
5cb6abf208 | ||
|
|
df69589808 | ||
|
|
698ef0a3e7 | ||
|
|
13e87e2127 | ||
|
|
f6defe2064 | ||
|
|
8ccf2a20fb | ||
|
|
642ed0e9ec | ||
|
|
6006bb78cc | ||
|
|
2051e5340c | ||
|
|
1e4d9e71cc | ||
|
|
d941eafc46 | ||
|
|
a78d1a1c28 | ||
|
|
b892828bcb | ||
|
|
4567103763 | ||
|
|
5573f8461b | ||
|
|
a77c0fd170 | ||
|
|
0d789f59d1 | ||
|
|
7ea31d3da0 | ||
|
|
1f2950be0b | ||
|
|
f0f01c9e23 | ||
|
|
efb04be6ae | ||
|
|
ba8b04a8d8 | ||
|
|
9c4a30eb45 | ||
|
|
5ebb0da9a5 | ||
|
|
423e52cef3 | ||
|
|
46ecde124e | ||
|
|
f1e420ce92 | ||
|
|
c527795867 | ||
|
|
713bde4c19 | ||
|
|
31c6c31e02 |
@@ -1,3 +1,7 @@
|
||||
2020-09-13 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* development.sh (development): Set to false.
|
||||
|
||||
2020-09-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/26391
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Controls whether to enable development-mode features by default.
|
||||
development=true
|
||||
development=false
|
||||
|
||||
# Indicate whether this is a release branch.
|
||||
experimental=true
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
In releases, the date is not included in either version strings or
|
||||
sonames. */
|
||||
#define BFD_VERSION_DATE 20200912
|
||||
#define BFD_VERSION_DATE 20201024
|
||||
#define BFD_VERSION @bfd_version@
|
||||
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
|
||||
#define REPORT_BUGS_TO @report_bugs_to@
|
||||
|
||||
128
gdb/ChangeLog
128
gdb/ChangeLog
@@ -1,3 +1,131 @@
|
||||
2020-10-24 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 10.1.
|
||||
|
||||
2020-10-22 Hannes Domani <ssbssa@yahoo.de>
|
||||
|
||||
* gdbtypes.c (init_complex_type): Check target type name.
|
||||
|
||||
2020-10-22 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
PR gdb/26693
|
||||
* dwarf2/read.c (load_full_comp_unit): Add existing_cu
|
||||
parameter.
|
||||
(load_cu): Pass existing CU.
|
||||
(process_imported_unit_die): Likewise.
|
||||
(follow_die_offset): Likewise.
|
||||
|
||||
2020-10-14 Mihails Strasuns <mihails.strasuns@intel.com>
|
||||
|
||||
* breakpoint.c (handle_jit_event): Add an argument, change how
|
||||
`jit_event_handler` is called.
|
||||
|
||||
2020-10-13 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
PR gdb/26642
|
||||
* infrun.c (do_target_wait_1): Clear TARGET_WNOHANG if the
|
||||
target can't do async.
|
||||
* target.c (target_wait): Assert that we don't pass
|
||||
TARGET_WNOHANG to a target that can't async.
|
||||
|
||||
2020-10-08 Shahab Vahedi <shahab@synopsys.com>
|
||||
|
||||
* NEWS: Mention ARC support in GDBserver.
|
||||
|
||||
2020-10-07 Anton Kolesov <anton.kolesov@synopsys.com>
|
||||
|
||||
* arc-linux-tdep.h: New file.
|
||||
* arc-linux-tdep.c (arc_linux_core_reg_offsets,
|
||||
arc_linux_supply_gregset, arc_linux_supply_v2_regset,
|
||||
arc_linux_collect_gregset, arc_linux_collect_v2_regset,
|
||||
arc_linux_gregset, arc_linux_v2_regset,
|
||||
arc_linux_iterate_over_regset_sections,
|
||||
arc_linux_core_read_description): Implement.
|
||||
(arc_linux_init_osabi): Set iterate_over_regset_sections.
|
||||
* arc-tdep.h (ARC_OFFSET_NO_REGISTER): Declare.
|
||||
(arc_gdbarch_features_create): Add.
|
||||
* arc-tdep.c (arc_gdbarch_features_create): Not static anymore.
|
||||
|
||||
2020-10-07 Shahab Vahedi <shahab@synopsys.com>
|
||||
|
||||
* arch/arc.h: Rename "arc_gdbarch_features" to
|
||||
"arc_arch_features".
|
||||
* arc-tdep.h: Likewise.
|
||||
* arc-tdep.c: Likewise.
|
||||
|
||||
2020-09-28 Gareth Rees <grees@undo.io> (tiny change)
|
||||
|
||||
PR python/26586
|
||||
* cli/cli-script.c (execute_control_commands): don't set
|
||||
instream to nullptr here as this breaks the from_tty argument
|
||||
to gdb.execute in Python.
|
||||
(execute_user_command): set instream to nullptr here instead.
|
||||
|
||||
2020-09-25 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
||||
|
||||
* breakpoint.c (commands_command_1): Make a copy of the 'arg'
|
||||
argument.
|
||||
|
||||
2020-09-24 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
PR tui/26638:
|
||||
* tui/tui-stack.h (struct tui_locator_window) <can_focus>: New
|
||||
method.
|
||||
* tui/tui-data.h (struct tui_win_info) <can_focus>: New method.
|
||||
* tui/tui-data.c (tui_next_win): Exclude non-focusable windows.
|
||||
(tui_prev_win): Rewrite.
|
||||
|
||||
2020-09-23 Hannes Domani <ssbssa@yahoo.de>
|
||||
|
||||
* nat/windows-nat.c (handle_exception): Handle 64bit breakpoints
|
||||
in WOW64 processes as SIGINT.
|
||||
* nat/windows-nat.h: Make wow64_process a shared variable.
|
||||
* windows-nat.c: Remove static wow64_process variable.
|
||||
|
||||
2020-09-18 Victor Collod <vcollod@nvidia.com>
|
||||
|
||||
PR gdb/26635
|
||||
* i386-tdep.c (i386_skip_endbr): Add a helper function to skip endbr.
|
||||
(i386_analyze_prologue): Call i386_skip_endbr.
|
||||
|
||||
2020-09-18 Pedro Alves <pedro@palves.net>
|
||||
|
||||
PR gdb/26631
|
||||
* thread.c (thread_find_command): Switch inferior before calling
|
||||
target methods.
|
||||
|
||||
2020-09-16 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
PR gdb/26598:
|
||||
* infrun.c (fill_in_stop_func): Use find_pc_partial_function_sym.
|
||||
|
||||
2020-09-14 Fredrik Hederstierna <fredrik.hederstierna@verisure.com>
|
||||
Adam Renquinha <arenquinha@cimeq.qc.ca>
|
||||
|
||||
* arm-tdep.c (arm_m_exception_cache): Try use correct stack
|
||||
pointer and stack frame offset when unwinding.
|
||||
|
||||
2020-09-13 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 10.0.90.DATE-git.
|
||||
|
||||
2020-09-13 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB 10.0.90 released.
|
||||
|
||||
2020-09-13 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 10.0.90.
|
||||
|
||||
2020-09-13 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* NEWS: Change "Changes since GDB 9" to "Changes in GDB 10".
|
||||
|
||||
2020-09-13 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB 10 branch created (8087c3fa8b5d695e3e29e69d70d0b35ec902ac59):
|
||||
* version.in: Bump version to 10.0.90.DATE-git.
|
||||
|
||||
2020-09-12 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* infrun.c (namespace selftests): Only define #if GDB_SELF_TEST.
|
||||
|
||||
4
gdb/NEWS
4
gdb/NEWS
@@ -1,7 +1,7 @@
|
||||
What has changed in GDB?
|
||||
(Organized release by release)
|
||||
|
||||
*** Changes since GDB 9
|
||||
*** Changes in GDB 10
|
||||
|
||||
* There are new feature names for ARC targets: "org.gnu.gdb.arc.core"
|
||||
and "org.gnu.gdb.arc.aux". The old names are still supported but
|
||||
@@ -47,6 +47,8 @@
|
||||
|
||||
* New features in the GDB remote stub, GDBserver
|
||||
|
||||
** GDBserver is now supported on ARC GNU/Linux.
|
||||
|
||||
** GDBserver is now supported on RISC-V GNU/Linux.
|
||||
|
||||
** GDBserver no longer supports these host triplets:
|
||||
|
||||
@@ -27,7 +27,65 @@
|
||||
|
||||
/* ARC header files. */
|
||||
#include "opcodes/arc-dis.h"
|
||||
#include "arc-linux-tdep.h"
|
||||
#include "arc-tdep.h"
|
||||
#include "arch/arc.h"
|
||||
|
||||
#define REGOFF(offset) (offset * ARC_REGISTER_SIZE)
|
||||
|
||||
/* arc_linux_core_reg_offsets[i] is the offset in the .reg section of GDB
|
||||
regnum i. Array index is an internal GDB register number, as defined in
|
||||
arc-tdep.h:arc_regnum.
|
||||
|
||||
From include/uapi/asm/ptrace.h in the ARC Linux sources. */
|
||||
|
||||
/* The layout of this struct is tightly bound to "arc_regnum" enum
|
||||
in arc-tdep.h. Any change of order in there, must be reflected
|
||||
here as well. */
|
||||
static const int arc_linux_core_reg_offsets[] = {
|
||||
/* R0 - R12. */
|
||||
REGOFF (22), REGOFF (21), REGOFF (20), REGOFF (19),
|
||||
REGOFF (18), REGOFF (17), REGOFF (16), REGOFF (15),
|
||||
REGOFF (14), REGOFF (13), REGOFF (12), REGOFF (11),
|
||||
REGOFF (10),
|
||||
|
||||
/* R13 - R25. */
|
||||
REGOFF (37), REGOFF (36), REGOFF (35), REGOFF (34),
|
||||
REGOFF (33), REGOFF (32), REGOFF (31), REGOFF (30),
|
||||
REGOFF (29), REGOFF (28), REGOFF (27), REGOFF (26),
|
||||
REGOFF (25),
|
||||
|
||||
REGOFF (9), /* R26 (GP) */
|
||||
REGOFF (8), /* FP */
|
||||
REGOFF (23), /* SP */
|
||||
ARC_OFFSET_NO_REGISTER, /* ILINK */
|
||||
ARC_OFFSET_NO_REGISTER, /* R30 */
|
||||
REGOFF (7), /* BLINK */
|
||||
|
||||
/* R32 - R59. */
|
||||
ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
|
||||
ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
|
||||
ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
|
||||
ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
|
||||
ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
|
||||
ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
|
||||
ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
|
||||
ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
|
||||
ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
|
||||
ARC_OFFSET_NO_REGISTER,
|
||||
|
||||
REGOFF (4), /* LP_COUNT */
|
||||
ARC_OFFSET_NO_REGISTER, /* RESERVED */
|
||||
ARC_OFFSET_NO_REGISTER, /* LIMM */
|
||||
ARC_OFFSET_NO_REGISTER, /* PCL */
|
||||
|
||||
REGOFF (39), /* PC */
|
||||
REGOFF (5), /* STATUS32 */
|
||||
REGOFF (2), /* LP_START */
|
||||
REGOFF (3), /* LP_END */
|
||||
REGOFF (1), /* BTA */
|
||||
REGOFF (6) /* ERET */
|
||||
};
|
||||
|
||||
/* Implement the "cannot_fetch_register" gdbarch method. */
|
||||
|
||||
@@ -227,6 +285,136 @@ arc_linux_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
arc_linux_supply_gregset (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *gregs, size_t size)
|
||||
{
|
||||
gdb_static_assert (ARC_LAST_REGNUM
|
||||
< ARRAY_SIZE (arc_linux_core_reg_offsets));
|
||||
|
||||
const bfd_byte *buf = (const bfd_byte *) gregs;
|
||||
|
||||
for (int reg = 0; reg <= ARC_LAST_REGNUM; reg++)
|
||||
if (arc_linux_core_reg_offsets[reg] != ARC_OFFSET_NO_REGISTER)
|
||||
regcache->raw_supply (reg, buf + arc_linux_core_reg_offsets[reg]);
|
||||
}
|
||||
|
||||
void
|
||||
arc_linux_supply_v2_regset (const struct regset *regset,
|
||||
struct regcache *regcache, int regnum,
|
||||
const void *v2_regs, size_t size)
|
||||
{
|
||||
const bfd_byte *buf = (const bfd_byte *) v2_regs;
|
||||
|
||||
/* user_regs_arcv2 is defined in linux arch/arc/include/uapi/asm/ptrace.h. */
|
||||
regcache->raw_supply (ARC_R30_REGNUM, buf);
|
||||
regcache->raw_supply (ARC_R58_REGNUM, buf + REGOFF (1));
|
||||
regcache->raw_supply (ARC_R59_REGNUM, buf + REGOFF (2));
|
||||
}
|
||||
|
||||
/* Populate BUF with register REGNUM from the REGCACHE. */
|
||||
|
||||
static void
|
||||
collect_register (const struct regcache *regcache, struct gdbarch *gdbarch,
|
||||
int regnum, gdb_byte *buf)
|
||||
{
|
||||
/* Skip non-existing registers. */
|
||||
if ((arc_linux_core_reg_offsets[regnum] == ARC_OFFSET_NO_REGISTER))
|
||||
return;
|
||||
|
||||
/* The address where the execution has stopped is in pseudo-register
|
||||
STOP_PC. However, when kernel code is returning from the exception,
|
||||
it uses the value from ERET register. Since, TRAP_S (the breakpoint
|
||||
instruction) commits, the ERET points to the next instruction. In
|
||||
other words: ERET != STOP_PC. To jump back from the kernel code to
|
||||
the correct address, ERET must be overwritten by GDB's STOP_PC. Else,
|
||||
the program will continue at the address after the current instruction.
|
||||
*/
|
||||
if (regnum == gdbarch_pc_regnum (gdbarch))
|
||||
regnum = ARC_ERET_REGNUM;
|
||||
regcache->raw_collect (regnum, buf + arc_linux_core_reg_offsets[regnum]);
|
||||
}
|
||||
|
||||
void
|
||||
arc_linux_collect_gregset (const struct regset *regset,
|
||||
const struct regcache *regcache,
|
||||
int regnum, void *gregs, size_t size)
|
||||
{
|
||||
gdb_static_assert (ARC_LAST_REGNUM
|
||||
< ARRAY_SIZE (arc_linux_core_reg_offsets));
|
||||
|
||||
gdb_byte *buf = (gdb_byte *) gregs;
|
||||
struct gdbarch *gdbarch = regcache->arch ();
|
||||
|
||||
/* regnum == -1 means writing all the registers. */
|
||||
if (regnum == -1)
|
||||
for (int reg = 0; reg <= ARC_LAST_REGNUM; reg++)
|
||||
collect_register (regcache, gdbarch, reg, buf);
|
||||
else if (regnum <= ARC_LAST_REGNUM)
|
||||
collect_register (regcache, gdbarch, regnum, buf);
|
||||
else
|
||||
gdb_assert_not_reached ("Invalid regnum in arc_linux_collect_gregset.");
|
||||
}
|
||||
|
||||
void
|
||||
arc_linux_collect_v2_regset (const struct regset *regset,
|
||||
const struct regcache *regcache, int regnum,
|
||||
void *v2_regs, size_t size)
|
||||
{
|
||||
bfd_byte *buf = (bfd_byte *) v2_regs;
|
||||
|
||||
regcache->raw_collect (ARC_R30_REGNUM, buf);
|
||||
regcache->raw_collect (ARC_R58_REGNUM, buf + REGOFF (1));
|
||||
regcache->raw_collect (ARC_R59_REGNUM, buf + REGOFF (2));
|
||||
}
|
||||
|
||||
/* Linux regset definitions. */
|
||||
|
||||
static const struct regset arc_linux_gregset = {
|
||||
arc_linux_core_reg_offsets,
|
||||
arc_linux_supply_gregset,
|
||||
arc_linux_collect_gregset,
|
||||
};
|
||||
|
||||
static const struct regset arc_linux_v2_regset = {
|
||||
NULL,
|
||||
arc_linux_supply_v2_regset,
|
||||
arc_linux_collect_v2_regset,
|
||||
};
|
||||
|
||||
/* Implement the `iterate_over_regset_sections` gdbarch method. */
|
||||
|
||||
static void
|
||||
arc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
|
||||
iterate_over_regset_sections_cb *cb,
|
||||
void *cb_data,
|
||||
const struct regcache *regcache)
|
||||
{
|
||||
/* There are 40 registers in Linux user_regs_struct, although some of
|
||||
them are now just a mere paddings, kept to maintain binary
|
||||
compatibility with older tools. */
|
||||
const int sizeof_gregset = 40 * ARC_REGISTER_SIZE;
|
||||
|
||||
cb (".reg", sizeof_gregset, sizeof_gregset, &arc_linux_gregset, NULL,
|
||||
cb_data);
|
||||
cb (".reg-arc-v2", ARC_LINUX_SIZEOF_V2_REGSET, ARC_LINUX_SIZEOF_V2_REGSET,
|
||||
&arc_linux_v2_regset, NULL, cb_data);
|
||||
}
|
||||
|
||||
/* Implement the `core_read_description` gdbarch method. */
|
||||
|
||||
static const struct target_desc *
|
||||
arc_linux_core_read_description (struct gdbarch *gdbarch,
|
||||
struct target_ops *target,
|
||||
bfd *abfd)
|
||||
{
|
||||
arc_arch_features features
|
||||
= arc_arch_features_create (abfd,
|
||||
gdbarch_bfd_arch_info (gdbarch)->mach);
|
||||
return arc_lookup_target_description (features);
|
||||
}
|
||||
|
||||
/* Initialization specific to Linux environment. */
|
||||
|
||||
static void
|
||||
@@ -260,6 +448,9 @@ arc_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
set_gdbarch_software_single_step (gdbarch, arc_linux_software_single_step);
|
||||
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
||||
set_gdbarch_skip_solib_resolver (gdbarch, arc_linux_skip_solib_resolver);
|
||||
set_gdbarch_iterate_over_regset_sections
|
||||
(gdbarch, arc_linux_iterate_over_regset_sections);
|
||||
set_gdbarch_core_read_description (gdbarch, arc_linux_core_read_description);
|
||||
|
||||
/* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
|
||||
and pointers (ILP32). */
|
||||
|
||||
52
gdb/arc-linux-tdep.h
Normal file
52
gdb/arc-linux-tdep.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Target dependent code for GNU/Linux ARC.
|
||||
|
||||
Copyright 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 ARC_LINUX_TDEP_H
|
||||
#define ARC_LINUX_TDEP_H
|
||||
|
||||
#include "gdbarch.h"
|
||||
#include "regset.h"
|
||||
|
||||
#define ARC_LINUX_SIZEOF_V2_REGSET (3 * ARC_REGISTER_SIZE)
|
||||
|
||||
/* Reads registers from the NT_PRSTATUS data array into the regcache. */
|
||||
|
||||
void arc_linux_supply_gregset (const struct regset *regset,
|
||||
struct regcache *regcache, int regnum,
|
||||
const void *gregs, size_t size);
|
||||
|
||||
/* Reads regsiters from the NT_ARC_V2 data array into the regcache. */
|
||||
|
||||
void arc_linux_supply_v2_regset (const struct regset *regset,
|
||||
struct regcache *regcache, int regnum,
|
||||
const void *v2_regs, size_t size);
|
||||
|
||||
/* Writes registers from the regcache into the NT_PRSTATUS data array. */
|
||||
|
||||
void arc_linux_collect_gregset (const struct regset *regset,
|
||||
const struct regcache *regcache,
|
||||
int regnum, void *gregs, size_t size);
|
||||
|
||||
/* Writes registers from the regcache into the NT_ARC_V2 data array. */
|
||||
|
||||
void arc_linux_collect_v2_regset (const struct regset *regset,
|
||||
const struct regcache *regcache,
|
||||
int regnum, void *v2_regs, size_t size);
|
||||
|
||||
#endif /* ARC_LINUX_TDEP_H */
|
||||
@@ -1883,11 +1883,10 @@ mach_type_to_arc_isa (const unsigned long mach)
|
||||
}
|
||||
}
|
||||
|
||||
/* Common construction code for ARC_GDBARCH_FEATURES struct. If there
|
||||
is no ABFD, then a FEATURE with default values is returned. */
|
||||
/* See arc-tdep.h. */
|
||||
|
||||
static arc_gdbarch_features
|
||||
arc_gdbarch_features_create (const bfd *abfd, const unsigned long mach)
|
||||
arc_arch_features
|
||||
arc_arch_features_create (const bfd *abfd, const unsigned long mach)
|
||||
{
|
||||
/* Use 4 as a fallback value. */
|
||||
int reg_size = 4;
|
||||
@@ -1915,7 +1914,7 @@ arc_gdbarch_features_create (const bfd *abfd, const unsigned long mach)
|
||||
case). */
|
||||
arc_isa isa = mach_type_to_arc_isa (mach);
|
||||
|
||||
return arc_gdbarch_features (reg_size, isa);
|
||||
return arc_arch_features (reg_size, isa);
|
||||
}
|
||||
|
||||
/* Look for obsolete core feature names in TDESC. */
|
||||
@@ -2085,9 +2084,9 @@ arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
|
||||
/* If target doesn't provide a description, use the default ones. */
|
||||
if (!tdesc_has_registers (tdesc_loc))
|
||||
{
|
||||
arc_gdbarch_features features
|
||||
= arc_gdbarch_features_create (info.abfd,
|
||||
info.bfd_arch_info->mach);
|
||||
arc_arch_features features
|
||||
= arc_arch_features_create (info.abfd,
|
||||
info.bfd_arch_info->mach);
|
||||
tdesc_loc = arc_lookup_target_description (features);
|
||||
}
|
||||
gdb_assert (tdesc_loc != nullptr);
|
||||
|
||||
@@ -85,7 +85,9 @@ enum arc_regnum
|
||||
ARC_LP_END_REGNUM,
|
||||
/* Branch target address. */
|
||||
ARC_BTA_REGNUM,
|
||||
ARC_LAST_AUX_REGNUM = ARC_BTA_REGNUM,
|
||||
/* Exception return address. */
|
||||
ARC_ERET_REGNUM,
|
||||
ARC_LAST_AUX_REGNUM = ARC_ERET_REGNUM,
|
||||
ARC_LAST_REGNUM = ARC_LAST_AUX_REGNUM,
|
||||
|
||||
/* Additional ABI constants. */
|
||||
@@ -105,6 +107,9 @@ enum arc_regnum
|
||||
/* STATUS32 register: current instruction is a delay slot. */
|
||||
#define ARC_STATUS32_DE_MASK (1 << 6)
|
||||
|
||||
/* Special value for register offset arrays. */
|
||||
#define ARC_OFFSET_NO_REGISTER (-1)
|
||||
|
||||
#define arc_print(fmt, args...) fprintf_unfiltered (gdb_stdlog, fmt, ##args)
|
||||
|
||||
extern int arc_debug;
|
||||
@@ -182,4 +187,9 @@ CORE_ADDR arc_insn_get_branch_target (const struct arc_instruction &insn);
|
||||
|
||||
CORE_ADDR arc_insn_get_linear_next_pc (const struct arc_instruction &insn);
|
||||
|
||||
/* Create an arc_arch_features instance from the provided data. */
|
||||
|
||||
arc_arch_features arc_arch_features_create (const bfd *abfd,
|
||||
const unsigned long mach);
|
||||
|
||||
#endif /* ARC_TDEP_H */
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#endif
|
||||
|
||||
STATIC_IN_GDB target_desc *
|
||||
arc_create_target_description (const struct arc_gdbarch_features &features)
|
||||
arc_create_target_description (const struct arc_arch_features &features)
|
||||
{
|
||||
/* Create a new target description. */
|
||||
target_desc *tdesc = allocate_target_description ();
|
||||
@@ -84,10 +84,10 @@ arc_create_target_description (const struct arc_gdbarch_features &features)
|
||||
#ifndef GDBSERVER
|
||||
|
||||
/* Wrapper used by std::unordered_map to generate hash for features set. */
|
||||
struct arc_gdbarch_features_hasher
|
||||
struct arc_arch_features_hasher
|
||||
{
|
||||
std::size_t
|
||||
operator() (const arc_gdbarch_features &features) const noexcept
|
||||
operator() (const arc_arch_features &features) const noexcept
|
||||
{
|
||||
return features.hash ();
|
||||
}
|
||||
@@ -95,14 +95,14 @@ struct arc_gdbarch_features_hasher
|
||||
|
||||
/* Cache of previously created target descriptions, indexed by the hash
|
||||
of the features set used to create them. */
|
||||
static std::unordered_map<arc_gdbarch_features,
|
||||
static std::unordered_map<arc_arch_features,
|
||||
const target_desc_up,
|
||||
arc_gdbarch_features_hasher> arc_tdesc_cache;
|
||||
arc_arch_features_hasher> arc_tdesc_cache;
|
||||
|
||||
/* See arch/arc.h. */
|
||||
|
||||
const target_desc *
|
||||
arc_lookup_target_description (const struct arc_gdbarch_features &features)
|
||||
arc_lookup_target_description (const struct arc_arch_features &features)
|
||||
{
|
||||
/* Lookup in the cache first. If found, return the pointer from the
|
||||
"target_desc_up" type which is a "unique_ptr". This should be fine
|
||||
|
||||
@@ -27,9 +27,9 @@ enum arc_isa
|
||||
ARC_ISA_ARCV2 /* such as ARC EM and ARC HS */
|
||||
};
|
||||
|
||||
struct arc_gdbarch_features
|
||||
struct arc_arch_features
|
||||
{
|
||||
arc_gdbarch_features (int reg_size, arc_isa isa)
|
||||
arc_arch_features (int reg_size, arc_isa isa)
|
||||
: reg_size (reg_size), isa (isa)
|
||||
{}
|
||||
|
||||
@@ -41,13 +41,13 @@ struct arc_gdbarch_features
|
||||
const arc_isa isa;
|
||||
|
||||
/* Equality operator. */
|
||||
bool operator== (const struct arc_gdbarch_features &rhs) const
|
||||
bool operator== (const struct arc_arch_features &rhs) const
|
||||
{
|
||||
return (reg_size == rhs.reg_size && isa == rhs.isa);
|
||||
}
|
||||
|
||||
/* Inequality operator. */
|
||||
bool operator!= (const struct arc_gdbarch_features &rhs) const
|
||||
bool operator!= (const struct arc_arch_features &rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
@@ -71,7 +71,7 @@ struct arc_gdbarch_features
|
||||
the returned data. */
|
||||
|
||||
target_desc *arc_create_target_description
|
||||
(const struct arc_gdbarch_features &features);
|
||||
(const struct arc_arch_features &features);
|
||||
|
||||
#else
|
||||
|
||||
@@ -79,7 +79,7 @@ target_desc *arc_create_target_description
|
||||
If nothing is found, then create one and return it. */
|
||||
|
||||
const target_desc *arc_lookup_target_description
|
||||
(const struct arc_gdbarch_features &features);
|
||||
(const struct arc_arch_features &features);
|
||||
|
||||
#endif /* GDBSERVER */
|
||||
|
||||
|
||||
125
gdb/arm-tdep.c
125
gdb/arm-tdep.c
@@ -469,7 +469,7 @@ arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr)
|
||||
}
|
||||
|
||||
/* Determine if the address specified equals any of these magic return
|
||||
values, called EXC_RETURN, defined by the ARM v6-M and v7-M
|
||||
values, called EXC_RETURN, defined by the ARM v6-M, v7-M and v8-M
|
||||
architectures.
|
||||
|
||||
From ARMv6-M Reference Manual B1.5.8
|
||||
@@ -500,13 +500,25 @@ arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr)
|
||||
0xFFFFFFFD Thread mode Process Basic
|
||||
|
||||
For more details see "B1.5.8 Exception return behavior"
|
||||
in both ARMv6-M and ARMv7-M Architecture Reference Manuals. */
|
||||
in both ARMv6-M and ARMv7-M Architecture Reference Manuals.
|
||||
|
||||
In the ARMv8-M Architecture Technical Reference also adds
|
||||
for implementations without the Security Extension:
|
||||
|
||||
EXC_RETURN Condition
|
||||
0xFFFFFFB0 Return to Handler mode.
|
||||
0xFFFFFFB8 Return to Thread mode using the main stack.
|
||||
0xFFFFFFBC Return to Thread mode using the process stack. */
|
||||
|
||||
static int
|
||||
arm_m_addr_is_magic (CORE_ADDR addr)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
/* Values from ARMv8-M Architecture Technical Reference. */
|
||||
case 0xffffffb0:
|
||||
case 0xffffffb8:
|
||||
case 0xffffffbc:
|
||||
/* Values from Tables in B1.5.8 the EXC_RETURN definitions of
|
||||
the exception return behavior. */
|
||||
case 0xffffffe1:
|
||||
@@ -2923,14 +2935,64 @@ arm_m_exception_cache (struct frame_info *this_frame)
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
struct arm_prologue_cache *cache;
|
||||
CORE_ADDR lr;
|
||||
CORE_ADDR sp;
|
||||
CORE_ADDR unwound_sp;
|
||||
LONGEST xpsr;
|
||||
uint32_t exc_return;
|
||||
uint32_t process_stack_used;
|
||||
uint32_t extended_frame_used;
|
||||
uint32_t secure_stack_used;
|
||||
|
||||
cache = FRAME_OBSTACK_ZALLOC (struct arm_prologue_cache);
|
||||
cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
|
||||
|
||||
unwound_sp = get_frame_register_unsigned (this_frame,
|
||||
ARM_SP_REGNUM);
|
||||
/* ARMv7-M Architecture Reference "B1.5.6 Exception entry behavior"
|
||||
describes which bits in LR that define which stack was used prior
|
||||
to the exception and if FPU is used (causing extended stack frame). */
|
||||
|
||||
lr = get_frame_register_unsigned (this_frame, ARM_LR_REGNUM);
|
||||
sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
|
||||
|
||||
/* Check EXC_RETURN indicator bits. */
|
||||
exc_return = (((lr >> 28) & 0xf) == 0xf);
|
||||
|
||||
/* Check EXC_RETURN bit SPSEL if Main or Thread (process) stack used. */
|
||||
process_stack_used = ((lr & (1 << 2)) != 0);
|
||||
if (exc_return && process_stack_used)
|
||||
{
|
||||
/* Thread (process) stack used.
|
||||
Potentially this could be other register defined by target, but PSP
|
||||
can be considered a standard name for the "Process Stack Pointer".
|
||||
To be fully aware of system registers like MSP and PSP, these could
|
||||
be added to a separate XML arm-m-system-profile that is valid for
|
||||
ARMv6-M and ARMv7-M architectures. Also to be able to debug eg a
|
||||
corefile off-line, then these registers must be defined by GDB,
|
||||
and also be included in the corefile regsets. */
|
||||
|
||||
int psp_regnum = user_reg_map_name_to_regnum (gdbarch, "psp", -1);
|
||||
if (psp_regnum == -1)
|
||||
{
|
||||
/* Thread (process) stack could not be fetched,
|
||||
give warning and exit. */
|
||||
|
||||
warning (_("no PSP thread stack unwinding supported."));
|
||||
|
||||
/* Terminate any further stack unwinding by refer to self. */
|
||||
cache->prev_sp = sp;
|
||||
return cache;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Thread (process) stack used, use PSP as SP. */
|
||||
unwound_sp = get_frame_register_unsigned (this_frame, psp_regnum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Main stack used, use MSP as SP. */
|
||||
unwound_sp = sp;
|
||||
}
|
||||
|
||||
/* The hardware saves eight 32-bit words, comprising xPSR,
|
||||
ReturnAddress, LR (R14), R12, R3, R2, R1, R0. See details in
|
||||
@@ -2940,15 +3002,62 @@ arm_m_exception_cache (struct frame_info *this_frame)
|
||||
cache->saved_regs[1].addr = unwound_sp + 4;
|
||||
cache->saved_regs[2].addr = unwound_sp + 8;
|
||||
cache->saved_regs[3].addr = unwound_sp + 12;
|
||||
cache->saved_regs[12].addr = unwound_sp + 16;
|
||||
cache->saved_regs[14].addr = unwound_sp + 20;
|
||||
cache->saved_regs[15].addr = unwound_sp + 24;
|
||||
cache->saved_regs[ARM_IP_REGNUM].addr = unwound_sp + 16;
|
||||
cache->saved_regs[ARM_LR_REGNUM].addr = unwound_sp + 20;
|
||||
cache->saved_regs[ARM_PC_REGNUM].addr = unwound_sp + 24;
|
||||
cache->saved_regs[ARM_PS_REGNUM].addr = unwound_sp + 28;
|
||||
|
||||
/* Check EXC_RETURN bit FTYPE if extended stack frame (FPU regs stored)
|
||||
type used. */
|
||||
extended_frame_used = ((lr & (1 << 4)) == 0);
|
||||
if (exc_return && extended_frame_used)
|
||||
{
|
||||
int i;
|
||||
int fpu_regs_stack_offset;
|
||||
|
||||
/* This code does not take into account the lazy stacking, see "Lazy
|
||||
context save of FP state", in B1.5.7, also ARM AN298, supported
|
||||
by Cortex-M4F architecture.
|
||||
To fully handle this the FPCCR register (Floating-point Context
|
||||
Control Register) needs to be read out and the bits ASPEN and LSPEN
|
||||
could be checked to setup correct lazy stacked FP registers.
|
||||
This register is located at address 0xE000EF34. */
|
||||
|
||||
/* Extended stack frame type used. */
|
||||
fpu_regs_stack_offset = unwound_sp + 0x20;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
cache->saved_regs[ARM_D0_REGNUM + i].addr = fpu_regs_stack_offset;
|
||||
fpu_regs_stack_offset += 4;
|
||||
}
|
||||
cache->saved_regs[ARM_FPSCR_REGNUM].addr = unwound_sp + 0x60;
|
||||
|
||||
/* Offset 0x64 is reserved. */
|
||||
cache->prev_sp = unwound_sp + 0x68;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Standard stack frame type used. */
|
||||
cache->prev_sp = unwound_sp + 0x20;
|
||||
}
|
||||
|
||||
/* Check EXC_RETURN bit S if Secure or Non-secure stack used. */
|
||||
secure_stack_used = ((lr & (1 << 6)) != 0);
|
||||
if (exc_return && secure_stack_used)
|
||||
{
|
||||
/* ARMv8-M Exception and interrupt handling is not considered here.
|
||||
In the ARMv8-M architecture also EXC_RETURN bit S is controlling if
|
||||
the Secure or Non-secure stack was used. To separate Secure and
|
||||
Non-secure stacks, processors that are based on the ARMv8-M
|
||||
architecture support 4 stack pointers: MSP_S, PSP_S, MSP_NS, PSP_NS.
|
||||
In addition, a stack limit feature is provided using stack limit
|
||||
registers (accessible using MSR and MRS instructions) in Privileged
|
||||
level. */
|
||||
}
|
||||
|
||||
/* If bit 9 of the saved xPSR is set, then there is a four-byte
|
||||
aligner between the top of the 32-byte stack frame and the
|
||||
previous context's stack pointer. */
|
||||
cache->prev_sp = unwound_sp + 32;
|
||||
if (safe_read_memory_integer (unwound_sp + 28, 4, byte_order, &xpsr)
|
||||
&& (xpsr & (1 << 9)) != 0)
|
||||
cache->prev_sp += 4;
|
||||
|
||||
@@ -1229,13 +1229,23 @@ commands_command_1 (const char *arg, int from_tty,
|
||||
|
||||
if (arg == NULL || !*arg)
|
||||
{
|
||||
/* Argument not explicitly given. Synthesize it. */
|
||||
if (breakpoint_count - prev_breakpoint_count > 1)
|
||||
new_arg = string_printf ("%d-%d", prev_breakpoint_count + 1,
|
||||
breakpoint_count);
|
||||
else if (breakpoint_count > 0)
|
||||
new_arg = string_printf ("%d", breakpoint_count);
|
||||
arg = new_arg.c_str ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a copy of ARG. This is needed because the "commands"
|
||||
command may be coming from a script. In that case, the read
|
||||
line buffer is going to be overwritten in the lambda of
|
||||
'map_breakpoint_numbers' below when reading the next line
|
||||
before we are are done parsing the breakpoint numbers. */
|
||||
new_arg = arg;
|
||||
}
|
||||
arg = new_arg.c_str ();
|
||||
|
||||
map_breakpoint_numbers
|
||||
(arg, [&] (breakpoint *b)
|
||||
@@ -5431,9 +5441,8 @@ bpstat_stop_status (const address_space *aspace,
|
||||
}
|
||||
|
||||
static void
|
||||
handle_jit_event (void)
|
||||
handle_jit_event (CORE_ADDR address)
|
||||
{
|
||||
struct frame_info *frame;
|
||||
struct gdbarch *gdbarch;
|
||||
|
||||
infrun_debug_printf ("handling bp_jit_event");
|
||||
@@ -5442,11 +5451,15 @@ handle_jit_event (void)
|
||||
breakpoint_re_set. */
|
||||
target_terminal::ours_for_output ();
|
||||
|
||||
frame = get_current_frame ();
|
||||
gdbarch = get_frame_arch (frame);
|
||||
objfile *jiter = symbol_objfile (get_frame_function (frame));
|
||||
|
||||
jit_event_handler (gdbarch, jiter);
|
||||
gdbarch = get_frame_arch (get_current_frame ());
|
||||
/* This event is caused by a breakpoint set in `jit_breakpoint_re_set`,
|
||||
thus it is expected that its objectfile can be found through
|
||||
minimal symbol lookup. If it doesn't work (and assert fails), it
|
||||
most likely means that `jit_breakpoint_re_set` was changes and this
|
||||
function needs to be updated too. */
|
||||
bound_minimal_symbol jit_bp_sym = lookup_minimal_symbol_by_pc (address);
|
||||
gdb_assert (jit_bp_sym.objfile != nullptr);
|
||||
jit_event_handler (gdbarch, jit_bp_sym.objfile);
|
||||
|
||||
target_terminal::inferior ();
|
||||
}
|
||||
@@ -5647,7 +5660,7 @@ bpstat_run_callbacks (bpstat bs_head)
|
||||
switch (b->type)
|
||||
{
|
||||
case bp_jit_event:
|
||||
handle_jit_event ();
|
||||
handle_jit_event (bs->bp_location_at->address);
|
||||
break;
|
||||
case bp_gnu_ifunc_resolver:
|
||||
gnu_ifunc_resolver_stop (b);
|
||||
|
||||
@@ -392,10 +392,6 @@ execute_cmd_post_hook (struct cmd_list_element *c)
|
||||
void
|
||||
execute_control_commands (struct command_line *cmdlines, int from_tty)
|
||||
{
|
||||
/* Set the instream to 0, indicating execution of a
|
||||
user-defined function. */
|
||||
scoped_restore restore_instream
|
||||
= make_scoped_restore (¤t_ui->instream, nullptr);
|
||||
scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
|
||||
scoped_restore save_nesting
|
||||
= make_scoped_restore (&command_nest_depth, command_nest_depth + 1);
|
||||
@@ -464,6 +460,11 @@ execute_user_command (struct cmd_list_element *c, const char *args)
|
||||
if (user_args_stack.size () > max_user_call_depth)
|
||||
error (_("Max user call depth exceeded -- command aborted."));
|
||||
|
||||
/* Set the instream to nullptr, indicating execution of a
|
||||
user-defined function. */
|
||||
scoped_restore restore_instream
|
||||
= make_scoped_restore (¤t_ui->instream, nullptr);
|
||||
|
||||
execute_control_commands (cmdlines, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1606,6 +1606,7 @@ static int create_all_type_units (dwarf2_per_objfile *per_objfile);
|
||||
|
||||
static void load_full_comp_unit (dwarf2_per_cu_data *per_cu,
|
||||
dwarf2_per_objfile *per_objfile,
|
||||
dwarf2_cu *existing_cu,
|
||||
bool skip_partial,
|
||||
enum language pretend_language);
|
||||
|
||||
@@ -2387,7 +2388,8 @@ load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
|
||||
if (per_cu->is_debug_types)
|
||||
load_full_type_unit (per_cu, per_objfile);
|
||||
else
|
||||
load_full_comp_unit (per_cu, per_objfile, skip_partial, language_minimal);
|
||||
load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
|
||||
skip_partial, language_minimal);
|
||||
|
||||
dwarf2_cu *cu = per_objfile->get_cu (per_cu);
|
||||
if (cu == nullptr)
|
||||
@@ -9230,17 +9232,22 @@ die_eq (const void *item_lhs, const void *item_rhs)
|
||||
return die_lhs->sect_off == die_rhs->sect_off;
|
||||
}
|
||||
|
||||
/* Load the DIEs associated with PER_CU into memory. */
|
||||
/* Load the DIEs associated with PER_CU into memory.
|
||||
|
||||
In some cases, the caller, while reading partial symbols, will need to load
|
||||
the full symbols for the CU for some reason. It will already have a
|
||||
dwarf2_cu object for THIS_CU and pass it as EXISTING_CU, so it can be re-used
|
||||
rather than creating a new one. */
|
||||
|
||||
static void
|
||||
load_full_comp_unit (dwarf2_per_cu_data *this_cu,
|
||||
dwarf2_per_objfile *per_objfile,
|
||||
dwarf2_cu *existing_cu,
|
||||
bool skip_partial,
|
||||
enum language pretend_language)
|
||||
{
|
||||
gdb_assert (! this_cu->is_debug_types);
|
||||
|
||||
dwarf2_cu *existing_cu = per_objfile->get_cu (this_cu);
|
||||
cutu_reader reader (this_cu, per_objfile, NULL, existing_cu, skip_partial);
|
||||
if (reader.dummy_p)
|
||||
return;
|
||||
@@ -10108,7 +10115,8 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
|
||||
|
||||
/* If necessary, add it to the queue and load its DIEs. */
|
||||
if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->language))
|
||||
load_full_comp_unit (per_cu, per_objfile, false, cu->language);
|
||||
load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
|
||||
false, cu->language);
|
||||
|
||||
cu->per_cu->imported_symtabs_push (per_cu);
|
||||
}
|
||||
@@ -22922,7 +22930,8 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
|
||||
|
||||
/* If necessary, add it to the queue and load its DIEs. */
|
||||
if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->language))
|
||||
load_full_comp_unit (per_cu, per_objfile, false, cu->language);
|
||||
load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
|
||||
false, cu->language);
|
||||
|
||||
target_cu = per_objfile->get_cu (per_cu);
|
||||
}
|
||||
@@ -22930,7 +22939,8 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
|
||||
{
|
||||
/* We're loading full DIEs during partial symbol reading. */
|
||||
gdb_assert (per_objfile->per_bfd->reading_partial_symbols);
|
||||
load_full_comp_unit (cu->per_cu, per_objfile, false, language_minimal);
|
||||
load_full_comp_unit (cu->per_cu, per_objfile, cu, false,
|
||||
language_minimal);
|
||||
}
|
||||
|
||||
*ref_cu = target_cu;
|
||||
|
||||
@@ -3283,7 +3283,7 @@ init_complex_type (const char *name, struct type *target_type)
|
||||
|
||||
if (TYPE_MAIN_TYPE (target_type)->flds_bnds.complex_type == nullptr)
|
||||
{
|
||||
if (name == nullptr)
|
||||
if (name == nullptr && target_type->name () != nullptr)
|
||||
{
|
||||
char *new_name
|
||||
= (char *) TYPE_ALLOC (target_type,
|
||||
|
||||
@@ -1538,6 +1538,24 @@ struct i386_insn i386_frame_setup_skip_insns[] =
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Check whether PC points to an endbr32 instruction. */
|
||||
static CORE_ADDR
|
||||
i386_skip_endbr (CORE_ADDR pc)
|
||||
{
|
||||
static const gdb_byte endbr32[] = { 0xf3, 0x0f, 0x1e, 0xfb };
|
||||
|
||||
gdb_byte buf[sizeof (endbr32)];
|
||||
|
||||
/* Stop there if we can't read the code */
|
||||
if (target_read_code (pc, buf, sizeof (endbr32)))
|
||||
return pc;
|
||||
|
||||
/* If the instruction isn't an endbr32, stop */
|
||||
if (memcmp (buf, endbr32, sizeof (endbr32)) != 0)
|
||||
return pc;
|
||||
|
||||
return pc + sizeof (endbr32);
|
||||
}
|
||||
|
||||
/* Check whether PC points to a no-op instruction. */
|
||||
static CORE_ADDR
|
||||
@@ -1815,6 +1833,7 @@ i386_analyze_prologue (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, CORE_ADDR current_pc,
|
||||
struct i386_frame_cache *cache)
|
||||
{
|
||||
pc = i386_skip_endbr (pc);
|
||||
pc = i386_skip_noop (pc);
|
||||
pc = i386_follow_jump (gdbarch, pc);
|
||||
pc = i386_analyze_struct_return (pc, current_pc, cache);
|
||||
|
||||
17
gdb/infrun.c
17
gdb/infrun.c
@@ -3533,6 +3533,11 @@ do_target_wait_1 (inferior *inf, ptid_t ptid,
|
||||
|
||||
/* But if we don't find one, we'll have to wait. */
|
||||
|
||||
/* We can't ask a non-async target to do a non-blocking wait, so this will be
|
||||
a blocking wait. */
|
||||
if (!target_can_async_p ())
|
||||
options &= ~TARGET_WNOHANG;
|
||||
|
||||
if (deprecated_target_wait_hook)
|
||||
event_ptid = deprecated_target_wait_hook (ptid, status, options);
|
||||
else
|
||||
@@ -4358,14 +4363,16 @@ fill_in_stop_func (struct gdbarch *gdbarch,
|
||||
if (!ecs->stop_func_filled_in)
|
||||
{
|
||||
const block *block;
|
||||
const general_symbol_info *gsi;
|
||||
|
||||
/* Don't care about return value; stop_func_start and stop_func_name
|
||||
will both be 0 if it doesn't work. */
|
||||
find_pc_partial_function (ecs->event_thread->suspend.stop_pc,
|
||||
&ecs->stop_func_name,
|
||||
&ecs->stop_func_start,
|
||||
&ecs->stop_func_end,
|
||||
&block);
|
||||
find_pc_partial_function_sym (ecs->event_thread->suspend.stop_pc,
|
||||
&gsi,
|
||||
&ecs->stop_func_start,
|
||||
&ecs->stop_func_end,
|
||||
&block);
|
||||
ecs->stop_func_name = gsi == nullptr ? nullptr : gsi->print_name ();
|
||||
|
||||
/* The call to find_pc_partial_function, above, will set
|
||||
stop_func_start and stop_func_end to the start and end
|
||||
|
||||
@@ -41,6 +41,7 @@ std::vector<pending_stop> pending_stops;
|
||||
EXCEPTION_RECORD siginfo_er;
|
||||
|
||||
#ifdef __x86_64__
|
||||
bool wow64_process = false;
|
||||
bool ignore_first_breakpoint = false;
|
||||
#endif
|
||||
|
||||
@@ -240,6 +241,20 @@ handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions)
|
||||
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
|
||||
ignore_first_breakpoint = false;
|
||||
}
|
||||
else if (wow64_process)
|
||||
{
|
||||
/* This breakpoint exception is triggered for WOW64 processes when
|
||||
reaching an int3 instruction in 64bit code.
|
||||
gdb checks for int3 in case of SIGTRAP, this fails because
|
||||
Wow64GetThreadContext can only report the pc of 32bit code, and
|
||||
gdb lets the target process continue.
|
||||
So handle it as SIGINT instead, then the target is stopped
|
||||
unconditionally. */
|
||||
DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
|
||||
rec->ExceptionCode = DBG_CONTROL_C;
|
||||
ourstatus->value.sig = GDB_SIGNAL_INT;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* FALLTHROUGH */
|
||||
case STATUS_WX86_BREAKPOINT:
|
||||
|
||||
@@ -215,6 +215,8 @@ extern std::vector<pending_stop> pending_stops;
|
||||
extern EXCEPTION_RECORD siginfo_er;
|
||||
|
||||
#ifdef __x86_64__
|
||||
/* The target is a WOW64 process */
|
||||
extern bool wow64_process;
|
||||
/* Ignore first breakpoint exception of WOW64 process */
|
||||
extern bool ignore_first_breakpoint;
|
||||
#endif
|
||||
|
||||
@@ -2009,7 +2009,12 @@ target_disconnect (const char *args, int from_tty)
|
||||
ptid_t
|
||||
target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
|
||||
{
|
||||
return current_top_target ()->wait (ptid, status, options);
|
||||
target_ops *target = current_top_target ();
|
||||
|
||||
if (!target->can_async_p ())
|
||||
gdb_assert ((options & TARGET_WNOHANG) == 0);
|
||||
|
||||
return target->wait (ptid, status, options);
|
||||
}
|
||||
|
||||
/* See target.h. */
|
||||
|
||||
@@ -1,3 +1,73 @@
|
||||
2020-10-22 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
PR gdb/26693
|
||||
* gdb.dwarf2/template-specification-full-name.exp: New test.
|
||||
|
||||
2020-10-13 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
PR gdb/26642
|
||||
* gdb.base/maint-target-async-off.c: New test.
|
||||
* gdb.base/maint-target-async-off.exp: New test.
|
||||
|
||||
2020-09-28 Gareth Rees <grees@undo.io> (tiny change)
|
||||
|
||||
PR python/26586
|
||||
* gdb.python/python.exp: add test cases for the from_tty
|
||||
argument to gdb.execute.
|
||||
|
||||
2020-09-25 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
||||
|
||||
* gdb.base/bp-cmds-sourced-script.c: New file.
|
||||
* gdb.base/bp-cmds-sourced-script.exp: New test.
|
||||
* gdb.base/bp-cmds-sourced-script.gdb: New file.
|
||||
|
||||
2020-09-24 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
PR tui/26638:
|
||||
* gdb.tui/list.exp: Check output of "focus next".
|
||||
|
||||
2020-09-18 Victor Collod <vcollod@nvidia.com>
|
||||
|
||||
PR gdb/26635
|
||||
* gdb.arch/amd64-prologue-skip-cf-protection.exp: Make the test
|
||||
compatible with i386, and move it to...
|
||||
* gdb.arch/i386-prologue-skip-cf-protection.exp: ... here.
|
||||
* gdb.arch/amd64-prologue-skip-cf-protection.c: Move to...
|
||||
* gdb.arch/i386-prologue-skip-cf-protection.c: ... here.
|
||||
|
||||
2020-09-18 Pedro Alves <pedro@palves.net>
|
||||
|
||||
PR gdb/26631
|
||||
* gdb.multi/multi-target-thread-find.exp: New file.
|
||||
|
||||
2020-09-18 Pedro Alves <pedro@palves.net>
|
||||
|
||||
* gdb.multi/multi-target-continue.exp: New file, factored out from
|
||||
multi-target.exp.
|
||||
* gdb.multi/multi-target-info-inferiors.exp: New file, factored out from
|
||||
multi-target.exp.
|
||||
* gdb.multi/multi-target-interrupt.exp: New file, factored out from
|
||||
multi-target.exp.
|
||||
* gdb.multi/multi-target-no-resumed.exp: New file, factored out from
|
||||
multi-target.exp.
|
||||
* gdb.multi/multi-target-ping-pong-next.exp: New file, factored out from
|
||||
multi-target.exp.
|
||||
* gdb.multi/multi-target.exp.tcl: New file, factored out from
|
||||
multi-target.exp.
|
||||
* gdb.multi/multi-target.exp: Delete.
|
||||
|
||||
2020-09-16 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
PR gdb/26598:
|
||||
* gdb.base/skipcxx.exp: New file.
|
||||
* gdb.base/skipcxx.cc: New file.
|
||||
|
||||
2020-09-15 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
PR rust/26197:
|
||||
* lib/rust-support.exp (rust_llvm_version): New proc.
|
||||
* gdb.rust/simple.exp: Check rust_llvm_version.
|
||||
|
||||
2020-09-11 Moritz Riesterer <moritz.riesterer@intel.com>
|
||||
Felix Willgerodt <Felix.Willgerodt@intel.com>
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
# Test skipping a prologue that was generated with gcc's -fcf-protection=full
|
||||
# (control flow protection) option.
|
||||
#
|
||||
# This option places an `endbr64` instruction at the start of all functions,
|
||||
# which can interfere with prologue analysis.
|
||||
# This option places an `endbr32`/`endbr64` instruction at the start of
|
||||
# all functions, which can interfere with prologue analysis.
|
||||
|
||||
standard_testfile .c
|
||||
set binfile ${binfile}
|
||||
|
||||
if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
|
||||
if { ![istarget x86_64-*-*] && ![istarget i?86-*-*] } {
|
||||
verbose "Skipping ${testfile}."
|
||||
return
|
||||
}
|
||||
22
gdb/testsuite/gdb.base/bp-cmds-sourced-script.c
Normal file
22
gdb/testsuite/gdb.base/bp-cmds-sourced-script.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2020 Free Software Foundation, Inc.
|
||||
|
||||
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/>. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
39
gdb/testsuite/gdb.base/bp-cmds-sourced-script.exp
Normal file
39
gdb/testsuite/gdb.base/bp-cmds-sourced-script.exp
Normal file
@@ -0,0 +1,39 @@
|
||||
# Copyright 2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>. */
|
||||
|
||||
# Test that breakpoint commands entered in a GDB script work as
|
||||
# expected when the commands are defined for multiple breakpoints.
|
||||
|
||||
standard_testfile
|
||||
|
||||
if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
set script_file ${srcdir}/${subdir}/$testfile.gdb
|
||||
|
||||
gdb_test "source $script_file" \
|
||||
"Breakpoint 1\[^\r\n\]*\r\nBreakpoint 2\[^\r\n\]*" \
|
||||
"source the script"
|
||||
|
||||
gdb_run_cmd
|
||||
|
||||
gdb_test_multiple "" "commands executed twice" {
|
||||
-re "\\$${decimal} = 100123\r\n\\$${decimal} = 100123\r\n$gdb_prompt $" {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
|
||||
gdb_continue_to_end
|
||||
20
gdb/testsuite/gdb.base/bp-cmds-sourced-script.gdb
Normal file
20
gdb/testsuite/gdb.base/bp-cmds-sourced-script.gdb
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright 2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>. */
|
||||
|
||||
break main
|
||||
break main
|
||||
commands 1 2
|
||||
print 100123
|
||||
end
|
||||
22
gdb/testsuite/gdb.base/maint-target-async-off.c
Normal file
22
gdb/testsuite/gdb.base/maint-target-async-off.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2020 Free Software Foundation, Inc.
|
||||
|
||||
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/>. */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
41
gdb/testsuite/gdb.base/maint-target-async-off.exp
Normal file
41
gdb/testsuite/gdb.base/maint-target-async-off.exp
Normal file
@@ -0,0 +1,41 @@
|
||||
# Copyright 2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Verify that debugging with "maintenance target-async off" works somewhat. At
|
||||
# least running to main and to the end of the program.
|
||||
|
||||
standard_testfile
|
||||
|
||||
save_vars { GDBFLAGS } {
|
||||
# Enable target-async off this way, because with board
|
||||
# native-extended-gdbserver, the remote target is already open when
|
||||
# returning from prepare_for_testing, and that would be too late to toggle
|
||||
# it.
|
||||
append GDBFLAGS { -ex "maintenance set target-async off" }
|
||||
|
||||
if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# Make sure our command-line flag worked.
|
||||
gdb_test "maintenance show target-async" "Controlling the inferior in asynchronous mode is off\\."
|
||||
|
||||
if { ![runto_main] } {
|
||||
fail "can't run to main"
|
||||
return
|
||||
}
|
||||
|
||||
gdb_continue_to_end
|
||||
32
gdb/testsuite/gdb.base/skipcxx.cc
Normal file
32
gdb/testsuite/gdb.base/skipcxx.cc
Normal file
@@ -0,0 +1,32 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2020 Free Software Foundation, Inc.
|
||||
|
||||
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/>. */
|
||||
|
||||
namespace somename
|
||||
{
|
||||
int func()
|
||||
{
|
||||
return 23;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int x = somename::func ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
29
gdb/testsuite/gdb.base/skipcxx.exp
Normal file
29
gdb/testsuite/gdb.base/skipcxx.exp
Normal file
@@ -0,0 +1,29 @@
|
||||
# Copyright 2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
standard_testfile .cc
|
||||
|
||||
if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
fail "can't run to main"
|
||||
return
|
||||
}
|
||||
|
||||
gdb_test "skip -rfu ^somename::" \
|
||||
[string_to_regexp "Function(s) ^somename:: will be skipped when stepping."]
|
||||
gdb_test "step" ".* return 0;"
|
||||
@@ -0,0 +1,77 @@
|
||||
# Copyright 2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Test to reproduce the crash described in PR 26693. The following DWARF was
|
||||
# crashing GDB while loading partial symbols: a DW_TAG_subprogram with a
|
||||
# DW_AT_specification (pointing to another subprogram), without a DW_AT_name
|
||||
# and with a template parameter (DW_TAG_template_type_parameter). More
|
||||
# precisely, the crash was happening when trying to compute the full name of the
|
||||
# subprogram.
|
||||
|
||||
load_lib dwarf.exp
|
||||
|
||||
if {![dwarf2_support]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
standard_testfile main.c .S
|
||||
|
||||
set asm_file [standard_output_file $srcfile2]
|
||||
Dwarf::assemble $asm_file {
|
||||
cu {} {
|
||||
DW_TAG_compile_unit {
|
||||
{DW_AT_language @DW_LANG_C_plus_plus}
|
||||
} {
|
||||
declare_labels templated_subprogram int
|
||||
|
||||
int: DW_TAG_base_type {
|
||||
{DW_AT_name "int"}
|
||||
{DW_AT_byte_size 4 DW_FORM_data1}
|
||||
{DW_AT_encoding @DW_ATE_signed}
|
||||
}
|
||||
|
||||
# The templated subprogram.
|
||||
templated_subprogram: DW_TAG_subprogram {
|
||||
{DW_AT_name "apply"}
|
||||
}
|
||||
|
||||
# The template specialization.
|
||||
#
|
||||
# The low and high PC are phony: we just need an address range that
|
||||
# is valid in the program, so we use the main function's range.
|
||||
DW_TAG_subprogram {
|
||||
{DW_AT_specification :$templated_subprogram}
|
||||
{MACRO_AT_range main}
|
||||
} {
|
||||
DW_TAG_template_type_param {
|
||||
{DW_AT_name "T"}
|
||||
{DW_AT_type :$int DW_FORM_ref4}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if { [prepare_for_testing "failed to prepare" ${testfile} \
|
||||
[list $srcfile $asm_file] {nodebug}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Just a sanity check to make sure GDB slurped the symbols correctly.
|
||||
gdb_test "print apply<int>" " = {void \\(void\\)} $hex <apply<int>\\(\\)>"
|
||||
105
gdb/testsuite/gdb.multi/multi-target-continue.exp
Normal file
105
gdb/testsuite/gdb.multi/multi-target-continue.exp
Normal file
@@ -0,0 +1,105 @@
|
||||
# Copyright 2017-2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Test "continue" to breakpoints in different targets. In non-stop
|
||||
# mode, also tests "interrupt -a".
|
||||
|
||||
source $srcdir/$subdir/multi-target.exp.tcl
|
||||
|
||||
if {![multi_target_prepare]} {
|
||||
return
|
||||
}
|
||||
|
||||
proc test_continue {non-stop} {
|
||||
if {![setup ${non-stop}]} {
|
||||
untested "setup failed"
|
||||
return
|
||||
}
|
||||
|
||||
proc set_break {inf} {
|
||||
gdb_test "break function${inf} thread ${inf}.1" \
|
||||
"Breakpoint .* function${inf}\\..*"
|
||||
}
|
||||
|
||||
# Select inferior INF, and then run to a breakpoint on inferior
|
||||
# INF+1.
|
||||
proc test_continue_inf {inf} {
|
||||
upvar 1 non-stop non-stop
|
||||
|
||||
global gdb_prompt
|
||||
delete_breakpoints
|
||||
|
||||
set next_inf [next_live_inferior $inf]
|
||||
|
||||
gdb_test "inferior $inf" "Switching to inferior $inf.*"
|
||||
set_break $next_inf
|
||||
|
||||
if {${non-stop} == "off"} {
|
||||
gdb_test "continue" "hit Breakpoint .* function${next_inf}.*"
|
||||
} else {
|
||||
set msg "continue"
|
||||
gdb_test_multiple "continue -a&" $msg {
|
||||
-re "Continuing.*$gdb_prompt " {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
|
||||
set msg "hit bp"
|
||||
gdb_test_multiple "" $msg {
|
||||
-re "hit Breakpoint .* function${next_inf}" {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
|
||||
set msg "stop all threads"
|
||||
gdb_test_multiple "interrupt -a" $msg {
|
||||
-re "$gdb_prompt " {
|
||||
for {set i 0} {$i < 7} {incr i} {
|
||||
set ok 0
|
||||
gdb_test_multiple "" $msg {
|
||||
-re "Thread\[^\r\n\]*stopped\\." {
|
||||
set ok 1
|
||||
}
|
||||
}
|
||||
if {!$ok} {
|
||||
break
|
||||
}
|
||||
}
|
||||
gdb_assert $ok $msg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for {set i 1} {$i <= 5} {incr i} {
|
||||
if {$i == 3} {
|
||||
# This is a core inferior.
|
||||
continue
|
||||
}
|
||||
|
||||
with_test_prefix "inf$i" {
|
||||
test_continue_inf $i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Some basic "continue" + breakpoints tests.
|
||||
with_test_prefix "continue" {
|
||||
foreach_with_prefix non-stop {"off" "on"} {
|
||||
test_continue ${non-stop}
|
||||
}
|
||||
}
|
||||
|
||||
multi_target_cleanup
|
||||
110
gdb/testsuite/gdb.multi/multi-target-info-inferiors.exp
Normal file
110
gdb/testsuite/gdb.multi/multi-target-info-inferiors.exp
Normal file
@@ -0,0 +1,110 @@
|
||||
# Copyright 2017-2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Test "info inferiors" and "info connections" with multiple targets.
|
||||
|
||||
source $srcdir/$subdir/multi-target.exp.tcl
|
||||
|
||||
if {![multi_target_prepare]} {
|
||||
return
|
||||
}
|
||||
|
||||
# Test "info inferiors" and "info connections". MULTI_PROCESS
|
||||
# indicates whether the multi-process feature of remote targets is
|
||||
# turned off or on.
|
||||
proc test_info_inferiors {multi_process} {
|
||||
setup "off"
|
||||
|
||||
gdb_test_no_output \
|
||||
"set remote multiprocess-feature-packet $multi_process"
|
||||
|
||||
# Get the description for inferior INF for when the current
|
||||
# inferior id is CURRENT.
|
||||
proc inf_desc {inf current} {
|
||||
set ws "\[ \t\]+"
|
||||
global decimal
|
||||
upvar multi_process multi_process
|
||||
|
||||
if {($multi_process == "off") && ($inf == 2 || $inf == 5)} {
|
||||
set desc "Remote target"
|
||||
} else {
|
||||
set desc "process ${decimal}"
|
||||
}
|
||||
|
||||
set desc "${inf}${ws}${desc}${ws}"
|
||||
if {$inf == $current} {
|
||||
return "\\* $desc"
|
||||
} else {
|
||||
return " $desc"
|
||||
}
|
||||
}
|
||||
|
||||
# Get the "Num" column for CONNECTION for when the current
|
||||
# inferior id is CURRENT_INF.
|
||||
proc connection_num {connection current_inf} {
|
||||
switch $current_inf {
|
||||
"4" { set current_connection "1"}
|
||||
"5" { set current_connection "4"}
|
||||
"6" { set current_connection "5"}
|
||||
default { set current_connection $current_inf}
|
||||
}
|
||||
if {$connection == $current_connection} {
|
||||
return "\\* $connection"
|
||||
} else {
|
||||
return " $connection"
|
||||
}
|
||||
}
|
||||
|
||||
set ws "\[ \t\]+"
|
||||
global decimal binfile
|
||||
|
||||
# Test "info connections" and "info inferior" by switching to each
|
||||
# inferior one by one.
|
||||
for {set inf 1} {$inf <= 6} {incr inf} {
|
||||
with_test_prefix "inferior $inf" {
|
||||
gdb_test "inferior $inf" "Switching to inferior $inf.*"
|
||||
|
||||
gdb_test "info connections" \
|
||||
[multi_line \
|
||||
"Num${ws}What${ws}Description${ws}" \
|
||||
"[connection_num 1 $inf]${ws}native${ws}Native process${ws}" \
|
||||
"[connection_num 2 $inf]${ws}extended-remote localhost:$decimal${ws}Extended remote serial target in gdb-specific protocol${ws}" \
|
||||
"[connection_num 3 $inf]${ws}core${ws}Local core dump file${ws}" \
|
||||
"[connection_num 4 $inf]${ws}extended-remote localhost:$decimal${ws}Extended remote serial target in gdb-specific protocol${ws}" \
|
||||
"[connection_num 5 $inf]${ws}core${ws}Local core dump file${ws}" \
|
||||
]
|
||||
|
||||
gdb_test "info inferiors" \
|
||||
[multi_line \
|
||||
"Num${ws}Description${ws}Connection${ws}Executable${ws}" \
|
||||
"[inf_desc 1 $inf]1 \\(native\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 2 $inf]2 \\(extended-remote localhost:$decimal\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 3 $inf]3 \\(core\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 4 $inf]1 \\(native\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 5 $inf]4 \\(extended-remote localhost:$decimal\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 6 $inf]5 \\(core\\)${ws}${binfile}${ws}" \
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test "info inferiors" and "info connections" commands.
|
||||
with_test_prefix "info-inferiors" {
|
||||
foreach_with_prefix multi_process {"on" "off"} {
|
||||
test_info_inferiors $multi_process
|
||||
}
|
||||
}
|
||||
|
||||
multi_target_cleanup
|
||||
79
gdb/testsuite/gdb.multi/multi-target-interrupt.exp
Normal file
79
gdb/testsuite/gdb.multi/multi-target-interrupt.exp
Normal file
@@ -0,0 +1,79 @@
|
||||
# Copyright 2017-2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Test interrupting multiple targets with Ctrl-C.
|
||||
|
||||
source $srcdir/$subdir/multi-target.exp.tcl
|
||||
|
||||
if {![multi_target_prepare]} {
|
||||
return
|
||||
}
|
||||
|
||||
proc test_ctrlc {} {
|
||||
if {![setup "off"]} {
|
||||
untested "setup failed"
|
||||
return
|
||||
}
|
||||
|
||||
delete_breakpoints
|
||||
|
||||
# Select inferior INF, continue all inferiors, and then Ctrl-C.
|
||||
proc test_ctrlc_inf {inf} {
|
||||
global gdb_prompt
|
||||
|
||||
gdb_test "inferior $inf" "Switching to inferior $inf.*"
|
||||
|
||||
set msg "continue"
|
||||
gdb_test_multiple "continue" $msg {
|
||||
-re "Continuing" {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
|
||||
after 200 { send_gdb "\003" }
|
||||
|
||||
set msg "send_gdb control C"
|
||||
gdb_test_multiple "" $msg {
|
||||
-re "received signal SIGINT.*$gdb_prompt $" {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
|
||||
set msg "all threads stopped"
|
||||
gdb_test_multiple "info threads" "$msg" {
|
||||
-re "\\\(running\\\).*$gdb_prompt $" {
|
||||
fail $msg
|
||||
}
|
||||
-re "$gdb_prompt $" {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for {set i 1} {$i <= 5} {incr i} {
|
||||
if {$i == 3} {
|
||||
# This is a core inferior.
|
||||
continue
|
||||
}
|
||||
|
||||
with_test_prefix "inf$i" {
|
||||
test_ctrlc_inf $i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_ctrlc
|
||||
|
||||
multi_target_cleanup
|
||||
90
gdb/testsuite/gdb.multi/multi-target-no-resumed.exp
Normal file
90
gdb/testsuite/gdb.multi/multi-target-no-resumed.exp
Normal file
@@ -0,0 +1,90 @@
|
||||
# Copyright 2017-2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Test that when there's a foreground execution command in progress, a
|
||||
# TARGET_WAITKIND_NO_RESUMED for a particular target is ignored when
|
||||
# other targets are still resumed.
|
||||
|
||||
source $srcdir/$subdir/multi-target.exp.tcl
|
||||
|
||||
if {![multi_target_prepare]} {
|
||||
return
|
||||
}
|
||||
|
||||
proc test_no_resumed_infs {inf_A inf_B} {
|
||||
global gdb_prompt
|
||||
|
||||
if {![setup "off"]} {
|
||||
untested "setup failed"
|
||||
return
|
||||
}
|
||||
|
||||
gdb_test "thread $inf_A.2" "Switching to thread $inf_A\.2 .*" \
|
||||
"select thread of target A"
|
||||
|
||||
gdb_test_no_output "set scheduler-locking on"
|
||||
|
||||
gdb_test_multiple "continue &" "" {
|
||||
-re "Continuing.*$gdb_prompt " {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "thread $inf_B.2" "Switching to thread $inf_B\.2 .*" \
|
||||
"select thread of target B"
|
||||
gdb_test "p exit_thread = 1" " = 1" \
|
||||
"set the thread to exit on resumption"
|
||||
|
||||
# Wait 3 seconds. If we see any response from GDB, such as
|
||||
# "No unwaited-for children left." it's a bug.
|
||||
gdb_test_multiple "continue" "continue" {
|
||||
-timeout 3
|
||||
timeout {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
|
||||
# Now stop the program (all targets).
|
||||
send_gdb "\003"
|
||||
gdb_test_multiple "" "send_gdb control C" {
|
||||
-re "received signal SIGINT.*$gdb_prompt $" {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test_multiple "info threads" "all threads stopped" {
|
||||
-re "\\\(running\\\).*$gdb_prompt $" {
|
||||
fail $gdb_test_name
|
||||
}
|
||||
-re "$gdb_prompt $" {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# inferior 1 -> native
|
||||
# inferior 2 -> extended-remote 1
|
||||
# inferior 5 -> extended-remote 2
|
||||
set inferiors {1 2 5}
|
||||
foreach_with_prefix inf_A $inferiors {
|
||||
foreach_with_prefix inf_B $inferiors {
|
||||
if {$inf_A == $inf_B} {
|
||||
continue
|
||||
}
|
||||
test_no_resumed_infs $inf_A $inf_B
|
||||
}
|
||||
}
|
||||
|
||||
multi_target_cleanup
|
||||
85
gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp
Normal file
85
gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp
Normal file
@@ -0,0 +1,85 @@
|
||||
# Copyright 2017-2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Test "next" bouncing between two breakpoints in two threads running
|
||||
# in different targets.
|
||||
|
||||
source $srcdir/$subdir/multi-target.exp.tcl
|
||||
|
||||
if {![multi_target_prepare]} {
|
||||
return
|
||||
}
|
||||
|
||||
proc test_ping_pong_next {} {
|
||||
global srcfile
|
||||
|
||||
if {![setup "off"]} {
|
||||
untested "setup failed"
|
||||
return
|
||||
}
|
||||
|
||||
# Block/unblock inferiors 1 and 2 according to INF1 and INF2.
|
||||
proc block {inf1 inf2} {
|
||||
gdb_test "thread apply 1.1 p wait_for_gdb = $inf1" " = $inf1"
|
||||
gdb_test "thread apply 2.1 p wait_for_gdb = $inf2" " = $inf2"
|
||||
}
|
||||
|
||||
# We'll use inferiors 1 and 2. Make sure they're really connected
|
||||
# to different targets.
|
||||
gdb_test "thread apply 1.1 maint print target-stack" \
|
||||
"- native.*"
|
||||
gdb_test "thread apply 2.1 maint print target-stack" \
|
||||
"- extended-remote.*"
|
||||
|
||||
# Set two breakpoints, one for each of inferior 1 and 2. Inferior
|
||||
# 1 is running on the native target, and inferior 2 is running on
|
||||
# extended-gdbserver. Run to breakpoint 1 to gets things started.
|
||||
set line1 [gdb_get_line_number "set break 1 here"]
|
||||
set line2 [gdb_get_line_number "set break 2 here"]
|
||||
|
||||
gdb_test "thread 1.1" "Switching to thread 1.1 .*"
|
||||
|
||||
gdb_test "break $srcfile:$line1 thread 1.1" \
|
||||
"Breakpoint .*$srcfile:$line1\\..*"
|
||||
|
||||
gdb_test "continue" "hit Breakpoint .*"
|
||||
|
||||
gdb_test "break $srcfile:$line2 thread 2.1" \
|
||||
"Breakpoint .*$srcfile:$line2\\..*"
|
||||
|
||||
# Now block inferior 1 and issue "next". We should stop at the
|
||||
# breakpoint for inferior 2, given schedlock off.
|
||||
with_test_prefix "next inf 1" {
|
||||
block 1 0
|
||||
gdb_test "next" "Thread 2.1 .*hit Breakpoint .*$srcfile:$line2.*"
|
||||
}
|
||||
|
||||
# Now unblock inferior 2 and block inferior 1. "next" should run
|
||||
# into the breakpoint in inferior 1.
|
||||
with_test_prefix "next inf 2" {
|
||||
block 0 1
|
||||
gdb_test "next" "Thread 1.1 .*hit Breakpoint .*$srcfile:$line1.*"
|
||||
}
|
||||
|
||||
# Try nexting inferior 1 again.
|
||||
with_test_prefix "next inf 1 again" {
|
||||
block 1 0
|
||||
gdb_test "next" "Thread 2.1 .*hit Breakpoint .*$srcfile:$line2.*"
|
||||
}
|
||||
}
|
||||
|
||||
test_ping_pong_next
|
||||
|
||||
multi_target_cleanup
|
||||
106
gdb/testsuite/gdb.multi/multi-target-thread-find.exp
Normal file
106
gdb/testsuite/gdb.multi/multi-target-thread-find.exp
Normal file
@@ -0,0 +1,106 @@
|
||||
# Copyright 2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Test "thread find" with multiple inferiors/targets. Regression test
|
||||
# for PR gdb/26631.
|
||||
|
||||
source $srcdir/$subdir/multi-target.exp.tcl
|
||||
|
||||
if {![multi_target_prepare]} {
|
||||
return
|
||||
}
|
||||
|
||||
proc test_thread_find {} {
|
||||
global decimal gdb_prompt
|
||||
|
||||
set NUM_INFS 6
|
||||
|
||||
if {![setup "off"]} {
|
||||
untested "setup failed"
|
||||
return
|
||||
}
|
||||
|
||||
# This makes sure we don't crash. See PR gdb/26631.
|
||||
gdb_test "thread find xxxyyyzzz" \
|
||||
"No threads match 'xxxyyyzzz'"
|
||||
|
||||
# Create thread names.
|
||||
for {set i 1} {$i <= $NUM_INFS} {incr i} {
|
||||
gdb_test "thread apply $i.1 thread name threadname_$i" \
|
||||
"Thread $i.1 .*" \
|
||||
"name thread $i"
|
||||
}
|
||||
|
||||
# Collect target ids.
|
||||
|
||||
for {set i 1} {$i <= $NUM_INFS} {incr i} {
|
||||
set target_id($i) ""
|
||||
}
|
||||
set any "\[^\r\n\]*"
|
||||
gdb_test_multiple "info threads" "collect thread id" {
|
||||
-re ". ($decimal).$decimal (Thread ${any}) \"threadname_\[0-9\]+\" $any" {
|
||||
set thr_num $expect_out(1,string)
|
||||
set target_id($thr_num) $expect_out(2,string)
|
||||
exp_continue
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
pass "collect target id"
|
||||
}
|
||||
}
|
||||
|
||||
# Find the threads by name. Note we repeat the search with each
|
||||
# inferior selected, so that we're sure that GDB doesn't get
|
||||
# confused with which target stack to consult.
|
||||
|
||||
with_test_prefix "find by name" {
|
||||
for {set sel_inf 1} {$sel_inf <= $NUM_INFS} {incr sel_inf} {
|
||||
with_test_prefix "inf $sel_inf" {
|
||||
|
||||
gdb_test "inferior $sel_inf" \
|
||||
"Switching to inferior $sel_inf .*"
|
||||
|
||||
for {set find_inf 1} {$find_inf <= $NUM_INFS} {incr find_inf} {
|
||||
gdb_test "thread find threadname_$find_inf" \
|
||||
"Thread $find_inf.1 has name 'threadname_$find_inf'" \
|
||||
"find thread name $find_inf"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Find the threads by target id. Likewise we repeat the search
|
||||
# with each inferior selected.
|
||||
|
||||
with_test_prefix "find by target id" {
|
||||
for {set sel_inf 1} {$sel_inf <= $NUM_INFS} {incr sel_inf} {
|
||||
with_test_prefix "inf $sel_inf" {
|
||||
|
||||
gdb_test "inferior $sel_inf" \
|
||||
"Switching to inferior $sel_inf .*"
|
||||
|
||||
for {set find_inf 1} {$find_inf <= $NUM_INFS} {incr find_inf} {
|
||||
set target_id_re [string_to_regexp $target_id($find_inf)]
|
||||
gdb_test "thread find $target_id($find_inf)" \
|
||||
"Thread $find_inf.1 has target id '$target_id_re'.*" \
|
||||
"find thread target id $find_inf"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_thread_find
|
||||
|
||||
multi_target_cleanup
|
||||
@@ -1,546 +0,0 @@
|
||||
# Copyright 2017-2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Test multi-target features.
|
||||
|
||||
load_lib gdbserver-support.exp
|
||||
|
||||
if { [skip_gdbserver_tests] } {
|
||||
return 0
|
||||
}
|
||||
|
||||
standard_testfile
|
||||
|
||||
# The plain remote target can't do multiple inferiors.
|
||||
if {[target_info gdb_protocol] != ""} {
|
||||
return
|
||||
}
|
||||
|
||||
if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \
|
||||
{debug pthreads}] } {
|
||||
return
|
||||
}
|
||||
|
||||
# Keep a list of (inferior ID, spawn ID).
|
||||
set server_spawn_ids [list]
|
||||
|
||||
proc connect_target_extended_remote {binfile num} {
|
||||
set res [gdbserver_start "--multi" ""]
|
||||
global server_spawn_ids server_spawn_id
|
||||
lappend server_spawn_ids $num $server_spawn_id
|
||||
set gdbserver_gdbport [lindex $res 1]
|
||||
return [gdb_target_cmd "extended-remote" $gdbserver_gdbport]
|
||||
}
|
||||
|
||||
# Add and start inferior number NUM. Returns true on success, false
|
||||
# otherwise.
|
||||
proc add_inferior {num target binfile {gcorefile ""}} {
|
||||
# Start another inferior.
|
||||
gdb_test "add-inferior -no-connection" "Added inferior $num" \
|
||||
"add empty inferior $num"
|
||||
gdb_test "inferior $num" "Switching to inferior $num.*" \
|
||||
"switch to inferior $num"
|
||||
gdb_test "file ${binfile}" ".*" "load file in inferior $num"
|
||||
gdb_test_no_output "set remote exec-file ${binfile}" \
|
||||
"set remote-exec file in inferior $num"
|
||||
|
||||
if {$target == "core"} {
|
||||
gdb_test "core $gcorefile" "Core was generated by.*" \
|
||||
"core [file tail $gcorefile], inf $num"
|
||||
return 1
|
||||
}
|
||||
|
||||
if {$target == "extended-remote"} {
|
||||
if {[connect_target_extended_remote $binfile $num]} {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
if ![runto "all_started"] then {
|
||||
return 0
|
||||
}
|
||||
delete_breakpoints
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
proc prepare_core {} {
|
||||
global gcorefile gcore_created
|
||||
global binfile
|
||||
|
||||
clean_restart ${binfile}
|
||||
|
||||
if ![runto all_started] then {
|
||||
return -1
|
||||
}
|
||||
|
||||
global testfile
|
||||
set gcorefile [standard_output_file $testfile.gcore]
|
||||
set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"]
|
||||
}
|
||||
|
||||
proc next_live_inferior {inf} {
|
||||
incr inf
|
||||
if {$inf == 3} {
|
||||
# 3 is a core.
|
||||
return 4
|
||||
}
|
||||
if {$inf > 5} {
|
||||
# 6 is a core.
|
||||
return 1
|
||||
}
|
||||
|
||||
return $inf
|
||||
}
|
||||
|
||||
# Clean up the server_spawn_ids.
|
||||
proc cleanup_gdbservers { } {
|
||||
global server_spawn_id
|
||||
global server_spawn_ids
|
||||
foreach { inferior_id spawn_id } $server_spawn_ids {
|
||||
set server_spawn_id $spawn_id
|
||||
gdb_test "inferior $inferior_id"
|
||||
gdbserver_exit 0
|
||||
}
|
||||
set server_spawn_ids [list]
|
||||
}
|
||||
|
||||
# Return true on success, false otherwise.
|
||||
|
||||
proc setup {non-stop} {
|
||||
global gcorefile gcore_created
|
||||
global binfile
|
||||
|
||||
cleanup_gdbservers
|
||||
clean_restart ${binfile}
|
||||
|
||||
# multi-target depends on target running in non-stop mode. Force
|
||||
# it on for remote targets, until this is the default.
|
||||
gdb_test_no_output "maint set target-non-stop on"
|
||||
|
||||
gdb_test_no_output "set non-stop ${non-stop}"
|
||||
|
||||
if ![runto all_started] then {
|
||||
return 0
|
||||
}
|
||||
|
||||
delete_breakpoints
|
||||
|
||||
# inferior 1 -> native
|
||||
# inferior 2 -> extended-remote
|
||||
# inferior 3 -> core
|
||||
# inferior 4 -> native
|
||||
# inferior 5 -> extended-remote
|
||||
# inferior 6 -> core
|
||||
if {![add_inferior 2 "extended-remote" $binfile]} {
|
||||
return 0
|
||||
}
|
||||
if {![add_inferior 3 "core" $binfile $gcorefile]} {
|
||||
return 0
|
||||
}
|
||||
if {![add_inferior 4 "native" $binfile]} {
|
||||
return 0
|
||||
}
|
||||
if {![add_inferior 5 "extended-remote" $binfile]} {
|
||||
return 0
|
||||
}
|
||||
if {![add_inferior 6 "core" $binfile $gcorefile]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
# For debugging.
|
||||
gdb_test "info threads" ".*"
|
||||
|
||||
# Make "continue" resume all inferiors.
|
||||
if {${non-stop} == "off"} {
|
||||
gdb_test_no_output "set schedule-multiple on"
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Test "continue" to breakpoints in different targets. In non-stop
|
||||
# mode, also tests "interrupt -a".
|
||||
proc test_continue {non-stop} {
|
||||
if {![setup ${non-stop}]} {
|
||||
untested "setup failed"
|
||||
return
|
||||
}
|
||||
|
||||
proc set_break {inf} {
|
||||
gdb_test "break function${inf} thread ${inf}.1" \
|
||||
"Breakpoint .* function${inf}\\..*"
|
||||
}
|
||||
|
||||
# Select inferior INF, and then run to a breakpoint on inferior
|
||||
# INF+1.
|
||||
proc test_continue_inf {inf} {
|
||||
upvar 1 non-stop non-stop
|
||||
|
||||
global gdb_prompt
|
||||
delete_breakpoints
|
||||
|
||||
set next_inf [next_live_inferior $inf]
|
||||
|
||||
gdb_test "inferior $inf" "Switching to inferior $inf.*"
|
||||
set_break $next_inf
|
||||
|
||||
if {${non-stop} == "off"} {
|
||||
gdb_test "continue" "hit Breakpoint .* function${next_inf}.*"
|
||||
} else {
|
||||
set msg "continue"
|
||||
gdb_test_multiple "continue -a&" $msg {
|
||||
-re "Continuing.*$gdb_prompt " {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
|
||||
set msg "hit bp"
|
||||
gdb_test_multiple "" $msg {
|
||||
-re "hit Breakpoint .* function${next_inf}" {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
|
||||
set msg "stop all threads"
|
||||
gdb_test_multiple "interrupt -a" $msg {
|
||||
-re "$gdb_prompt " {
|
||||
for {set i 0} {$i < 7} {incr i} {
|
||||
set ok 0
|
||||
gdb_test_multiple "" $msg {
|
||||
-re "Thread\[^\r\n\]*stopped\\." {
|
||||
set ok 1
|
||||
}
|
||||
}
|
||||
if {!$ok} {
|
||||
break
|
||||
}
|
||||
}
|
||||
gdb_assert $ok $msg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for {set i 1} {$i <= 5} {incr i} {
|
||||
if {$i == 3} {
|
||||
# This is a core inferior.
|
||||
continue
|
||||
}
|
||||
|
||||
with_test_prefix "inf$i" {
|
||||
test_continue_inf $i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test interrupting multiple targets with Ctrl-C.
|
||||
|
||||
proc test_ctrlc {} {
|
||||
if {![setup "off"]} {
|
||||
untested "setup failed"
|
||||
return
|
||||
}
|
||||
|
||||
delete_breakpoints
|
||||
|
||||
# Select inferior INF, continue all inferiors, and then Ctrl-C.
|
||||
proc test_ctrlc_inf {inf} {
|
||||
global gdb_prompt
|
||||
|
||||
gdb_test "inferior $inf" "Switching to inferior $inf.*"
|
||||
|
||||
set msg "continue"
|
||||
gdb_test_multiple "continue" $msg {
|
||||
-re "Continuing" {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
|
||||
after 200 { send_gdb "\003" }
|
||||
|
||||
set msg "send_gdb control C"
|
||||
gdb_test_multiple "" $msg {
|
||||
-re "received signal SIGINT.*$gdb_prompt $" {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
|
||||
set msg "all threads stopped"
|
||||
gdb_test_multiple "info threads" "$msg" {
|
||||
-re "\\\(running\\\).*$gdb_prompt $" {
|
||||
fail $msg
|
||||
}
|
||||
-re "$gdb_prompt $" {
|
||||
pass $msg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for {set i 1} {$i <= 5} {incr i} {
|
||||
if {$i == 3} {
|
||||
# This is a core inferior.
|
||||
continue
|
||||
}
|
||||
|
||||
with_test_prefix "inf$i" {
|
||||
test_ctrlc_inf $i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test "next" bouncing between two breakpoints in two threads running
|
||||
# in different targets.
|
||||
proc test_ping_pong_next {} {
|
||||
global srcfile
|
||||
|
||||
if {![setup "off"]} {
|
||||
untested "setup failed"
|
||||
return
|
||||
}
|
||||
|
||||
# block/unblock inferiors 1 and 2 according to INF1 and INF2.
|
||||
proc block {inf1 inf2} {
|
||||
gdb_test "thread apply 1.1 p wait_for_gdb = $inf1" " = $inf1"
|
||||
gdb_test "thread apply 2.1 p wait_for_gdb = $inf2" " = $inf2"
|
||||
}
|
||||
|
||||
# We're use inferiors 1 and 2. Make sure they're really connected
|
||||
# to different targets.
|
||||
gdb_test "thread apply 1.1 maint print target-stack" \
|
||||
"- native.*"
|
||||
gdb_test "thread apply 2.1 maint print target-stack" \
|
||||
"- extended-remote.*"
|
||||
|
||||
# Set two breakpoints, one for each of inferior 1 and 2. Inferior
|
||||
# 1 is running on the native target, and inferior 2 is running on
|
||||
# extended-gdbserver. Run to breakpoint 1 to gets things started.
|
||||
set line1 [gdb_get_line_number "set break 1 here"]
|
||||
set line2 [gdb_get_line_number "set break 2 here"]
|
||||
|
||||
gdb_test "thread 1.1" "Switching to thread 1.1 .*"
|
||||
|
||||
gdb_test "break $srcfile:$line1 thread 1.1" \
|
||||
"Breakpoint .*$srcfile:$line1\\..*"
|
||||
|
||||
gdb_test "continue" "hit Breakpoint .*"
|
||||
|
||||
gdb_test "break $srcfile:$line2 thread 2.1" \
|
||||
"Breakpoint .*$srcfile:$line2\\..*"
|
||||
|
||||
# Now block inferior 1 and issue "next". We should stop at the
|
||||
# breakpoint for inferior 2, given schedlock off.
|
||||
with_test_prefix "next inf 1" {
|
||||
block 1 0
|
||||
gdb_test "next" "Thread 2.1 .*hit Breakpoint .*$srcfile:$line2.*"
|
||||
}
|
||||
|
||||
# Now unblock inferior 2 and block inferior 1. "next" should run
|
||||
# into the breakpoint in inferior 1.
|
||||
with_test_prefix "next inf 2" {
|
||||
block 0 1
|
||||
gdb_test "next" "Thread 1.1 .*hit Breakpoint .*$srcfile:$line1.*"
|
||||
}
|
||||
|
||||
# Try nexting inferior 1 again.
|
||||
with_test_prefix "next inf 1 again" {
|
||||
block 1 0
|
||||
gdb_test "next" "Thread 2.1 .*hit Breakpoint .*$srcfile:$line2.*"
|
||||
}
|
||||
}
|
||||
|
||||
# Test "info inferiors" and "info connections". MULTI_PROCESS
|
||||
# indicates whether the multi-process feature of remote targets is
|
||||
# turned off or on.
|
||||
proc test_info_inferiors {multi_process} {
|
||||
setup "off"
|
||||
|
||||
gdb_test_no_output \
|
||||
"set remote multiprocess-feature-packet $multi_process"
|
||||
|
||||
# Get the description for inferior INF for when the current
|
||||
# inferior id is CURRENT.
|
||||
proc inf_desc {inf current} {
|
||||
set ws "\[ \t\]+"
|
||||
global decimal
|
||||
upvar multi_process multi_process
|
||||
|
||||
if {($multi_process == "off") && ($inf == 2 || $inf == 5)} {
|
||||
set desc "Remote target"
|
||||
} else {
|
||||
set desc "process ${decimal}"
|
||||
}
|
||||
|
||||
set desc "${inf}${ws}${desc}${ws}"
|
||||
if {$inf == $current} {
|
||||
return "\\* $desc"
|
||||
} else {
|
||||
return " $desc"
|
||||
}
|
||||
}
|
||||
|
||||
# Get the "Num" column for CONNECTION for when the current
|
||||
# inferior id is CURRENT_INF.
|
||||
proc connection_num {connection current_inf} {
|
||||
switch $current_inf {
|
||||
"4" { set current_connection "1"}
|
||||
"5" { set current_connection "4"}
|
||||
"6" { set current_connection "5"}
|
||||
default { set current_connection $current_inf}
|
||||
}
|
||||
if {$connection == $current_connection} {
|
||||
return "\\* $connection"
|
||||
} else {
|
||||
return " $connection"
|
||||
}
|
||||
}
|
||||
|
||||
set ws "\[ \t\]+"
|
||||
global decimal binfile
|
||||
|
||||
# Test "info connections" and "info inferior" by switching to each
|
||||
# inferior one by one.
|
||||
for {set inf 1} {$inf <= 6} {incr inf} {
|
||||
with_test_prefix "inferior $inf" {
|
||||
gdb_test "inferior $inf" "Switching to inferior $inf.*"
|
||||
|
||||
gdb_test "info connections" \
|
||||
[multi_line \
|
||||
"Num${ws}What${ws}Description${ws}" \
|
||||
"[connection_num 1 $inf]${ws}native${ws}Native process${ws}" \
|
||||
"[connection_num 2 $inf]${ws}extended-remote localhost:$decimal${ws}Extended remote serial target in gdb-specific protocol${ws}" \
|
||||
"[connection_num 3 $inf]${ws}core${ws}Local core dump file${ws}" \
|
||||
"[connection_num 4 $inf]${ws}extended-remote localhost:$decimal${ws}Extended remote serial target in gdb-specific protocol${ws}" \
|
||||
"[connection_num 5 $inf]${ws}core${ws}Local core dump file${ws}" \
|
||||
]
|
||||
|
||||
gdb_test "info inferiors" \
|
||||
[multi_line \
|
||||
"Num${ws}Description${ws}Connection${ws}Executable${ws}" \
|
||||
"[inf_desc 1 $inf]1 \\(native\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 2 $inf]2 \\(extended-remote localhost:$decimal\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 3 $inf]3 \\(core\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 4 $inf]1 \\(native\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 5 $inf]4 \\(extended-remote localhost:$decimal\\)${ws}${binfile}${ws}" \
|
||||
"[inf_desc 6 $inf]5 \\(core\\)${ws}${binfile}${ws}" \
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test that when there's a foreground execution command in progress, a
|
||||
# TARGET_WAITKIND_NO_RESUMED for a particular target is ignored when
|
||||
# other targets are still resumed.
|
||||
|
||||
proc test_no_resumed {} {
|
||||
proc test_no_resumed_infs {inf_A inf_B} {
|
||||
global gdb_prompt
|
||||
|
||||
if {![setup "off"]} {
|
||||
untested "setup failed"
|
||||
return
|
||||
}
|
||||
|
||||
gdb_test "thread $inf_A.2" "Switching to thread $inf_A\.2 .*" \
|
||||
"select thread of target A"
|
||||
|
||||
gdb_test_no_output "set scheduler-locking on"
|
||||
|
||||
gdb_test_multiple "continue &" "" {
|
||||
-re "Continuing.*$gdb_prompt " {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "thread $inf_B.2" "Switching to thread $inf_B\.2 .*" \
|
||||
"select thread of target B"
|
||||
gdb_test "p exit_thread = 1" " = 1" \
|
||||
"set the thread to exit on resumption"
|
||||
|
||||
# Wait 3 seconds. If we see any response from GDB, such as
|
||||
# "No unwaited-for children left." it's a bug.
|
||||
gdb_test_multiple "continue" "continue" {
|
||||
-timeout 3
|
||||
timeout {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
|
||||
# Now stop the program (all targets).
|
||||
send_gdb "\003"
|
||||
gdb_test_multiple "" "send_gdb control C" {
|
||||
-re "received signal SIGINT.*$gdb_prompt $" {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test_multiple "info threads" "all threads stopped" {
|
||||
-re "\\\(running\\\).*$gdb_prompt $" {
|
||||
fail $gdb_test_name
|
||||
}
|
||||
-re "$gdb_prompt $" {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# inferior 1 -> native
|
||||
# inferior 2 -> extended-remote 1
|
||||
# inferior 5 -> extended-remote 2
|
||||
set inferiors {1 2 5}
|
||||
foreach_with_prefix inf_A $inferiors {
|
||||
foreach_with_prefix inf_B $inferiors {
|
||||
if {$inf_A == $inf_B} {
|
||||
continue
|
||||
}
|
||||
test_no_resumed_infs $inf_A $inf_B
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Make a core file with two threads upfront. Several tests load the
|
||||
# same core file.
|
||||
prepare_core
|
||||
|
||||
# Some basic "continue" + breakpoints tests.
|
||||
with_test_prefix "continue" {
|
||||
foreach_with_prefix non-stop {"off" "on"} {
|
||||
test_continue ${non-stop}
|
||||
}
|
||||
}
|
||||
|
||||
# Some basic all-stop Ctrl-C tests.
|
||||
with_test_prefix "interrupt" {
|
||||
test_ctrlc
|
||||
}
|
||||
|
||||
# Test ping-ponging between two targets with "next".
|
||||
with_test_prefix "ping-pong" {
|
||||
test_ping_pong_next
|
||||
}
|
||||
|
||||
# Test "info inferiors" and "info connections" commands.
|
||||
with_test_prefix "info-inferiors" {
|
||||
foreach_with_prefix multi_process {"on" "off"} {
|
||||
test_info_inferiors $multi_process
|
||||
}
|
||||
}
|
||||
|
||||
# Test TARGET_WAITKIND_NO_RESUMED handling with multiple targets.
|
||||
with_test_prefix "no-resumed" {
|
||||
test_no_resumed
|
||||
}
|
||||
|
||||
cleanup_gdbservers
|
||||
185
gdb/testsuite/gdb.multi/multi-target.exp.tcl
Normal file
185
gdb/testsuite/gdb.multi/multi-target.exp.tcl
Normal file
@@ -0,0 +1,185 @@
|
||||
# Copyright 2017-2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# Common routines for testing multi-target features.
|
||||
|
||||
load_lib gdbserver-support.exp
|
||||
|
||||
standard_testfile multi-target.c
|
||||
|
||||
# Keep a list of (inferior ID, spawn ID).
|
||||
set server_spawn_ids [list]
|
||||
|
||||
proc connect_target_extended_remote {binfile num} {
|
||||
set res [gdbserver_start "--multi" ""]
|
||||
global server_spawn_ids server_spawn_id
|
||||
lappend server_spawn_ids $num $server_spawn_id
|
||||
set gdbserver_gdbport [lindex $res 1]
|
||||
return [gdb_target_cmd "extended-remote" $gdbserver_gdbport]
|
||||
}
|
||||
|
||||
# Add and start inferior number NUM. Returns true on success, false
|
||||
# otherwise.
|
||||
proc add_inferior {num target binfile {gcorefile ""}} {
|
||||
# Start another inferior.
|
||||
gdb_test "add-inferior -no-connection" "Added inferior $num" \
|
||||
"add empty inferior $num"
|
||||
gdb_test "inferior $num" "Switching to inferior $num.*" \
|
||||
"switch to inferior $num"
|
||||
gdb_test "file ${binfile}" ".*" "load file in inferior $num"
|
||||
gdb_test_no_output "set remote exec-file ${binfile}" \
|
||||
"set remote-exec file in inferior $num"
|
||||
|
||||
if {$target == "core"} {
|
||||
gdb_test "core $gcorefile" "Core was generated by.*" \
|
||||
"core [file tail $gcorefile], inf $num"
|
||||
return 1
|
||||
}
|
||||
|
||||
if {$target == "extended-remote"} {
|
||||
if {[connect_target_extended_remote $binfile $num]} {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
if ![runto "all_started"] then {
|
||||
return 0
|
||||
}
|
||||
delete_breakpoints
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
proc prepare_core {} {
|
||||
global gcorefile gcore_created
|
||||
global binfile
|
||||
|
||||
clean_restart ${binfile}
|
||||
|
||||
if ![runto all_started] then {
|
||||
return -1
|
||||
}
|
||||
|
||||
global testfile
|
||||
set gcorefile [standard_output_file $testfile.gcore]
|
||||
set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"]
|
||||
}
|
||||
|
||||
proc next_live_inferior {inf} {
|
||||
incr inf
|
||||
if {$inf == 3} {
|
||||
# 3 is a core.
|
||||
return 4
|
||||
}
|
||||
if {$inf > 5} {
|
||||
# 6 is a core.
|
||||
return 1
|
||||
}
|
||||
|
||||
return $inf
|
||||
}
|
||||
|
||||
# Clean up the server_spawn_ids.
|
||||
proc cleanup_gdbservers { } {
|
||||
global server_spawn_id
|
||||
global server_spawn_ids
|
||||
foreach { inferior_id spawn_id } $server_spawn_ids {
|
||||
set server_spawn_id $spawn_id
|
||||
gdb_test "inferior $inferior_id"
|
||||
gdbserver_exit 0
|
||||
}
|
||||
set server_spawn_ids [list]
|
||||
}
|
||||
|
||||
# Return true on success, false otherwise.
|
||||
|
||||
proc setup {non-stop} {
|
||||
global gcorefile gcore_created
|
||||
global binfile
|
||||
|
||||
cleanup_gdbservers
|
||||
clean_restart ${binfile}
|
||||
|
||||
# multi-target depends on target running in non-stop mode. Force
|
||||
# it on for remote targets, until this is the default.
|
||||
gdb_test_no_output "maint set target-non-stop on"
|
||||
|
||||
gdb_test_no_output "set non-stop ${non-stop}"
|
||||
|
||||
if ![runto all_started] then {
|
||||
return 0
|
||||
}
|
||||
|
||||
delete_breakpoints
|
||||
|
||||
# inferior 1 -> native
|
||||
# inferior 2 -> extended-remote
|
||||
# inferior 3 -> core
|
||||
# inferior 4 -> native
|
||||
# inferior 5 -> extended-remote
|
||||
# inferior 6 -> core
|
||||
if {![add_inferior 2 "extended-remote" $binfile]} {
|
||||
return 0
|
||||
}
|
||||
if {![add_inferior 3 "core" $binfile $gcorefile]} {
|
||||
return 0
|
||||
}
|
||||
if {![add_inferior 4 "native" $binfile]} {
|
||||
return 0
|
||||
}
|
||||
if {![add_inferior 5 "extended-remote" $binfile]} {
|
||||
return 0
|
||||
}
|
||||
if {![add_inferior 6 "core" $binfile $gcorefile]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
# For debugging.
|
||||
gdb_test "info threads" ".*"
|
||||
|
||||
# Make "continue" resume all inferiors.
|
||||
if {${non-stop} == "off"} {
|
||||
gdb_test_no_output "set schedule-multiple on"
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
proc multi_target_prepare {} {
|
||||
global binfile srcfile
|
||||
|
||||
if { [skip_gdbserver_tests] } {
|
||||
return 0
|
||||
}
|
||||
|
||||
# The plain remote target can't do multiple inferiors.
|
||||
if {[target_info gdb_protocol] != ""} {
|
||||
return 0
|
||||
}
|
||||
|
||||
if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \
|
||||
{debug pthreads}] } {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Make a core file with two threads upfront. Several tests load
|
||||
# the same core file.
|
||||
prepare_core
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
proc multi_target_cleanup {} {
|
||||
cleanup_gdbservers
|
||||
}
|
||||
@@ -526,3 +526,16 @@ gdb_test "print \$cvar3" "= void" \
|
||||
# Test PR 23669, the following would invoke the "commands" command instead of
|
||||
# "show commands".
|
||||
gdb_test "python gdb.execute(\"show commands\")" "$decimal print \\\$cvar3.*"
|
||||
|
||||
# Test that the from_tty argument to gdb.execute is effective. If
|
||||
# False, the user is not prompted for decisions such as restarting the
|
||||
# program, and "yes" is assumed. If True, the user is prompted.
|
||||
gdb_test "python gdb.execute('starti', from_tty=False)" \
|
||||
"Program stopped.*" \
|
||||
"starti via gdb.execute, not from tty"
|
||||
gdb_test_multiple "python gdb.execute('starti', from_tty=True)" \
|
||||
"starti via gdb.execute, from tty" {
|
||||
-re {The program being debugged has been started already\.\r\nStart it from the beginning\? \(y or n\) $} {
|
||||
gdb_test "y" "Starting program:.*" "starti via interactive input"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,5 +375,14 @@ gdb_test "python print(e.type.fields()\[0\].artificial)" "True"
|
||||
gdb_test "python print(e.type.fields()\[1\].name)" "Two"
|
||||
|
||||
gdb_test "python print(e.type.dynamic)" "False"
|
||||
gdb_test "python print(gdb.lookup_type('simple::MoreComplicated').dynamic)" \
|
||||
"True"
|
||||
|
||||
# Before LLVM 8, the rust compiler would emit two types named
|
||||
# "simple::MoreComplicated" -- the C-like "underlying" enum type and
|
||||
# the Rust enum. lookup_type seems to get the former, which isn't
|
||||
# very useful. With later versions of LLVM, this test works
|
||||
# correctly.
|
||||
set v [split [rust_llvm_version] .]
|
||||
if {[lindex $v 0] >= 8} {
|
||||
gdb_test "python print(gdb.lookup_type('simple::MoreComplicated').dynamic)" \
|
||||
"True"
|
||||
}
|
||||
|
||||
@@ -39,3 +39,4 @@ Term::check_contents "list main" "21 *return 0"
|
||||
# The following 'focus next' must be immediately after 'list main' to
|
||||
# ensure that GDB has a valid idea of what is currently focused.
|
||||
Term::command "focus next"
|
||||
Term::check_contents "focus next" "Focus set to cmd window"
|
||||
|
||||
@@ -35,3 +35,22 @@ proc gdb_compile_rust {sources dest options} {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
# Return the version of LLVM used by the Rust compiler. Note that
|
||||
# older versions of rustc don't print this -- in this case the
|
||||
# returned version is "0.0".
|
||||
gdb_caching_proc rust_llvm_version {
|
||||
set rustc [find_rustc]
|
||||
if {$rustc == ""} {
|
||||
verbose "could not find rustc"
|
||||
} else {
|
||||
set output [lindex [remote_exec host "$rustc --version --verbose"] 1]
|
||||
foreach line [split $output \n] {
|
||||
if {[regexp "LLVM version: (.+)\$" $output ignore version]} {
|
||||
return $version
|
||||
}
|
||||
}
|
||||
verbose "could not match rustc version output: $output"
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
@@ -1946,9 +1946,15 @@ thread_find_command (const char *arg, int from_tty)
|
||||
if (tmp != 0)
|
||||
error (_("Invalid regexp (%s): %s"), tmp, arg);
|
||||
|
||||
/* We're going to be switching threads. */
|
||||
scoped_restore_current_thread restore_thread;
|
||||
|
||||
update_thread_list ();
|
||||
|
||||
for (thread_info *tp : all_threads ())
|
||||
{
|
||||
switch_to_inferior_no_thread (tp->inf);
|
||||
|
||||
if (tp->name != NULL && re_exec (tp->name))
|
||||
{
|
||||
printf_filtered (_("Thread %s has name '%s'\n"),
|
||||
|
||||
@@ -113,9 +113,18 @@ tui_next_win (struct tui_win_info *cur_win)
|
||||
auto iter = std::find (tui_windows.begin (), tui_windows.end (), cur_win);
|
||||
gdb_assert (iter != tui_windows.end ());
|
||||
|
||||
++iter;
|
||||
if (iter == tui_windows.end ())
|
||||
return tui_windows[0];
|
||||
gdb_assert (cur_win->can_focus ());
|
||||
/* This won't loop forever since we can't have just an un-focusable
|
||||
window. */
|
||||
while (true)
|
||||
{
|
||||
++iter;
|
||||
if (iter == tui_windows.end ())
|
||||
iter = tui_windows.begin ();
|
||||
if ((*iter)->can_focus ())
|
||||
break;
|
||||
}
|
||||
|
||||
return *iter;
|
||||
}
|
||||
|
||||
@@ -125,12 +134,21 @@ tui_next_win (struct tui_win_info *cur_win)
|
||||
struct tui_win_info *
|
||||
tui_prev_win (struct tui_win_info *cur_win)
|
||||
{
|
||||
auto iter = std::find (tui_windows.begin (), tui_windows.end (), cur_win);
|
||||
gdb_assert (iter != tui_windows.end ());
|
||||
auto iter = std::find (tui_windows.rbegin (), tui_windows.rend (), cur_win);
|
||||
gdb_assert (iter != tui_windows.rend ());
|
||||
|
||||
gdb_assert (cur_win->can_focus ());
|
||||
/* This won't loop forever since we can't have just an un-focusable
|
||||
window. */
|
||||
while (true)
|
||||
{
|
||||
++iter;
|
||||
if (iter == tui_windows.rend ())
|
||||
iter = tui_windows.rbegin ();
|
||||
if ((*iter)->can_focus ())
|
||||
break;
|
||||
}
|
||||
|
||||
if (iter == tui_windows.begin ())
|
||||
return tui_windows.back ();
|
||||
--iter;
|
||||
return *iter;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,12 @@ public:
|
||||
return handle != nullptr;
|
||||
}
|
||||
|
||||
/* Return true if this window can accept the focus. */
|
||||
virtual bool can_focus () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Disable output until the next call to doupdate. */
|
||||
void no_refresh ()
|
||||
{
|
||||
|
||||
@@ -52,6 +52,11 @@ struct tui_locator_window : public tui_win_info
|
||||
return false;
|
||||
}
|
||||
|
||||
bool can_focus () const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void rerender () override;
|
||||
|
||||
/* Update the locator, with the provided arguments.
|
||||
|
||||
@@ -1 +1 @@
|
||||
10.0.50.DATE-git
|
||||
10.1
|
||||
|
||||
@@ -233,9 +233,6 @@ static std::vector<windows_thread_info *> thread_list;
|
||||
/* Counts of things. */
|
||||
static int saw_create;
|
||||
static int open_process_used = 0;
|
||||
#ifdef __x86_64__
|
||||
static bool wow64_process = false;
|
||||
#endif
|
||||
|
||||
/* User options. */
|
||||
static bool new_console = false;
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
2020-10-07 Anton Kolesov <anton.kolesov@synopsys.com>
|
||||
|
||||
* configure.srv: Support ARC architecture.
|
||||
* Makefile.in: Add linux-arc-low.cc and arch/arc.o.
|
||||
* linux-arc-low.cc: New file.
|
||||
|
||||
2020-09-23 Hannes Domani <ssbssa@yahoo.de>
|
||||
|
||||
* win32-low.cc: Remove local wow64_process variable.
|
||||
* win32-low.h: Remove local wow64_process variable.
|
||||
|
||||
2020-09-10 Kamil Rytarowski <n54@gmx.com>
|
||||
|
||||
* netbsd-low.cc: Add.
|
||||
|
||||
@@ -179,6 +179,7 @@ SFILES = \
|
||||
$(srcdir)/i387-fp.cc \
|
||||
$(srcdir)/inferiors.cc \
|
||||
$(srcdir)/linux-aarch64-low.cc \
|
||||
$(srcdir)/linux-arc-low.cc \
|
||||
$(srcdir)/linux-arm-low.cc \
|
||||
$(srcdir)/linux-ia64-low.cc \
|
||||
$(srcdir)/linux-low.cc \
|
||||
@@ -209,6 +210,7 @@ SFILES = \
|
||||
$(srcdir)/win32-low.cc \
|
||||
$(srcdir)/x86-low.cc \
|
||||
$(srcdir)/../gdb/alloc.c \
|
||||
$(srcdir)/../gdb/arch/arc.c \
|
||||
$(srcdir)/../gdb/arch/arm.c \
|
||||
$(srcdir)/../gdb/arch/arm-get-next-pcs.c \
|
||||
$(srcdir)/../gdb/arch/arm-linux.c \
|
||||
|
||||
@@ -61,6 +61,17 @@ case "${gdbserver_host}" in
|
||||
ipa_obj="${ipa_obj} linux-aarch64-tdesc-ipa.o"
|
||||
ipa_obj="${ipa_obj} arch/aarch64-ipa.o"
|
||||
;;
|
||||
arc*-*-linux*)
|
||||
srv_regobj=""
|
||||
srv_tgtobj="linux-arc-low.o arch/arc.o $srv_linux_obj"
|
||||
srv_xmlfiles="arc/v1-core.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arc/v1-aux.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arc/v2-core.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arc/v2-aux.xml"
|
||||
srv_linux_regsets=yes
|
||||
srv_linux_usrregs=yes
|
||||
srv_linux_thread_db=yes
|
||||
;;
|
||||
arm*-*-linux*) srv_tgtobj="$srv_linux_obj linux-arm-low.o"
|
||||
srv_tgtobj="$srv_tgtobj linux-arm-tdesc.o"
|
||||
srv_tgtobj="$srv_tgtobj linux-aarch32-low.o"
|
||||
|
||||
418
gdbserver/linux-arc-low.cc
Normal file
418
gdbserver/linux-arc-low.cc
Normal file
@@ -0,0 +1,418 @@
|
||||
/* Target dependent code for the remote server for GNU/Linux ARC.
|
||||
|
||||
Copyright 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 "server.h"
|
||||
#include "regdef.h"
|
||||
#include "linux-low.h"
|
||||
#include "tdesc.h"
|
||||
#include "arch/arc.h"
|
||||
|
||||
#include <linux/elf.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* Linux starting with 4.12 supports NT_ARC_V2 note type, which adds R30,
|
||||
R58 and R59 registers. */
|
||||
#ifdef NT_ARC_V2
|
||||
#define ARC_HAS_V2_REGSET
|
||||
#endif
|
||||
|
||||
/* The encoding of the instruction "TRAP_S 1" (endianness agnostic). */
|
||||
#define TRAP_S_1_OPCODE 0x783e
|
||||
#define TRAP_S_1_SIZE 2
|
||||
|
||||
/* Using a mere "uint16_t arc_linux_traps_s = TRAP_S_1_OPCODE" would
|
||||
work as well, because the endianness will end up correctly when
|
||||
the code is compiled for the same endianness as the target (see
|
||||
the notes for "low_breakpoint_at" in this file). However, this
|
||||
illustrates how the __BIG_ENDIAN__ macro can be used to make
|
||||
easy-to-understand codes. */
|
||||
#if defined(__BIG_ENDIAN__)
|
||||
/* 0x78, 0x3e. */
|
||||
static gdb_byte arc_linux_trap_s[TRAP_S_1_SIZE]
|
||||
= {TRAP_S_1_OPCODE >> 8, TRAP_S_1_OPCODE & 0xFF};
|
||||
#else
|
||||
/* 0x3e, 0x78. */
|
||||
static gdb_byte arc_linux_trap_s[TRAP_S_1_SIZE]
|
||||
= {TRAP_S_1_OPCODE && 0xFF, TRAP_S_1_OPCODE >> 8};
|
||||
#endif
|
||||
|
||||
/* Linux target op definitions for the ARC architecture.
|
||||
Note for future: in case of adding the protected method low_get_next_pcs(),
|
||||
the public method supports_software_single_step() should be added to return
|
||||
"true". */
|
||||
|
||||
class arc_target : public linux_process_target
|
||||
{
|
||||
public:
|
||||
|
||||
const regs_info *get_regs_info () override;
|
||||
|
||||
const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
|
||||
|
||||
protected:
|
||||
|
||||
void low_arch_setup () override;
|
||||
|
||||
bool low_cannot_fetch_register (int regno) override;
|
||||
|
||||
bool low_cannot_store_register (int regno) override;
|
||||
|
||||
bool low_supports_breakpoints () override;
|
||||
|
||||
CORE_ADDR low_get_pc (regcache *regcache) override;
|
||||
|
||||
void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
|
||||
|
||||
bool low_breakpoint_at (CORE_ADDR where) override;
|
||||
};
|
||||
|
||||
/* The singleton target ops object. */
|
||||
|
||||
static arc_target the_arc_target;
|
||||
|
||||
bool
|
||||
arc_target::low_supports_breakpoints ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
arc_target::low_get_pc (regcache *regcache)
|
||||
{
|
||||
return linux_get_pc_32bit (regcache);
|
||||
}
|
||||
|
||||
void
|
||||
arc_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
|
||||
{
|
||||
linux_set_pc_32bit (regcache, pc);
|
||||
}
|
||||
|
||||
static const struct target_desc *
|
||||
arc_linux_read_description (void)
|
||||
{
|
||||
#ifdef __ARC700__
|
||||
arc_arch_features features (4, ARC_ISA_ARCV1);
|
||||
#else
|
||||
arc_arch_features features (4, ARC_ISA_ARCV2);
|
||||
#endif
|
||||
struct target_desc *tdesc = arc_create_target_description (features);
|
||||
|
||||
static const char *expedite_regs[] = { "sp", "status32", nullptr };
|
||||
init_target_desc (tdesc, expedite_regs);
|
||||
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
void
|
||||
arc_target::low_arch_setup ()
|
||||
{
|
||||
current_process ()->tdesc = arc_linux_read_description ();
|
||||
}
|
||||
|
||||
bool
|
||||
arc_target::low_cannot_fetch_register (int regno)
|
||||
{
|
||||
return (regno >= current_process ()->tdesc->reg_defs.size ());
|
||||
}
|
||||
|
||||
bool
|
||||
arc_target::low_cannot_store_register (int regno)
|
||||
{
|
||||
return (regno >= current_process ()->tdesc->reg_defs.size ());
|
||||
}
|
||||
|
||||
/* This works for both endianness. Below you see an illustration of how
|
||||
the "trap_s 1" instruction encoded for both endianness in the memory
|
||||
will end up as the TRAP_S_1_OPCODE constant:
|
||||
|
||||
BE: 0x78 0x3e --> at INSN addr: 0x78 0x3e --> INSN = 0x783e
|
||||
LE: 0x3e 0x78 --> at INSN addr: 0x3e 0x78 --> INSN = 0x783e
|
||||
|
||||
One can employ "memcmp()" for comparing the arrays too. */
|
||||
|
||||
bool
|
||||
arc_target::low_breakpoint_at (CORE_ADDR where)
|
||||
{
|
||||
uint16_t insn;
|
||||
|
||||
/* "the_target" global variable is the current object at hand. */
|
||||
this->read_memory (where, (gdb_byte *) &insn, TRAP_S_1_SIZE);
|
||||
return (insn == TRAP_S_1_OPCODE);
|
||||
}
|
||||
|
||||
/* PTRACE_GETREGSET/NT_PRSTATUS and PTRACE_SETREGSET/NT_PRSTATUS work with
|
||||
regsets in a struct, "user_regs_struct", defined in the
|
||||
linux/arch/arc/include/uapi/asm/ptrace.h header. This code supports
|
||||
ARC Linux ABI v3 and v4. */
|
||||
|
||||
/* Populate a ptrace NT_PRSTATUS regset from a regcache.
|
||||
|
||||
This appears to be a unique approach to populating the buffer, but
|
||||
being name, rather than offset based, it is robust to future API
|
||||
changes, as there is no need to create a regmap of registers in the
|
||||
user_regs_struct. */
|
||||
|
||||
static void
|
||||
arc_fill_gregset (struct regcache *regcache, void *buf)
|
||||
{
|
||||
struct user_regs_struct *regbuf = (struct user_regs_struct *) buf;
|
||||
|
||||
/* Core registers. */
|
||||
collect_register_by_name (regcache, "r0", &(regbuf->scratch.r0));
|
||||
collect_register_by_name (regcache, "r1", &(regbuf->scratch.r1));
|
||||
collect_register_by_name (regcache, "r2", &(regbuf->scratch.r2));
|
||||
collect_register_by_name (regcache, "r3", &(regbuf->scratch.r3));
|
||||
collect_register_by_name (regcache, "r4", &(regbuf->scratch.r4));
|
||||
collect_register_by_name (regcache, "r5", &(regbuf->scratch.r5));
|
||||
collect_register_by_name (regcache, "r6", &(regbuf->scratch.r6));
|
||||
collect_register_by_name (regcache, "r7", &(regbuf->scratch.r7));
|
||||
collect_register_by_name (regcache, "r8", &(regbuf->scratch.r8));
|
||||
collect_register_by_name (regcache, "r9", &(regbuf->scratch.r9));
|
||||
collect_register_by_name (regcache, "r10", &(regbuf->scratch.r10));
|
||||
collect_register_by_name (regcache, "r11", &(regbuf->scratch.r11));
|
||||
collect_register_by_name (regcache, "r12", &(regbuf->scratch.r12));
|
||||
collect_register_by_name (regcache, "r13", &(regbuf->callee.r13));
|
||||
collect_register_by_name (regcache, "r14", &(regbuf->callee.r14));
|
||||
collect_register_by_name (regcache, "r15", &(regbuf->callee.r15));
|
||||
collect_register_by_name (regcache, "r16", &(regbuf->callee.r16));
|
||||
collect_register_by_name (regcache, "r17", &(regbuf->callee.r17));
|
||||
collect_register_by_name (regcache, "r18", &(regbuf->callee.r18));
|
||||
collect_register_by_name (regcache, "r19", &(regbuf->callee.r19));
|
||||
collect_register_by_name (regcache, "r20", &(regbuf->callee.r20));
|
||||
collect_register_by_name (regcache, "r21", &(regbuf->callee.r21));
|
||||
collect_register_by_name (regcache, "r22", &(regbuf->callee.r22));
|
||||
collect_register_by_name (regcache, "r23", &(regbuf->callee.r23));
|
||||
collect_register_by_name (regcache, "r24", &(regbuf->callee.r24));
|
||||
collect_register_by_name (regcache, "r25", &(regbuf->callee.r25));
|
||||
collect_register_by_name (regcache, "gp", &(regbuf->scratch.gp));
|
||||
collect_register_by_name (regcache, "fp", &(regbuf->scratch.fp));
|
||||
collect_register_by_name (regcache, "sp", &(regbuf->scratch.sp));
|
||||
collect_register_by_name (regcache, "blink", &(regbuf->scratch.blink));
|
||||
|
||||
/* Loop registers. */
|
||||
collect_register_by_name (regcache, "lp_count", &(regbuf->scratch.lp_count));
|
||||
collect_register_by_name (regcache, "lp_start", &(regbuf->scratch.lp_start));
|
||||
collect_register_by_name (regcache, "lp_end", &(regbuf->scratch.lp_end));
|
||||
|
||||
/* The current "pc" value must be written to "eret" (exception return
|
||||
address) register, because that is the address that the kernel code
|
||||
will jump back to after a breakpoint exception has been raised.
|
||||
The "pc_stop" value is ignored by the genregs_set() in
|
||||
linux/arch/arc/kernel/ptrace.c. */
|
||||
collect_register_by_name (regcache, "pc", &(regbuf->scratch.ret));
|
||||
|
||||
/* Currently ARC Linux ptrace doesn't allow writes to status32 because
|
||||
some of its bits are kernel mode-only and shoudn't be writable from
|
||||
user-space. Writing status32 from debugger could be useful, though,
|
||||
so ability to write non-priviliged bits will be added to kernel
|
||||
sooner or later. */
|
||||
|
||||
/* BTA. */
|
||||
collect_register_by_name (regcache, "bta", &(regbuf->scratch.bta));
|
||||
}
|
||||
|
||||
/* Populate a regcache from a ptrace NT_PRSTATUS regset. */
|
||||
|
||||
static void
|
||||
arc_store_gregset (struct regcache *regcache, const void *buf)
|
||||
{
|
||||
const struct user_regs_struct *regbuf = (const struct user_regs_struct *) buf;
|
||||
|
||||
/* Core registers. */
|
||||
supply_register_by_name (regcache, "r0", &(regbuf->scratch.r0));
|
||||
supply_register_by_name (regcache, "r1", &(regbuf->scratch.r1));
|
||||
supply_register_by_name (regcache, "r2", &(regbuf->scratch.r2));
|
||||
supply_register_by_name (regcache, "r3", &(regbuf->scratch.r3));
|
||||
supply_register_by_name (regcache, "r4", &(regbuf->scratch.r4));
|
||||
supply_register_by_name (regcache, "r5", &(regbuf->scratch.r5));
|
||||
supply_register_by_name (regcache, "r6", &(regbuf->scratch.r6));
|
||||
supply_register_by_name (regcache, "r7", &(regbuf->scratch.r7));
|
||||
supply_register_by_name (regcache, "r8", &(regbuf->scratch.r8));
|
||||
supply_register_by_name (regcache, "r9", &(regbuf->scratch.r9));
|
||||
supply_register_by_name (regcache, "r10", &(regbuf->scratch.r10));
|
||||
supply_register_by_name (regcache, "r11", &(regbuf->scratch.r11));
|
||||
supply_register_by_name (regcache, "r12", &(regbuf->scratch.r12));
|
||||
supply_register_by_name (regcache, "r13", &(regbuf->callee.r13));
|
||||
supply_register_by_name (regcache, "r14", &(regbuf->callee.r14));
|
||||
supply_register_by_name (regcache, "r15", &(regbuf->callee.r15));
|
||||
supply_register_by_name (regcache, "r16", &(regbuf->callee.r16));
|
||||
supply_register_by_name (regcache, "r17", &(regbuf->callee.r17));
|
||||
supply_register_by_name (regcache, "r18", &(regbuf->callee.r18));
|
||||
supply_register_by_name (regcache, "r19", &(regbuf->callee.r19));
|
||||
supply_register_by_name (regcache, "r20", &(regbuf->callee.r20));
|
||||
supply_register_by_name (regcache, "r21", &(regbuf->callee.r21));
|
||||
supply_register_by_name (regcache, "r22", &(regbuf->callee.r22));
|
||||
supply_register_by_name (regcache, "r23", &(regbuf->callee.r23));
|
||||
supply_register_by_name (regcache, "r24", &(regbuf->callee.r24));
|
||||
supply_register_by_name (regcache, "r25", &(regbuf->callee.r25));
|
||||
supply_register_by_name (regcache, "gp", &(regbuf->scratch.gp));
|
||||
supply_register_by_name (regcache, "fp", &(regbuf->scratch.fp));
|
||||
supply_register_by_name (regcache, "sp", &(regbuf->scratch.sp));
|
||||
supply_register_by_name (regcache, "blink", &(regbuf->scratch.blink));
|
||||
|
||||
/* Loop registers. */
|
||||
supply_register_by_name (regcache, "lp_count", &(regbuf->scratch.lp_count));
|
||||
supply_register_by_name (regcache, "lp_start", &(regbuf->scratch.lp_start));
|
||||
supply_register_by_name (regcache, "lp_end", &(regbuf->scratch.lp_end));
|
||||
|
||||
/* The genregs_get() in linux/arch/arc/kernel/ptrace.c populates the
|
||||
pseudo register "stop_pc" with the "efa" (exception fault address)
|
||||
register. This was deemed necessary, because the breakpoint
|
||||
instruction, "trap_s 1", is a committing one; i.e. the "eret"
|
||||
(exception return address) register will be pointing to the next
|
||||
instruction, while "efa" points to the address that raised the
|
||||
breakpoint. */
|
||||
supply_register_by_name (regcache, "pc", &(regbuf->stop_pc));
|
||||
unsigned long pcl = regbuf->stop_pc & ~3L;
|
||||
supply_register_by_name (regcache, "pcl", &pcl);
|
||||
|
||||
/* Other auxilliary registers. */
|
||||
supply_register_by_name (regcache, "status32", &(regbuf->scratch.status32));
|
||||
|
||||
/* BTA. */
|
||||
supply_register_by_name (regcache, "bta", &(regbuf->scratch.bta));
|
||||
}
|
||||
|
||||
#ifdef ARC_HAS_V2_REGSET
|
||||
|
||||
/* Look through a regcache's TDESC for a register named NAME.
|
||||
If found, return true; false, otherwise. */
|
||||
|
||||
static bool
|
||||
is_reg_name_available_p (const struct target_desc *tdesc,
|
||||
const char *name)
|
||||
{
|
||||
for (const gdb::reg ® : tdesc->reg_defs)
|
||||
if (strcmp (name, reg.name) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Copy registers from regcache to user_regs_arcv2. */
|
||||
|
||||
static void
|
||||
arc_fill_v2_regset (struct regcache *regcache, void *buf)
|
||||
{
|
||||
struct user_regs_arcv2 *regbuf = (struct user_regs_arcv2 *) buf;
|
||||
|
||||
if (is_reg_name_available_p (regcache->tdesc, "r30"))
|
||||
collect_register_by_name (regcache, "r30", &(regbuf->r30));
|
||||
|
||||
if (is_reg_name_available_p (regcache->tdesc, "r58"))
|
||||
collect_register_by_name (regcache, "r58", &(regbuf->r58));
|
||||
|
||||
if (is_reg_name_available_p (regcache->tdesc, "r59"))
|
||||
collect_register_by_name (regcache, "r59", &(regbuf->r59));
|
||||
}
|
||||
|
||||
/* Copy registers from user_regs_arcv2 to regcache. */
|
||||
|
||||
static void
|
||||
arc_store_v2_regset (struct regcache *regcache, const void *buf)
|
||||
{
|
||||
struct user_regs_arcv2 *regbuf = (struct user_regs_arcv2 *) buf;
|
||||
|
||||
if (is_reg_name_available_p (regcache->tdesc, "r30"))
|
||||
supply_register_by_name (regcache, "r30", &(regbuf->r30));
|
||||
|
||||
if (is_reg_name_available_p (regcache->tdesc, "r58"))
|
||||
supply_register_by_name (regcache, "r58", &(regbuf->r58));
|
||||
|
||||
if (is_reg_name_available_p (regcache->tdesc, "r59"))
|
||||
supply_register_by_name (regcache, "r59", &(regbuf->r59));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Fetch the thread-local storage pointer for libthread_db. Note that
|
||||
this function is not called from GDB, but is called from libthread_db.
|
||||
|
||||
This is the same function as for other architectures, for example in
|
||||
linux-arm-low.c. */
|
||||
|
||||
ps_err_e
|
||||
ps_get_thread_area (struct ps_prochandle *ph, lwpid_t lwpid,
|
||||
int idx, void **base)
|
||||
{
|
||||
if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, nullptr, base) != 0)
|
||||
return PS_ERR;
|
||||
|
||||
/* IDX is the bias from the thread pointer to the beginning of the
|
||||
thread descriptor. It has to be subtracted due to implementation
|
||||
quirks in libthread_db. */
|
||||
*base = (void *) ((char *) *base - idx);
|
||||
|
||||
return PS_OK;
|
||||
}
|
||||
|
||||
static struct regset_info arc_regsets[] =
|
||||
{
|
||||
{ PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
|
||||
sizeof (struct user_regs_struct), GENERAL_REGS,
|
||||
arc_fill_gregset, arc_store_gregset
|
||||
},
|
||||
#ifdef ARC_HAS_V2_REGSET
|
||||
{ PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARC_V2,
|
||||
sizeof (struct user_regs_arcv2), GENERAL_REGS,
|
||||
arc_fill_v2_regset, arc_store_v2_regset
|
||||
},
|
||||
#endif
|
||||
NULL_REGSET
|
||||
};
|
||||
|
||||
static struct regsets_info arc_regsets_info =
|
||||
{
|
||||
arc_regsets, /* regsets */
|
||||
0, /* num_regsets */
|
||||
nullptr, /* disabled regsets */
|
||||
};
|
||||
|
||||
static struct regs_info arc_regs_info =
|
||||
{
|
||||
nullptr, /* regset_bitmap */
|
||||
nullptr, /* usrregs */
|
||||
&arc_regsets_info
|
||||
};
|
||||
|
||||
const regs_info *
|
||||
arc_target::get_regs_info ()
|
||||
{
|
||||
return &arc_regs_info;
|
||||
}
|
||||
|
||||
/* One of the methods necessary for Z0 packet support. */
|
||||
|
||||
const gdb_byte *
|
||||
arc_target::sw_breakpoint_from_kind (int kind, int *size)
|
||||
{
|
||||
gdb_assert (kind == TRAP_S_1_SIZE);
|
||||
*size = kind;
|
||||
return arc_linux_trap_s;
|
||||
}
|
||||
|
||||
/* The linux target ops object. */
|
||||
|
||||
linux_process_target *the_linux_target = &the_arc_target;
|
||||
|
||||
void
|
||||
initialize_low_arch (void)
|
||||
{
|
||||
initialize_regsets_info (&arc_regsets_info);
|
||||
}
|
||||
@@ -91,10 +91,6 @@ static int faked_breakpoint = 0;
|
||||
/* True if current_process_handle needs to be closed. */
|
||||
static bool open_process_used = false;
|
||||
|
||||
#ifdef __x86_64__
|
||||
bool wow64_process = false;
|
||||
#endif
|
||||
|
||||
const struct target_desc *win32_tdesc;
|
||||
#ifdef __x86_64__
|
||||
const struct target_desc *wow64_win32_tdesc;
|
||||
|
||||
@@ -30,8 +30,6 @@ extern const struct target_desc *win32_tdesc;
|
||||
#ifdef __x86_64__
|
||||
extern const struct target_desc *wow64_win32_tdesc;
|
||||
|
||||
extern bool wow64_process;
|
||||
|
||||
typedef BOOL (WINAPI *winapi_Wow64GetThreadContext) (HANDLE, PWOW64_CONTEXT);
|
||||
extern winapi_Wow64GetThreadContext win32_Wow64GetThreadContext;
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
2020-10-09 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB PR build/26607
|
||||
* patches/0002-stat-fstat-windows-older-vista: New patch.
|
||||
* patches/0003-stat-fstat-windows-old-mingw: New patch.
|
||||
* update-gnulib.sh: Update to use the two new patches above.
|
||||
* import/m4/fstat.m4: Update after applying patches above.
|
||||
* import/m4/stat.m4: Ditto.
|
||||
* import/stat-w32.c: Ditto.
|
||||
* config.in: Regenerate.
|
||||
* configure: Regenerate.
|
||||
|
||||
2020-09-08 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
PR win32/25302:
|
||||
|
||||
@@ -693,6 +693,9 @@
|
||||
/* Define to 1 if the system has the type `sa_family_t'. */
|
||||
#undef HAVE_SA_FAMILY_T
|
||||
|
||||
/* Define to 1 if you have the <sdkddkver.h> header file. */
|
||||
#undef HAVE_SDKDDKVER_H
|
||||
|
||||
/* Define to 1 if you have the <search.h> header file. */
|
||||
#undef HAVE_SEARCH_H
|
||||
|
||||
|
||||
21
gnulib/configure
vendored
21
gnulib/configure
vendored
@@ -10107,6 +10107,25 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
case "$host_os" in
|
||||
mingw*)
|
||||
for ac_header in sdkddkver.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "sdkddkver.h" "ac_cv_header_sdkddkver_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_sdkddkver_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_SDKDDKVER_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5
|
||||
$as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; }
|
||||
if ${gl_cv_func_lstat_dereferences_slashed_symlink+:} false; then :
|
||||
@@ -19576,6 +19595,7 @@ $as_echo "#define GNULIB_TEST_FREXPL 1" >>confdefs.h
|
||||
esac
|
||||
|
||||
|
||||
|
||||
:
|
||||
|
||||
fi
|
||||
@@ -27005,6 +27025,7 @@ $as_echo "#define REPLACE_FUNC_STAT_FILE 1" >>confdefs.h
|
||||
esac
|
||||
|
||||
|
||||
|
||||
:
|
||||
|
||||
fi
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# fstat.m4 serial 6
|
||||
# fstat.m4 serial 7
|
||||
dnl Copyright (C) 2011-2020 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
@@ -35,5 +35,6 @@ AC_DEFUN([gl_FUNC_FSTAT],
|
||||
# Prerequisites of lib/fstat.c and lib/stat-w32.c.
|
||||
AC_DEFUN([gl_PREREQ_FSTAT], [
|
||||
AC_REQUIRE([gl_HEADER_SYS_STAT_H])
|
||||
AC_REQUIRE([gl_PREREQ_STAT_W32])
|
||||
:
|
||||
])
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# serial 16
|
||||
# serial 17
|
||||
|
||||
# Copyright (C) 2009-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
@@ -70,5 +70,16 @@ AC_DEFUN([gl_FUNC_STAT],
|
||||
# Prerequisites of lib/stat.c and lib/stat-w32.c.
|
||||
AC_DEFUN([gl_PREREQ_STAT], [
|
||||
AC_REQUIRE([gl_HEADER_SYS_STAT_H])
|
||||
AC_REQUIRE([gl_PREREQ_STAT_W32])
|
||||
:
|
||||
])
|
||||
|
||||
# Prerequisites of lib/stat-w32.c.
|
||||
AC_DEFUN([gl_PREREQ_STAT_W32], [
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
case "$host_os" in
|
||||
mingw*)
|
||||
AC_CHECK_HEADERS([sdkddkver.h])
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
@@ -20,10 +20,22 @@
|
||||
|
||||
#if defined _WIN32 && ! defined __CYGWIN__
|
||||
|
||||
/* Ensure that <windows.h> defines FILE_ID_INFO. */
|
||||
#if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN8)
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT _WIN32_WINNT_WIN8
|
||||
/* Attempt to make <windows.h> define FILE_ID_INFO.
|
||||
But ensure that the redefinition of _WIN32_WINNT does not make us assume
|
||||
Windows Vista or newer when building for an older version of Windows. */
|
||||
#if HAVE_SDKDDKVER_H
|
||||
# include <sdkddkver.h>
|
||||
# if _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
# define WIN32_ASSUME_VISTA 1
|
||||
# else
|
||||
# define WIN32_ASSUME_VISTA 0
|
||||
# endif
|
||||
# if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN8)
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT _WIN32_WINNT_WIN8
|
||||
# endif
|
||||
#else
|
||||
# define WIN32_ASSUME_VISTA (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -46,7 +58,12 @@
|
||||
#undef GetFinalPathNameByHandle
|
||||
#define GetFinalPathNameByHandle GetFinalPathNameByHandleA
|
||||
|
||||
#if !(_WIN32_WINNT >= _WIN32_WINNT_VISTA)
|
||||
/* Older mingw headers do not define VOLUME_NAME_NONE. */
|
||||
#ifndef VOLUME_NAME_NONE
|
||||
# define VOLUME_NAME_NONE 4
|
||||
#endif
|
||||
|
||||
#if !WIN32_ASSUME_VISTA
|
||||
|
||||
/* Avoid warnings from gcc -Wcast-function-type. */
|
||||
# define GetProcAddress \
|
||||
@@ -149,7 +166,7 @@ _gl_fstat_by_handle (HANDLE h, const char *path, struct stat *buf)
|
||||
DWORD type = GetFileType (h);
|
||||
if (type == FILE_TYPE_DISK)
|
||||
{
|
||||
#if !(_WIN32_WINNT >= _WIN32_WINNT_VISTA)
|
||||
#if !WIN32_ASSUME_VISTA
|
||||
if (!initialized)
|
||||
initialize ();
|
||||
#endif
|
||||
|
||||
116
gnulib/patches/0002-stat-fstat-windows-older-vista
Normal file
116
gnulib/patches/0002-stat-fstat-windows-older-vista
Normal file
@@ -0,0 +1,116 @@
|
||||
From 1796cda9975bd459a87222676030b943869c686e Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Wed, 16 Sep 2020 23:51:52 +0200
|
||||
Subject: [PATCH 1/2] stat, fstat: Fix when compiling for versions older than
|
||||
Windows Vista.
|
||||
|
||||
Reported by Eli Zaretskii <eliz@gnu.org> in
|
||||
<https://lists.gnu.org/archive/html/bug-gnulib/2020-09/msg00027.html>.
|
||||
|
||||
* lib/stat-w32.c: Include <sdkddkver.h>. Test the value of _WIN32_WINNT
|
||||
that was originally set before we redefined it.
|
||||
* m4/stat.m4 (gl_PREREQ_STAT_W32): New macro.
|
||||
(gl_PREREQ_STAT): Require it.
|
||||
* m4/fstat.m4 (gl_PREREQ_FSTAT): Likewise.
|
||||
---
|
||||
stat-w32.c | 24 ++++++++++++++++++------
|
||||
m4/fstat.m4 | 3 ++-
|
||||
m4/stat.m4 | 13 ++++++++++++-
|
||||
4 files changed, 43 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/gnulib/import/stat-w32.c b/gnulib/import/stat-w32.c
|
||||
index 19bdfaa37..72442e933 100644
|
||||
--- a/gnulib/import/stat-w32.c
|
||||
+++ b/gnulib/import/stat-w32.c
|
||||
@@ -20,10 +20,22 @@
|
||||
|
||||
#if defined _WIN32 && ! defined __CYGWIN__
|
||||
|
||||
-/* Ensure that <windows.h> defines FILE_ID_INFO. */
|
||||
-#if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN8)
|
||||
-# undef _WIN32_WINNT
|
||||
-# define _WIN32_WINNT _WIN32_WINNT_WIN8
|
||||
+/* Attempt to make <windows.h> define FILE_ID_INFO.
|
||||
+ But ensure that the redefinition of _WIN32_WINNT does not make us assume
|
||||
+ Windows Vista or newer when building for an older version of Windows. */
|
||||
+#if HAVE_SDKDDKVER_H
|
||||
+# include <sdkddkver.h>
|
||||
+# if _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
+# define WIN32_ASSUME_VISTA 1
|
||||
+# else
|
||||
+# define WIN32_ASSUME_VISTA 0
|
||||
+# endif
|
||||
+# if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN8)
|
||||
+# undef _WIN32_WINNT
|
||||
+# define _WIN32_WINNT _WIN32_WINNT_WIN8
|
||||
+# endif
|
||||
+#else
|
||||
+# define WIN32_ASSUME_VISTA (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -46,7 +58,7 @@
|
||||
#undef GetFinalPathNameByHandle
|
||||
#define GetFinalPathNameByHandle GetFinalPathNameByHandleA
|
||||
|
||||
-#if !(_WIN32_WINNT >= _WIN32_WINNT_VISTA)
|
||||
+#if !WIN32_ASSUME_VISTA
|
||||
|
||||
/* Avoid warnings from gcc -Wcast-function-type. */
|
||||
# define GetProcAddress \
|
||||
@@ -149,7 +161,7 @@ _gl_fstat_by_handle (HANDLE h, const char *path, struct stat *buf)
|
||||
DWORD type = GetFileType (h);
|
||||
if (type == FILE_TYPE_DISK)
|
||||
{
|
||||
-#if !(_WIN32_WINNT >= _WIN32_WINNT_VISTA)
|
||||
+#if !WIN32_ASSUME_VISTA
|
||||
if (!initialized)
|
||||
initialize ();
|
||||
#endif
|
||||
diff --git a/gnulib/import/m4/fstat.m4 b/gnulib/import/m4/fstat.m4
|
||||
index 53c089619..bd8cb7966 100644
|
||||
--- a/gnulib/import/m4/fstat.m4
|
||||
+++ b/gnulib/import/m4/fstat.m4
|
||||
@@ -1,4 +1,4 @@
|
||||
-# fstat.m4 serial 6
|
||||
+# fstat.m4 serial 7
|
||||
dnl Copyright (C) 2011-2020 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
@@ -35,5 +35,6 @@ AC_DEFUN([gl_FUNC_FSTAT],
|
||||
# Prerequisites of lib/fstat.c and lib/stat-w32.c.
|
||||
AC_DEFUN([gl_PREREQ_FSTAT], [
|
||||
AC_REQUIRE([gl_HEADER_SYS_STAT_H])
|
||||
+ AC_REQUIRE([gl_PREREQ_STAT_W32])
|
||||
:
|
||||
])
|
||||
diff --git a/gnulib/import/m4/stat.m4 b/gnulib/import/m4/stat.m4
|
||||
index 46e9abcee..db2038f63 100644
|
||||
--- a/gnulib/import/m4/stat.m4
|
||||
+++ b/gnulib/import/m4/stat.m4
|
||||
@@ -1,4 +1,4 @@
|
||||
-# serial 16
|
||||
+# serial 17
|
||||
|
||||
# Copyright (C) 2009-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
@@ -70,5 +70,16 @@ AC_DEFUN([gl_FUNC_STAT],
|
||||
# Prerequisites of lib/stat.c and lib/stat-w32.c.
|
||||
AC_DEFUN([gl_PREREQ_STAT], [
|
||||
AC_REQUIRE([gl_HEADER_SYS_STAT_H])
|
||||
+ AC_REQUIRE([gl_PREREQ_STAT_W32])
|
||||
:
|
||||
])
|
||||
+
|
||||
+# Prerequisites of lib/stat-w32.c.
|
||||
+AC_DEFUN([gl_PREREQ_STAT_W32], [
|
||||
+ AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
+ case "$host_os" in
|
||||
+ mingw*)
|
||||
+ AC_CHECK_HEADERS([sdkddkver.h])
|
||||
+ ;;
|
||||
+ esac
|
||||
+])
|
||||
--
|
||||
2.17.1
|
||||
|
||||
34
gnulib/patches/0003-stat-fstat-windows-old-mingw
Normal file
34
gnulib/patches/0003-stat-fstat-windows-old-mingw
Normal file
@@ -0,0 +1,34 @@
|
||||
From f8c23f202d11992182e87736e73929bcc369cc75 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Wed, 16 Sep 2020 23:52:44 +0200
|
||||
Subject: [PATCH 2/2] stat, fstat: Fix compilation error with old mingw
|
||||
headers.
|
||||
|
||||
Reported by Eli Zaretskii <eliz@gnu.org> in
|
||||
<https://lists.gnu.org/archive/html/bug-gnulib/2020-09/msg00027.html>.
|
||||
|
||||
* lib/stat-w32.c (VOLUME_NAME_NONE): Define if the Windows headers don't
|
||||
define it.
|
||||
---
|
||||
stat-w32.c | 5 +++++
|
||||
2 files changed, 13 insertions(+)
|
||||
|
||||
diff --git a/gnulib/import/stat-w32.c b/gnulib/import/stat-w32.c
|
||||
index 72442e933..108ce199c 100644
|
||||
--- a/gnulib/import/stat-w32.c
|
||||
+++ b/gnulib/import/stat-w32.c
|
||||
@@ -58,6 +58,11 @@
|
||||
#undef GetFinalPathNameByHandle
|
||||
#define GetFinalPathNameByHandle GetFinalPathNameByHandleA
|
||||
|
||||
+/* Older mingw headers do not define VOLUME_NAME_NONE. */
|
||||
+#ifndef VOLUME_NAME_NONE
|
||||
+# define VOLUME_NAME_NONE 4
|
||||
+#endif
|
||||
+
|
||||
#if !WIN32_ASSUME_VISTA
|
||||
|
||||
/* Avoid warnings from gcc -Wcast-function-type. */
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -174,6 +174,12 @@ apply_patches ()
|
||||
}
|
||||
|
||||
apply_patches "patches/0001-use-windows-stat"
|
||||
# The following two patches are specific imports of two commits
|
||||
# already in gnulib's master. We import those patches individually
|
||||
# because we want to avoid doing a standard gnulib update, which
|
||||
# would be too disruptive for a release branch.
|
||||
apply_patches "patches/0002-stat-fstat-windows-older-vista"
|
||||
apply_patches "patches/0003-stat-fstat-windows-old-mingw"
|
||||
|
||||
# Regenerate all necessary files...
|
||||
aclocal &&
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
2020-10-22 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* csky-dis.c (csky_get_disassembler): Don't return NULL when there
|
||||
is no BFD.
|
||||
|
||||
2020-09-10 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* ppc-dis.c (ppc_symbol_is_valid): New function. Returns false
|
||||
|
||||
@@ -239,23 +239,25 @@ csky_get_disassembler (bfd *abfd)
|
||||
obj_attribute *attr;
|
||||
const char *sec_name = NULL;
|
||||
if (!abfd)
|
||||
return NULL;
|
||||
|
||||
mach_flag = elf_elfheader (abfd)->e_flags;
|
||||
|
||||
sec_name = get_elf_backend_data (abfd)->obj_attrs_section;
|
||||
/* Skip any input that hasn't attribute section.
|
||||
This enables to link object files without attribute section with
|
||||
any others. */
|
||||
if (bfd_get_section_by_name (abfd, sec_name) != NULL)
|
||||
{
|
||||
attr = elf_known_obj_attributes_proc (abfd);
|
||||
dis_info.isa = attr[Tag_CSKY_ISA_EXT_FLAGS].i;
|
||||
dis_info.isa <<= 32;
|
||||
dis_info.isa |= attr[Tag_CSKY_ISA_FLAGS].i;
|
||||
}
|
||||
else
|
||||
dis_info.isa = CSKY_DEFAULT_ISA;
|
||||
else
|
||||
{
|
||||
mach_flag = elf_elfheader (abfd)->e_flags;
|
||||
|
||||
sec_name = get_elf_backend_data (abfd)->obj_attrs_section;
|
||||
/* Skip any input that hasn't attribute section.
|
||||
This enables to link object files without attribute section with
|
||||
any others. */
|
||||
if (bfd_get_section_by_name (abfd, sec_name) != NULL)
|
||||
{
|
||||
attr = elf_known_obj_attributes_proc (abfd);
|
||||
dis_info.isa = attr[Tag_CSKY_ISA_EXT_FLAGS].i;
|
||||
dis_info.isa <<= 32;
|
||||
dis_info.isa |= attr[Tag_CSKY_ISA_FLAGS].i;
|
||||
}
|
||||
else
|
||||
dis_info.isa = CSKY_DEFAULT_ISA;
|
||||
}
|
||||
|
||||
return print_insn_csky;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user