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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits