-/* Target-dependent code for Cygwin running on i386's, for GDB.
+/* Target-dependent code for Windows (including Cygwin) running on i386's,
+ for GDB.
Copyright (C) 2003-2020 Free Software Foundation, Inc.
data->module_count++;
out:
- if (buf)
- xfree (buf);
+ xfree (buf);
return;
}
}
static CORE_ADDR
-i386_cygwin_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+i386_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
return i386_pe_skip_trampoline_code (frame, pc, NULL);
}
static const char *
-i386_cygwin_auto_wide_charset (void)
+i386_windows_auto_wide_charset (void)
{
return "UTF-16";
}
+/* Implement the "push_dummy_call" gdbarch method. */
+
+static CORE_ADDR
+i386_windows_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+ struct regcache *regcache, CORE_ADDR bp_addr,
+ int nargs, struct value **args, CORE_ADDR sp,
+ function_call_return_method return_method,
+ CORE_ADDR struct_addr)
+{
+ /* For non-static member functions of 32bit Windows programs, the thiscall
+ calling convention is used, so the 'this' pointer is passed in ECX. */
+ bool thiscall = false;
+
+ struct type *type = check_typedef (value_type (function));
+ if (type->code () == TYPE_CODE_PTR)
+ type = check_typedef (TYPE_TARGET_TYPE (type));
+
+ /* read_subroutine_type sets for non-static member functions the
+ artificial flag of the first parameter ('this' pointer). */
+ if (type->code () == TYPE_CODE_METHOD
+ && type->num_fields () > 0
+ && TYPE_FIELD_ARTIFICIAL (type, 0)
+ && TYPE_FIELD_TYPE (type, 0)->code () == TYPE_CODE_PTR)
+ thiscall = 1;
+
+ return i386_thiscall_push_dummy_call (gdbarch, function, regcache, bp_addr,
+ nargs, args, sp, return_method,
+ struct_addr, thiscall);
+}
+
+/* Common parts for gdbarch initialization for Windows and Cygwin on i386. */
+
static void
-i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+i386_windows_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- windows_init_abi (info, gdbarch);
-
- set_gdbarch_skip_trampoline_code (gdbarch, i386_cygwin_skip_trampoline_code);
+ set_gdbarch_skip_trampoline_code (gdbarch, i386_windows_skip_trampoline_code);
set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue);
(gdbarch, windows_core_xfer_shared_libraries);
set_gdbarch_core_pid_to_str (gdbarch, i386_windows_core_pid_to_str);
- set_gdbarch_auto_wide_charset (gdbarch, i386_cygwin_auto_wide_charset);
+ set_gdbarch_auto_wide_charset (gdbarch, i386_windows_auto_wide_charset);
}
-static enum gdb_osabi
-i386_cygwin_osabi_sniffer (bfd *abfd)
+/* gdbarch initialization for Windows on i386. */
+
+static void
+i386_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ i386_windows_init_abi_common (info, gdbarch);
+ windows_init_abi (info, gdbarch);
+
+ set_gdbarch_push_dummy_call (gdbarch, i386_windows_push_dummy_call);
+}
+
+/* gdbarch initialization for Cygwin on i386. */
+
+static void
+i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ i386_windows_init_abi_common (info, gdbarch);
+ cygwin_init_abi (info, gdbarch);
+}
+
+static gdb_osabi
+i386_windows_osabi_sniffer (bfd *abfd)
{
const char *target_name = bfd_get_target (abfd);
- if (strcmp (target_name, "pei-i386") == 0)
- return GDB_OSABI_WINDOWS;
+ if (!streq (target_name, "pei-i386"))
+ return GDB_OSABI_UNKNOWN;
- return GDB_OSABI_UNKNOWN;
+ if (is_linked_with_cygwin_dll (abfd))
+ return GDB_OSABI_CYGWIN;
+
+ return GDB_OSABI_WINDOWS;
}
static enum gdb_osabi
return GDB_OSABI_UNKNOWN;
}
-void _initialize_i386_cygwin_tdep ();
+void _initialize_i386_windows_tdep ();
void
-_initialize_i386_cygwin_tdep ()
+_initialize_i386_windows_tdep ()
{
gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
- i386_cygwin_osabi_sniffer);
+ i386_windows_osabi_sniffer);
/* Cygwin uses elf core dumps. */
gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
i386_cygwin_core_osabi_sniffer);
- /* The Cygwin and Windows OS ABIs are currently equivalent. */
- gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
- i386_cygwin_init_abi);
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_WINDOWS,
- i386_cygwin_init_abi);
+ i386_windows_init_abi);
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
+ i386_cygwin_init_abi);
}