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 <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef _LIBUNWIND_IS_BAREMETAL
|
#if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32)
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -97,7 +97,12 @@ extern char __exidx_end;
|
||||||
// independent ELF header traversal is not provided by <link.h> on some
|
// independent ELF header traversal is not provided by <link.h> on some
|
||||||
// systems (e.g., FreeBSD). On these systems the data structures are
|
// systems (e.g., FreeBSD). On these systems the data structures are
|
||||||
// just called Elf_XXX. Define ElfW() locally.
|
// just called Elf_XXX. Define ElfW() locally.
|
||||||
|
#ifndef _WIN32
|
||||||
#include <link.h>
|
#include <link.h>
|
||||||
|
#else
|
||||||
|
#include <windows.h>
|
||||||
|
#include <psapi.h>
|
||||||
|
#endif
|
||||||
#if !defined(ElfW)
|
#if !defined(ElfW)
|
||||||
#define ElfW(type) Elf_##type
|
#define ElfW(type) Elf_##type
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -356,6 +361,43 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
|
||||||
info.arm_section, info.arm_section_length);
|
info.arm_section, info.arm_section_length);
|
||||||
if (info.arm_section && info.arm_section_length)
|
if (info.arm_section && info.arm_section_length)
|
||||||
return true;
|
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)
|
#elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||||
struct dl_iterate_cb_data {
|
struct dl_iterate_cb_data {
|
||||||
LocalAddressSpace *addressSpace;
|
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,
|
inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
|
||||||
size_t bufLen,
|
size_t bufLen,
|
||||||
unw_word_t *offset) {
|
unw_word_t *offset) {
|
||||||
#ifndef _LIBUNWIND_IS_BAREMETAL
|
#if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32)
|
||||||
Dl_info dyldInfo;
|
Dl_info dyldInfo;
|
||||||
if (dladdr((void *)addr, &dyldInfo)) {
|
if (dladdr((void *)addr, &dyldInfo)) {
|
||||||
if (dyldInfo.dli_sname != NULL) {
|
if (dyldInfo.dli_sname != NULL) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
|
||||||
#
|
#
|
||||||
# void libunwind::Registers_x86::jumpto()
|
# 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:
|
# On entry:
|
||||||
# + +
|
# + +
|
||||||
# +-----------------------+
|
# +-----------------------+
|
||||||
|
|
@ -27,6 +31,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
|
||||||
# +-----------------------+ <-- SP
|
# +-----------------------+ <-- SP
|
||||||
# + +
|
# + +
|
||||||
movl 4(%esp), %eax
|
movl 4(%esp), %eax
|
||||||
|
#endif
|
||||||
# set up eax and ret on new stack location
|
# set up eax and ret on new stack location
|
||||||
movl 28(%eax), %edx # edx holds new stack pointer
|
movl 28(%eax), %edx # edx holds new stack pointer
|
||||||
subl $8,%edx
|
subl $8,%edx
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,14 @@
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#define HIDDEN_DIRECTIVE .private_extern
|
#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
|
#else
|
||||||
#define HIDDEN_DIRECTIVE .hidden
|
#define HIDDEN_DIRECTIVE .hidden
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@
|
||||||
#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND
|
#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND
|
||||||
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
|
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
|
||||||
#endif
|
#endif
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
|
||||||
#else
|
#else
|
||||||
#if defined(__ARM_DWARF_EH__) || !defined(__arm__)
|
#if defined(__ARM_DWARF_EH__) || !defined(__arm__)
|
||||||
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
|
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue