Introduce assign_operation
[deliverable/binutils-gdb.git] / gdb / i386-windows-tdep.c
index bd6107b02f1f8e4d79f51a644c20f5b0f5a19fb1..b561d60e0f839f93135e9ea63c2d523941899087 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for Windows (including Cygwin) running on i386's,
    for GDB.
 
-   Copyright (C) 2003-2020 Free Software Foundation, Inc.
+   Copyright (C) 2003-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -89,105 +89,6 @@ static int i386_windows_gregset_reg_offset[] =
 
 #define I386_WINDOWS_SIZEOF_GREGSET 716
 
-struct cpms_data
-{
-  struct gdbarch *gdbarch;
-  struct obstack *obstack;
-  int module_count;
-};
-
-static void
-core_process_module_section (bfd *abfd, asection *sect, void *obj)
-{
-  struct cpms_data *data = (struct cpms_data *) obj;
-  enum bfd_endian byte_order = gdbarch_byte_order (data->gdbarch);
-
-  char *module_name;
-  size_t module_name_size;
-  CORE_ADDR base_addr;
-
-  gdb_byte *buf = NULL;
-
-  if (!startswith (sect->name, ".module"))
-    return;
-
-  buf = (gdb_byte *) xmalloc (bfd_section_size (sect) + 1);
-  if (!buf)
-    {
-      printf_unfiltered ("memory allocation failed for %s\n", sect->name);
-      goto out;
-    }
-  if (!bfd_get_section_contents (abfd, sect,
-                                buf, 0, bfd_section_size (sect)))
-    goto out;
-
-
-
-  /* A DWORD (data_type) followed by struct windows_core_module_info.  */
-
-  base_addr =
-    extract_unsigned_integer (buf + 4, 4, byte_order);
-
-  module_name_size =
-    extract_unsigned_integer (buf + 8, 4, byte_order);
-
-  if (12 + module_name_size > bfd_section_size (sect))
-    goto out;
-  module_name = (char *) buf + 12;
-
-  /* The first module is the .exe itself.  */
-  if (data->module_count != 0)
-    windows_xfer_shared_library (module_name, base_addr,
-                                NULL, data->gdbarch, data->obstack);
-  data->module_count++;
-
-out:
-  if (buf)
-    xfree (buf);
-  return;
-}
-
-static ULONGEST
-windows_core_xfer_shared_libraries (struct gdbarch *gdbarch,
-                                 gdb_byte *readbuf,
-                                 ULONGEST offset, ULONGEST len)
-{
-  struct obstack obstack;
-  const char *buf;
-  ULONGEST len_avail;
-  struct cpms_data data = { gdbarch, &obstack, 0 };
-
-  obstack_init (&obstack);
-  obstack_grow_str (&obstack, "<library-list>\n");
-  bfd_map_over_sections (core_bfd,
-                        core_process_module_section,
-                        &data);
-  obstack_grow_str0 (&obstack, "</library-list>\n");
-
-  buf = (const char *) obstack_finish (&obstack);
-  len_avail = strlen (buf);
-  if (offset >= len_avail)
-    return 0;
-
-  if (len > len_avail - offset)
-    len = len_avail - offset;
-  memcpy (readbuf, buf + offset, len);
-
-  obstack_free (&obstack, NULL);
-  return len;
-}
-
-/* This is how we want PTIDs from core files to be printed.  */
-
-static std::string
-i386_windows_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
-{
-  if (ptid.lwp () != 0)
-    return string_printf ("Thread 0x%lx", ptid.lwp ());
-
-  return normal_pid_to_str (ptid);
-}
-
 static CORE_ADDR
 i386_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 {
@@ -200,13 +101,43 @@ 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 (0).type ()->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_windows_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_windows_skip_trampoline_code);
 
   set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue);
@@ -222,11 +153,31 @@ i386_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Core file support.  */
   set_gdbarch_core_xfer_shared_libraries
     (gdbarch, windows_core_xfer_shared_libraries);
-  set_gdbarch_core_pid_to_str (gdbarch, i386_windows_core_pid_to_str);
+  set_gdbarch_core_pid_to_str (gdbarch, windows_core_pid_to_str);
 
   set_gdbarch_auto_wide_charset (gdbarch, i386_windows_auto_wide_charset);
 }
 
+/* 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)
 {
@@ -264,15 +215,14 @@ void
 _initialize_i386_windows_tdep ()
 {
   gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
-                                  i386_windows_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);
+                                 i386_cygwin_core_osabi_sniffer);
 
-  /* The Windows and Cygwin OS ABIs are currently equivalent.  */
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_WINDOWS,
-                          i386_windows_init_abi);
+                         i386_windows_init_abi);
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
-                          i386_windows_init_abi);
+                         i386_cygwin_init_abi);
 }
This page took 0.030065 seconds and 4 git commands to generate.