Compare commits

...

69 Commits

Author SHA1 Message Date
Joel Brobecker
1510de4294 Set GDB version number to 10.1.
gdb/ChangeLog:

	* version.in: Set GDB version number to 10.1.
2020-10-24 08:23:02 +04:00
GDB Administrator
893aa14fb9 Automatic date update in version.in 2020-10-24 00:00:32 +00:00
GDB Administrator
34718bcc22 Automatic date update in version.in 2020-10-23 00:00:45 +00:00
Hannes Domani
7565d82a50 Don't create _Complex type name if there is no target type name
This causes gdb to crash in strlen.

Happens if init_complex_type is called for a type created by
dbx_init_float_type in stabsread.c.

gdb/ChangeLog:

2020-10-22  Hannes Domani  <ssbssa@yahoo.de>

	* gdbtypes.c (init_complex_type): Check target type name.
2020-10-22 20:05:32 +02:00
Andrew Burgess
a9e3b91950 opcodes/csky: return the default disassembler when there is no bfd
The disassembler function should return a valid disassembler function
even when there is no BFD present.  This is implied (I believe) by the
comment in dis-asm.h which says the BFD may be NULL.  Further, it
makes sense when considering that the disassembler is used in GDB, and
GDB may connect to a target and perform debugging even without a BFD
being supplied.

This commit makes the csky_get_disassembler function return the
default disassembler configuration when no bfd is supplied, this is
the same default configuration as is used when a BFD is supplied, but
the BFD has no attributes section.

Before the change configuring GDB with --enable-targets=all and
running the tests gdb.base/all-architectures-2.exp results in many
errors, but after this change there are no failures.

opcodes/ChangeLog:

	* csky-dis.c (csky_get_disassembler): Don't return NULL when there
	is no BFD.
2020-10-22 17:11:34 +02:00
Simon Marchi
4c02be1198 gdb/dwarf: fix reading subprogram with DW_AT_specification (PR gdb/26693)
Fix a regression introduced by commit 7188ed02d2 ("Replace
dwarf2_per_cu_data::cu backlink with per-objfile map").

This patch targets both master and gdb-10-branch, since this is a
regression from GDB 9.

Analysis
--------

The DWARF generated by the included test case looks like:

    0x0000000b: DW_TAG_compile_unit
                  DW_AT_language [DW_FORM_sdata]    (4)

    0x0000000d:   DW_TAG_base_type
                    DW_AT_name [DW_FORM_string]     ("int")
                    DW_AT_byte_size [DW_FORM_data1] (0x04)
                    DW_AT_encoding [DW_FORM_sdata]  (5)

    0x00000014:   DW_TAG_subprogram
                    DW_AT_name [DW_FORM_string]     ("apply")

    0x0000001b:   DW_TAG_subprogram
                    DW_AT_specification [DW_FORM_ref4]      (0x00000014 "apply")
                    DW_AT_low_pc [DW_FORM_addr]     (0x0000000000001234)
                    DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000020)

    0x00000030:     DW_TAG_template_type_parameter
                      DW_AT_name [DW_FORM_string]   ("T")
                      DW_AT_type [DW_FORM_ref4]     (0x0000000d "int")

    0x00000037:     NULL

    0x00000038:   NULL

Simply loading the file in GDB makes it crash:

    $ ./gdb -nx --data-directory=data-directory testsuite/outputs/gdb.dwarf2/pr26693/pr26693
    [1]    15188 abort (core dumped)  ./gdb -nx --data-directory=data-directory

The crash happens here, where htab (a dwarf2_cu::die_hash field) is
unexpectedly NULL while generating partial symbols:

    #0  0x000055555fa28188 in htab_find_with_hash (htab=0x0, element=0x7fffffffbfa0, hash=27) at /home/simark/src/binutils-gdb/libiberty/hashtab.c:591
    #1  0x000055555cb4eb2e in follow_die_offset (sect_off=(unknown: 27), offset_in_dwz=0, ref_cu=0x7fffffffc110) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22951
    #2  0x000055555cb4edfb in follow_die_ref (src_die=0x0, attr=0x7fffffffc130, ref_cu=0x7fffffffc110) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22968
    #3  0x000055555caa48c5 in partial_die_full_name (pdi=0x621000157e70, cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8441
    #4  0x000055555caa4d79 in add_partial_symbol (pdi=0x621000157e70, cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8469
    #5  0x000055555caa7d8c in add_partial_subprogram (pdi=0x621000157e70, lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0, set_addrmap=1, cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8737
    #6  0x000055555caa265c in scan_partial_symbols (first_die=0x621000157e00, lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0, set_addrmap=1, cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8230
    #7  0x000055555ca98e3f in process_psymtab_comp_unit_reader (reader=0x7fffffffc6b0, info_ptr=0x60600009650d "\003int", comp_unit_die=0x621000157d10, pretend_language=language_minimal) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7614
    #8  0x000055555ca9aa2c in process_psymtab_comp_unit (this_cu=0x621000155510, per_objfile=0x613000009f80, want_partial_unit=false, pretend_language=language_minimal) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7712
    #9  0x000055555caa051a in dwarf2_build_psymtabs_hard (per_objfile=0x613000009f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8073

The special thing about this DWARF is that the subprogram at 0x1b is a
template specialization described with DW_AT_specification, and has no
DW_AT_name in itself.  To compute the name of this subprogram,
partial_die_full_name needs to load the full DIE for this partial DIE.
The name is generated from the templated function name and the actual
tempalate parameter values of the specialization.

To load the full DIE, partial_die_full_name creates a dummy DWARF
attribute of form DW_FORM_ref_addr that points to our subprogram's DIE,
and calls follow_die_ref on it.  This eventually causes
load_full_comp_unit to be called for the exact same CU we are currently
making partial symbols for:

    #0  load_full_comp_unit (this_cu=0x621000155510, per_objfile=0x613000009f80, skip_partial=false, pretend_language=language_minimal) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:9238
    #1  0x000055555cb4e943 in follow_die_offset (sect_off=(unknown: 27), offset_in_dwz=0, ref_cu=0x7fffffffc110) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22942
    #2  0x000055555cb4edfb in follow_die_ref (src_die=0x0, attr=0x7fffffffc130, ref_cu=0x7fffffffc110) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22968
    #3  0x000055555caa48c5 in partial_die_full_name (pdi=0x621000157e70, cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8441
    #4  0x000055555caa4d79 in add_partial_symbol (pdi=0x621000157e70, cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8469
    #5  0x000055555caa7d8c in add_partial_subprogram (pdi=0x621000157e70, lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0, set_addrmap=1, cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8737
    #6  0x000055555caa265c in scan_partial_symbols (first_die=0x621000157e00, lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0, set_addrmap=1, cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8230
    #7  0x000055555ca98e3f in process_psymtab_comp_unit_reader (reader=0x7fffffffc6b0, info_ptr=0x60600009650d "\003int", comp_unit_die=0x621000157d10, pretend_language=language_minimal) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7614
    #8  0x000055555ca9aa2c in process_psymtab_comp_unit (this_cu=0x621000155510, per_objfile=0x613000009f80, want_partial_unit=false, pretend_language=language_minimal) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7712
    #9  0x000055555caa051a in dwarf2_build_psymtabs_hard (per_objfile=0x613000009f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8073

load_full_comp_unit creates a cutu_reader for the CU.  Since a dwarf2_cu
object already exists for the CU, load_full_comp_unit is expected to
find it and pass it to cutu_reader, so that cutu_reader doesn't create
a new dwarf2_cu for the CU.

And this is the difference between before and after the regression.
Before commit 7188ed02d2, the dwarf2_per_cu_data -> dwarf2_cu link was
a simple pointer in dwarf2_per_cu_data.  This pointer was set up when
starting the read the partial symbols.  So it was already available at
that point where load_full_comp_unit gets called.  Post-7188ed02d2a7,
this link is per-objfile, kept in the dwarf2_per_objfile::m_dwarf2_cus
hash map.  The entry is only put in the hash map once the partial
symbols have been successfully read, when cutu_reader::keep is called.
Therefore, it is _not_ set at the point load_full_comp_unit is called.

As a consequence, a new dwarf2_cu object gets created and initialized by
load_full_comp_unit (including initializing that dwarf2_cu::die_hash
field).  Meanwhile, the dwarf2_cu object created and used by the callers
up the stack does not get initialized for full symbol reading, and the
dwarf2_cu::die_hash field stays unexpectedly NULL.

Solution
--------

Since the caller of load_full_comp_unit knows about the existing
dwarf2_cu object for the CU we are reading (the one load_full_comp_unit
is expected to find), we can simply make it pass it down, instead of
having load_full_comp_unit look up the per-objfile map.

load_full_comp_unit therefore gets a new `existing_cu` parameter.  All
other callers get updated to pass `per_objfile->get_cu (per_cu)`, so the
behavior shouldn't change for them, compared to the current HEAD.

A test is added, which is the bare minimum to reproduce the issue.

Notes
-----

The original problem was reproduced by downloading

    https://github.com/oneapi-src/oneTBB/releases/download/v2020.3/tbb-2020.3-lin.tgz

and loading libtbb.so in GDB.  This code was compiled with the Intel
C/C++ compiler.  I was not able to reproduce the issue using GCC, I
think because GCC puts a DW_AT_name in the specialized subprogram, so
there's no need for partial_die_full_name to load the full DIE of the
subprogram, and the faulty code doesn't execute.

gdb/ChangeLog:

	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.

gdb/testsuite/ChangeLog:

	PR gdb/26693
	* gdb.dwarf2/template-specification-full-name.exp: New test.

Change-Id: I57c8042f96c45f15797a3848e4d384181c56bb44
2020-10-22 10:47:07 -04:00
GDB Administrator
9a312e4904 Automatic date update in version.in 2020-10-22 00:00:26 +00:00
GDB Administrator
43b860e8c4 Automatic date update in version.in 2020-10-21 00:00:32 +00:00
GDB Administrator
974fee813c Automatic date update in version.in 2020-10-20 00:00:26 +00:00
Mihails Strasuns
a606acc8d2 gdb: get jiter objfile from a bound minsym
This fixes a regression introduced by the following commit:

fe053b9e85 gdb/jit: pass the jiter objfile as an argument to jit_event_handler

In the refactoring `handle_jit_event` function was changed to pass a matching
objfile pointer to the `jit_event_handler` explicitly, rather using internal
storage:

```
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5448,8 +5448,9 @@ handle_jit_event (void)

   frame = get_current_frame ();
   gdbarch = get_frame_arch (frame);
+  objfile *jiter = symbol_objfile (get_frame_function (frame));

-  jit_event_handler (gdbarch);
+  jit_event_handler (gdbarch, jiter);
```

This was needed to add support for multiple jiters.  However it has also
introduced a regression, because `get_frame_function (frame)` here may
return `nullptr`, resulting in a crash.

A more resilient way would be to use an approach mirroring
`jit_breakpoint_re_set` - to find a minimal symbol matching the
breakpoint location and use its object file.  We know that this
breakpoint event comes from a breakpoint set by `jit_breakpoint_re_set`,
thus using the reverse approach should be reliable enough.

gdb/Changelog:
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-19 16:46:44 +02:00
GDB Administrator
aa873d8315 Automatic date update in version.in 2020-10-19 00:00:32 +00:00
GDB Administrator
628b363a6a Automatic date update in version.in 2020-10-18 00:00:27 +00:00
GDB Administrator
c94703dc45 Automatic date update in version.in 2020-10-17 00:00:24 +00:00
GDB Administrator
b96b7cf31f Automatic date update in version.in 2020-10-16 00:00:29 +00:00
GDB Administrator
2acc8db7ed Automatic date update in version.in 2020-10-15 00:00:28 +00:00
GDB Administrator
2e052fd569 Automatic date update in version.in 2020-10-14 00:00:28 +00:00
Simon Marchi
f9052d5c0e gdb: don't pass TARGET_WNOHANG to targets that can't async (PR 26642)
Debugging with "maintenance set target-async off" on Linux has been
broken since 5b6d1e4fa4 ("Multi-target support").

The issue is easy to reproduce:

    $ ./gdb -q --data-directory=data-directory -nx ./test
    Reading symbols from ./test...
    (gdb) maintenance set target-async off
    (gdb) start
    Temporary breakpoint 1 at 0x1151: file test.c, line 5.
    Starting program: /home/simark/build/binutils-gdb/gdb/test

... and it hangs there.

The difference between pre-5b6d1e4fa4f and 5b6d1e4fa4 is that
fetch_inferior_event now calls target_wait with TARGET_WNOHANG for
non-async-capable targets, whereas it didn't before.

For non-async-capable targets, this is how it's expected to work when
resuming execution:

1. we call resume
2. the infrun async handler is marked in prepare_to_wait, to immediately
   wake up the event loop when we get back to it
3. fetch_inferior_event calls the target's wait method without
   TARGET_WNOHANG, effectively blocking until the target has something
   to report

However, since we call the target's wait method with TARGET_WNOHANG,
this happens:

1. we call resume
2. the infrun async handler is marked in prepare_to_wait, to immediately
   wake up the event loop when we get back to it
3. fetch_inferior_event calls the target's wait method with
   TARGET_WNOHANG, the target has nothing to report yet
4. we go back to blocking on the event loop
5. SIGCHLD finally arrives, but the event loop is not woken up, because
   we are not in async mode.  Normally, we should have been stuck in
   waitpid the SIGCHLD would have unblocked us.

We end up in this situation because these two necessary conditions are
met:

1. GDB uses the TARGET_WNOHANG option with a target that can't do async.
   I don't think this makes sense.  I mean, it's technically possible,
   the doc for TARGET_WNOHANG is:

  /* Return immediately if there's no event already queued.  If this
     options is not requested, target_wait blocks waiting for an
     event.  */
  TARGET_WNOHANG = 1,

   ... which isn't in itself necessarily incompatible with synchronous
   targets.  It could be possible for a target to support non-blocking
   polls, while not having a way to asynchronously wake up the event
   loop, which is also necessary to support async.  But as of today,
   we don't expect GDB and sync targets to work this way.

2. The linux-nat target, even in the mode where it emulates a
   synchronous target (with "maintenance set target-async off") respects
   TARGET_WNOHANG.  Other non-async targets, such as windows_nat_target,
   simply don't check / support TARGET_WNOHANG, so their wait method is
   always blocking.

Fix the first issue by avoiding using TARGET_WNOHANG on non-async
targets, in do_target_wait_1.  Add an assert in target_wait to verify it
doesn't happen.

The new test gdb.base/maint-target-async-off.exp is a simple test that
just tries running to main and then to the end of the program, with
"maintenance set target-async off".

gdb/ChangeLog:

	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.

gdb/testsuite/ChangeLog:

	PR gdb/26642
	* gdb.base/maint-target-async-off.c: New test.
	* gdb.base/maint-target-async-off.exp: New test.

Change-Id: I69ad3a14598863d21338a8c4e78700a58ce7ad86
2020-10-13 14:28:13 -04:00
GDB Administrator
0241ddc77d Automatic date update in version.in 2020-10-13 00:00:31 +00:00
GDB Administrator
5d09cf9879 Automatic date update in version.in 2020-10-12 00:00:23 +00:00
GDB Administrator
e610101040 Automatic date update in version.in 2020-10-11 00:00:26 +00:00
GDB Administrator
f7a8799115 Automatic date update in version.in 2020-10-10 00:00:23 +00:00
Joel Brobecker
dc37fea759 gnulib: fix stat/fstat build errors on old Windows version or using old MinGW
This commit imports two commits from gnulib's master branch fixing
a build error when building on a version of Windows that's older
than Vista, or when using an mingw's MinGW.

gnulib/ChangeLog:

	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-10-09 12:50:50 -07:00
GDB Administrator
114f9fd9e9 Automatic date update in version.in 2020-10-09 00:00:29 +00:00
Shahab Vahedi
223de168bb Update GDB NEWS with ARC support in GDBserver
gdb/ChangeLog:

	* NEWS: Mention ARC support in GDBserver.
2020-10-08 13:53:28 +02:00
GDB Administrator
f39391b6f0 Automatic date update in version.in 2020-10-08 00:00:25 +00:00
Anton Kolesov
460fd13b5b arc: Add support for Linux coredump files
With the implemenations in this patch, ARC gdb can handle
coredump related matters.  The binutils counter part of
this patch has already been pushed [1].

v2 [2]:
- arc_linux_collect_gregset: Use "reg <= ARC_LAST_REGNUM" instead of
  "reg < ARC_LAST_REGNUM" for the condition check of the for-loop.
- arc-linux-tdep.c: Use "ARC_LAST_REGNUM < ARRAY_SIZE (...)" instead of
  "ARC_LAST_REGNUM <= ARRAY_SIZE (...)" for the "asserts".
- Use "buf + arc_linux_core_reg_offsets[ARC_ERET_REGNUM]" instead of
  "buf + REG_OFF (6)".
- Fix a few typos/indentation.

v3 [3]:
- Use gdb_assert_not_reached(text) instead of gdb_assert (!text).
- Remove unnecessary braces in the for loop.

[1] arc: Add support for ARC HS extra registers in core files
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=2745674244d6aecddcf636475034bdb9c0a6b4a0

[2] First remarks
https://sourceware.org/pipermail/gdb-patches/2020-September/171912.html

[3] Second remarks
https://sourceware.org/pipermail/gdb-patches/2020-October/172302.html

gdb/ChangeLog:

	* 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 18:29:35 +02:00
Shahab Vahedi
94265abc20 gdb/gdbserver: Add the missing ChangeLog entries
I forgot to add the ChangeLog entries for these 2 patches:

b13599da1a gdbserver: Add GNU/Linux support for ARC
e26d3e9b76 arc: Rename "arc_gdbarch_features" struct
2020-10-07 18:16:19 +02:00
Anton Kolesov
b13599da1a gdbserver: Add GNU/Linux support for ARC
This gdbserver implementation supports ARC ABI v3 and v4 (older ARC ABI
versions are not supported by other modern GNU tools or Linux itself).
Gdbserver supports inspection of ARC HS registers R30, R58 and R59 - feature
that has been added to Linux 4.12.  Whether gdbserver build will actually
support this feature depends on the version of Linux headers used to build
the server.

v2 [1]:
- Use "this->read_memory ()" instead of "the_target->read_memory ()".
- Remove the unnecessary "arch-arc.o:" target from the "Makefile.in".
- Got rid of "ntohs()" function and added lots of comments about
  endianness.
- Clarify why "pc" value is read from and saved to different fields
  in user regs struct.
- In function "is_reg_name_available_p()", use a range-based iterator
  to loop over the registers.
- Removed mentioning of issue number that was not related to sourceware.
- A few typo's fixed.

[1] Remarks
https://sourceware.org/pipermail/gdb-patches/2020-September/171911.html
https://sourceware.org/pipermail/gdb-patches/2020-September/171919.html

gdbserver/ChangeLog:

	* configure.srv: Support ARC architecture.
	* Makefile.in: Add linux-arc-low.cc and arch/arc.o.
	* linux-arc-low.cc: New file.
2020-10-07 18:00:36 +02:00
Shahab Vahedi
e26d3e9b76 arc: Rename "arc_gdbarch_features" struct
"arc_gdbarch_features" is a data structure containing information
about the ARC architecture: ISA version, register size, etc.
This name is misleading, because although it carries the phrase
"gdbarch", it has nothing to do with the type/interface in GDB.
Traditionaly, "gdbarch" structures are only used for that purpose.
To rectify this, this patch changes the name to "arc_arch_features".

gdb/ChangeLog:

	* arch/arc.h: Rename "arc_gdbarch_features" to
	"arc_arch_features".
	* arc-tdep.h: Likewise.
	* arc-tdep.c: Likewise.
2020-10-07 18:00:26 +02:00
GDB Administrator
8f97e9b79d Automatic date update in version.in 2020-10-07 00:00:26 +00:00
GDB Administrator
e68941ba17 Automatic date update in version.in 2020-10-06 00:00:29 +00:00
GDB Administrator
7ba0e35baa Automatic date update in version.in 2020-10-05 00:00:29 +00:00
GDB Administrator
522605be60 Automatic date update in version.in 2020-10-04 00:00:30 +00:00
GDB Administrator
fdb72ad268 Automatic date update in version.in 2020-10-03 00:00:24 +00:00
GDB Administrator
ea9cc728dc Automatic date update in version.in 2020-10-02 00:00:28 +00:00
GDB Administrator
2378f62126 Automatic date update in version.in 2020-10-01 00:00:29 +00:00
GDB Administrator
7e7e2357fc Automatic date update in version.in 2020-09-30 00:00:31 +00:00
GDB Administrator
ccf7653413 Automatic date update in version.in 2020-09-29 00:00:29 +00:00
Gareth Rees
f6c03ee4ad gdb: Fix from_tty argument to gdb.execute in Python.
Prior to commit 56bcdbea2b, the from_tty keyword argument to the
Python function gdb.execute controlled whether the command took input
from the terminal. When from_tty=True, "starti" and similar commands
prompted the user:

    (gdb) python gdb.execute("starti", from_tty=True)
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /bin/true

    Program stopped.

When from_tty=False, these commands did not prompt the user, and "yes"
was assumed:

    (gdb) python gdb.execute("starti", from_tty=False)

    Program stopped.

However, after commit 56bcdbea2b, the from_tty keyword argument no
longer had this effect. For example, as of commit 7ade7fba75:

    (gdb) python gdb.execute("starti", from_tty=True)
    The program being debugged has been started already.
    Start it from the beginning? (y or n) [answered Y; input not from terminal]
    Starting program: /bin/true

    Program stopped.

Note the "[answered Y; input not from terminal]" in the output even
though from_tty=True was requested.

Looking at commit 56bcdbea2b, it seems that the behaviour of the
from_tty argument was changed accidentally. The commit message said:

    Let gdb.execute handle multi-line commands

    This changes the Python API so that gdb.execute can now handle
    multi-line commands, like "commands" or "define".

and there was no mention of changing the effect of the from_tty
argument. It looks as though the code for setting the instream to
nullptr was accidentally moved from execute_user_command() to
execute_control_commands() along with the other scoped restores.

Accordingly, the simplest way to fix this is to partially reverse
commit 56bcdbea2b by moving the code for setting the instream to
nullptr back to execute_user_command() where it was to begin with.

Additionally, add a test case to reduce the risk of similar breakage
in future.

gdb/ChangeLog:

	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.

gdb/testsuite/ChangeLog:

	PR python/26586
	* gdb.python/python.exp: add test cases for the from_tty
	argument to gdb.execute.

(cherry picked from commit 8f9929bb97)
2020-09-28 13:15:59 -07:00
GDB Administrator
5cb6abf208 Automatic date update in version.in 2020-09-28 00:00:32 +00:00
GDB Administrator
df69589808 Automatic date update in version.in 2020-09-27 00:00:29 +00:00
GDB Administrator
698ef0a3e7 Automatic date update in version.in 2020-09-26 00:00:28 +00:00
Tankut Baris Aktemur
13e87e2127 gdb/breakpoint: make a copy of the "commands" command's argument
When GDB reads commands from the input, its internal buffer is re-used
for each line.  This is usually just fine because commands are
executed in order; by the time we read the next line, we are already
done with the current line.  However, a problematic case is breakpoint
commands that are input from a script.  The header (e.g. commands 1 2)
is overwritten with the next line before the breakpoint numbers are
processed completely.

For example, suppose we have the following script:

  break main
  break main
  commands 1 2
    print 100123
  end

and source this script:

  (gdb) source script.gdb
  Breakpoint 1 at 0x1245: file main.cpp, line 27.
  Breakpoint 2 at 0x1245: file main.cpp, line 27.
  No breakpoint number 123.

Note the "No breakpoint number 123." error message.  This happens
because GDB first reads "commands 1 2" into its internal buffer

  buffer -> "commands 1 2"

and then starts parsing the breakpoint numbers.  After parsing the first
token, the "next token" pointer is as below:

  buffer -> "commands 1 2"
  next-token -----------^

So, if we continue parsing, we would tokenize "2" correctly.  However,
before parsing the next number, GDB reads the commands to attach them
to breakpoint 1.  Reading the commands causes the buffer to be
overwritten:

  buffer -> "  print 100123"
  next-token -----------^

So, the next time we parse the breakpoint number, we read "123".

To fix, simply create a copy of the arguments of the header.

gdb/ChangeLog:
2020-09-25  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

	* breakpoint.c (commands_command_1): Make a copy of the 'arg'
	argument.

gdb/testsuite/ChangeLog:
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-25 17:58:04 +02:00
GDB Administrator
f6defe2064 Automatic date update in version.in 2020-09-25 00:00:24 +00:00
Tom Tromey
8ccf2a20fb Don't let TUI focus on locator
PR tui/26638 notes that the C-x o binding can put the focus on the
locator window.  However, this is not useful and did not happen
historically.  This patch changes the TUI to skip this window when
switching focus.

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.

gdb/testsuite/ChangeLog
2020-09-24  Tom Tromey  <tromey@adacore.com>

	PR tui/26638:
	* gdb.tui/list.exp: Check output of "focus next".
2020-09-24 13:03:18 -06:00
Hannes Domani
642ed0e9ec Handle 64bit breakpoints of WOW64 processes as SIGINT
When a WOW64 process triggers a breakpoint exception in 64bit code (which
happens when a 64bit gdb calls DebugBreakProcess for a 32bit target),
gdb ignores the breakpoint (because Wow64GetThreadContext can only report
the pc of 32bit code, and there is not int3 at this location).

But if these 64bit breakpoint exceptions are handled as SIGINT, gdb
doesn't check for int3, and always stops the target.

gdb/ChangeLog:

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.

gdbserver/ChangeLog:

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-24 19:47:26 +02:00
GDB Administrator
6006bb78cc Automatic date update in version.in 2020-09-24 00:00:30 +00:00
GDB Administrator
2051e5340c Automatic date update in version.in 2020-09-23 00:00:23 +00:00
GDB Administrator
1e4d9e71cc Automatic date update in version.in 2020-09-22 00:00:24 +00:00
GDB Administrator
d941eafc46 Automatic date update in version.in 2020-09-21 00:00:24 +00:00
GDB Administrator
a78d1a1c28 Automatic date update in version.in 2020-09-20 00:00:40 +00:00
Victor Collod
b892828bcb gdb: Update i386_analyze_prologue to skip endbr32
With -m32 -fcf-protection, GCC generates an `endbr32` instruction at the
function entry:

[hjl@gnu-cfl-2 gdb]$ cat /tmp/x.c
int
main(void)
{
  return 0;
}
[hjl@gnu-cfl-2 gdb]$ gcc -g -fcf-protection /tmp/x.c -m32
(gdb) b main
Breakpoint 1 at 0x8049176: file /tmp/x.c, line 3.
(gdb) r
Breakpoint 1, main () at /tmp/x.c:3
3	{
(gdb) disass
Dump of assembler code for function main:
=> 0x08049176 <+0>:	endbr32
   0x0804917a <+4>:	push   %ebp
   0x0804917b <+5>:	mov    %esp,%ebp
   0x0804917d <+7>:	mov    $0x0,%eax
   0x08049182 <+12>:	pop    %ebp
   0x08049183 <+13>:	ret
End of assembler dump.
(gdb)

Update i386_analyze_prologue to skip `endbr32`:

(gdb) b main
Breakpoint 1 at 0x804917d: file /tmp/x.c, line 4.
(gdb) r
Breakpoint 1, main () at /tmp/x.c:4
4	  return 0;
(gdb) disass
Dump of assembler code for function main:
   0x08049176 <+0>:	endbr32
   0x0804917a <+4>:	push   %ebp
   0x0804917b <+5>:	mov    %esp,%ebp
=> 0x0804917d <+7>:	mov    $0x0,%eax
   0x08049182 <+12>:	pop    %ebp
   0x08049183 <+13>:	ret
End of assembler dump.
(gdb)

Tested with

$ make check RUNTESTFLAGS="--target_board='unix{-m32,}' i386-prologue-skip-cf-protection.exp"

on Fedora 32/x86-64.

2020-0X-YY  Victor Collod  <vcollod@nvidia.com>

gdb/ChangeLog:

	PR gdb/26635
	* i386-tdep.c (i386_skip_endbr): Add a helper function to skip endbr.
	(i386_analyze_prologue): Call i386_skip_endbr.

gdb/testsuite/ChangeLog:

	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-19 19:53:05 -04:00
GDB Administrator
4567103763 Automatic date update in version.in 2020-09-19 00:00:46 +00:00
Pedro Alves
5573f8461b Fix "thread find" with multiple inferiors/targets (PR gdb/26631)
"thread find" with multiple inferiors got broken with the multi-target
work:

 Thread 1 "gdb" hit Breakpoint 1, internal_error (...) at ../../src/gdbsupport/errors.cc:51
 51      {
 (top-gdb) bt
 #0  internal_error (file=0xffffd4d0 <error: Cannot access memory at address 0xffffd4d0>, line=0, fmt=0x555556330320 "en_US.UTF-8") at ../../src/gdbsupport/errors.cc:51
 #1  0x0000555555bca4c7 in target_thread_name (info=0x555556801290) at ../../src/gdb/target.c:2035
 #2  0x0000555555beb07a in thread_find_command (arg=0x7fffffffe08e "1", from_tty=0) at ../../src/gdb/thread.c:1959
 #3  0x000055555572ec49 in do_const_cfunc (c=0x555556786bc0, args=0x7fffffffe08e "1", from_tty=0) at ../../src/gdb/cli/cli-decode.c:95
 #4  0x0000555555732abd in cmd_func (cmd=0x555556786bc0, args=0x7fffffffe08e "1", from_tty=0) at ../../src/gdb/cli/cli-decode.c:2181
 #5  0x0000555555bf1245 in execute_command (p=0x7fffffffe08e "1", from_tty=0) at ../../src/gdb/top.c:664
 #6  0x00005555559cad10 in catch_command_errors (command=0x555555bf0c31 <execute_command(char const*, int)>, arg=0x7fffffffe082 "thread find 1", from_tty=0) at ../../src/gdb/main.c:457
 #7  0x00005555559cc33d in captured_main_1 (context=0x7fffffffdb60) at ../../src/gdb/main.c:1218
 #8  0x00005555559cc571 in captured_main (data=0x7fffffffdb60) at ../../src/gdb/main.c:1243
 #9  0x00005555559cc5e8 in gdb_main (args=0x7fffffffdb60) at ../../src/gdb/main.c:1268
 #10 0x0000555555623816 in main (argc=17, argv=0x7fffffffdc78) at ../../src/gdb/gdb.c:32

The problem is that we're not switching to the inferior/target before
calling target methods, which trips on an assertion put in place
exactly to catch this sort of problem.

gdb/testsuite/ChangeLog:

	PR gdb/26631
	* gdb.multi/multi-target-thread-find.exp: New file.

gdb/ChangeLog:

	PR gdb/26631
	* thread.c (thread_find_command): Switch inferior before calling
	target methods.
2020-09-18 13:40:55 +01:00
Pedro Alves
a77c0fd170 Split gdb.multi/multi-target.exp into separate testcases
gdb.multi/multi-target.exp sets up a debug environment with multiple
gdbservers, multiple native processes, and multiple cores, which has
proved useful for exercising a number of multi-target scenarios.

But, as we add more tests to gdb.base/multi-target.exp, it is growing
a bit too large (making a bit cumbersome to debug) and too slow to run
(if you have glibc debug info).

This commit thus splits the multi-target.exp into several testcases,
one per use case.  The common setup code is moved to a new
multi-target.exp.tcl file that is included by all the resulting
multi-target testcases.

gdb/testsuite/ChangeLog:

	* 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-18 13:40:55 +01:00
GDB Administrator
0d789f59d1 Automatic date update in version.in 2020-09-18 00:00:42 +00:00
GDB Administrator
7ea31d3da0 Automatic date update in version.in 2020-09-17 00:00:38 +00:00
Tom Tromey
1f2950be0b Match demangled name in "skip"
PR gdb/26598 notes that, before commit bcfe6157ca ("Use the linkage
name if it exists"), the "skip" command would match the demangled name
of a symbol, but now only matches the linkage name.

This patch fixes this regression.  I looked at all calls to
function_name_is_marked_for_skip, and only one used the linkage name.

2020-09-16  Tom Tromey  <tromey@adacore.com>

	PR gdb/26598:
	* infrun.c (fill_in_stop_func): Use find_pc_partial_function_sym.

gdb/testsuite/ChangeLog
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-16 13:55:37 -06:00
GDB Administrator
f0f01c9e23 Automatic date update in version.in 2020-09-16 00:00:39 +00:00
Tom Tromey
efb04be6ae Avoid running one Rust test against older LLVM
LLVM 8.0 introduced some changes to let the Rust compiler emit DWARF
variant parts.  Before this change, the compiler would emit two types
with the same name, and unfortunately gdb happens to pick the wrong
one.  So, this patch disables the test when using an older version of
LLVM.

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-15 09:31:22 -06:00
Fredrik Hederstierna
ba8b04a8d8 Fix exception stack unwinding for ARM Cortex-M
For Cortex-M targets using floating-point, eg the Cortex-M4F, its not possible
to get any call-stack backtrace if setting a breakpoint in ISR.

The exception stack unwinder for Cortex-M does not consider if floating-point
registers was stacked or not, further the Cortex-M has two stack pointers: MSP
(Main Stack Pointer) and PSP (Process Stack Pointer).
This is not handled when GDB tries to backtrace in the exception stack
unwinder.

This patch fixes this, and gives a correct call-stack backtrace from
breakpoints set in a handler or ISR.

gdb/ChangeLog:

        * arm-tdep.c (arm_m_exception_cache): Try use correct stack
        pointer and stack frame offset when unwinding.
2020-09-15 14:57:49 +01:00
GDB Administrator
9c4a30eb45 Automatic date update in version.in 2020-09-15 00:00:51 +00:00
GDB Administrator
5ebb0da9a5 Automatic date update in version.in 2020-09-14 00:00:48 +00:00
Joel Brobecker
423e52cef3 Bump GDB version number to 10.0.90.DATE-git.
gdb/ChangeLog:

	* version.in: Set GDB version number to 10.0.90.DATE-git.
2020-09-12 20:06:27 -07:00
Joel Brobecker
46ecde124e Document the GDB 10.0.90 release in gdb/ChangeLog
gdb/ChangeLog:

	GDB 10.0.90 released.
2020-09-12 20:06:13 -07:00
Joel Brobecker
f1e420ce92 Set GDB version number to 10.0.90.
gdb/ChangeLog:

	* version.in: Set GDB version number to 10.0.90.
2020-09-12 19:57:18 -07:00
Joel Brobecker
c527795867 gdb/NEWS: Change "since GDB 9" to "in GDB 10"
gdb/ChangeLog:

	* NEWS: Change "Changes since GDB 9" to "Changes in GDB 10".
2020-09-12 19:49:53 -07:00
Joel Brobecker
713bde4c19 Set development mode to "off" by default.
bfd/ChangeLog:

	* development.sh (development): Set to false.
2020-09-12 19:34:37 -07:00
Joel Brobecker
31c6c31e02 Bump version to 10.0.90.DATE-git.
Now that the GDB 10 branch has been created, we can
bump the version number.

gdb/ChangeLog:

	GDB 10 branch created (8087c3fa8b):
	* version.in: Bump version to 10.0.90.DATE-git.
2020-09-12 19:34:15 -07:00
67 changed files with 2522 additions and 651 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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@

View File

@@ -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.

View File

@@ -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:

View File

@@ -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
View 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 */

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 (&current_ui->instream, nullptr);
scoped_restore save_async = make_scoped_restore (&current_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 (&current_ui->instream, nullptr);
execute_control_commands (cmdlines, 0);
}

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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. */

View File

@@ -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>

View File

@@ -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
}

View 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;
}

View 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

View 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

View 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;
}

View 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

View 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;
}

View 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;"

View File

@@ -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>\\(\\)>"

View 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

View 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

View 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

View 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

View 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

View 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

View File

@@ -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

View 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
}

View File

@@ -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"
}
}

View File

@@ -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"
}

View File

@@ -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"

View File

@@ -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
}

View File

@@ -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"),

View File

@@ -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;
}

View File

@@ -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 ()
{

View File

@@ -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.

View File

@@ -1 +1 @@
10.0.50.DATE-git
10.1

View File

@@ -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;

View File

@@ -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.

View File

@@ -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 \

View File

@@ -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
View 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 &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);
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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:

View File

@@ -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
View File

@@ -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

View File

@@ -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])
:
])

View File

@@ -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
])

View File

@@ -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

View 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

View 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

View File

@@ -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 &&

View File

@@ -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

View File

@@ -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;
}