forked from OSchip/llvm-project
Support DWARF unwinding on i386 windows
In practice, with code built with clang, there are still unresolved issues with DW_CFA_GNU_args_size though. Differential Revision: https://reviews.llvm.org/D38679 llvm-svn: 315498
This commit is contained in:
parent
b03f480c8d
commit
210d9f43a3
|
@ -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 @@ extern char __exidx_end;
|
|||
// 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 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
|
|||
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::findOtherFDE(pint_t targetAddr, pint_t &fde) {
|
|||
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) {
|
||||
|
|
|
@ -18,6 +18,10 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
|
|||
#
|
||||
# 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 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
|
|||
# +-----------------------+ <-- 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue