This revision was automatically updated to reflect the committed changes.
Closed by commit rL315498: Support DWARF unwinding on i386 windows (authored by 
mstorsjo).

Changed prior to commit:
  https://reviews.llvm.org/D38679?vs=118263&id=118673#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D38679

Files:
  libunwind/trunk/src/AddressSpace.hpp
  libunwind/trunk/src/UnwindRegistersRestore.S
  libunwind/trunk/src/assembly.h
  libunwind/trunk/src/config.h

Index: libunwind/trunk/src/UnwindRegistersRestore.S
===================================================================
--- libunwind/trunk/src/UnwindRegistersRestore.S
+++ libunwind/trunk/src/UnwindRegistersRestore.S
@@ -18,6 +18,10 @@
 #
 # void libunwind::Registers_x86::jumpto()
 #
+#if defined(_WIN32)
+# On windows, the 'this' pointer is passed in ecx instead of on the stack
+  movl   %ecx, %eax
+#else
 # On entry:
 #  +                       +
 #  +-----------------------+
@@ -27,6 +31,7 @@
 #  +-----------------------+   <-- SP
 #  +                       +
   movl   4(%esp), %eax
+#endif
   # set up eax and ret on new stack location
   movl  28(%eax), %edx # edx holds new stack pointer
   subl  $8,%edx
Index: libunwind/trunk/src/config.h
===================================================================
--- libunwind/trunk/src/config.h
+++ libunwind/trunk/src/config.h
@@ -37,6 +37,8 @@
     #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND
     #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
   #endif
+#elif defined(_WIN32)
+  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
 #else
   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
     #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
Index: libunwind/trunk/src/AddressSpace.hpp
===================================================================
--- libunwind/trunk/src/AddressSpace.hpp
+++ libunwind/trunk/src/AddressSpace.hpp
@@ -18,7 +18,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#ifndef _LIBUNWIND_IS_BAREMETAL
+#if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32)
 #include <dlfcn.h>
 #endif
 
@@ -97,7 +97,12 @@
 // independent ELF header traversal is not provided by <link.h> on some
 // systems (e.g., FreeBSD). On these systems the data structures are
 // just called Elf_XXX. Define ElfW() locally.
+#ifndef _WIN32
 #include <link.h>
+#else
+#include <windows.h>
+#include <psapi.h>
+#endif
 #if !defined(ElfW)
 #define ElfW(type) Elf_##type
 #endif
@@ -356,6 +361,43 @@
                              info.arm_section, info.arm_section_length);
   if (info.arm_section && info.arm_section_length)
     return true;
+#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32)
+  HMODULE mods[1024];
+  HANDLE process = GetCurrentProcess();
+  DWORD needed;
+
+  if (!EnumProcessModules(process, mods, sizeof(mods), &needed))
+    return false;
+
+  for (unsigned i = 0; i < (needed / sizeof(HMODULE)); i++) {
+    PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)mods[i];
+    PIMAGE_NT_HEADERS pinh = (PIMAGE_NT_HEADERS)((BYTE *)pidh + pidh->e_lfanew);
+    PIMAGE_FILE_HEADER pifh = (PIMAGE_FILE_HEADER)&pinh->FileHeader;
+    PIMAGE_SECTION_HEADER pish = IMAGE_FIRST_SECTION(pinh);
+    bool found_obj = false;
+    bool found_hdr = false;
+
+    info.dso_base = (uintptr_t)mods[i];
+    for (unsigned j = 0; j < pifh->NumberOfSections; j++, pish++) {
+      uintptr_t begin = pish->VirtualAddress + (uintptr_t)mods[i];
+      uintptr_t end = begin + pish->Misc.VirtualSize;
+      if (!strncmp((const char *)pish->Name, ".text",
+                   IMAGE_SIZEOF_SHORT_NAME)) {
+        if (targetAddr >= begin && targetAddr < end)
+          found_obj = true;
+      } else if (!strncmp((const char *)pish->Name, ".eh_frame",
+                          IMAGE_SIZEOF_SHORT_NAME)) {
+        // FIXME: This section name actually is truncated, ideally we
+        // should locate and check the full long name instead.
+        info.dwarf_section = begin;
+        info.dwarf_section_length = pish->Misc.VirtualSize;
+        found_hdr = true;
+      }
+      if (found_obj && found_hdr)
+        return true;
+    }
+  }
+  return false;
 #elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   struct dl_iterate_cb_data {
     LocalAddressSpace *addressSpace;
@@ -478,7 +520,7 @@
 inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
                                                 size_t bufLen,
                                                 unw_word_t *offset) {
-#ifndef _LIBUNWIND_IS_BAREMETAL
+#if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32)
   Dl_info dyldInfo;
   if (dladdr((void *)addr, &dyldInfo)) {
     if (dyldInfo.dli_sname != NULL) {
Index: libunwind/trunk/src/assembly.h
===================================================================
--- libunwind/trunk/src/assembly.h
+++ libunwind/trunk/src/assembly.h
@@ -26,6 +26,14 @@
 
 #if defined(__APPLE__)
 #define HIDDEN_DIRECTIVE .private_extern
+#elif defined(_WIN32)
+// In the COFF object file format, there's no attributes for a global,
+// non-static symbol to make it somehow hidden. So on windows, we don't
+// want to set this at all. To avoid conditionals in
+// DEFINE_LIBUNWIND_PRIVATE_FUNCTION below, make it .globl (which it already
+// is, defined in the same DEFINE_LIBUNWIND_PRIVATE_FUNCTION macro; the
+// duplicate .globl directives are harmless).
+#define HIDDEN_DIRECTIVE .globl
 #else
 #define HIDDEN_DIRECTIVE .hidden
 #endif
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to