Commit Graph

355 Commits

Author SHA1 Message Date
Luis Machado
d88cb738e6 [aarch64] Fix removal of non-address bits for PAuth
PR gdb/28947

The address_significant gdbarch setting was introduced as a way to remove
non-address bits from pointers, and it is specified by a constant.  This
constant represents the number of address bits in a pointer.

Right now AArch64 is the only architecture that uses it, and 56 was a
correct option so far.

But if we are using Pointer Authentication (PAuth), we might use up to 2 bytes
from the address space to store the required information.  We could also have
cases where we're using both PAuth and MTE.

We could adjust the constant to 48 to cover those cases, but this doesn't
cover the case where GDB needs to sign-extend kernel addresses after removal
of the non-address bits.

This has worked so far because bit 55 is used to select between kernel-space
and user-space addresses.  But trying to clear a range of bits crossing the
bit 55 boundary requires the hook to be smarter.

The following patch renames the gdbarch hook from significant_addr_bit to
remove_non_address_bits and passes a pointer as opposed to the number of
bits.  The hook is now responsible for removing the required non-address bits
and sign-extending the address if needed.

While at it, make GDB and GDBServer share some more code for aarch64 and add a
new arch-specific testcase gdb.arch/aarch64-non-address-bits.exp.

Bug-url: https://sourceware.org/bugzilla/show_bug.cgi?id=28947

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2022-12-16 11:18:32 +00:00
Simon Marchi
de75275fe5 gdbsupport: change xml_escape_text_append's parameter from pointer to reference
The passed in string can't be nullptr, it makes more sense to pass in a
reference.

Change-Id: Idc8bd38abe1d6d9b44aa227d7856956848c233b3
2022-12-15 21:56:25 -05:00
Luis Machado
ba60b96371 [aarch64] Add TPIDR2 register support for Linux
With the AArch64 Scalable Matrix Extension we have a new TPIDR2 register, and
it will be added to the existing NT_ARM_TLS register set. Kernel patches are
being reviewed here:

https://lore.kernel.org/linux-arm-kernel/20220818170111.351889-1-broonie@kernel.org/

From GDB's perspective, we handle it in a similar way to the existing TPIDR
register. But we need to consider cases of systems that only have TPIDR and
systems that have both TPIDR and TPIDR2.

With that in mind, the following patch adds the required code to support
TPIDR2 and turns the org.gnu.gdb.aarch64.tls feature into a
dynamically-generated target description as opposed to a static target
description containing only TPIDR.

That means we can remove the gdb/features/aarch64-tls.xml file and replace the
existing gdb/features/aarch64-tls.c auto-generated file with a new file that
dynamically generates the target description containing either TPIDR alone or
TPIDR and TPIDR2.

In the future, when *BSD's start to support this register, they can just
enable it as is being done for the AArch64 Linux target.

The core file read/write code has been updated to support TPIDR2 as well.

On GDBserver's side, there is a small change to the find_regno function to
expose a non-throwing version of it.

It always seemed strange to me how find_regno causes the whole operation to
abort if it doesn't find a particular register name. The patch moves code
from find_regno into find_regno_no_throw and makes find_regno call
find_regno_no_throw instead.

This allows us to do register name lookups to find a particular register
number without risking erroring out if nothing is found.

The patch also adjusts the feature detection code for aarch64-fbsd, since
the infrastructure is shared amongst all aarch64 targets. I haven't added
code to support TPIDR2 in aarch64-fbsd though, as I'm not sure when/if
that will happen.
2022-12-09 13:41:15 +00:00
Simon Marchi
3295ff3bfb gdbserver: switch to right process in find_one_thread
New in this version: add a dedicated test.

When I do this:

    $ ./gdb -nx --data-directory=data-directory -q \
        /bin/sleep \
	-ex "maint set target-non-stop on" \
	-ex "tar ext :1234" \
	-ex "set remote exec-file /bin/sleep" \
	-ex "run 1231 &" \
	-ex add-inferior \
	-ex "inferior 2"
    Reading symbols from /bin/sleep...
    (No debugging symbols found in /bin/sleep)
    Remote debugging using :1234
    Starting program: /bin/sleep 1231
    Reading /lib64/ld-linux-x86-64.so.2 from remote target...
    warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
    Reading /lib64/ld-linux-x86-64.so.2 from remote target...
    Reading /usr/lib/debug/.build-id/a6/7a1408f18db3576757eea210d07ba3fc560dff.debug from remote target...
    [New inferior 2]
    Added inferior 2 on connection 1 (extended-remote :1234)
    [Switching to inferior 2 [<null>] (<noexec>)]
    (gdb) Reading /lib/x86_64-linux-gnu/libc.so.6 from remote target...
    attach 3659848
    Attaching to process 3659848
    /home/smarchi/src/binutils-gdb/gdb/thread.c:85: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed.

Note the "attach" command just above.  When doing it on the command-line
with a -ex switch, the bug doesn't trigger.

The internal error of GDB is actually caused by GDBserver crashing, and
the error recovery of GDB is not on point.  This patch aims to fix just
the GDBserver crash, not the GDB problem.

GDBserver crashes with a segfault here:

    (gdb) bt
    #0  0x00005555557fb3f4 in find_one_thread (ptid=...) at /home/smarchi/src/binutils-gdb/gdbserver/thread-db.cc:177
    #1  0x00005555557fd5cf in thread_db_thread_handle (ptid=<error reading variable: Cannot access memory at address 0xffffffffffffffa0>, handle=0x7fffffffc400, handle_len=0x7fffffffc3f0)
        at /home/smarchi/src/binutils-gdb/gdbserver/thread-db.cc:461
    #2  0x000055555578a0b6 in linux_process_target::thread_handle (this=0x5555558a64c0 <the_x86_target>, ptid=<error reading variable: Cannot access memory at address 0xffffffffffffffa0>, handle=0x7fffffffc400,
        handle_len=0x7fffffffc3f0) at /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:6905
    #3  0x00005555556dfcc6 in handle_qxfer_threads_worker (thread=0x60b000000510, buffer=0x7fffffffc8a0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1645
    #4  0x00005555556e00e6 in operator() (__closure=0x7fffffffc5e0, thread=0x60b000000510) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1696
    #5  0x00005555556f54be in for_each_thread<handle_qxfer_threads_proper(buffer*)::<lambda(thread_info*)> >(struct {...}) (func=...) at /home/smarchi/src/binutils-gdb/gdbserver/gdbthread.h:159
    #6  0x00005555556e0242 in handle_qxfer_threads_proper (buffer=0x7fffffffc8a0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1694
    #7  0x00005555556e04ba in handle_qxfer_threads (annex=0x629000000213 "", readbuf=0x621000019100 '\276' <repeats 200 times>..., writebuf=0x0, offset=0, len=4097)
        at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1732
    #8  0x00005555556e1989 in handle_qxfer (own_buf=0x629000000200 "qXfer:threads", packet_len=26, new_packet_len_p=0x7fffffffd630) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:2045
    #9  0x00005555556e720a in handle_query (own_buf=0x629000000200 "qXfer:threads", packet_len=26, new_packet_len_p=0x7fffffffd630) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:2685
    #10 0x00005555556f1a01 in process_serial_event () at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4176
    #11 0x00005555556f4457 in handle_serial_event (err=0, client_data=0x0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4514
    #12 0x0000555555820f56 in handle_file_event (file_ptr=0x607000000250, ready_mask=1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:573
    #13 0x0000555555821895 in gdb_wait_for_event (block=1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:694
    #14 0x000055555581f533 in gdb_do_one_event (mstimeout=-1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:264
    #15 0x00005555556ec9fb in start_event_loop () at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3512
    #16 0x00005555556f0769 in captured_main (argc=4, argv=0x7fffffffe0d8) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3992
    #17 0x00005555556f0e3f in main (argc=4, argv=0x7fffffffe0d8) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4078

The reason is a wrong current process when find_one_thread is called.
The current process is the 2nd one, which was just attached.  It does
not yet have thread_db data (proc->priv->thread_db is nullptr).  As we
iterate on all threads of all process to fulfull the qxfer:threads:read
request, we get to a thread of process 1 for which we haven't read
thread_db information yet (lwp_info::thread_known is false), so we get
into find_one_thread.  find_one_thread uses
`current_process ()->priv->thread_db`, assuming the current process
matches the ptid passed as a parameter, which is wrong.  A segfault
happens when trying to dereference that thread_db pointer.

Fix this by making find_one_thread not assume what the current process /
current thread is.  If it needs to call into libthread_db, which we know
will try to read memory from the current process, then temporarily set
the current process.

In the case where the thread is already know and we return early, we
don't need to switch process.

Add a test to reproduce this specific situation.

Change-Id: I09b00883e8b73b7e5f89d0f47cb4e9c0f3d6caaa
Approved-By: Andrew Burgess <aburgess@redhat.com>
2022-11-28 09:13:30 -05:00
Tom de Vries
4c35c4c6a7 [gdb/server] Emit warning for SIGINT failure
Consider the executable from test-case gdb.base/interrupt-daemon.exp.

When starting it using gdbserver:
...
$ ./build/gdbserver/gdbserver localhost:2345 \
  ./outputs/gdb.base/interrupt-daemon/interrupt-daemon
...
and connecting to it using gdb:
...
$ gdb -q -ex "target remote localhost:2345" \
    -ex "set follow-fork-mode child" \
    -ex "break daemon_main" -ex cont
...
we are setup to do the same as in the test-case: interrupt a running inferior
using ^C.

So let's try:
...
(gdb) continue
Continuing.
^C
...
After pressing ^C, nothing happens.  This a known problem, filed as
PR remote/18772.

The problem is that in linux_process_target::request_interrupt, a kill is used
to send a SIGINT, but it fails.  And it fails silently.

Make the failure verbose by adding a warning, such that the gdbserver output
becomes more helpful:
...
Process interrupt-daemon created; pid = 15068
Listening on port 2345
Remote debugging from host ::1, port 35148
Detaching from process 15068
Detaching from process 15085
gdbserver: Sending SIGINT to process group of pid 15068 failed: \
  No such process
...

Note that the failure can easily be reproduced using the test-case and target
board native-gdbserver:
...
(gdb) continue^M
Continuing.^M
PASS: gdb.base/interrupt-daemon.exp: fg: continue
^CFAIL: gdb.base/interrupt-daemon.exp: fg: ctrl-c stops process (timeout)
...
as reported in PR server/23382.

Tested on x86_64-linux.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
2022-11-27 10:31:50 +01:00
Simon Marchi
5e219e0f46 gdbserver/linux-x86: move lwp declaration out of __x86_64__ region
Commit 4855cbdc3d ("gdbserver/linux-x86: make is_64bit_tdesc accept
thread as a parameter") caused this when building in 32 bits / i386
mode:

      CXX    linux-x86-low.o
    In file included from /home/smarchi/src/binutils-gdb/gdbserver/linux-x86-low.cc:24:
    /home/smarchi/src/binutils-gdb/gdbserver/linux-x86-low.cc: In member function ‘virtual int x86_target::low_get_thread_area(int, CORE_ADDR*)’:
    /home/smarchi/src/binutils-gdb/gdbserver/linux-x86-low.cc:357:47: error: ‘lwp’ was not declared in this scope
      357 |     struct thread_info *thr = get_lwp_thread (lwp);
          |                                               ^~~
    /home/smarchi/src/binutils-gdb/gdbserver/linux-low.h:709:31: note: in definition of macro ‘get_lwp_thread’
      709 | #define get_lwp_thread(lwp) ((lwp)->thread)
          |                               ^~~

This is because it moved the lwp variable declaration inside the
__x86_64__ guard, making it unavailable when building in 32 bits mode.
Move the lwp variable outside of the __x86_64__ region.

Change-Id: I7fa3938c6b44b345c27a52c8b8d3ea12aba53e05
2022-11-18 12:18:53 -05:00
Simon Marchi
c0cb02a4cf gdbserver: use current_process in ps_getpid
The following patch ("gdbserver: switch to right process in
find_one_thread") makes it so find_one_thread calls into libthread_db
with a current process but no current thread.  This tripped on ps_getpid
using current_thread in order to get the process' pid.  Get the pid from
`current_process ()` instead, which removes the need to have a current
thread.  Eventually, it would be good to get it from the
gdb_ps_prochandle_t structure, to avoid the need for a current process
as well.

Reviewed-By: Andrew Burgess <aburgess@redhat.com>
Change-Id: I9d2fae266419199a2fbc2fde0a5104c6e0dbd2d5
2022-11-18 11:21:22 -05:00
Simon Marchi
4855cbdc3d gdbserver/linux-x86: make is_64bit_tdesc accept thread as a parameter
ps_get_thread_area receives as a parameter the lwpid it must work on.
It then calls is_64bit_tdesc, which uses the current_thread as the
thread to work on.  However, it is not said that both are the same.

This became a problem when working in a following patch that makes
find_one_thread switch to a process but to no thread (current_thread ==
nullptr).  When libthread_db needed to get the thread area,
is_64bit_tdesc would try to get the regcache of a nullptr thread.

Fix that by making is_64bit_tdesc accept the thread to work on as a
parameter.  Find the right thread from the context, when possible (when
we know the lwpid to work on).  Otherwise, pass "current_thread", to
retain the existing behavior.

Reviewed-By: Andrew Burgess <aburgess@redhat.com>
Change-Id: I44394d6be92392fa28de71982fd04517ce8a3007
2022-11-18 11:11:42 -05:00
Simon Marchi
d4895ba2df gdbserver/linux: take condition out of callback in find_lwp_pid
Just a small optimization, it's not necessary to recompute lwp at each
iteration.

While at it, change the variable type to long, as ptid_t::lwp returns a
long.

Reviewed-By: Andrew Burgess <aburgess@redhat.com>
Change-Id: I181670ce1f90b59cb09ea4899367750be2ad9105
2022-11-18 11:09:11 -05:00
Tankut Baris Aktemur
8263b346fa gdbserver: do not report btrace support if target does not announce it
Gdbserver unconditionally reports support for btrace packets.  Do not
report the support, if the underlying target does not say it supports
it.  Otherwise GDB would query the server with btrace-related packets
unnecessarily.
2022-11-09 17:46:21 +01:00
Pedro Alves
f34652de0b internal_error: remove need to pass __FILE__/__LINE__
Currently, every internal_error call must be passed __FILE__/__LINE__
explicitly, like:

  internal_error (__FILE__, __LINE__, "foo %d", var);

The need to pass in explicit __FILE__/__LINE__ is there probably
because the function predates widespread and portable variadic macros
availability.  We can use variadic macros nowadays, and in fact, we
already use them in several places, including the related
gdb_assert_not_reached.

So this patch renames the internal_error function to something else,
and then reimplements internal_error as a variadic macro that expands
__FILE__/__LINE__ itself.

The result is that we now should call internal_error like so:

  internal_error ("foo %d", var);

Likewise for internal_warning.

The patch adjusts all calls sites.  99% of the adjustments were done
with a perl/sed script.

The non-mechanical changes are in gdbsupport/errors.h,
gdbsupport/gdb_assert.h, and gdb/gdbarch.py.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: Ia6f372c11550ca876829e8fd85048f4502bdcf06
2022-10-19 15:32:36 +01:00
Markus Metzger
2733d9d5d6 gdb, gdbserver: extend RSP to support namespaces
Introduce a new qXfer:libraries-svr4:read annex key/value pair

    lmid=<namespace identifier>

to be used together with start and prev to provide the namespace of start
and prev to gdbserver.

Unknown key/value pairs are ignored by gdbserver so no new supports check
is needed.

Introduce a new library-list-svr4 library attribute

    lmid

to provide the namespace of a library entry to GDB.

This implementation uses the address of a namespace's r_debug object as
namespace identifier.

This should have incremented the minor version but since unknown XML
attributes are ignored, anyway, and since changing the version results in
a warning from GDB, the version is left at 1.0.
2022-10-18 14:16:09 +02:00
Markus Metzger
ad10f44e56 gdbserver: move main_lm handling into caller
When listing SVR4 shared libraries, special care has to be taken about the
first library in the default namespace as that refers to the main
executable.  The load map address of this main executable is provided in
an attribute of the library-list-svr4 element.

Move that code from where we enumerate libraries inside a single namespace
to where we generate the rest of the library-list-svr4 element.  This
allows us to complete the library-list-svr4 element inside one function.

There should be no functional change.
2022-10-18 14:16:08 +02:00
Markus Metzger
8d56636a0e gdb, gdbserver: support dlmopen()
In glibc, the r_debug structure contains (amongst others) the following
fields:

  int r_version:
    Version number for this protocol.  It should be greater than 0.

If r_version is 2, struct r_debug is extended to struct r_debug_extended
with one additional field:

  struct r_debug_extended *r_next;
    Link to the next r_debug_extended structure.  Each r_debug_extended
    structure represents a different namespace.  The first r_debug_extended
    structure is for the default namespace.

1. Change solib_svr4_r_map argument to take the debug base.
2. Add solib_svr4_r_next to find the link map in the next namespace from
the r_next field.
3. Update svr4_current_sos_direct to get the link map in the next namespace
from the r_next field.
4. Don't check shared libraries in other namespaces when updating shared
libraries in a new namespace.
5. Update svr4_same to check the load offset in addition to the name
6. Update svr4_default_sos to also set l_addr_inferior
7. Change the flat solib_list into a per-namespace list using the
namespace's r_debug address to identify the namespace.

Add gdb.base/dlmopen.exp to test this.

To remain backwards compatible with older gdbserver, we reserve the
namespace zero for a flat list of solibs from all namespaces.  Subsequent
patches will extend RSP to allow listing libraries grouped by namespace.

This fixes PR 11839.

Co-authored-by: Lu, Hongjiu  <hongjiu.lu@intel.com>
2022-10-18 14:16:08 +02:00
Pedro Alves
93362ef59e Renenerate {gdb,gdbserver}/configure
Pick up config/lib-ld.m4 changes from:

 commit 67d1991b78
 Author:     Alan Modra <amodra@gmail.com>
 AuthorDate: Wed Sep 28 13:37:31 2022 +0930
 Commit:     Alan Modra <amodra@gmail.com>
 CommitDate: Wed Sep 28 13:37:31 2022 +0930

     egrep in binutils

Change-Id: Ifc84d30f1fca015e80bafa80f9a35616b0077220
2022-09-28 13:06:06 +01:00
Enze Li
b7098e650c gdbserver: remove unused for loop
In this commit,

  commit cf6c1e710e
  Date:   Mon Jul 11 20:53:48 2022 +0800

    gdbserver: remove unused variable

I removed an unused variable in handle_v_run.  Pedro then pointed out
that the for loop after it was also unused.  After a period of smoke
testing, no exceptions were found.

Tested on x86_64-linux.
2022-09-24 11:59:59 +08:00
Simon Marchi
198f946ffe gdbsupport: move include/gdb/fileio.h contents to fileio.h
I don't see why include/gdb/fileio.h is placed there.  It's not
installed by "make install", and it's not included by anything outside
of gdb/gdbserver/gdbsupport.

Move its content back to gdbsupport/fileio.h.  I have omitted the bits
inside an `#if 0`, since it's obviously not used, as well as the
"limits" constants, which are also unused.

Change-Id: I6fbc2ea10fbe4cfcf15f9f76006b31b99c20e5a9
2022-09-21 14:11:03 -04:00
Jiangshuai Li
02cd1b4e97 gdbserver/csky add csky gdbserver support
Add new files:
  gdb/arch/csky.c
  gdb/arch/csky.h
  gdb/features/cskyv2-linux.c
  gdbserver/linux-csky-low.cc

1. In gdb/arch/csky.c file, add function "csky_create_target_description()"
for csky_target::low_arch_setup(). later, it can be used for csky native gdb.

2. In gdb/features/cskyv2-linux.c file, create target_tdesc for csky, include
gprs, pc, hi, lo, float, vector and float control registers.

3. In gdbserver/linux-csky-low.cc file, using PTRACE_GET/SET_RGESET to
get/set registers. The main data structures in asm/ptrace.h are:
struct pt_regs {
    unsigned long   tls;
    unsigned long   lr;
    unsigned long   pc;
    unsigned long   sr;
    unsigned long   usp;

    /*
     * a0, a1, a2, a3:
     * r0, r1, r2, r3
     */
    unsigned long   orig_a0;
    unsigned long   a0;
    unsigned long   a1;
    unsigned long   a2;
    unsigned long   a3;

    /*
     * r4 ~ r13
     */
    unsigned long   regs[10];

    /* r16 ~ r30 */
    unsigned long   exregs[15];

    unsigned long   rhi;
    unsigned long   rlo;
    unsigned long   dcsr;
};

struct user_fp {
    unsigned long   vr[96];
    unsigned long   fcr;
    unsigned long   fesr;
    unsigned long   fid;
    unsigned long   reserved;
};
2022-09-13 11:20:54 +08:00
Tom Tromey
02d04eac24 Use strwinerror in gdb/windows-nat.c
When working on windows-nat.c, it's useful to see an error message in
addition to the error number given by GetLastError.  This patch moves
strwinerror from gdbserver to gdbsupport, and then updates
windows-nat.c to use it.  A couple of minor changes to strwinerror
(constify the return type and use the ARRAY_SIZE macro) are also
included.
2022-08-16 08:04:37 -06:00
Feiyang Chen
ea3352172e gdb/gdbserver: LoongArch: Improve implementation of fcc registers
The current implementation of the fcc register is referenced to the
user_fp_state structure of the kernel uapi [1].

struct user_fp_state {
	uint64_t    fpr[32];
	uint64_t    fcc;
	uint32_t    fcsr;
};

But it is mistakenly defined as a 64-bit fputype register, resulting
in a confusing output of "info register".

(gdb) info register
...
fcc            {f = 0x0, d = 0x0}  {f = 0, d = 0}
...

According to "Condition Flag Register" in "LoongArch Reference Manual"
[2], there are 8 condition flag registers of size 1. Use 8 registers of
uint8 to make it easier for users to view the fcc register groups.

(gdb) info register
...
fcc0           0x1                 1
fcc1           0x0                 0
fcc2           0x0                 0
fcc3           0x0                 0
fcc4           0x0                 0
fcc5           0x0                 0
fcc6           0x0                 0
fcc7           0x0                 0
...

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/loongarch/include/uapi/asm/ptrace.h
[2] https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_condition_flag_register

Signed-off-by: Feiyang Chen <chenfeiyang@loongson.cn>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-08-09 22:22:23 +08:00
Enze Li
cf6c1e710e gdbserver: remove unused variable
When building with clang 15, I got this error:

  CXX    server.o
server.cc:2985:10: error: variable 'new_argc' set but not used [-Werror,-Wunused-but-set-variable]
  int i, new_argc;
             ^
Remove the unused variable to eliminate the error.

Tested by rebuilding on x86_64-linux with clang 15.
2022-07-13 20:10:18 +08:00
Tiezhu Yang
3f6227c2f4 gdbserver: LoongArch: Add floating-point support
This commit adds floating-point support for LoongArch gdbserver.

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-07-12 20:14:52 +08:00
Youling Tang
74baa6cd1c gdbserver: LoongArch: Add orig_a0 processing
Commit 736918239b ("gdb: LoongArch: add orig_a0 into register set")
introduced orig_a0, similar processing needs to be done in gdbserver.

At the same time, add orig_a0 related comments.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-07-10 17:27:55 +08:00
Youling Tang
3eba483364 gdbserver: LoongArch: Simplify code with register number macros
Move "enum loongarch_regnum" to gdb/arch/loongarch.h so that the
macro definitions can be used in gdbserver/linux-loongarch-low.cc
to simplify the code.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-07-10 17:27:50 +08:00
Pedro Alves
7e8621cf6d Fix GDBserver regression due to change to avoid reading shell registers
Simon reported that the recent change to make GDB and GDBserver avoid
reading shell registers caused a GDBserver regression, caught with
ASan while running gdb.server/non-existing-program.exp:

 $ /home/smarchi/build/binutils-gdb/gdb/testsuite/../../gdb/../gdbserver/gdbserver stdio non-existing-program
 =================================================================
 ==127719==ERROR: AddressSanitizer: heap-use-after-free on address 0x60f0000000e9 at pc 0x55bcbfa301f4 bp 0x7ffd238a7320 sp 0x7ffd238a7310
 WRITE of size 1 at 0x60f0000000e9 thread T0
     #0 0x55bcbfa301f3 in scoped_restore_tmpl<bool>::~scoped_restore_tmpl() /home/smarchi/src/binutils-gdb/gdbserver/../gdbsupport/scoped_restore.h:86
     #1 0x55bcbfa2ffe9 in post_fork_inferior(int, char const*) /home/smarchi/src/binutils-gdb/gdbserver/fork-child.cc:120
     #2 0x55bcbf9c9199 in linux_process_target::create_inferior(char const*, std::__debug::vector<char*, std::allocator<char*> > const&) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:991
     #3 0x55bcbf954549 in captured_main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3941
     #4 0x55bcbf9552f0 in main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4084
     #5 0x7ff9d663b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)
     #6 0x55bcbf8ef2bd in _start (/home/smarchi/build/binutils-gdb/gdbserver/gdbserver+0x1352bd)

 0x60f0000000e9 is located 169 bytes inside of 176-byte region [0x60f000000040,0x60f0000000f0)
 freed by thread T0 here:
     #0 0x7ff9d6c6f0c7 in operator delete(void*) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:160
     #1 0x55bcbf910d00 in remove_process(process_info*) /home/smarchi/src/binutils-gdb/gdbserver/inferiors.cc:164
     #2 0x55bcbf9c4ac7 in linux_process_target::remove_linux_process(process_info*) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:454
     #3 0x55bcbf9cdaa6 in linux_process_target::mourn(process_info*) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:1599
     #4 0x55bcbf988dc4 in target_mourn_inferior(ptid_t) /home/smarchi/src/binutils-gdb/gdbserver/target.cc:205
     #5 0x55bcbfa32020 in startup_inferior(process_stratum_target*, int, int, target_waitstatus*, ptid_t*) /home/smarchi/src/binutils-gdb/gdbserver/../gdb/nat/fork-inferior.c:515
     #6 0x55bcbfa2fdeb in post_fork_inferior(int, char const*) /home/smarchi/src/binutils-gdb/gdbserver/fork-child.cc:111
     #7 0x55bcbf9c9199 in linux_process_target::create_inferior(char const*, std::__debug::vector<char*, std::allocator<char*> > const&) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:991
     #8 0x55bcbf954549 in captured_main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3941
     #9 0x55bcbf9552f0 in main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4084
     #10 0x7ff9d663b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)

 previously allocated by thread T0 here:
     #0 0x7ff9d6c6e5a7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
     #1 0x55bcbf910ad0 in add_process(int, int) /home/smarchi/src/binutils-gdb/gdbserver/inferiors.cc:144
     #2 0x55bcbf9c477d in linux_process_target::add_linux_process_no_mem_file(int, int) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:425
     #3 0x55bcbf9c8f4c in linux_process_target::create_inferior(char const*, std::__debug::vector<char*, std::allocator<char*> > const&) /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:985
     #4 0x55bcbf954549 in captured_main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3941
     #5 0x55bcbf9552f0 in main /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4084
     #6 0x7ff9d663b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)

Above we see that in the non-existing-program case, the process gets
deleted before the starting_up flag gets restored to false.

This happens because startup_inferior calls target_mourn_inferior
before throwing an error, and in GDBserver, unlike in GDB, mourning
deletes the process.

Fix this by not using a scoped_restore to manage the starting_up flag,
since we should only clear it when startup_inferior doesn't throw.

Change-Id: I67325d6f81c64de4e89e20e4ec4556f57eac7f6c
2022-06-29 19:32:07 +01:00
Pedro Alves
a9deee17d3 gdb+gdbserver/Linux: avoid reading registers while going through shell
For every stop, Linux GDB and GDBserver save the stopped thread's PC,
in lwp->stop_pc.  This is done in save_stop_reason, in both
gdb/linux-nat.c and gdbserver/linux-low.cc.  However, while we're
going through the shell after "run", in startup_inferior, we shouldn't
be reading registers, as we haven't yet determined the target's
architecture -- the shell's architecture may not even be the same as
the final inferior's.

In gdb/linux-nat.c, lwp->stop_pc is only needed when the thread has
stopped for a breakpoint, and since when going through the shell, no
breakpoint is going to hit, we could simply teach save_stop_reason to
only record the stop pc when the thread stopped for a breakpoint.

However, in gdbserver/linux-low.cc, lwp->stop_pc is used in more cases
than breakpoint hits (e.g., it's used in tracepoints & the
"while-stepping" feature).

So to avoid GDB vs GDBserver divergence, we apply the same approach to
both implementations.

We set a flag in the inferior (process in GDBserver) whenever it is
being nursed through the shell, and when that flag is set,
save_stop_reason bails out early.  While going through the shell,
we'll only ever get process exits (normal or signalled), random
signals, and exec events, so nothing is lost.

Change-Id: If0f01831514d3a74d17efd102875de7d2c6401ad
2022-06-28 18:11:29 +01:00
Pedro Alves
171fba11ab Make GDBserver abort on internal error in development mode
Currently, if GDBserver hits some internal assertion, it exits with
error status, instead of aborting.  This makes it harder to debug
GDBserver, as you can't just debug a core file if GDBserver fails an
assertion.  I've had to hack the code to make GDBserver abort to debug
something several times before.

I believe the reason it exits instead of aborting, is to prevent
potentially littering the filesystem of smaller embedded targets with
core files.  I think I recall Daniel Jacobowitz once saying that many
years ago, but I can't be sure.  Anyhow, that seems reasonable to me.

Since we nowadays have a distinction between development and release
modes, I propose to make GDBserver abort on internal error if in
development mode, while keeping the status quo when in release mode.

Thus, after this patch, in development mode, you get:

 $ ../gdbserver/gdbserver
 ../../src/gdbserver/server.cc:3711: A problem internal to GDBserver has been detected.
 captured_main: Assertion `0' failed.
 Aborted (core dumped)
 $

while in release mode, you'll continue to get:

 $ ../gdbserver/gdbserver
 ../../src/gdbserver/server.cc:3711: A problem internal to GDBserver has been detected.
 captured_main: Assertion `0' failed.
 $ echo $?
 1

I do not think that this requires a separate configure switch.

A "--target_board=native-extended-gdbserver" run on Ubuntu 20.04 ends
up with:

		 === gdb Summary ===

 # of unexpected core files      29
 ...

for me, of which 8 are GDBserver core dumps, 7 more than without this
patch.

Change-Id: I6861e08ad71f65a0332c91ec95ca001d130b0e9d
2022-06-27 13:55:36 +01:00
Youling Tang
e5ab6af52d gdbserver: Add LoongArch/Linux support
Implement LoongArch/Linux support, including XML target description
handling based on features determined, GPR regset support, and software
breakpoint handling.

In the Linux kernel code of LoongArch, ptrace implements PTRACE_POKEUSR
and PTRACE_PEEKUSR in the arch_ptrace function, so srv_linux_usrregs is
set to yes.

With this patch on LoongArch:

  $ make check-gdb TESTS="gdb.server/server-connect.exp"
  [...]
  # of expected passes		18
  [...]

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-06-14 22:21:43 +08:00
Tom Tromey
20489cca90 Use subclasses of windows_process_info
This changes windows_process_info to use virtual methods for its
callbacks, and then changes the two clients of this code to subclass
this class to implement the methods.

I considered using CRTP here, but that would require making the new
structures visible to the compilation of of nat/windows-nat.c.  This
seemed like a bit of a pain, so I didn't do it.

This change then lets us change all the per-inferior globals to be
members of the new subclass.  Note that there can still only be a
single inferior -- currently there's a single global of the new type.
This is just another step toward possibly implementing multi-inferior
for Windows.

It's possible this could be cleaned up further... ideally I'd like to
move more of the data into the base class.  However, because gdb
supports Cygwin and gdbserver does not, and because I don't have a way
to build or test Cygwin, larger refactorings are difficult.
2022-06-07 11:44:53 -06:00
Tom Tromey
bcb9251f02 Allow ASLR to be disabled on Windows
On Windows, it is possible to disable ASLR when creating a process.
This patch adds code to do this, and hooks it up to gdb's existing
disable-randomization feature.  Because the Windows documentation
cautions that this isn't available on all versions of Windows, the
CreateProcess wrapper function is updated to make the attempt, and
then fall back to the current approach if it fails.
2022-06-07 09:59:41 -06:00
Tom Tromey
8fea1a81c7 Introduce wrapper for CreateProcess
This is a small refactoring that introduces a wrapper for the Windows
CreateProcess function.  This is done to make the next patch a bit
simpler.
2022-06-07 09:59:40 -06:00
John Baldwin
0ee6b1c511 Use aarch64_features to describe register features in target descriptions.
Replace the sve bool member of aarch64_features with a vq member that
holds the vector quotient.  It is zero if SVE is not present.

Add std::hash<> specialization and operator== so that aarch64_features
can be used as a key with std::unordered_map<>.

Change the various functions that create or lookup aarch64 target
descriptions to accept a const aarch64_features object rather than a
growing number of arguments.

Replace the multi-dimension tdesc_aarch64_list arrays used to cache
target descriptions with unordered_maps indexed by aarch64_feature.
2022-05-18 13:32:04 -07:00
Tom Tromey
fcab58390f Implement pid_to_exec_file for Windows in gdbserver
I noticed that gdbserver did not implement pid_to_exec_file for
Windows, while gdb did implement it.  This patch moves the code to
nat/windows-nat.c, so that it can be shared.  This makes the gdbserver
implementation trivial.
2022-05-13 08:21:16 -06:00
Tom Tromey
4eab18b566 Remove windows_process_info::id
I noticed that windows_process_info::id is only used by gdbserver, and
not really necessary.  This patch removes it.
2022-05-13 08:21:16 -06:00
Luis Machado
d8a7353308 Fix build failure for aarch64 gdbserver
We're missing an argument.
2022-05-04 15:36:47 +01:00
Pedro Alves
5890af36e5 Fix GDBserver Aarch64 Linux regression
Luis noticed that the recent changes to gdbserver to make it track
process and threads independently regressed a few gdb.multi/*.exp
tests for aarch64-linux.

We started seeing the following internal error for
gdb.multi/multi-target-continue.exp for example:

 Starting program: binutils-gdb/gdb/testsuite/outputs/gdb.multi/multi-target-continue/multi-target-continue ^M
 Error in re-setting breakpoint 2: Remote connection closed^M
 ../../../repos/binutils-gdb/gdb/thread.c:85: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed.^M
 A problem internal to GDB has been detected,^M
 further debugging may prove unreliable.

A backtrace looks like:

 #0  thread_regcache_data (thread=thread@entry=0x0) at ../../../repos/binutils-gdb/gdbserver/inferiors.cc:120
 #1  0x0000aaaaaaabf0e8 in get_thread_regcache (thread=0x0, fetch=fetch@entry=0) at ../../../repos/binutils-gdb/gdbserver/regcache.cc:31
 #2  0x0000aaaaaaad785c in is_64bit_tdesc () at ../../../repos/binutils-gdb/gdbserver/linux-aarch64-low.cc:194
 #3  0x0000aaaaaaad8a48 in aarch64_target::sw_breakpoint_from_kind (this=<optimized out>, kind=4, size=0xffffffffef04) at ../../../repos/binutils-gdb/gdbserver/linux-aarch64-low.cc:3226
 #4  0x0000aaaaaaabe220 in bp_size (bp=0xaaaaaab6f3d0) at ../../../repos/binutils-gdb/gdbserver/mem-break.cc:226
 #5  check_mem_read (mem_addr=187649984471104, buf=buf@entry=0xaaaaaab625d0 "\006", mem_len=mem_len@entry=56) at ../../../repos/binutils-gdb/gdbserver/mem-break.cc:1862
 #6  0x0000aaaaaaacc660 in read_inferior_memory (memaddr=<optimized out>, myaddr=0xaaaaaab625d0 "\006", len=56) at ../../../repos/binutils-gdb/gdbserver/target.cc:93
 #7  0x0000aaaaaaac3d9c in gdb_read_memory (len=56, myaddr=0xaaaaaab625d0 "\006", memaddr=187649984471104) at ../../../repos/binutils-gdb/gdbserver/server.cc:1071
 #8  gdb_read_memory (memaddr=187649984471104, myaddr=0xaaaaaab625d0 "\006", len=56) at ../../../repos/binutils-gdb/gdbserver/server.cc:1048
 #9  0x0000aaaaaaac82a4 in process_serial_event () at ../../../repos/binutils-gdb/gdbserver/server.cc:4307
 #10 handle_serial_event (err=<optimized out>, client_data=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:4520
 #11 0x0000aaaaaaafbcd0 in gdb_wait_for_event (block=block@entry=1) at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:700
 #12 0x0000aaaaaaafc0b0 in gdb_wait_for_event (block=1) at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:596
 #13 gdb_do_one_event () at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:237
 #14 0x0000aaaaaaacacb0 in start_event_loop () at ../../../repos/binutils-gdb/gdbserver/server.cc:3518
 #15 captured_main (argc=4, argv=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:3998
 #16 0x0000aaaaaaab66dc in main (argc=<optimized out>, argv=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:4084

This sequence of functions is invoked due to a series of conditions:

 1 - The probe-based breakpoint mechanism failed (for some reason) so ...

 2 - ... gdbserver has to know what type of architecture it is dealing
     with so it can pick the right breakpoint kind, so it wants to
     check if we have a 64-bit target.

 3 - To determine the size of a register, we currently fetch the
     current thread's register cache, and the current thread pointer
     is now nullptr.

In #3, the current thread is nullptr because gdb_read_memory clears it
on purpose, via set_desired_process, exactly to expose code relying on
the current thread when it shouldn't.  It was always possible to end
up in this situation (when the current thread exits), but it was
harder to reproduce before.

This commit fixes it by tweaking is_64bit_tdesc to look at the current
process's tdesc instead of the current thread's tdesc.

Note that the thread's tdesc is itself filled from the process's
tdesc, so this should be equivalent:

 struct regcache *
 get_thread_regcache (struct thread_info *thread, int fetch)
 {
   struct regcache *regcache;

   regcache = thread_regcache_data (thread);

 ...
   if (regcache == NULL)
     {
       struct process_info *proc = get_thread_process (thread);

       gdb_assert (proc->tdesc != NULL);

       regcache = new_register_cache (proc->tdesc);
       set_thread_regcache_data (thread, regcache);
     }
 ...

Change-Id: Ibc809d7345e70a2f058b522bdc5cdbdca97e2cdc
2022-05-04 14:42:58 +01:00
John Baldwin
24ef0d41ac gdbserver: Fix build after adding tls feature to arm tdesc. 2022-05-03 21:38:12 -07:00
John Baldwin
9c27bc99e4 gdbserver: Read the tpidr register from NT_ARM_TLS on Linux. 2022-05-03 16:05:10 -07:00
John Baldwin
414d5848bb Add an aarch64-tls feature which includes the tpidr register. 2022-05-03 16:05:10 -07:00
Pedro Alves
7f8acedeeb gdbserver: track current process as well as current thread
The recent commit 421490af33 ("gdbserver/linux: Access memory even
if threads are running") caused a regression in
gdb.threads/access-mem-running-thread-exit.exp with gdbserver, which I
somehow missed.  Like so:

 (gdb) print global_var
 Cannot access memory at address 0x555555558010
 (gdb) FAIL: gdb.threads/access-mem-running-thread-exit.exp: non-stop: access mem (print global_var after writing, inf=2, iter=1)

The problem starts with GDB telling GDBserver to select a thread, via
the Hg packet, which GDBserver complies with, then that thread exits,
and GDB, without knowing the thread is gone, tries to write to memory,
through the context of the previously selected Hg thread.

GDBserver's GDB-facing memory access routines, gdb_read_memory and
gdb_write_memory, call set_desired_thread to make GDBserver re-select
the thread that GDB has selected with the Hg packet.  Since the thread
is gone, set_desired_thread returns false, and the memory access
fails.

Now, to access memory, it doesn't really matter which thread is
selected.  All we should need is the target process.  Even if the
thread that GDB previously selected is gone, and GDB does not yet know
about that exit, it shouldn't matter, GDBserver should still know
which process that thread belonged to.

Fix this by making GDBserver track the current process separately,
like GDB also does.  Add a new set_desired_process routine that is
similar to set_desired_thread, but just sets the current process,
leaving the current thread as NULL.  Use it in the GDB-facing memory
read and write routines, to avoid failing if the selected thread is
gone, but the process is still around.

Change-Id: I4ff97cb6f42558efbed224b30d5c71f6112d44cd
2022-05-03 15:10:22 +01:00
Tom Tromey
fc0b8a976d Fix libinproctrace.so build on PPC
The recent gnulib import caused a build failure of libinproctrace.so
on PPC:

    alloc.c:(.text+0x20): undefined reference to `rpl_malloc'
    alloc.c:(.text+0x70): undefined reference to `rpl_realloc'

This patch fixes the problem using the same workaround that was
previously used for free.
2022-04-28 12:47:11 -06:00
Tom Tromey
801eb70f9a Fix gdbserver build for x86-64 Windows
I broke the gdbserver build on x86-64 Windows a little while back.
Previously, I could not build this configuration, but today I found
out that if I configure with:

    --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32

using the Fedora 34 tools, it will in fact build.  I'm not certain,
but maybe the gnulib update helped with this.

This patch fixes the build.  I'm checking it in.
2022-04-27 10:45:10 -06:00
Simon Marchi
f551c8ef32 gdbserver/linux: free process_info_private and arch_process_info when failing to attach
Running

  $ ../gdbserver/gdbserver --once --attach :1234 539436

with ASan while /proc/sys/kernel/yama/ptrace_scope is set to 1 (prevents
attaching) shows that we fail to free some platform-specific objects
tied to the process_info (process_info_private and arch_process_info):

    Direct leak of 32 byte(s) in 1 object(s) allocated from:
        #0 0x7f6b558b3fb9 in __interceptor_calloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x562eaf15d04a in xcalloc /home/simark/src/binutils-gdb/gdbserver/../gdb/alloc.c:100
        #2 0x562eaf251548 in xcnew<process_info_private> /home/simark/src/binutils-gdb/gdbserver/../gdbsupport/poison.h:122
        #3 0x562eaf22810c in linux_process_target::add_linux_process_no_mem_file(int, int) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:426
        #4 0x562eaf22d33f in linux_process_target::attach(unsigned long) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:1132
        #5 0x562eaf1a7222 in attach_inferior /home/simark/src/binutils-gdb/gdbserver/server.cc:308
        #6 0x562eaf1c1016 in captured_main /home/simark/src/binutils-gdb/gdbserver/server.cc:3949
        #7 0x562eaf1c1d60 in main /home/simark/src/binutils-gdb/gdbserver/server.cc:4084
        #8 0x7f6b552f630f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)

    Indirect leak of 56 byte(s) in 1 object(s) allocated from:
        #0 0x7f6b558b3fb9 in __interceptor_calloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x562eaf15d04a in xcalloc /home/simark/src/binutils-gdb/gdbserver/../gdb/alloc.c:100
        #2 0x562eaf2a0d79 in xcnew<arch_process_info> /home/simark/src/binutils-gdb/gdbserver/../gdbsupport/poison.h:122
        #3 0x562eaf295e2c in x86_target::low_new_process() /home/simark/src/binutils-gdb/gdbserver/linux-x86-low.cc:723
        #4 0x562eaf22819b in linux_process_target::add_linux_process_no_mem_file(int, int) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:428
        #5 0x562eaf22d33f in linux_process_target::attach(unsigned long) /home/simark/src/binutils-gdb/gdbserver/linux-low.cc:1132
        #6 0x562eaf1a7222 in attach_inferior /home/simark/src/binutils-gdb/gdbserver/server.cc:308
        #7 0x562eaf1c1016 in captured_main /home/simark/src/binutils-gdb/gdbserver/server.cc:3949
        #8 0x562eaf1c1d60 in main /home/simark/src/binutils-gdb/gdbserver/server.cc:4084
        #9 0x7f6b552f630f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)

Those objects are deleted by linux_process_target::mourn, but that is
not called if we fail to attach, we only call remove_process.  I
initially fixed this by making linux_process_target::attach call
linux_process_target::mourn on failure (before calling error).  But this
isn't done anywhere else (including in GDB) so it would just be
confusing to do things differently here.

Instead, add a linux_process_target::remove_linux_process helper method
(which calls remove_process), and call that instead of remove_process in
the Linux target.  Move the free-ing of the extra data from the mourn
method to that new method.

Change-Id: I277059a69d5f08087a7f3ef0b8f1792a1fcf7a85
2022-04-22 14:04:36 -04:00
Simon Marchi
7ab2607f97 gdbsupport: make gdb_abspath return an std::string
I'm trying to switch these functions to use std::string instead of char
arrays, as much as possible.  Some callers benefit from it (can avoid
doing a copy of the result), while others suffer (have to make one more
copy).

Change-Id: Iced49b8ee2f189744c5072a3b217aab5af17a993
2022-04-18 15:48:03 -04:00
Pedro Alves
8e347faf8f gdbserver: Eliminate prepare_to_access_memory
Given:

 - The prepare_to_access_memory machinery was added for non-stop mode.

 - Only Linux supports non-stop.

 - Linux no longer needs the prepare_to_access_memory machinery.  In
   fact, after the previous patch,
   linux_process_target::prepare_to_access_memory became a nop.

Thus, prepare_to_access_memory can go away, simplifying core GDBserver
code.

Change-Id: I93ac8bfe66bd61c3d1c4a0e7d419335163120ecf
2022-04-14 20:22:56 +01:00
Pedro Alves
421490af33 gdbserver/linux: Access memory even if threads are running
Similarly to how the native Linux target was changed
and subsequently reworked in these commits:

 05c06f318f Linux: Access memory even if threads are running
 8a89ddbda2 Avoid /proc/pid/mem races (PR 28065)

... teach GDBserver to access memory even when the current thread is
running, by always accessing memory via /proc/PID/mem.

The existing comment:

  /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
     running LWP.  */

... is incorrect for /proc/PID/mem does allow that.

Actually, from GDB's perspective, GDBserver could already access
memory while threads were running, but at the expense of pausing all
threads for the duration of the memory access, via
prepare_to_access_memory.  This new implementation does not require
pausing any thread, thus
linux_process_target::prepare_to_access_memory /
linux_process_target::done_accessing_memory become nops.  A subsequent
patch will remove the whole prepare_to_access_memory infrastructure
completely.

The GDBserver linux-low.cc implementation is simpler than GDB's
linux-nat.c's, because GDBserver always adds the unfollowed vfork/fork
children to the process list immediately when the fork/vfork event is
seen out of ptrace.  I.e., there's no need to keep the file descriptor
stored on a side map, we can store it directly in the process
structure.

Change-Id: I0abfd782ceaa4ddce8d3e5f3e2dfc5928862ef61
2022-04-14 20:22:56 +01:00
Pedro Alves
366e3746c5 gdbserver: special case target_write_memory len==0
The next patch in this series adds a common helper routine for both
memory reads and writes, like this:

 static int
 proc_xfer_memory (CORE_ADDR memaddr, unsigned char *readbuf,
		  const gdb_byte *writebuf, int len)
 {
   gdb_assert ((readbuf == nullptr) != (writebuf == nullptr));
   ...
 }

 int
 linux_process_target::read_memory (CORE_ADDR memaddr,
                                    unsigned char *myaddr, int len)
 {
   return proc_xfer_memory (memaddr, myaddr, nullptr, len);
 }

 linux_process_target::write_memory (CORE_ADDR memaddr,
                                    const unsigned char *myaddr, int len)
 {
   return proc_xfer_memory (memaddr, nullptr, myaddr, len);
 }

Surprisingly, the assertion fails.  That happens because it can happen
that target_write_memory is called with LEN==0, due to this in
gdb/remote.c:

 /* Determine whether the remote target supports binary downloading.
    This is accomplished by sending a no-op memory write of zero length
    to the target at the specified address. (...) */

 void
 remote_target::check_binary_download (CORE_ADDR addr)
 {
 ...
       p = rs->buf.data ();
       *p++ = 'X';
       p += hexnumstr (p, (ULONGEST) addr);
       *p++ = ',';
       p += hexnumstr (p, (ULONGEST) 0);
       *p++ = ':';
       *p = '\0';

In this scenario, in gdbserver's target_write_memory, the "myaddr"
argument of the_target->write_memory is passed the data() of a local
gdb::byte_vector (which is a specialized std::vector).  It's valid for
std::vector::data() to return NULL when the vector is empty.

This commit adds an early return to target_write_memory to avoid
target backends having to care about this.  For good measure, do the
same on the read side, in read_inferior_memory.

Change-Id: Iac8f04fcf99014c624ef4036bd318ca1771ad491
2022-04-14 20:22:42 +01:00
Pedro Alves
330d63093c gdbserver/qXfer::threads, prepare_to_access_memory=>target_pause_all
handle_qxfer_threads_proper needs to pause all threads even if the
target can read memory when threads are running, so use
target_pause_all instead, which is what the Linux implementation of
prepare_to_access_memory uses.  (Only Linux implements this hook.)

A following patch will make the Linux backend be able to access memory
when threads are running, and thus will also make
prepare_to_access_memory do nothing, which would cause testsuite
regressions without this change.

Change-Id: I127fec7246b7c45b60dfa7341e781606bf54b5da
2022-04-14 20:21:11 +01:00
Tom Tromey
8bbdbd6985 Use GetThreadDescription on Windows
Windows 10 introduced SetThreadDescription and GetThreadDescription, a
simpler way to set a thread's name.  This changes gdb and gdbserver to
use this convention when it is available.

This is part of PR win32/29050.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29050
2022-04-14 12:12:35 -06:00
Tom Tromey
42a5971407 Implement thread_name for gdbserver
This changes gdbserver to implement thread_name method.
2022-04-14 12:12:34 -06:00