+2014-11-20 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ PR breakpoints/10737
+ * amd64-linux-tdep.c (amd64_linux_init_abi_common): Adjust call to
+ set_xml_syscall_file_name to provide gdbarch.
+ * arm-linux-tdep.c (arm_linux_init_abi): Likewise.
+ * bfin-linux-tdep.c (bfin_linux_init_abi): Likewise.
+ * breakpoint.c (print_it_catch_syscall): Adjust call to
+ get_syscall_by_number to provide gdbarch.
+ (print_one_catch_syscall): Likewise.
+ (print_mention_catch_syscall): Likewise.
+ (print_recreate_catch_syscall): Likewise.
+ (catch_syscall_split_args): Adjust calls to get_syscall_by_number
+ and get_syscall_by_name to provide gdbarch.
+ (catch_syscall_completer): Adjust call to get_syscall_names to
+ provide gdbarch.
+ * gdbarch.c: Regenerate.
+ * gdbarch.h: Likewise.
+ * gdbarch.sh: Forward declare "struct syscalls_info".
+ (xml_syscall_file): New variable.
+ (syscalls_info): Likewise.
+ * i386-linux-tdep.c (i386_linux_init_abi): Adjust call to
+ set_xml_syscall_file_name to provide gdbarch.
+ * mips-linux-tdep.c (mips_linux_init_abi): Likewise.
+ * ppc-linux-tdep.c (ppc_linux_init_abi): Likewise.
+ * s390-linux-tdep.c (s390_gdbarch_init): Likewise.
+ * sparc-linux-tdep.c (sparc32_linux_init_abi): Likewise.
+ * sparc64-linux-tdep.c (sparc64_linux_init_abi): Likewise.
+ * xml-syscall.c: Include gdbarch.h.
+ (set_xml_syscall_file_name): Accept gdbarch parameter.
+ (get_syscall_by_number): Likewise.
+ (get_syscall_by_name): Likewise.
+ (get_syscall_names): Likewise.
+ (my_gdb_datadir): Delete global variable.
+ (struct syscalls_info) <my_gdb_datadir>: New variable.
+ (struct syscalls_info) <sysinfo>: Rename variable to
+ "syscalls_info".
+ (sysinfo): Delete global variable.
+ (have_initialized_sysinfo): Likewise.
+ (xml_syscall_file): Likewise.
+ (sysinfo_free_syscalls_desc): Rename to...
+ (syscalls_info_free_syscalls_desc): ... this.
+ (free_syscalls_info): Rename "sysinfo" to "syscalls_info". Adjust
+ code to the new layout of "struct syscalls_info".
+ (make_cleanup_free_syscalls_info): Rename parameter "sysinfo" to
+ "syscalls_info".
+ (syscall_create_syscall_desc): Likewise.
+ (syscall_start_syscall): Likewise.
+ (syscall_parse_xml): Likewise.
+ (xml_init_syscalls_info): Likewise. Drop "const" from return value.
+ (init_sysinfo): Rename to...
+ (init_syscalls_info): ...this. Add gdbarch as a parameter.
+ Adjust function to deal with gdbarch.
+ (xml_get_syscall_number): Delete parameter sysinfo. Accept
+ gdbarch as a parameter. Adjust code.
+ (xml_get_syscall_name): Likewise.
+ (xml_list_of_syscalls): Likewise.
+ (set_xml_syscall_file_name): Accept gdbarch as parameter.
+ (get_syscall_by_number): Likewise.
+ (get_syscall_by_name): Likewise.
+ (get_syscall_names): Likewise.
+ * xml-syscall.h (set_xml_syscall_file_name): Likewise.
+ (get_syscall_by_number): Likewise.
+ (get_syscall_by_name): Likewise.
+ (get_syscall_names): Likewise.
+
2014-11-20 Doug Evans <xdje42@gmail.com>
Split struct symtab into two: struct symtab and compunit_symtab.
tdep->register_reggroup_p = amd64_linux_register_reggroup_p;
/* Functions for 'catch syscall'. */
- set_xml_syscall_file_name (XML_SYSCALL_FILENAME_AMD64);
+ set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_AMD64);
set_gdbarch_get_syscall_number (gdbarch,
amd64_linux_get_syscall_number);
tdep->syscall_next_pc = arm_linux_syscall_next_pc;
/* `catch syscall' */
- set_xml_syscall_file_name ("syscalls/arm-linux.xml");
+ set_xml_syscall_file_name (gdbarch, "syscalls/arm-linux.xml");
set_gdbarch_get_syscall_number (gdbarch, arm_linux_get_syscall_number);
/* Syscall record. */
tramp_frame_prepend_unwinder (gdbarch, &bfin_linux_sigframe);
/* Functions for 'catch syscall'. */
- set_xml_syscall_file_name ("syscalls/bfin-linux.xml");
+ set_xml_syscall_file_name (gdbarch, "syscalls/bfin-linux.xml");
set_gdbarch_get_syscall_number (gdbarch,
bfin_linux_get_syscall_number);
}
ptid_t ptid;
struct target_waitstatus last;
struct syscall s;
+ struct gdbarch *gdbarch = bs->bp_location_at->gdbarch;
get_last_target_status (&ptid, &last);
- get_syscall_by_number (last.value.syscall_number, &s);
+ get_syscall_by_number (gdbarch, last.value.syscall_number, &s);
annotate_catchpoint (b->number);
struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
struct value_print_options opts;
struct ui_out *uiout = current_uiout;
+ struct gdbarch *gdbarch = b->loc->gdbarch;
get_user_print_options (&opts);
/* Field 4, the address, is omitted (which makes the columns not
{
char *x = text;
struct syscall s;
- get_syscall_by_number (iter, &s);
+ get_syscall_by_number (gdbarch, iter, &s);
if (s.name != NULL)
text = xstrprintf ("%s%s, ", text, s.name);
print_mention_catch_syscall (struct breakpoint *b)
{
struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+ struct gdbarch *gdbarch = b->loc->gdbarch;
if (c->syscalls_to_be_caught)
{
i++)
{
struct syscall s;
- get_syscall_by_number (iter, &s);
+ get_syscall_by_number (gdbarch, iter, &s);
if (s.name)
printf_filtered (" '%s' [%d]", s.name, s.number);
print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
{
struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+ struct gdbarch *gdbarch = b->loc->gdbarch;
fprintf_unfiltered (fp, "catch syscall");
{
struct syscall s;
- get_syscall_by_number (iter, &s);
+ get_syscall_by_number (gdbarch, iter, &s);
if (s.name)
fprintf_unfiltered (fp, " %s", s.name);
else
{
VEC(int) *result = NULL;
struct cleanup *cleanup = make_cleanup (VEC_cleanup (int), &result);
+ struct gdbarch *gdbarch = target_gdbarch ();
while (*arg != '\0')
{
/* Check if the user provided a syscall name or a number. */
syscall_number = (int) strtol (cur_name, &endptr, 0);
if (*endptr == '\0')
- get_syscall_by_number (syscall_number, &s);
+ get_syscall_by_number (gdbarch, syscall_number, &s);
else
{
/* We have a name. Let's check if it's valid and convert it
to a number. */
- get_syscall_by_name (cur_name, &s);
+ get_syscall_by_name (gdbarch, cur_name, &s);
if (s.number == UNKNOWN_SYSCALL)
/* Here we have to issue an error instead of a warning,
to get the syscall XML file loaded or, most important,
to display a warning to the user if there's no XML file
for his/her architecture. */
- get_syscall_by_number (0, &s);
+ get_syscall_by_number (gdbarch, 0, &s);
/* The allowed syntax is:
catch syscall
catch_syscall_completer (struct cmd_list_element *cmd,
const char *text, const char *word)
{
- const char **list = get_syscall_names ();
+ const char **list = get_syscall_names (get_current_arch ());
VEC (char_ptr) *retlist
= (list == NULL) ? NULL : complete_on_enum (list, word, word);
gdbarch_get_siginfo_type_ftype *get_siginfo_type;
gdbarch_record_special_symbol_ftype *record_special_symbol;
gdbarch_get_syscall_number_ftype *get_syscall_number;
+ const char * xml_syscall_file;
+ struct syscalls_info * syscalls_info;
const char *const * stap_integer_prefixes;
const char *const * stap_integer_suffixes;
const char *const * stap_register_prefixes;
/* Skip verify of get_siginfo_type, has predicate. */
/* Skip verify of record_special_symbol, has predicate. */
/* Skip verify of get_syscall_number, has predicate. */
+ /* Skip verify of xml_syscall_file, invalid_p == 0 */
+ /* Skip verify of syscalls_info, invalid_p == 0 */
/* Skip verify of stap_integer_prefixes, invalid_p == 0 */
/* Skip verify of stap_integer_suffixes, invalid_p == 0 */
/* Skip verify of stap_register_prefixes, invalid_p == 0 */
fprintf_unfiltered (file,
"gdbarch_dump: static_transform_name = <%s>\n",
host_address_to_string (gdbarch->static_transform_name));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: syscalls_info = %s\n",
+ host_address_to_string (gdbarch->syscalls_info));
fprintf_unfiltered (file,
"gdbarch_dump: target_desc = %s\n",
host_address_to_string (gdbarch->target_desc));
fprintf_unfiltered (file,
"gdbarch_dump: write_pc = <%s>\n",
host_address_to_string (gdbarch->write_pc));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: xml_syscall_file = %s\n",
+ pstring (gdbarch->xml_syscall_file));
if (gdbarch->dump_tdep != NULL)
gdbarch->dump_tdep (gdbarch, file);
}
gdbarch->get_syscall_number = get_syscall_number;
}
+const char *
+gdbarch_xml_syscall_file (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of xml_syscall_file, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_xml_syscall_file called\n");
+ return gdbarch->xml_syscall_file;
+}
+
+void
+set_gdbarch_xml_syscall_file (struct gdbarch *gdbarch,
+ const char * xml_syscall_file)
+{
+ gdbarch->xml_syscall_file = xml_syscall_file;
+}
+
+struct syscalls_info *
+gdbarch_syscalls_info (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of syscalls_info, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_syscalls_info called\n");
+ return gdbarch->syscalls_info;
+}
+
+void
+set_gdbarch_syscalls_info (struct gdbarch *gdbarch,
+ struct syscalls_info * syscalls_info)
+{
+ gdbarch->syscalls_info = syscalls_info;
+}
+
const char *const *
gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch)
{
struct ravenscar_arch_ops;
struct elf_internal_linux_prpsinfo;
struct mem_range;
+struct syscalls_info;
/* The architecture associated with the inferior through the
connection to the target.
extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid);
extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number);
+/* The filename of the XML syscall for this architecture. */
+
+extern const char * gdbarch_xml_syscall_file (struct gdbarch *gdbarch);
+extern void set_gdbarch_xml_syscall_file (struct gdbarch *gdbarch, const char * xml_syscall_file);
+
+/* Information about system calls from this architecture */
+
+extern struct syscalls_info * gdbarch_syscalls_info (struct gdbarch *gdbarch);
+extern void set_gdbarch_syscalls_info (struct gdbarch *gdbarch, struct syscalls_info * syscalls_info);
+
/* SystemTap related fields and functions.
A NULL-terminated array of prefixes used to mark an integer constant
on the architecture's assembly.
# Get architecture-specific system calls information from registers.
M:LONGEST:get_syscall_number:ptid_t ptid:ptid
+# The filename of the XML syscall for this architecture.
+v:const char *:xml_syscall_file:::0:0::0:pstring (gdbarch->xml_syscall_file)
+
+# Information about system calls from this architecture
+v:struct syscalls_info *:syscalls_info:::0:0::0:host_address_to_string (gdbarch->syscalls_info)
+
# SystemTap related fields and functions.
# A NULL-terminated array of prefixes used to mark an integer constant
struct ravenscar_arch_ops;
struct elf_internal_linux_prpsinfo;
struct mem_range;
+struct syscalls_info;
/* The architecture associated with the inferior through the
connection to the target.
displaced_step_at_entry_point);
/* Functions for 'catch syscall'. */
- set_xml_syscall_file_name (XML_SYSCALL_FILENAME_I386);
+ set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_I386);
set_gdbarch_get_syscall_number (gdbarch,
i386_linux_get_syscall_number);
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_sigframe);
tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_rt_sigframe);
- set_xml_syscall_file_name ("syscalls/mips-o32-linux.xml");
+ set_xml_syscall_file_name (gdbarch, "syscalls/mips-o32-linux.xml");
break;
case MIPS_ABI_N32:
set_gdbarch_get_longjmp_target (gdbarch,
does not distinguish between quiet and signalling NaNs). */
set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
tramp_frame_prepend_unwinder (gdbarch, &mips_linux_n32_rt_sigframe);
- set_xml_syscall_file_name ("syscalls/mips-n32-linux.xml");
+ set_xml_syscall_file_name (gdbarch, "syscalls/mips-n32-linux.xml");
break;
case MIPS_ABI_N64:
set_gdbarch_get_longjmp_target (gdbarch,
does not distinguish between quiet and signalling NaNs). */
set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
tramp_frame_prepend_unwinder (gdbarch, &mips_linux_n64_rt_sigframe);
- set_xml_syscall_file_name ("syscalls/mips-n64-linux.xml");
+ set_xml_syscall_file_name (gdbarch, "syscalls/mips-n64-linux.xml");
break;
default:
break;
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
/* Setting the correct XML syscall filename. */
- set_xml_syscall_file_name (XML_SYSCALL_FILENAME_PPC);
+ set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC);
/* Trampolines. */
tramp_frame_prepend_unwinder (gdbarch,
(gdbarch, svr4_lp64_fetch_link_map_offsets);
/* Setting the correct XML syscall filename. */
- set_xml_syscall_file_name (XML_SYSCALL_FILENAME_PPC64);
+ set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC64);
/* Trampolines. */
tramp_frame_prepend_unwinder (gdbarch,
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
- set_xml_syscall_file_name (XML_SYSCALL_FILENAME_S390);
+ set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390);
break;
case ABI_LINUX_ZSERIES:
s390_address_class_type_flags_to_name);
set_gdbarch_address_class_name_to_type_flags (gdbarch,
s390_address_class_name_to_type_flags);
- set_xml_syscall_file_name (XML_SYSCALL_FILENAME_S390);
+ set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390);
break;
}
set_gdbarch_write_pc (gdbarch, sparc_linux_write_pc);
/* Functions for 'catch syscall'. */
- set_xml_syscall_file_name (XML_SYSCALL_FILENAME_SPARC32);
+ set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC32);
set_gdbarch_get_syscall_number (gdbarch,
sparc32_linux_get_syscall_number);
set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc);
/* Functions for 'catch syscall'. */
- set_xml_syscall_file_name (XML_SYSCALL_FILENAME_SPARC64);
+ set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC64);
set_gdbarch_get_syscall_number (gdbarch,
sparc64_linux_get_syscall_number);
}
+2014-11-20 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ PR breakpoints/10737
+ * gdb.base/catch-syscall.exp (do_syscall_tests): Call
+ test_catch_syscall_multi_arch.
+ (test_catch_syscall_multi_arch): New function.
+
2014-11-20 Doug Evans <xdje42@gmail.com>
* gdb.base/maint.exp: Update expected output.
# Testing the 'catch' syscall command during a restart of
# the inferior.
if [runto_main] then { test_catch_syscall_restarting_inferior }
+
+ # Testing if the 'catch syscall' command works when switching to
+ # different architectures on-the-fly (PR gdb/10737).
+ if [runto_main] then { test_catch_syscall_multi_arch }
}
proc test_catch_syscall_without_args_noxml {} {
}
}
+proc test_catch_syscall_multi_arch {} {
+ global decimal binfile
+
+ if { [istarget "i*86-*-*"] || [istarget "x86_64-*-*"] } {
+ set arch1 "i386"
+ set arch2 "i386:x86-64"
+ set syscall1_name "exit"
+ set syscall2_name "write"
+ set syscall_number 1
+ } elseif { [istarget "powerpc-*-linux*"] \
+ || [istarget "powerpc64-*-linux*"] } {
+ set arch1 "powerpc:common"
+ set arch2 "powerpc:common64"
+ set syscall1_name "openat"
+ set syscall2_name "unlinkat"
+ set syscall_number 286
+ } elseif { [istarget "sparc-*-linux*"] \
+ || [istarget "sparc64-*-linux*"] } {
+ set arch1 "sparc"
+ set arch2 "sparc:v9"
+ set syscall1_name "setresuid32"
+ set syscall2_name "setresuid"
+ set syscall_number 108
+ } elseif { [istarget "mips*-linux*"] } {
+ # MIPS does not use the same numbers for syscalls on 32 and 64
+ # bits.
+ verbose "Not testing MIPS for multi-arch syscall support"
+ return
+ } elseif { [istarget "arm*-linux*"] } {
+ # catch syscall supports only 32-bit ARM for now.
+ verbose "Not testing ARM for multi-arch syscall support"
+ return
+ } elseif { [istarget "s390*-linux*"] } {
+ set arch1 ""
+ set arch2 "s390:64-bit"
+ set syscall1_name "_newselect"
+ set syscall2_name "select"
+ set syscall_number 142
+ }
+
+ with_test_prefix "multiple targets" {
+ # We are not interested in loading any binary here, and in
+ # some systems (PowerPC, for example), if we load a binary
+ # there is no way to set other architecture.
+ gdb_exit
+ gdb_start
+
+ gdb_test "set architecture $arch1" \
+ "The target architecture is assumed to be $arch1" \
+ "set arch to $arch1"
+
+ gdb_test "catch syscall $syscall_number" \
+ "Catchpoint $decimal \\(syscall .${syscall1_name}. \\\[${syscall_number}\\\]\\)" \
+ "insert catch syscall on syscall $syscall_number -- $syscall1_name on $arch1"
+
+ gdb_test "set architecture $arch2" \
+ "The target architecture is assumed to be $arch2" \
+ "set arch to $arch2"
+
+ gdb_test "catch syscall $syscall_number" \
+ "Catchpoint $decimal \\(syscall .${syscall2_name}. \\\[${syscall_number}\\\]\\)" \
+ "insert catch syscall on syscall $syscall_number -- $syscall2_name on $arch2"
+
+ clean_restart $binfile
+ }
+}
+
proc do_syscall_tests_without_xml {} {
# Make sure GDB doesn't load the syscalls xml from the system data
# directory.
#include "gdbtypes.h"
#include "xml-support.h"
#include "xml-syscall.h"
+#include "gdbarch.h"
/* For the struct syscall definition. */
#include "target.h"
}
void
-set_xml_syscall_file_name (const char *name)
+set_xml_syscall_file_name (const struct gdbarch *gdbarch,
+ const char *name)
{
return;
}
void
-get_syscall_by_number (int syscall_number,
- struct syscall *s)
+get_syscall_by_number (const struct gdbarch *gdbarch,
+ int syscall_number, struct syscall *s)
{
syscall_warn_user ();
s->number = syscall_number;
}
void
-get_syscall_by_name (const char *syscall_name,
- struct syscall *s)
+get_syscall_by_name (const struct gdbarch *gdbarch,
+ const char *syscall_name, struct syscall *s)
{
syscall_warn_user ();
s->number = UNKNOWN_SYSCALL;
}
const char **
-get_syscall_names (void)
+get_syscall_names (const struct gdbarch *gdbarch)
{
syscall_warn_user ();
return NULL;
#else /* ! HAVE_LIBEXPAT */
-/* Variable that will hold the last known data-directory. This is useful to
- know whether we should re-read the XML info for the target. */
-static char *my_gdb_datadir = NULL;
-
/* Structure which describes a syscall. */
typedef struct syscall_desc
{
/* The syscalls. */
VEC(syscall_desc_p) *syscalls;
+
+ /* Variable that will hold the last known data-directory. This is
+ useful to know whether we should re-read the XML info for the
+ target. */
+
+ char *my_gdb_datadir;
};
/* Callback data for syscall information parsing. */
{
/* The syscalls_info we are building. */
- struct syscalls_info *sysinfo;
+ struct syscalls_info *syscalls_info;
};
-/* Structure used to store information about the available syscalls in
- the system. */
-static const struct syscalls_info *sysinfo = NULL;
-
-/* A flag to tell if we already initialized the structure above. */
-static int have_initialized_sysinfo = 0;
-
-/* The filename of the syscall's XML. */
-static const char *xml_syscall_file = NULL;
-
static struct syscalls_info *
allocate_syscalls_info (void)
{
}
static void
-sysinfo_free_syscalls_desc (struct syscall_desc *sd)
+syscalls_info_free_syscalls_desc (struct syscall_desc *sd)
{
xfree (sd->name);
}
static void
free_syscalls_info (void *arg)
{
- struct syscalls_info *sysinfo = arg;
+ struct syscalls_info *syscalls_info = arg;
struct syscall_desc *sysdesc;
int i;
- for (i = 0;
- VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc);
- i++)
- sysinfo_free_syscalls_desc (sysdesc);
- VEC_free (syscall_desc_p, sysinfo->syscalls);
+ xfree (syscalls_info->my_gdb_datadir);
+
+ if (syscalls_info->syscalls != NULL)
+ {
+ for (i = 0;
+ VEC_iterate (syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
+ i++)
+ syscalls_info_free_syscalls_desc (sysdesc);
+ VEC_free (syscall_desc_p, syscalls_info->syscalls);
+ }
- xfree (sysinfo);
+ xfree (syscalls_info);
}
static struct cleanup *
-make_cleanup_free_syscalls_info (struct syscalls_info *sysinfo)
+make_cleanup_free_syscalls_info (struct syscalls_info *syscalls_info)
{
- return make_cleanup (free_syscalls_info, sysinfo);
+ return make_cleanup (free_syscalls_info, syscalls_info);
}
static void
-syscall_create_syscall_desc (struct syscalls_info *sysinfo,
+syscall_create_syscall_desc (struct syscalls_info *syscalls_info,
const char *name, int number)
{
struct syscall_desc *sysdesc = XCNEW (struct syscall_desc);
sysdesc->name = xstrdup (name);
sysdesc->number = number;
- VEC_safe_push (syscall_desc_p, sysinfo->syscalls, sysdesc);
+ VEC_safe_push (syscall_desc_p, syscalls_info->syscalls, sysdesc);
}
/* Handle the start of a <syscall> element. */
}
gdb_assert (name);
- syscall_create_syscall_desc (data->sysinfo, name, number);
+ syscall_create_syscall_desc (data->syscalls_info, name, number);
}
struct cleanup *result_cleanup;
struct syscall_parsing_data data;
- data.sysinfo = allocate_syscalls_info ();
- result_cleanup = make_cleanup_free_syscalls_info (data.sysinfo);
+ data.syscalls_info = allocate_syscalls_info ();
+ result_cleanup = make_cleanup_free_syscalls_info (data.syscalls_info);
if (gdb_xml_parse_quick (_("syscalls info"), NULL,
syselements, document, &data) == 0)
{
/* Parsed successfully. */
discard_cleanups (result_cleanup);
- return data.sysinfo;
+ return data.syscalls_info;
}
else
{
struct syscalls_info with the values.
Returns the struct syscalls_info if the file is valid, NULL otherwise. */
-static const struct syscalls_info *
+static struct syscalls_info *
xml_init_syscalls_info (const char *filename)
{
char *full_file;
char *dirname;
- struct syscalls_info *sysinfo;
+ struct syscalls_info *syscalls_info;
struct cleanup *back_to;
full_file = xml_fetch_content_from_file (filename, gdb_datadir);
if (dirname != NULL)
make_cleanup (xfree, dirname);
- sysinfo = syscall_parse_xml (full_file,
- xml_fetch_content_from_file, dirname);
+ syscalls_info = syscall_parse_xml (full_file,
+ xml_fetch_content_from_file, dirname);
do_cleanups (back_to);
- return sysinfo;
+ return syscalls_info;
}
/* Initializes the syscalls_info structure according to the
architecture. */
static void
-init_sysinfo (void)
+init_syscalls_info (struct gdbarch *gdbarch)
{
+ struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
+ const char *xml_syscall_file = gdbarch_xml_syscall_file (gdbarch);
+
/* Should we re-read the XML info for this target? */
- if (my_gdb_datadir && filename_cmp (my_gdb_datadir, gdb_datadir) != 0)
+ if (syscalls_info != NULL && syscalls_info->my_gdb_datadir != NULL
+ && filename_cmp (syscalls_info->my_gdb_datadir, gdb_datadir) != 0)
{
/* The data-directory changed from the last time we used it.
It means that we have to re-read the XML info. */
- have_initialized_sysinfo = 0;
- xfree (my_gdb_datadir);
- my_gdb_datadir = NULL;
- if (sysinfo)
- free_syscalls_info ((void *) sysinfo);
+ free_syscalls_info (syscalls_info);
+ syscalls_info = NULL;
+ set_gdbarch_syscalls_info (gdbarch, NULL);
}
- /* Did we already try to initialize the structure? */
- if (have_initialized_sysinfo)
+ /* Did we succeed at initializing this? */
+ if (syscalls_info != NULL)
return;
- sysinfo = xml_init_syscalls_info (xml_syscall_file);
+ syscalls_info = xml_init_syscalls_info (xml_syscall_file);
- have_initialized_sysinfo = 1;
+ /* If there was some error reading the XML file, we initialize
+ gdbarch->syscalls_info anyway, in order to store information
+ about our attempt. */
+ if (syscalls_info == NULL)
+ syscalls_info = allocate_syscalls_info ();
- if (sysinfo == NULL)
+ if (syscalls_info->syscalls == NULL)
{
- if (xml_syscall_file)
+ if (xml_syscall_file != NULL)
warning (_("Could not load the syscall XML file `%s/%s'."),
gdb_datadir, xml_syscall_file);
else
}
/* Saving the data-directory used to read this XML info. */
- my_gdb_datadir = xstrdup (gdb_datadir);
+ syscalls_info->my_gdb_datadir = xstrdup (gdb_datadir);
+
+ set_gdbarch_syscalls_info (gdbarch, syscalls_info);
}
static int
-xml_get_syscall_number (const struct syscalls_info *sysinfo,
+xml_get_syscall_number (struct gdbarch *gdbarch,
const char *syscall_name)
{
+ struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
struct syscall_desc *sysdesc;
int i;
- if (sysinfo == NULL
+ if (syscalls_info == NULL
|| syscall_name == NULL)
return UNKNOWN_SYSCALL;
for (i = 0;
- VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc);
+ VEC_iterate(syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
i++)
if (strcmp (sysdesc->name, syscall_name) == 0)
return sysdesc->number;
}
static const char *
-xml_get_syscall_name (const struct syscalls_info *sysinfo,
+xml_get_syscall_name (struct gdbarch *gdbarch,
int syscall_number)
{
+ struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
struct syscall_desc *sysdesc;
int i;
- if (sysinfo == NULL
+ if (syscalls_info == NULL
|| syscall_number < 0)
return NULL;
for (i = 0;
- VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc);
+ VEC_iterate(syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
i++)
if (sysdesc->number == syscall_number)
return sysdesc->name;
}
static const char **
-xml_list_of_syscalls (const struct syscalls_info *sysinfo)
+xml_list_of_syscalls (struct gdbarch *gdbarch)
{
+ struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
struct syscall_desc *sysdesc;
const char **names = NULL;
int nsyscalls;
int i;
- if (sysinfo == NULL)
+ if (syscalls_info == NULL)
return NULL;
- nsyscalls = VEC_length (syscall_desc_p, sysinfo->syscalls);
+ nsyscalls = VEC_length (syscall_desc_p, syscalls_info->syscalls);
names = xmalloc ((nsyscalls + 1) * sizeof (char *));
for (i = 0;
- VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc);
+ VEC_iterate (syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
i++)
names[i] = sysdesc->name;
}
void
-set_xml_syscall_file_name (const char *name)
+set_xml_syscall_file_name (struct gdbarch *gdbarch, const char *name)
{
- xml_syscall_file = name;
+ set_gdbarch_xml_syscall_file (gdbarch, name);
}
void
-get_syscall_by_number (int syscall_number,
- struct syscall *s)
+get_syscall_by_number (struct gdbarch *gdbarch,
+ int syscall_number, struct syscall *s)
{
- init_sysinfo ();
+ init_syscalls_info (gdbarch);
s->number = syscall_number;
- s->name = xml_get_syscall_name (sysinfo, syscall_number);
+ s->name = xml_get_syscall_name (gdbarch, syscall_number);
}
void
-get_syscall_by_name (const char *syscall_name,
- struct syscall *s)
+get_syscall_by_name (struct gdbarch *gdbarch,
+ const char *syscall_name, struct syscall *s)
{
- init_sysinfo ();
+ init_syscalls_info (gdbarch);
- s->number = xml_get_syscall_number (sysinfo, syscall_name);
+ s->number = xml_get_syscall_number (gdbarch, syscall_name);
s->name = syscall_name;
}
const char **
-get_syscall_names (void)
+get_syscall_names (struct gdbarch *gdbarch)
{
- init_sysinfo ();
+ init_syscalls_info (gdbarch);
- return xml_list_of_syscalls (sysinfo);
+ return xml_list_of_syscalls (gdbarch);
}
#endif /* ! HAVE_LIBEXPAT */
GDB won't be able to find the correct XML file to open and get
the syscalls definitions. */
-void set_xml_syscall_file_name (const char *name);
+void set_xml_syscall_file_name (struct gdbarch *gdbarch,
+ const char *name);
/* Function that retrieves the syscall name corresponding to the given
number. It puts the requested information inside 'struct syscall'. */
-void get_syscall_by_number (int syscall_number, struct syscall *s);
+void get_syscall_by_number (struct gdbarch *gdbarch,
+ int syscall_number, struct syscall *s);
/* Function that retrieves the syscall number corresponding to the given
name. It puts the requested information inside 'struct syscall'. */
-void get_syscall_by_name (const char *syscall_name, struct syscall *s);
+void get_syscall_by_name (struct gdbarch *gdbarch,
+ const char *syscall_name, struct syscall *s);
/* Function used to retrieve the list of syscalls in the system. This list
is returned as an array of strings. Returns the list of syscalls in the
system, or NULL otherwise. */
-const char **get_syscall_names (void);
+const char **get_syscall_names (struct gdbarch *gdbarch);
#endif /* XML_SYSCALL_H */