binutils-gdb/gdb/netbsd-tdep.c
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

622 lines
17 KiB
C

/* Common target-dependent code for NetBSD systems.
Copyright (C) 2002-2022 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "auxv.h"
#include "solib-svr4.h"
#include "netbsd-tdep.h"
#include "gdbarch.h"
#include "objfiles.h"
#include "xml-syscall.h"
/* Flags in the 'kve_protection' field in struct kinfo_vmentry. These
match the KVME_PROT_* constants in <sys/sysctl.h>. */
#define KINFO_VME_PROT_READ 0x00000001
#define KINFO_VME_PROT_WRITE 0x00000002
#define KINFO_VME_PROT_EXEC 0x00000004
/* Flags in the 'kve_flags' field in struct kinfo_vmentry. These
match the KVME_FLAG_* constants in <sys/sysctl.h>. */
#define KINFO_VME_FLAG_COW 0x00000001
#define KINFO_VME_FLAG_NEEDS_COPY 0x00000002
#define KINFO_VME_FLAG_NOCOREDUMP 0x00000004
#define KINFO_VME_FLAG_PAGEABLE 0x00000008
#define KINFO_VME_FLAG_GROWS_UP 0x00000010
#define KINFO_VME_FLAG_GROWS_DOWN 0x00000020
/* FIXME: kettenis/20060115: We should really eliminate the next two
functions completely. */
struct link_map_offsets *
nbsd_ilp32_solib_svr4_fetch_link_map_offsets (void)
{
return svr4_ilp32_fetch_link_map_offsets ();
}
struct link_map_offsets *
nbsd_lp64_solib_svr4_fetch_link_map_offsets (void)
{
return svr4_lp64_fetch_link_map_offsets ();
}
int
nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *func_name)
{
/* Check for libc-provided signal trampoline. All such trampolines
have function names which begin with "__sigtramp". */
return (func_name != NULL
&& startswith (func_name, "__sigtramp"));
}
/* This enum is derived from NETBSD's <sys/signal.h>. */
enum
{
NBSD_SIGHUP = 1,
NBSD_SIGINT = 2,
NBSD_SIGQUIT = 3,
NBSD_SIGILL = 4,
NBSD_SIGTRAP = 5,
NBSD_SIGABRT = 6,
NBSD_SIGEMT = 7,
NBSD_SIGFPE = 8,
NBSD_SIGKILL = 9,
NBSD_SIGBUS = 10,
NBSD_SIGSEGV = 11,
NBSD_SIGSYS = 12,
NBSD_SIGPIPE = 13,
NBSD_SIGALRM = 14,
NBSD_SIGTERM = 15,
NBSD_SIGURG = 16,
NBSD_SIGSTOP = 17,
NBSD_SIGTSTP = 18,
NBSD_SIGCONT = 19,
NBSD_SIGCHLD = 20,
NBSD_SIGTTIN = 21,
NBSD_SIGTTOU = 22,
NBSD_SIGIO = 23,
NBSD_SIGXCPU = 24,
NBSD_SIGXFSZ = 25,
NBSD_SIGVTALRM = 26,
NBSD_SIGPROF = 27,
NBSD_SIGWINCH = 28,
NBSD_SIGINFO = 29,
NBSD_SIGUSR1 = 30,
NBSD_SIGUSR2 = 31,
NBSD_SIGPWR = 32,
NBSD_SIGRTMIN = 33,
NBSD_SIGRTMAX = 63,
};
/* Implement the "gdb_signal_from_target" gdbarch method. */
static enum gdb_signal
nbsd_gdb_signal_from_target (struct gdbarch *gdbarch, int signal)
{
switch (signal)
{
case 0:
return GDB_SIGNAL_0;
case NBSD_SIGHUP:
return GDB_SIGNAL_HUP;
case NBSD_SIGINT:
return GDB_SIGNAL_INT;
case NBSD_SIGQUIT:
return GDB_SIGNAL_QUIT;
case NBSD_SIGILL:
return GDB_SIGNAL_ILL;
case NBSD_SIGTRAP:
return GDB_SIGNAL_TRAP;
case NBSD_SIGABRT:
return GDB_SIGNAL_ABRT;
case NBSD_SIGEMT:
return GDB_SIGNAL_EMT;
case NBSD_SIGFPE:
return GDB_SIGNAL_FPE;
case NBSD_SIGKILL:
return GDB_SIGNAL_KILL;
case NBSD_SIGBUS:
return GDB_SIGNAL_BUS;
case NBSD_SIGSEGV:
return GDB_SIGNAL_SEGV;
case NBSD_SIGSYS:
return GDB_SIGNAL_SYS;
case NBSD_SIGPIPE:
return GDB_SIGNAL_PIPE;
case NBSD_SIGALRM:
return GDB_SIGNAL_ALRM;
case NBSD_SIGTERM:
return GDB_SIGNAL_TERM;
case NBSD_SIGURG:
return GDB_SIGNAL_URG;
case NBSD_SIGSTOP:
return GDB_SIGNAL_STOP;
case NBSD_SIGTSTP:
return GDB_SIGNAL_TSTP;
case NBSD_SIGCONT:
return GDB_SIGNAL_CONT;
case NBSD_SIGCHLD:
return GDB_SIGNAL_CHLD;
case NBSD_SIGTTIN:
return GDB_SIGNAL_TTIN;
case NBSD_SIGTTOU:
return GDB_SIGNAL_TTOU;
case NBSD_SIGIO:
return GDB_SIGNAL_IO;
case NBSD_SIGXCPU:
return GDB_SIGNAL_XCPU;
case NBSD_SIGXFSZ:
return GDB_SIGNAL_XFSZ;
case NBSD_SIGVTALRM:
return GDB_SIGNAL_VTALRM;
case NBSD_SIGPROF:
return GDB_SIGNAL_PROF;
case NBSD_SIGWINCH:
return GDB_SIGNAL_WINCH;
case NBSD_SIGINFO:
return GDB_SIGNAL_INFO;
case NBSD_SIGUSR1:
return GDB_SIGNAL_USR1;
case NBSD_SIGUSR2:
return GDB_SIGNAL_USR2;
case NBSD_SIGPWR:
return GDB_SIGNAL_PWR;
/* SIGRTMIN and SIGRTMAX are not continuous in <gdb/signals.def>,
therefore we have to handle them here. */
case NBSD_SIGRTMIN:
return GDB_SIGNAL_REALTIME_33;
case NBSD_SIGRTMAX:
return GDB_SIGNAL_REALTIME_63;
}
if (signal >= NBSD_SIGRTMIN + 1 && signal <= NBSD_SIGRTMAX - 1)
{
int offset = signal - NBSD_SIGRTMIN + 1;
return (enum gdb_signal) ((int) GDB_SIGNAL_REALTIME_34 + offset);
}
return GDB_SIGNAL_UNKNOWN;
}
/* Implement the "gdb_signal_to_target" gdbarch method. */
static int
nbsd_gdb_signal_to_target (struct gdbarch *gdbarch,
enum gdb_signal signal)
{
switch (signal)
{
case GDB_SIGNAL_0:
return 0;
case GDB_SIGNAL_HUP:
return NBSD_SIGHUP;
case GDB_SIGNAL_INT:
return NBSD_SIGINT;
case GDB_SIGNAL_QUIT:
return NBSD_SIGQUIT;
case GDB_SIGNAL_ILL:
return NBSD_SIGILL;
case GDB_SIGNAL_TRAP:
return NBSD_SIGTRAP;
case GDB_SIGNAL_ABRT:
return NBSD_SIGABRT;
case GDB_SIGNAL_EMT:
return NBSD_SIGEMT;
case GDB_SIGNAL_FPE:
return NBSD_SIGFPE;
case GDB_SIGNAL_KILL:
return NBSD_SIGKILL;
case GDB_SIGNAL_BUS:
return NBSD_SIGBUS;
case GDB_SIGNAL_SEGV:
return NBSD_SIGSEGV;
case GDB_SIGNAL_SYS:
return NBSD_SIGSYS;
case GDB_SIGNAL_PIPE:
return NBSD_SIGPIPE;
case GDB_SIGNAL_ALRM:
return NBSD_SIGALRM;
case GDB_SIGNAL_TERM:
return NBSD_SIGTERM;
case GDB_SIGNAL_URG:
return NBSD_SIGSTOP;
case GDB_SIGNAL_TSTP:
return NBSD_SIGTSTP;
case GDB_SIGNAL_CONT:
return NBSD_SIGCONT;
case GDB_SIGNAL_CHLD:
return NBSD_SIGCHLD;
case GDB_SIGNAL_TTIN:
return NBSD_SIGTTIN;
case GDB_SIGNAL_TTOU:
return NBSD_SIGTTOU;
case GDB_SIGNAL_IO:
return NBSD_SIGIO;
case GDB_SIGNAL_XCPU:
return NBSD_SIGXCPU;
case GDB_SIGNAL_XFSZ:
return NBSD_SIGXFSZ;
case GDB_SIGNAL_VTALRM:
return NBSD_SIGVTALRM;
case GDB_SIGNAL_PROF:
return NBSD_SIGPROF;
case GDB_SIGNAL_WINCH:
return NBSD_SIGWINCH;
case GDB_SIGNAL_INFO:
return NBSD_SIGINFO;
case GDB_SIGNAL_USR1:
return NBSD_SIGUSR1;
case GDB_SIGNAL_USR2:
return NBSD_SIGUSR2;
case GDB_SIGNAL_PWR:
return NBSD_SIGPWR;
/* GDB_SIGNAL_REALTIME_33 is not continuous in <gdb/signals.def>,
therefore we have to handle it here. */
case GDB_SIGNAL_REALTIME_33:
return NBSD_SIGRTMIN;
/* Same comment applies to _64. */
case GDB_SIGNAL_REALTIME_63:
return NBSD_SIGRTMAX;
}
if (signal >= GDB_SIGNAL_REALTIME_34
&& signal <= GDB_SIGNAL_REALTIME_62)
{
int offset = signal - GDB_SIGNAL_REALTIME_32;
return NBSD_SIGRTMIN + 1 + offset;
}
return -1;
}
/* Shared library resolver handling. */
static CORE_ADDR
nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
{
struct bound_minimal_symbol msym;
msym = lookup_minimal_symbol ("_rtld_bind_start", NULL, NULL);
if (msym.minsym && msym.value_address () == pc)
return frame_unwind_caller_pc (get_current_frame ());
else
return find_solib_trampoline_target (get_current_frame (), pc);
}
struct nbsd_gdbarch_data
{
struct type *siginfo_type = nullptr;
};
static const registry<gdbarch>::key<nbsd_gdbarch_data>
nbsd_gdbarch_data_handle;
static struct nbsd_gdbarch_data *
get_nbsd_gdbarch_data (struct gdbarch *gdbarch)
{
struct nbsd_gdbarch_data *result = nbsd_gdbarch_data_handle.get (gdbarch);
if (result == nullptr)
result = nbsd_gdbarch_data_handle.emplace (gdbarch);
return result;
}
/* Implement the "get_siginfo_type" gdbarch method. */
static struct type *
nbsd_get_siginfo_type (struct gdbarch *gdbarch)
{
nbsd_gdbarch_data *nbsd_gdbarch_data = get_nbsd_gdbarch_data (gdbarch);
if (nbsd_gdbarch_data->siginfo_type != NULL)
return nbsd_gdbarch_data->siginfo_type;
type *char_type = builtin_type (gdbarch)->builtin_char;
type *int_type = builtin_type (gdbarch)->builtin_int;
type *long_type = builtin_type (gdbarch)->builtin_long;
type *void_ptr_type
= lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
type *int32_type = builtin_type (gdbarch)->builtin_int32;
type *uint32_type = builtin_type (gdbarch)->builtin_uint32;
type *uint64_type = builtin_type (gdbarch)->builtin_uint64;
bool lp64 = void_ptr_type->length () == 8;
size_t char_bits = gdbarch_addressable_memory_unit_size (gdbarch) * 8;
/* pid_t */
type *pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
int32_type->length () * char_bits, "pid_t");
pid_type->set_target_type (int32_type);
/* uid_t */
type *uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
uint32_type->length () * char_bits, "uid_t");
uid_type->set_target_type (uint32_type);
/* clock_t */
type *clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
int_type->length () * char_bits, "clock_t");
clock_type->set_target_type (int_type);
/* lwpid_t */
type *lwpid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
int32_type->length () * char_bits,
"lwpid_t");
lwpid_type->set_target_type (int32_type);
/* union sigval */
type *sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
sigval_type->set_name (gdbarch_obstack_strdup (gdbarch, "sigval"));
append_composite_type_field (sigval_type, "sival_int", int_type);
append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type);
/* union _option */
type *option_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
option_type->set_name (gdbarch_obstack_strdup (gdbarch, "_option"));
append_composite_type_field (option_type, "_pe_other_pid", pid_type);
append_composite_type_field (option_type, "_pe_lwp", lwpid_type);
/* union _reason */
type *reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
/* _rt */
type *t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
append_composite_type_field (t, "_pid", pid_type);
append_composite_type_field (t, "_uid", uid_type);
append_composite_type_field (t, "_value", sigval_type);
append_composite_type_field (reason_type, "_rt", t);
/* _child */
t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
append_composite_type_field (t, "_pid", pid_type);
append_composite_type_field (t, "_uid", uid_type);
append_composite_type_field (t, "_status", int_type);
append_composite_type_field (t, "_utime", clock_type);
append_composite_type_field (t, "_stime", clock_type);
append_composite_type_field (reason_type, "_child", t);
/* _fault */
t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
append_composite_type_field (t, "_addr", void_ptr_type);
append_composite_type_field (t, "_trap", int_type);
append_composite_type_field (t, "_trap2", int_type);
append_composite_type_field (t, "_trap3", int_type);
append_composite_type_field (reason_type, "_fault", t);
/* _poll */
t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
append_composite_type_field (t, "_band", long_type);
append_composite_type_field (t, "_fd", int_type);
append_composite_type_field (reason_type, "_poll", t);
/* _syscall */
t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
append_composite_type_field (t, "_sysnum", int_type);
append_composite_type_field (t, "_retval",
init_vector_type (int_type, 2));
append_composite_type_field (t, "_error", int_type);
append_composite_type_field (t, "_args",
init_vector_type (uint64_type, 8));
append_composite_type_field (reason_type, "_syscall", t);
/* _ptrace_state */
t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
append_composite_type_field (t, "_pe_report_event", int_type);
append_composite_type_field (t, "_option", option_type);
append_composite_type_field (reason_type, "_ptrace_state", t);
/* struct _ksiginfo */
type *ksiginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
ksiginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "_ksiginfo"));
append_composite_type_field (ksiginfo_type, "_signo", int_type);
append_composite_type_field (ksiginfo_type, "_code", int_type);
append_composite_type_field (ksiginfo_type, "_errno", int_type);
if (lp64)
append_composite_type_field (ksiginfo_type, "_pad", int_type);
append_composite_type_field (ksiginfo_type, "_reason", reason_type);
/* union siginfo */
type *siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
siginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "siginfo"));
append_composite_type_field (siginfo_type, "si_pad",
init_vector_type (char_type, 128));
append_composite_type_field (siginfo_type, "_info", ksiginfo_type);
nbsd_gdbarch_data->siginfo_type = siginfo_type;
return siginfo_type;
}
/* See netbsd-tdep.h. */
void
nbsd_info_proc_mappings_header (int addr_bit)
{
gdb_printf (_("Mapped address spaces:\n\n"));
if (addr_bit == 64)
{
gdb_printf (" %18s %18s %10s %10s %9s %s\n",
"Start Addr",
" End Addr",
" Size", " Offset", "Flags ", "File");
}
else
{
gdb_printf ("\t%10s %10s %10s %10s %9s %s\n",
"Start Addr",
" End Addr",
" Size", " Offset", "Flags ", "File");
}
}
/* Helper function to generate mappings flags for a single VM map
entry in 'info proc mappings'. */
static const char *
nbsd_vm_map_entry_flags (int kve_flags, int kve_protection)
{
static char vm_flags[9];
vm_flags[0] = (kve_protection & KINFO_VME_PROT_READ) ? 'r' : '-';
vm_flags[1] = (kve_protection & KINFO_VME_PROT_WRITE) ? 'w' : '-';
vm_flags[2] = (kve_protection & KINFO_VME_PROT_EXEC) ? 'x' : '-';
vm_flags[3] = ' ';
vm_flags[4] = (kve_flags & KINFO_VME_FLAG_COW) ? 'C' : '-';
vm_flags[5] = (kve_flags & KINFO_VME_FLAG_NEEDS_COPY) ? 'N' : '-';
vm_flags[6] = (kve_flags & KINFO_VME_FLAG_PAGEABLE) ? 'P' : '-';
vm_flags[7] = (kve_flags & KINFO_VME_FLAG_GROWS_UP) ? 'U'
: (kve_flags & KINFO_VME_FLAG_GROWS_DOWN) ? 'D' : '-';
vm_flags[8] = '\0';
return vm_flags;
}
void
nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start,
ULONGEST kve_end, ULONGEST kve_offset,
int kve_flags, int kve_protection,
const char *kve_path)
{
if (addr_bit == 64)
{
gdb_printf (" %18s %18s %10s %10s %9s %s\n",
hex_string (kve_start),
hex_string (kve_end),
hex_string (kve_end - kve_start),
hex_string (kve_offset),
nbsd_vm_map_entry_flags (kve_flags, kve_protection),
kve_path);
}
else
{
gdb_printf ("\t%10s %10s %10s %10s %9s %s\n",
hex_string (kve_start),
hex_string (kve_end),
hex_string (kve_end - kve_start),
hex_string (kve_offset),
nbsd_vm_map_entry_flags (kve_flags, kve_protection),
kve_path);
}
}
/* Implement the "get_syscall_number" gdbarch method. */
static LONGEST
nbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
{
/* NetBSD doesn't use gdbarch_get_syscall_number since NetBSD
native targets fetch the system call number from the
'si_sysnum' member of siginfo_t in nbsd_nat_target::wait.
However, system call catching requires this function to be
set. */
internal_error (_("nbsd_get_sycall_number called"));
}
/* See netbsd-tdep.h. */
void
nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
set_gdbarch_gdb_signal_from_target (gdbarch, nbsd_gdb_signal_from_target);
set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target);
set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse);
set_gdbarch_get_siginfo_type (gdbarch, nbsd_get_siginfo_type);
/* `catch syscall' */
set_xml_syscall_file_name (gdbarch, "syscalls/netbsd.xml");
set_gdbarch_get_syscall_number (gdbarch, nbsd_get_syscall_number);
}