Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Libunwind cherry pick #10

Merged
merged 4 commits into from
Mar 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions libunwind/include/libunwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,32 +125,6 @@ extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUN

extern unw_addr_space_t unw_local_addr_space;

#ifdef UNW_REMOTE
/*
* Mac OS X "remote" API for unwinding other processes on same machine
*
*/
extern unw_addr_space_t unw_create_addr_space_for_task(task_t);
extern void unw_destroy_addr_space(unw_addr_space_t);
extern int unw_init_remote_thread(unw_cursor_t *, unw_addr_space_t, thread_t *);
#endif /* UNW_REMOTE */

/*
* traditional libunwind "remote" API
* NOT IMPLEMENTED on Mac OS X
*
* extern int unw_init_remote(unw_cursor_t*, unw_addr_space_t,
* thread_t*);
* extern unw_accessors_t unw_get_accessors(unw_addr_space_t);
* extern unw_addr_space_t unw_create_addr_space(unw_accessors_t, int);
* extern void unw_flush_cache(unw_addr_space_t, unw_word_t,
* unw_word_t);
* extern int unw_set_caching_policy(unw_addr_space_t,
* unw_caching_policy_t);
* extern void _U_dyn_register(unw_dyn_info_t*);
* extern void _U_dyn_cancel(unw_dyn_info_t*);
*/

#ifdef __cplusplus
}
#endif
Expand Down
132 changes: 0 additions & 132 deletions libunwind/src/AddressSpace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,138 +601,6 @@ inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
return false;
}



#ifdef UNW_REMOTE

/// RemoteAddressSpace is used as a template parameter to UnwindCursor when
/// unwinding a thread in the another process. The other process can be a
/// different endianness and a different pointer size which is handled by
/// the P template parameter.
template <typename P>
class RemoteAddressSpace {
public:
RemoteAddressSpace(task_t task) : fTask(task) {}

typedef typename P::uint_t pint_t;

uint8_t get8(pint_t addr);
uint16_t get16(pint_t addr);
uint32_t get32(pint_t addr);
uint64_t get64(pint_t addr);
pint_t getP(pint_t addr);
uint64_t getRegister(pint_t addr);
uint64_t getULEB128(pint_t &addr, pint_t end);
int64_t getSLEB128(pint_t &addr, pint_t end);
pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
pint_t datarelBase = 0);
bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
unw_word_t *offset);
bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
bool findOtherFDE(pint_t targetAddr, pint_t &fde);
private:
void *localCopy(pint_t addr);

task_t fTask;
};

template <typename P> uint8_t RemoteAddressSpace<P>::get8(pint_t addr) {
return *((uint8_t *)localCopy(addr));
}

template <typename P> uint16_t RemoteAddressSpace<P>::get16(pint_t addr) {
return P::E::get16(*(uint16_t *)localCopy(addr));
}

template <typename P> uint32_t RemoteAddressSpace<P>::get32(pint_t addr) {
return P::E::get32(*(uint32_t *)localCopy(addr));
}

template <typename P> uint64_t RemoteAddressSpace<P>::get64(pint_t addr) {
return P::E::get64(*(uint64_t *)localCopy(addr));
}

template <typename P>
typename P::uint_t RemoteAddressSpace<P>::getP(pint_t addr) {
return P::getP(*(uint64_t *)localCopy(addr));
}

template <typename P>
typename P::uint_t OtherAddressSpace<P>::getRegister(pint_t addr) {
return P::getRegister(*(uint64_t *)localCopy(addr));
}

template <typename P>
uint64_t OtherAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) {
uintptr_t size = (end - addr);
LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
LocalAddressSpace::pint_t sladdr = laddr;
uint64_t result = LocalAddressSpace::getULEB128(laddr, laddr + size);
addr += (laddr - sladdr);
return result;
}

template <typename P>
int64_t RemoteAddressSpace<P>::getSLEB128(pint_t &addr, pint_t end) {
uintptr_t size = (end - addr);
LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
LocalAddressSpace::pint_t sladdr = laddr;
uint64_t result = LocalAddressSpace::getSLEB128(laddr, laddr + size);
addr += (laddr - sladdr);
return result;
}

template <typename P> void *RemoteAddressSpace<P>::localCopy(pint_t addr) {
// FIX ME
}

template <typename P>
bool RemoteAddressSpace<P>::findFunctionName(pint_t addr, char *buf,
size_t bufLen,
unw_word_t *offset) {
// FIX ME
}

/// unw_addr_space is the base class that abstract unw_addr_space_t type in
/// libunwind.h points to.
struct unw_addr_space {
cpu_type_t cpuType;
task_t taskPort;
};

/// unw_addr_space_i386 is the concrete instance that a unw_addr_space_t points
/// to when examining
/// a 32-bit intel process.
struct unw_addr_space_i386 : public unw_addr_space {
unw_addr_space_i386(task_t task) : oas(task) {}
RemoteAddressSpace<Pointer32<LittleEndian>> oas;
};

/// unw_addr_space_x86_64 is the concrete instance that a unw_addr_space_t
/// points to when examining
/// a 64-bit intel process.
struct unw_addr_space_x86_64 : public unw_addr_space {
unw_addr_space_x86_64(task_t task) : oas(task) {}
RemoteAddressSpace<Pointer64<LittleEndian>> oas;
};

/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points
/// to when examining
/// a 32-bit PowerPC process.
struct unw_addr_space_ppc : public unw_addr_space {
unw_addr_space_ppc(task_t task) : oas(task) {}
RemoteAddressSpace<Pointer32<BigEndian>> oas;
};

/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points
/// to when examining a 64-bit PowerPC process.
struct unw_addr_space_ppc64 : public unw_addr_space {
unw_addr_space_ppc64(task_t task) : oas(task) {}
RemoteAddressSpace<Pointer64<LittleEndian>> oas;
};

#endif // UNW_REMOTE

} // namespace libunwind

#endif // __ADDRESSSPACE_HPP__
15 changes: 9 additions & 6 deletions libunwind/src/Unwind-seh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,20 +442,23 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) {
static int
_unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) {
#ifdef _LIBUNWIND_TARGET_X86_64
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86_64>(
context, LocalAddressSpace::sThisAddressSpace);
new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor))
UnwindCursor<LocalAddressSpace, Registers_x86_64>(
context, LocalAddressSpace::sThisAddressSpace);
auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor);
co->setInfoBasedOnIPRegister();
return UNW_ESUCCESS;
#elif defined(_LIBUNWIND_TARGET_ARM)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm>(
context, LocalAddressSpace::sThisAddressSpace);
new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor))
UnwindCursor<LocalAddressSpace, Registers_arm>(
context, LocalAddressSpace::sThisAddressSpace);
auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor);
co->setInfoBasedOnIPRegister();
return UNW_ESUCCESS;
#elif defined(_LIBUNWIND_TARGET_AARCH64)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm64>(
context, LocalAddressSpace::sThisAddressSpace);
new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor))
UnwindCursor<LocalAddressSpace, Registers_arm64>(
context, LocalAddressSpace::sThisAddressSpace);
auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor);
co->setInfoBasedOnIPRegister();
return UNW_ESUCCESS;
Expand Down
8 changes: 8 additions & 0 deletions libunwind/src/UnwindCursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,10 @@ class UnwindCursor : public AbstractUnwindCursor {
DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; }
void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; }

// libunwind does not and should not depend on C++ library which means that we
// need our own defition of inline placement new.
static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }

private:

pint_t getLastPC() const { return _dispContext.ControlPc; }
Expand Down Expand Up @@ -892,6 +896,10 @@ class UnwindCursor : public AbstractUnwindCursor{
virtual void saveVFPAsX();
#endif

// libunwind does not and should not depend on C++ library which means that we
// need our own defition of inline placement new.
static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }

private:

#if defined(_LIBUNWIND_ARM_EHABI)
Expand Down
89 changes: 3 additions & 86 deletions libunwind/src/libunwind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
#ifndef NDEBUG
#include <cstdlib> // getenv
#endif
#include <new>
#include <algorithm>

#include "libunwind_ext.h"
#include "config.h"
Expand Down Expand Up @@ -73,97 +71,16 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
# error Architecture not supported
#endif
// Use "placement new" to allocate UnwindCursor in the cursor buffer.
new ((void *)cursor) UnwindCursor<LocalAddressSpace, REGISTER_KIND>(
context, LocalAddressSpace::sThisAddressSpace);
new (reinterpret_cast<UnwindCursor<LocalAddressSpace, REGISTER_KIND> *>(cursor))
UnwindCursor<LocalAddressSpace, REGISTER_KIND>(
context, LocalAddressSpace::sThisAddressSpace);
#undef REGISTER_KIND
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
co->setInfoBasedOnIPRegister();

return UNW_ESUCCESS;
}

#ifdef UNW_REMOTE
/// Create a cursor into a thread in another process.
_LIBUNWIND_EXPORT int unw_init_remote_thread(unw_cursor_t *cursor,
unw_addr_space_t as,
void *arg) {
// special case: unw_init_remote(xx, unw_local_addr_space, xx)
if (as == (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace)
return unw_init_local(cursor, NULL); //FIXME

// use "placement new" to allocate UnwindCursor in the cursor buffer
switch (as->cpuType) {
case CPU_TYPE_I386:
new ((void *)cursor)
UnwindCursor<RemoteAddressSpace<Pointer32<LittleEndian>>,
Registers_x86>(((unw_addr_space_i386 *)as)->oas, arg);
break;
case CPU_TYPE_X86_64:
new ((void *)cursor)
UnwindCursor<RemoteAddressSpace<Pointer64<LittleEndian>>,
Registers_x86_64>(((unw_addr_space_x86_64 *)as)->oas, arg);
break;
case CPU_TYPE_POWERPC:
new ((void *)cursor)
UnwindCursor<RemoteAddressSpace<Pointer32<BigEndian>>,
Registers_ppc>(((unw_addr_space_ppc *)as)->oas, arg);
break;
default:
return UNW_EUNSPEC;
}
return UNW_ESUCCESS;
}


static bool is64bit(task_t task) {
return false; // FIXME
}

/// Create an address_space object for use in examining another task.
_LIBUNWIND_EXPORT unw_addr_space_t unw_create_addr_space_for_task(task_t task) {
#if __i386__
if (is64bit(task)) {
unw_addr_space_x86_64 *as = new unw_addr_space_x86_64(task);
as->taskPort = task;
as->cpuType = CPU_TYPE_X86_64;
//as->oas
} else {
unw_addr_space_i386 *as = new unw_addr_space_i386(task);
as->taskPort = task;
as->cpuType = CPU_TYPE_I386;
//as->oas
}
#else
// FIXME
#endif
}


/// Delete an address_space object.
_LIBUNWIND_EXPORT void unw_destroy_addr_space(unw_addr_space_t asp) {
switch (asp->cpuType) {
#if __i386__ || __x86_64__
case CPU_TYPE_I386: {
unw_addr_space_i386 *as = (unw_addr_space_i386 *)asp;
delete as;
}
break;
case CPU_TYPE_X86_64: {
unw_addr_space_x86_64 *as = (unw_addr_space_x86_64 *)asp;
delete as;
}
break;
#endif
case CPU_TYPE_POWERPC: {
unw_addr_space_ppc *as = (unw_addr_space_ppc *)asp;
delete as;
}
break;
}
}
#endif // UNW_REMOTE


/// Get value of specified register at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_word_t *value) {
Expand Down