binutils-gdb/gdb/configure.tgt
Simon Marchi 18b4d0736b gdb: initial support for ROCm platform (AMDGPU) debugging
This patch adds the foundation for GDB to be able to debug programs
offloaded to AMD GPUs using the AMD ROCm platform [1].  The latest
public release of the ROCm release at the time of writing is 5.4, so
this is what this patch targets.

The ROCm platform allows host programs to schedule bits of code for
execution on GPUs or similar accelerators.  The programs running on GPUs
are typically referred to as `kernels` (not related to operating system
kernels).

Programs offloaded with the AMD ROCm platform can be written in the HIP
language [2], OpenCL and OpenMP, but we're going to focus on HIP here.
The HIP language consists of a C++ Runtime API and kernel language.
Here's an example of a very simple HIP program:

    #include "hip/hip_runtime.h"
    #include <cassert>

    __global__ void
    do_an_addition (int a, int b, int *out)
    {
      *out = a + b;
    }

    int
    main ()
    {
      int *result_ptr, result;

      /* Allocate memory for the device to write the result to.  */
      hipError_t error = hipMalloc (&result_ptr, sizeof (int));
      assert (error == hipSuccess);

      /* Run `do_an_addition` on one workgroup containing one work item.  */
      do_an_addition<<<dim3(1), dim3(1), 0, 0>>> (1, 2, result_ptr);

      /* Copy result from device to host.  Note that this acts as a synchronization
         point, waiting for the kernel dispatch to complete.  */
      error = hipMemcpyDtoH (&result, result_ptr, sizeof (int));
      assert (error == hipSuccess);

      printf ("result is %d\n", result);
      assert (result == 3);

      return 0;
    }

This program can be compiled with:

    $ hipcc simple.cpp -g -O0 -o simple

... where `hipcc` is the HIP compiler, shipped with ROCm releases.  This
generates an ELF binary for the host architecture, containing another
ELF binary with the device code.  The ELF for the device can be
inspected with:

    $ roc-obj-ls simple
    1       host-x86_64-unknown-linux                                           file://simple#offset=8192&size=0
    1       hipv4-amdgcn-amd-amdhsa--gfx906                                     file://simple#offset=8192&size=34216
    $ roc-obj-extract 'file://simple#offset=8192&size=34216'
    $ file simple-offset8192-size34216.co
    simple-offset8192-size34216.co: ELF 64-bit LSB shared object, *unknown arch 0xe0* version 1, dynamically linked, with debug_info, not stripped
                                                                                 ^
                       amcgcn architecture that my `file` doesn't know about ----´

Running the program gives the very unimpressive result:

    $ ./simple
    result is 3

While running, this host program has copied the device program into the
GPU's memory and spawned an execution thread on it.  The goal of this
GDB port is to let the user debug host threads and these GPU threads
simultaneously.  Here's a sample session using a GDB with this patch
applied:

    $ ./gdb -q -nx --data-directory=data-directory ./simple
    Reading symbols from ./simple...
    (gdb) break do_an_addition
    Function "do_an_addition" not defined.
    Make breakpoint pending on future shared library load? (y or [n]) y
    Breakpoint 1 (do_an_addition) pending.
    (gdb) r
    Starting program: /home/smarchi/build/binutils-gdb-amdgpu/gdb/simple
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    [New Thread 0x7ffff5db7640 (LWP 1082911)]
    [New Thread 0x7ffef53ff640 (LWP 1082913)]
    [Thread 0x7ffef53ff640 (LWP 1082913) exited]
    [New Thread 0x7ffdecb53640 (LWP 1083185)]
    [New Thread 0x7ffff54bf640 (LWP 1083186)]
    [Thread 0x7ffdecb53640 (LWP 1083185) exited]
    [Switching to AMDGPU Wave 2:2:1:1 (0,0,0)/0]

    Thread 6 hit Breakpoint 1, do_an_addition (a=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        b=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        out=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>) at simple.cpp:24
    24        *out = a + b;
    (gdb) info inferiors
      Num  Description       Connection           Executable
    * 1    process 1082907   1 (native)           /home/smarchi/build/binutils-gdb-amdgpu/gdb/simple
    (gdb) info threads
      Id   Target Id                                    Frame
      1    Thread 0x7ffff5dc9240 (LWP 1082907) "simple" 0x00007ffff5e9410b in ?? () from /opt/rocm-5.4.0/lib/libhsa-runtime64.so.1
      2    Thread 0x7ffff5db7640 (LWP 1082911) "simple" __GI___ioctl (fd=3, request=3222817548) at ../sysdeps/unix/sysv/linux/ioctl.c:36
      5    Thread 0x7ffff54bf640 (LWP 1083186) "simple" __GI___ioctl (fd=3, request=3222817548) at ../sysdeps/unix/sysv/linux/ioctl.c:36
    * 6    AMDGPU Wave 2:2:1:1 (0,0,0)/0                do_an_addition (
        a=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        b=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        out=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>) at simple.cpp:24
    (gdb) bt
    Python Exception <class 'gdb.error'>: Unhandled dwarf expression opcode 0xe1
    #0  do_an_addition (a=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        b=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        out=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>) at simple.cpp:24
    (gdb) continue
    Continuing.
    result is 3
    warning: Temporarily disabling breakpoints for unloaded shared library "file:///home/smarchi/build/binutils-gdb-amdgpu/gdb/simple#offset=8192&size=67208"
    [Thread 0x7ffff54bf640 (LWP 1083186) exited]
    [Thread 0x7ffff5db7640 (LWP 1082911) exited]
    [Inferior 1 (process 1082907) exited normally]

One thing to notice is the host and GPU threads appearing under
the same inferior.  This is a design goal for us, as programmers tend to
think of the threads running on the GPU as part of the same program as
the host threads, so showing them in the same inferior in GDB seems
natural.  Also, the host and GPU threads share a global memory space,
which fits the inferior model.

Another thing to notice is the error messages when trying to read
variables or printing a backtrace.  This is expected for the moment,
since the AMD GPU compiler produces some DWARF that uses some
non-standard extensions:

  https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html

There were already some patches posted by Zoran Zaric earlier to make
GDB support these extensions:

  https://inbox.sourceware.org/gdb-patches/20211105113849.118800-1-zoran.zaric@amd.com/

We think it's better to get the basic support for AMD GPU in first,
which will then give a better justification for GDB to support these
extensions.

GPU threads are named `AMDGPU Wave`: a wave is essentially a hardware
thread using the SIMT (single-instruction, multiple-threads) [3]
execution model.

GDB uses the amd-dbgapi library [4], included in the ROCm platform, for
a few things related to AMD GPU threads debugging.  Different components
talk to the library, as show on the following diagram:

    +---------------------------+     +-------------+     +------------------+
    | GDB   | amd-dbgapi target | <-> |     AMD     |     |    Linux kernel  |
    |       +-------------------+     |   Debugger  |     +--------+         |
    |       | amdgcn gdbarch    | <-> |     API     | <=> | AMDGPU |         |
    |       +-------------------+     |             |     | driver |         |
    |       | solib-rocm        | <-> | (dbgapi.so) |     +--------+---------+
    +---------------------------+     +-------------+

  - The amd-dbgapi target is a target_ops implementation used to control
    execution of GPU threads.  While the debugging of host threads works
    by using the ptrace / wait Linux kernel interface (as usual), control
    of GPU threads is done through a special interface (dubbed `kfd`)
    exposed by the `amdgpu` Linux kernel module.  GDB doesn't interact
    directly with `kfd`, but instead goes through the amd-dbgapi library
    (AMD Debugger API on the diagram).

    Since it provides execution control, the amd-dbgapi target should
    normally be a process_stratum_target, not just a target_ops.  More
    on that later.

  - The amdgcn gdbarch (describing the hardware architecture of the GPU
    execution units) offloads some requests to the amd-dbgapi library,
    so that knowledge about the various architectures doesn't need to be
    duplicated and baked in GDB.  This is for example for things like
    the list of registers.

  - The solib-rocm component is an solib provider that fetches the list of
    code objects loaded on the device from the amd-dbgapi library, and
    makes GDB read their symbols.  This is very similar to other solib
    providers that handle shared libraries, except that here the shared
    libraries are the pieces of code loaded on the device.

Given that Linux host threads are managed by the linux-nat target, and
the GPU threads are managed by the amd-dbgapi target, having all threads
appear in the same inferior requires the two targets to be in that
inferior's target stack.  However, there can only be one
process_stratum_target in a given target stack, since there can be only
one target per slot.  To achieve it, we therefore resort the hack^W
solution of placing the amd-dbgapi target in the arch_stratum slot of
the target stack, on top of the linux-nat target.  Doing so allows the
amd-dbgapi target to intercept target calls and handle them if they
concern GPU threads, and offload to beneath otherwise.  See
amd_dbgapi_target::fetch_registers for a simple example:

    void
    amd_dbgapi_target::fetch_registers (struct regcache *regcache, int regno)
    {
      if (!ptid_is_gpu (regcache->ptid ()))
        {
          beneath ()->fetch_registers (regcache, regno);
          return;
        }

      // handle it
    }

ptids of GPU threads are crafted with the following pattern:

  (pid, 1, wave id)

Where pid is the inferior's pid and "wave id" is the wave handle handed
to us by the amd-dbgapi library (in practice, a monotonically
incrementing integer).  The idea is that on Linux systems, the
combination (pid != 1, lwp == 1) is not possible.  lwp == 1 would always
belong to the init process, which would also have pid == 1 (and it's
improbable for the init process to offload work to the GPU and much less
for the user to debug it).  We can therefore differentiate GPU and
non-GPU ptids this way.  See ptid_is_gpu for more details.

Note that we believe that this scheme could break down in the context of
containers, where the initial process executed in a container has pid 1
(in its own pid namespace).  For instance, if you were to execute a ROCm
program in a container, then spawn a GDB in that container and attach to
the process, it will likely not work.  This is a known limitation.  A
workaround for this is to have a dummy process (like a shell) fork and
execute the program of interest.

The amd-dbgapi target watches native inferiors, and "attaches" to them
using amd_dbgapi_process_attach, which gives it a notifier fd that is
registered in the event loop (see enable_amd_dbgapi).  Note that this
isn't the same "attach" as in PTRACE_ATTACH, but being ptrace-attached
is a precondition for amd_dbgapi_process_attach to work.  When the
debugged process enables the ROCm runtime, the amd-dbgapi target gets
notified through that fd, and pushes itself on the target stack of the
inferior.  The amd-dbgapi target is then able to intercept target_ops
calls.  If the debugged process disables the ROCm runtime, the
amd-dbgapi target unpushes itself from the target stack.

This way, the amd-dbgapi target's footprint stays minimal when debugging
a process that doesn't use the AMD ROCm platform, it does not intercept
target calls.

The amd-dbgapi library is found using pkg-config.  Since enabling
support for the amdgpu architecture (amdgpu-tdep.c) depends on the
amd-dbgapi library being present, we have the following logic for
the interaction with --target and --enable-targets:

 - if the user explicitly asks for amdgcn support with
   --target=amdgcn-*-* or --enable-targets=amdgcn-*-*, we probe for
   the amd-dbgapi and fail if not found

 - if the user uses --enable-targets=all, we probe for amd-dbgapi,
   enable amdgcn support if found, disable amdgcn support if not found

 - if the user uses --enable-targets=all and --with-amd-dbgapi=yes,
   we probe for amd-dbgapi, enable amdgcn if found and fail if not found

 - if the user uses --enable-targets=all and --with-amd-dbgapi=no,
   we do not probe for amd-dbgapi, disable amdgcn support

 - otherwise, amd-dbgapi is not probed for and support for amdgcn is not
   enabled

Finally, a simple test is included.  It only tests hitting a breakpoint
in device code and resuming execution, pretty much like the example
shown above.

[1] https://docs.amd.com/category/ROCm_v5.4
[2] https://docs.amd.com/bundle/HIP-Programming-Guide-v5.4
[3] https://en.wikipedia.org/wiki/Single_instruction,_multiple_threads
[4] https://docs.amd.com/bundle/ROCDebugger-API-Guide-v5.4

Change-Id: I591edca98b8927b1e49e4b0abe4e304765fed9ee
Co-Authored-By: Zoran Zaric <zoran.zaric@amd.com>
Co-Authored-By: Laurent Morichetti <laurent.morichetti@amd.com>
Co-Authored-By: Tony Tye <Tony.Tye@amd.com>
Co-Authored-By: Lancelot SIX <lancelot.six@amd.com>
Co-Authored-By: Pedro Alves <pedro@palves.net>
2023-02-02 10:02:34 -05:00

827 lines
20 KiB
Plaintext

# Mappings from configurations to GDB target definitions. This is
# invoked from the autoconf generated configure script.
# This file sets the following shell variables:
# gdb_target_obs target-specific object files to use
# gdb_sim simulator library for target
# gdb_osabi default OS ABI to use with target
# gdb_have_gcore set to "true"/"false" if this target can run gcore
# gdb_require_amd_dbgapi set to "true" if this target requires the amd-dbgapi
# target
# NOTE: Every file added to a gdb_target_obs variable for any target here
# must also be added to either:
#
# - ALL_TARGET_OBS
# - ALL_64_TARGET_OBS
# - ALL_AMD_DBGAPI_TARGET_OBS
#
# in Makefile.in!
case $targ in
*-*-irix* | \
*-*-solaris2.[01] | *-*-solaris2.[2-9]* | *-*-solaris2.10* | \
*-*-netbsdpe* | \
alpha*-*-osf* | \
alpha*-*-freebsd* | \
alpha*-*-kfreebsd*-gnu | \
d10v-*-* | \
hppa*-*-hiux* | \
i[34567]86-ncr-* | \
m68*-cisco*-* | \
m68*-tandem-* | \
m68*-*-os68k* | \
mips*-*-pe | \
rs6000-*-lynxos* | \
score-*-* | \
sh*-*-pe | \
hppa*-*-hpux* | \
ia64-*-hpux* | \
*-*-vxworks* | \
mt-*-* | \
null)
echo "*** Configuration $targ is obsolete." >&2
echo "*** Support has been REMOVED." >&2
exit 1
;;
esac
x86_tobjs="x86-tdep.o"
i386_tobjs="i386-tdep.o arch/i386.o i387-tdep.o ${x86_tobjs}"
amd64_tobjs="ravenscar-thread.o amd64-ravenscar-thread.o \
amd64-tdep.o arch/amd64.o ${x86_tobjs}"
# Here are three sections to get a list of target specific object
# files according to target triplet $TARG.
# 1. Get the objects per cpu in $TARG.
case "${targ}" in
aarch64*-*-*)
cpu_obs="aarch32-tdep.o aarch64-tdep.o arch/aarch32.o \
arch/aarch64-insn.o arch/aarch64.o ravenscar-thread.o \
aarch64-ravenscar-thread.o";;
alpha*-*-*)
# Target: Alpha
cpu_obs="alpha-tdep.o"
;;
arc*-*-*)
# Target: Unidentified ARC target
cpu_obs="arc-tdep.o arch/arc.o"
;;
arm*-*-*)
cpu_obs="aarch32-tdep.o arch/aarch32.o arch/arm.o \
arch/arm-get-next-pcs.o arm-tdep.o arm-none-tdep.o"
;;
hppa*-*-*)
# Target: HP PA-RISC
cpu_obs="hppa-tdep.o"
;;
i[34567]86-*-*)
cpu_obs="${i386_tobjs}"
if test "x$enable_64_bit_bfd" = "xyes"; then
cpu_obs="${amd64_tobjs} ${cpu_obs}"
fi
;;
ia16*-*-*)
# Target: Intel IA-16
cpu_obs="${i386_tobjs}"
;;
ia64*-*-*)
# Target: Intel IA-64
cpu_obs="ia64-tdep.o"
;;
loongarch*-*-*)
# Target: LoongArch baremetal
cpu_obs="loongarch-tdep.o arch/loongarch.o"
;;
riscv*-*-*)
cpu_obs="riscv-tdep.o riscv-none-tdep.o arch/riscv.o \
ravenscar-thread.o riscv-ravenscar-thread.o";;
x86_64-*-*)
cpu_obs="${i386_tobjs} ${amd64_tobjs}";;
xtensa*)
# Target: Tensilica Xtensa processors
cpu_obs="xtensa-tdep.o xtensa-config.o solib-svr4.o"
;;
esac
# 2. Get the objects per os in $TARG.
case "${targ}" in
*-*-freebsd* | *-*-kfreebsd*-gnu)
os_obs="fbsd-tdep.o solib-svr4.o";;
*-*-netbsd* | *-*-knetbsd*-gnu)
os_obs="netbsd-tdep.o solib-svr4.o";;
*-*-openbsd*)
os_obs="obsd-tdep.o solib-svr4.o";;
esac
# 3. Get the rest of objects.
case "${targ}" in
aarch64*-*-elf | aarch64*-*-rtems*)
# Target: AArch64 embedded system
gdb_target_obs="aarch64-newlib-tdep.o"
;;
aarch64*-*-freebsd*)
# Target: FreeBSD/aarch64
gdb_target_obs="aarch64-fbsd-tdep.o"
;;
aarch64*-*-linux*)
# Target: AArch64 linux
gdb_target_obs="aarch64-linux-tdep.o arch/aarch64.o\
arch/aarch64-mte-linux.o \
arch/arm.o arch/arm-linux.o arch/arm-get-next-pcs.o \
arm-tdep.o arm-linux-tdep.o \
glibc-tdep.o linux-tdep.o solib-svr4.o \
symfile-mem.o linux-record.o"
;;
alpha*-*-linux*)
# Target: Little-endian Alpha running Linux
gdb_target_obs="alpha-mdebug-tdep.o alpha-linux-tdep.o \
linux-tdep.o solib-svr4.o"
;;
alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu)
# Target: NetBSD/alpha
gdb_target_obs="alpha-mdebug-tdep.o alpha-bsd-tdep.o \
alpha-netbsd-tdep.o"
;;
alpha*-*-openbsd*)
# Target: OpenBSD/alpha
gdb_target_obs="alpha-mdebug-tdep.o alpha-bsd-tdep.o \
alpha-netbsd-tdep.o alpha-obsd-tdep.o netbsd-tdep.o"
;;
amdgcn*-*-*)
# Target: AMDGPU
gdb_require_amd_dbgapi=true
gdb_target_obs="amdgpu-tdep.o solib-rocm.o"
;;
am33_2.0*-*-linux*)
# Target: Matsushita mn10300 (AM33) running Linux
gdb_target_obs="mn10300-tdep.o mn10300-linux-tdep.o linux-tdep.o \
solib-svr4.o"
;;
arc*-*-elf32)
# Target: baremetal ARC elf32 (newlib) target
gdb_target_obs="arc-newlib-tdep.o"
;;
arc*-*-linux*)
# Target: ARC machine running Linux
gdb_target_obs="arc-linux-tdep.o linux-tdep.o solib-svr4.o"
;;
arm*-wince-pe | arm*-*-mingw32ce*)
# Target: ARM based machine running Windows CE (win32)
gdb_target_obs="arm-wince-tdep.o windows-tdep.o"
;;
arm*-*-linux*)
# Target: ARM based machine running GNU/Linux
gdb_target_obs="arch/arm-linux.o arm-linux-tdep.o glibc-tdep.o \
solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o"
;;
arm*-*-freebsd*)
# Target: FreeBSD/arm
gdb_target_obs="arm-fbsd-tdep.o"
;;
arm*-*-netbsd* | arm*-*-knetbsd*-gnu)
# Target: NetBSD/arm
gdb_target_obs="arm-netbsd-tdep.o"
;;
arm*-*-openbsd*)
# Target: OpenBSD/arm
gdb_target_obs="arm-bsd-tdep.o arm-obsd-tdep.o"
;;
arm*-*-*)
# Target: ARM embedded system
gdb_target_obs="arm-pikeos-tdep.o"
;;
avr-*-*)
# Target: AVR
gdb_target_obs="avr-tdep.o"
;;
bfin-*-*linux*)
# Target: Blackfin Linux
gdb_target_obs="bfin-tdep.o bfin-linux-tdep.o linux-tdep.o"
;;
bfin-*-*)
# Target: Blackfin processor
gdb_target_obs="bfin-tdep.o"
;;
bpf-*-*)
# Target: eBPF
gdb_target_obs="bpf-tdep.o"
;;
cris*)
# Target: CRIS
gdb_target_obs="cris-tdep.o cris-linux-tdep.o linux-tdep.o solib-svr4.o"
;;
csky*-*-linux*)
# Target: CSKY running GNU/Linux
gdb_target_obs="csky-tdep.o csky-linux-tdep.o glibc-tdep.o \
linux-tdep.o solib-svr4.o"
;;
csky*-*-*)
# Target: CSKY bare metal
gdb_target_obs="csky-tdep.o"
;;
frv-*-*)
# Target: Fujitsu FRV processor
gdb_target_obs="frv-tdep.o frv-linux-tdep.o linux-tdep.o solib-frv.o"
;;
moxie-*-elf | moxie-*-moxiebox | moxie-*-rtems*)
gdb_target_obs="moxie-tdep.o"
;;
h8300-*-*)
# Target: H8300 processor
gdb_target_obs="h8300-tdep.o"
;;
hppa*-*-linux*)
# Target: HP PA-RISC running Linux
gdb_target_obs="hppa-linux-tdep.o glibc-tdep.o \
linux-tdep.o solib-svr4.o symfile-mem.o"
;;
hppa*-*-netbsd*)
# Target: NetBSD/hppa
gdb_target_obs="hppa-bsd-tdep.o hppa-netbsd-tdep.o solib-svr4.o"
;;
hppa*-*-openbsd*)
# Target: OpenBSD/hppa
gdb_target_obs="hppa-bsd-tdep.o hppa-obsd-tdep.o solib-svr4.o"
;;
i[34567]86-*-darwin*)
# Target: Darwin/i386
gdb_target_obs="i386-darwin-tdep.o solib-darwin.o"
if test "x$enable_64_bit_bfd" = "xyes"; then
# Target: GNU/Linux x86-64
gdb_target_obs="amd64-darwin-tdep.o ${gdb_target_obs}"
fi
;;
i[34567]86-*-dicos*)
# Target: DICOS/i386
gdb_target_obs="dicos-tdep.o i386-dicos-tdep.o"
;;
i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
# Target: FreeBSD/i386
gdb_target_obs="i386-bsd-tdep.o i386-fbsd-tdep.o "
;;
i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
# Target: NetBSD/i386
gdb_target_obs="i386-bsd-tdep.o i386-netbsd-tdep.o "
;;
i[34567]86-*-openbsd*)
# Target: OpenBSD/i386
gdb_target_obs="i386-bsd-tdep.o i386-obsd-tdep.o bsd-uthread.o"
;;
i[34567]86-*-nto*)
# Target: Intel 386 running qnx6.
gdb_target_obs="solib-svr4.o \
i386-nto-tdep.o nto-tdep.o"
;;
i[34567]86-*-solaris2* | x86_64-*-solaris2*)
# Target: Solaris x86_64
gdb_target_obs="${i386_tobjs} ${amd64_tobjs} \
amd64-sol2-tdep.o i386-sol2-tdep.o sol2-tdep.o \
solib-svr4.o"
;;
i[34567]86-*-linux*)
# Target: Intel 386 running GNU/Linux
gdb_target_obs="i386-linux-tdep.o \
glibc-tdep.o \
solib-svr4.o symfile-mem.o \
linux-tdep.o linux-record.o"
if test "x$enable_64_bit_bfd" = "xyes"; then
# Target: GNU/Linux x86-64
gdb_target_obs="amd64-linux-tdep.o ${gdb_target_obs}"
fi
;;
i[34567]86-*-gnu*)
# Target: Intel 386 running the GNU Hurd
gdb_target_obs="i386-gnu-tdep.o solib-svr4.o"
;;
i[34567]86-*-cygwin*)
# Target: Intel 386 running win32
gdb_target_obs="i386-windows-tdep.o windows-tdep.o"
;;
i[34567]86-*-mingw32*)
# Target: Intel 386 running win32
gdb_target_obs="i386-windows-tdep.o windows-tdep.o"
;;
i[34567]86-*-go32* | i[34567]86-*-msdosdjgpp*)
# Target: i386 running DJGPP/go32.
gdb_target_obs="i386-go32-tdep.o"
;;
ia64-*-linux*)
# Target: Intel IA-64 running GNU/Linux
gdb_target_obs="ia64-linux-tdep.o linux-tdep.o \
solib-svr4.o symfile-mem.o"
;;
ia64-*-*vms*)
# Target: Intel IA-64 running OpenVMS
gdb_target_obs="ia64-vms-tdep.o"
;;
iq2000-*-*)
gdb_target_obs="iq2000-tdep.o"
;;
lm32-*-*)
gdb_target_obs="lm32-tdep.o"
;;
loongarch*-*-linux*)
# Target: LoongArch running Linux
gdb_target_obs="loongarch-linux-tdep.o glibc-tdep.o \
linux-tdep.o solib-svr4.o"
;;
m32c-*-*)
# Target: Renesas M32C family
gdb_target_obs="m32c-tdep.o"
;;
m32r*-*-linux*)
# Target: Renesas M32R running GNU/Linux
gdb_target_obs="m32r-tdep.o m32r-linux-tdep.o \
glibc-tdep.o solib-svr4.o symfile-mem.o \
linux-tdep.o"
;;
m32r*-*-*)
# Target: Renesas m32r processor
gdb_target_obs="m32r-tdep.o"
;;
m68hc11*-*-*|m6811*-*-*)
# Target: Motorola 68HC11 processor
gdb_target_obs="m68hc11-tdep.o"
;;
m68*-*-aout* | m68*-*-coff* | m68*-*-elf* | m68*-*-rtems* | m68*-*-uclinux* | \
fido-*-elf*)
# Target: Motorola m68k embedded
gdb_target_obs="m68k-tdep.o"
;;
m68*-*-linux*)
# Target: Motorola m68k with a.out and ELF
gdb_target_obs="m68k-tdep.o m68k-linux-tdep.o solib-svr4.o \
linux-tdep.o glibc-tdep.o symfile-mem.o"
;;
m68*-*-netbsd* | m68*-*-knetbsd*-gnu)
# Target: NetBSD/m68k
gdb_target_obs="m68k-tdep.o m68k-bsd-tdep.o"
;;
m68*-*-openbsd*)
# Target: OpenBSD/m68k
gdb_target_obs="m68k-tdep.o m68k-bsd-tdep.o"
;;
mep-*-*)
# Target: Toshiba Media Processor (MEP)
gdb_target_obs="mep-tdep.o"
# No sim needed. Target uses SID.
;;
microblaze*-linux-*|microblaze*-*-linux*)
# Target: Xilinx MicroBlaze running Linux
gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o solib-svr4.o \
symfile-mem.o linux-tdep.o"
;;
microblaze*-*-*)
# Target: Xilinx MicroBlaze running standalone
gdb_target_obs="microblaze-tdep.o"
;;
mips*-*-linux*)
# Target: Linux/MIPS
gdb_target_obs="mips-tdep.o mips-linux-tdep.o glibc-tdep.o \
solib-svr4.o symfile-mem.o linux-tdep.o"
;;
mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
# Target: MIPS running NetBSD
gdb_target_obs="mips-tdep.o mips-netbsd-tdep.o"
;;
mips*-*-freebsd*)
# Target: MIPS running FreeBSD
gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o"
;;
mips64*-*-openbsd*)
# Target: OpenBSD/mips64
gdb_target_obs="mips-tdep.o mips64-obsd-tdep.o"
;;
mips*-sde*-elf*)
# Target: MIPS SDE
gdb_target_obs="mips-tdep.o mips-sde-tdep.o"
;;
mips*-*-elf)
# Target: MIPS ELF
gdb_target_obs="mips-tdep.o"
;;
mips*-*-*)
# Target: MIPS
gdb_target_obs="mips-tdep.o"
;;
mn10300-*-*)
# Target: Matsushita mn10300
gdb_target_obs="mn10300-tdep.o"
;;
msp430-*-elf*)
gdb_target_obs="msp430-tdep.o"
;;
nds32*-*-elf)
# Target: AndesTech NDS32 core
gdb_target_obs="nds32-tdep.o"
;;
nios2*-*-linux*)
# Target: Altera Nios II running Linux
gdb_target_obs="nios2-tdep.o nios2-linux-tdep.o solib-svr4.o \
symfile-mem.o glibc-tdep.o linux-tdep.o"
;;
nios2*-*-*)
# Target: Altera Nios II bare-metal
gdb_target_obs="nios2-tdep.o"
;;
or1k*-*-linux*)
# Target: OpenCores OpenRISC 1000 32-bit running Linux
gdb_target_obs="or1k-tdep.o or1k-linux-tdep.o solib-svr4.o \
symfile-mem.o glibc-tdep.o linux-tdep.o"
;;
or1k-*-* | or1knd-*-*)
# Target: OpenCores OpenRISC 1000 32-bit implementation bare metal
gdb_target_obs="or1k-tdep.o"
;;
powerpc*-*-freebsd*)
# Target: FreeBSD/powerpc
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
ppc-fbsd-tdep.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
# Target: NetBSD/powerpc
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc-netbsd-tdep.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
powerpc-*-openbsd*)
# Target: OpenBSD/powerpc
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc-obsd-tdep.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
# Target: PowerPC running AIX
gdb_target_obs="rs6000-tdep.o rs6000-aix-tdep.o xcoffread.o \
ppc-sysv-tdep.o solib-aix.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
powerpc*-*-linux*)
# Target: PowerPC running Linux
gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \
ppc64-tdep.o solib-svr4.o \
glibc-tdep.o symfile-mem.o linux-tdep.o \
ravenscar-thread.o ppc-ravenscar-thread.o \
linux-record.o \
arch/ppc-linux-common.o"
;;
powerpc-*-lynx*178)
# Target: PowerPC running Lynx178.
gdb_target_obs="rs6000-tdep.o rs6000-lynx178-tdep.o \
xcoffread.o ppc-sysv-tdep.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
powerpc*-*-*)
# Target: PowerPC running eabi
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o solib-svr4.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
s390*-*-linux*)
# Target: S390 running Linux
gdb_target_obs="s390-linux-tdep.o s390-tdep.o solib-svr4.o \
linux-tdep.o linux-record.o symfile-mem.o"
;;
riscv*-*-freebsd*)
# Target: FreeBSD/riscv
gdb_target_obs="riscv-fbsd-tdep.o"
;;
riscv*-*-linux*)
# Target: Linux/RISC-V
gdb_target_obs="riscv-linux-tdep.o glibc-tdep.o \
linux-tdep.o solib-svr4.o symfile-mem.o linux-record.o"
;;
riscv*-*-*)
# Target: RISC-V architecture
gdb_target_obs=""
;;
rl78-*-elf)
# Target: Renesas rl78
gdb_target_obs="rl78-tdep.o"
;;
rx-*-*)
# Target: Renesas RX
gdb_target_obs="rx-tdep.o"
;;
sh*-*-linux*)
# Target: GNU/Linux Super-H
gdb_target_obs="sh-tdep.o sh-linux-tdep.o \
solib-svr4.o symfile-mem.o \
glibc-tdep.o linux-tdep.o"
;;
sh*-*-netbsd* | sh*-*-knetbsd*-gnu)
# Target: NetBSD/sh
gdb_target_obs="sh-tdep.o sh-netbsd-tdep.o"
;;
sh*-*-openbsd*)
# Target: OpenBSD/sh
gdb_target_obs="sh-tdep.o sh-netbsd-tdep.o"
;;
sh*)
# Target: Embedded Renesas Super-H processor
gdb_target_obs="sh-tdep.o"
;;
sparc-*-linux*)
# Target: GNU/Linux SPARC
gdb_target_obs="sparc-tdep.o \
sparc-linux-tdep.o solib-svr4.o symfile-mem.o \
linux-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
if test "x$enable_64_bit_bfd" = "xyes"; then
# Target: GNU/Linux UltraSPARC
gdb_target_obs="sparc64-tdep.o \
sparc64-linux-tdep.o ${gdb_target_obs}"
fi
;;
sparc64-*-linux*)
# Target: GNU/Linux UltraSPARC
gdb_target_obs="sparc64-tdep.o \
sparc64-linux-tdep.o sparc-tdep.o \
sparc-linux-tdep.o solib-svr4.o linux-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
# Target: FreeBSD/sparc64
gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64-fbsd-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
# Target: NetBSD/sparc
gdb_target_obs="sparc-tdep.o sparc-netbsd-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu)
# Target: NetBSD/sparc64
gdb_target_obs="sparc64-tdep.o sparc64-netbsd-tdep.o sparc-tdep.o \
sparc-netbsd-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-openbsd*)
# Target: OpenBSD/sparc
gdb_target_obs="sparc-tdep.o sparc-netbsd-tdep.o sparc-obsd-tdep.o \
netbsd-tdep.o bsd-uthread.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc64-*-openbsd*)
# Target: OpenBSD/sparc64
gdb_target_obs="sparc64-tdep.o sparc64-netbsd-tdep.o sparc64-obsd-tdep.o \
sparc-tdep.o sparc-netbsd-tdep.o sparc-obsd-tdep.o \
netbsd-tdep.o bsd-uthread.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-solaris2* | sparcv9-*-solaris2* | sparc64-*-solaris2*)
# Target: Solaris UltraSPARC
gdb_target_obs="sparc64-tdep.o sparc64-sol2-tdep.o sparc-tdep.o \
sparc-sol2-tdep.o sol2-tdep.o solib-svr4.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-*)
# Target: SPARC
gdb_target_obs="sparc-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc64-*-*)
# Target: UltraSPARC
gdb_target_obs="sparc-tdep.o sparc64-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
s12z-*-*)
# Target: Freescale S12z
gdb_target_obs="s12z-tdep.o"
;;
tic6x-*-*linux)
# Target: GNU/Linux TI C6x
gdb_target_obs="tic6x-tdep.o tic6x-linux-tdep.o solib-dsbt.o \
glibc-tdep.o linux-tdep.o"
;;
tic6x-*-*)
# Target: TI C6X
gdb_target_obs="tic6x-tdep.o"
;;
tilegx-*-linux*)
# Target: TILE-Gx
gdb_target_obs="tilegx-tdep.o tilegx-linux-tdep.o solib-svr4.o \
symfile-mem.o glibc-tdep.o linux-tdep.o"
;;
xstormy16-*-*)
# Target: Sanyo Xstormy16a processor
gdb_target_obs="xstormy16-tdep.o"
# No simulator libraries are needed -- target uses SID.
;;
ft32-*-elf)
gdb_target_obs="ft32-tdep.o"
;;
v850*-*-elf | v850*-*-rtems*)
# Target: NEC V850 processor
gdb_target_obs="v850-tdep.o"
;;
vax-*-netbsd* | vax-*-knetbsd*-gnu)
# Target: NetBSD/vax
gdb_target_obs="vax-tdep.o solib-svr4.o"
;;
vax-*-openbsd*)
# Target: OpenBSD/vax
gdb_target_obs="vax-tdep.o"
;;
vax-*-*)
# Target: VAX
gdb_target_obs="vax-tdep.o"
;;
x86_64-*-darwin*)
# Target: Darwin/x86-64
gdb_target_obs="${i386_tobjs} \
i386-darwin-tdep.o amd64-darwin-tdep.o \
solib-darwin.o"
;;
x86_64-*-dicos*)
# Target: DICOS/x86-64
gdb_target_obs="${i386_tobjs} \
dicos-tdep.o i386-dicos-tdep.o amd64-dicos-tdep.o"
;;
x86_64-*-elf*)
gdb_target_obs="${i386_tobjs}"
;;
x86_64-*-linux*)
# Target: GNU/Linux x86-64
gdb_target_obs="amd64-linux-tdep.o ${i386_tobjs} \
i386-linux-tdep.o glibc-tdep.o \
solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o"
;;
x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
# Target: FreeBSD/amd64
gdb_target_obs="amd64-fbsd-tdep.o ${i386_tobjs} \
i386-bsd-tdep.o i386-fbsd-tdep.o"
;;
x86_64-*-mingw* | x86_64-*-cygwin*)
# Target: MingW/amd64
gdb_target_obs="amd64-windows-tdep.o \
${i386_tobjs} i386-windows-tdep.o \
windows-tdep.o"
;;
x86_64-*-netbsd* | x86_64-*-knetbsd*-gnu)
# Target: NetBSD/amd64
gdb_target_obs="amd64-netbsd-tdep.o ${i386_tobjs}"
;;
x86_64-*-openbsd*)
# Target: OpenBSD/amd64
gdb_target_obs="amd64-obsd-tdep.o ${i386_tobjs} \
i386-bsd-tdep.o i386-obsd-tdep.o \
bsd-uthread.o"
;;
x86_64-*-rtems*)
gdb_target_obs="${amd64_tobjs} ${i386_tobjs} i386-bsd-tdep.o"
;;
xtensa*-*-*linux*)
# Target: GNU/Linux Xtensa
gdb_target_obs="xtensa-linux-tdep.o symfile-mem.o linux-tdep.o"
;;
z80*)
# Target: Z80
gdb_target_obs="z80-tdep.o"
;;
esac
# Put them together.
gdb_target_obs="${cpu_obs} ${os_obs} ${gdb_target_obs}"
# Get the sim settings.
# NB: Target matching is aligned with sim/configure.ac. Changes must be kept
# in sync with that file.
case "${targ}" in
aarch64*-*-*) gdb_sim=aarch64 ;;
arm*-*-*) gdb_sim=arm ;;
avr*-*-*) gdb_sim=avr ;;
bfin-*-*) gdb_sim=bfin ;;
bpf-*-*) gdb_sim=bpf ;;
cris-*-*|cris32-*-*) gdb_sim=cris ;;
frv-*-*) gdb_sim=frv ;;
ft32-*-*) gdb_sim=ft32 ;;
h8300*-*-*) gdb_sim=h8300 ;;
iq2000-*-*) gdb_sim=iq2000 ;;
lm32-*-*) gdb_sim=lm32 ;;
m32c-*-*) gdb_sim=m32c ;;
m32r-*-*) gdb_sim=m32r ;;
m68hc11-*-*|m6811-*-*) gdb_sim=m68hc11 ;;
microblaze*-*-*) gdb_sim=microblaze ;;
mips*-*-*) gdb_sim=mips ;;
mn10300*-*-*) gdb_sim=mn10300 ;;
moxie-*-*) gdb_sim=moxie ;;
msp430*-*-*) gdb_sim=msp430 ;;
or1k*-*-*) gdb_sim=or1k ;;
powerpc*-*-*) gdb_sim=ppc ;;
riscv*-*-*) gdb_sim=riscv ;;
rl78-*-*) gdb_sim=rl78 ;;
rx-*-*) gdb_sim=rx ;;
sh*-*-*) gdb_sim=sh ;;
sparc-*-*) gdb_sim=erc32 ;;
v850*-*-*) gdb_sim=v850 ;;
esac
if test "x$gdb_sim" != "x"; then
gdb_sim="../sim/${gdb_sim}/libsim.a"
fi
# map target onto default OS ABI
case "${targ}" in
*-*-freebsd* | *-*-kfreebsd*-gnu)
gdb_osabi=GDB_OSABI_FREEBSD ;;
*-*-linux* | *-*-uclinux*)
gdb_osabi=GDB_OSABI_LINUX ;;
*-*-nto*) gdb_osabi=GDB_OSABI_QNXNTO ;;
m68*-*-openbsd* | m88*-*-openbsd* | vax-*-openbsd*) ;;
*-*-openbsd*) gdb_osabi=GDB_OSABI_OPENBSD ;;
*-*-solaris*) gdb_osabi=GDB_OSABI_SOLARIS ;;
*-*-*-gnu*) ;; # prevent non-GNU kernels to match the Hurd rule below
*-*-gnu*) gdb_osabi=GDB_OSABI_HURD ;;
*-*-mingw32ce*) gdb_osabi=GDB_OSABI_WINCE ;;
*-*-mingw*) gdb_osabi=GDB_OSABI_WINDOWS ;;
*-*-cygwin*) gdb_osabi=GDB_OSABI_CYGWIN ;;
*-*-dicos*) gdb_osabi=GDB_OSABI_DICOS ;;
powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
gdb_osabi=GDB_OSABI_AIX ;;
esac
# Check whether this target supports gcore.
# Such target has to call set_gdbarch_find_memory_regions.
gdb_have_gcore=false
for t in x ${gdb_target_obs}; do
if test "$t" = linux-tdep.o; then
gdb_have_gcore=true
fi
done