From 6d6cbf64e0b9c601ece8b48b184a8430b3325001 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Fri, 25 Jan 2019 21:39:46 +0000 Subject: [PATCH 1/4] [libunwind] Use placement new to avoid dependency C++ library The rest of libunwind already uses placement new, these are the only places where non-placement new is being used introducing undesirable C++ library dependency. Differential Revision: https://reviews.llvm.org/D57251 llvm-svn: 352245 --- libunwind/src/libunwind.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp index f4d71a1863bf46..60e1cc03ace0ac 100644 --- a/libunwind/src/libunwind.cpp +++ b/libunwind/src/libunwind.cpp @@ -15,8 +15,6 @@ #ifndef NDEBUG #include // getenv #endif -#include -#include #include "libunwind_ext.h" #include "config.h" @@ -123,12 +121,14 @@ static bool is64bit(task_t 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); + unw_addr_space_x86_64 *as = malloc(sizeof(unw_addr_space_x86_64)); + new (as) 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); + unw_addr_space_i386 *as = malloc(sizeof(unw_addr_space_i386)); + new (as) unw_addr_space_i386(task); as->taskPort = task; as->cpuType = CPU_TYPE_I386; //as->oas @@ -145,18 +145,21 @@ _LIBUNWIND_EXPORT void unw_destroy_addr_space(unw_addr_space_t asp) { #if __i386__ || __x86_64__ case CPU_TYPE_I386: { unw_addr_space_i386 *as = (unw_addr_space_i386 *)asp; - delete as; + as->~unw_addr_space_i386(); + free(as); } break; case CPU_TYPE_X86_64: { unw_addr_space_x86_64 *as = (unw_addr_space_x86_64 *)asp; - delete as; + as->~unw_addr_space_x86_64(); + free(as); } break; #endif case CPU_TYPE_POWERPC: { unw_addr_space_ppc *as = (unw_addr_space_ppc *)asp; - delete as; + as->~unw_addr_space_ppc(); + free(as); } break; } From 59d65bed0210ed7fa139e6a6d7caf9911f7a63c9 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Sat, 2 Feb 2019 20:54:03 +0000 Subject: [PATCH 2/4] [libunwind] Remove the remote unwinding support This is unfinished, unused and incomplete. This could be brought back in the future if there's a desire to build a more complete implementation, but at the moment it's just bitrotting. Differential Revision: https://reviews.llvm.org/D57252 llvm-svn: 352965 --- libunwind/include/libunwind.h | 26 ------- libunwind/src/AddressSpace.hpp | 132 --------------------------------- libunwind/src/libunwind.cpp | 87 ---------------------- 3 files changed, 245 deletions(-) diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h index 29c4aebde5ac72..4feef9b71175ef 100644 --- a/libunwind/include/libunwind.h +++ b/libunwind/include/libunwind.h @@ -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 diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp index 49bb360d794111..157eae9bc75a70 100644 --- a/libunwind/src/AddressSpace.hpp +++ b/libunwind/src/AddressSpace.hpp @@ -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 -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 uint8_t RemoteAddressSpace

::get8(pint_t addr) { - return *((uint8_t *)localCopy(addr)); -} - -template uint16_t RemoteAddressSpace

::get16(pint_t addr) { - return P::E::get16(*(uint16_t *)localCopy(addr)); -} - -template uint32_t RemoteAddressSpace

::get32(pint_t addr) { - return P::E::get32(*(uint32_t *)localCopy(addr)); -} - -template uint64_t RemoteAddressSpace

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

::getP(pint_t addr) { - return P::getP(*(uint64_t *)localCopy(addr)); -} - -template -typename P::uint_t OtherAddressSpace

::getRegister(pint_t addr) { - return P::getRegister(*(uint64_t *)localCopy(addr)); -} - -template -uint64_t OtherAddressSpace

::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 -int64_t RemoteAddressSpace

::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 void *RemoteAddressSpace

::localCopy(pint_t addr) { - // FIX ME -} - -template -bool RemoteAddressSpace

::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> 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> 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> 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> oas; -}; - -#endif // UNW_REMOTE - } // namespace libunwind #endif // __ADDRESSSPACE_HPP__ diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp index 60e1cc03ace0ac..94b74b40770c74 100644 --- a/libunwind/src/libunwind.cpp +++ b/libunwind/src/libunwind.cpp @@ -80,93 +80,6 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor, 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>, - Registers_x86>(((unw_addr_space_i386 *)as)->oas, arg); - break; - case CPU_TYPE_X86_64: - new ((void *)cursor) - UnwindCursor>, - Registers_x86_64>(((unw_addr_space_x86_64 *)as)->oas, arg); - break; - case CPU_TYPE_POWERPC: - new ((void *)cursor) - UnwindCursor>, - 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 = malloc(sizeof(unw_addr_space_x86_64)); - new (as) unw_addr_space_x86_64(task); - as->taskPort = task; - as->cpuType = CPU_TYPE_X86_64; - //as->oas - } else { - unw_addr_space_i386 *as = malloc(sizeof(unw_addr_space_i386)); - new (as) 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; - as->~unw_addr_space_i386(); - free(as); - } - break; - case CPU_TYPE_X86_64: { - unw_addr_space_x86_64 *as = (unw_addr_space_x86_64 *)asp; - as->~unw_addr_space_x86_64(); - free(as); - } - break; -#endif - case CPU_TYPE_POWERPC: { - unw_addr_space_ppc *as = (unw_addr_space_ppc *)asp; - as->~unw_addr_space_ppc(); - free(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) { From f8aa4976acc0eb7d7ad13d2dd97d15f92618c9f8 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Sat, 2 Feb 2019 21:15:49 +0000 Subject: [PATCH 3/4] [libunwind] Provide placement new definition While Clang automatically generates the code for placement new, g++ doesn't do that so we need to provide our own definition. Differential Revision: https://reviews.llvm.org/D57455 llvm-svn: 352966 --- libunwind/src/Unwind-seh.cpp | 15 +++++++++------ libunwind/src/UnwindCursor.hpp | 4 ++++ libunwind/src/libunwind.cpp | 5 +++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/libunwind/src/Unwind-seh.cpp b/libunwind/src/Unwind-seh.cpp index c5cf7c47d40dc5..190bd75cd602d8 100644 --- a/libunwind/src/Unwind-seh.cpp +++ b/libunwind/src/Unwind-seh.cpp @@ -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( - context, LocalAddressSpace::sThisAddressSpace); + new (reinterpret_cast *>(cursor)) + UnwindCursor( + context, LocalAddressSpace::sThisAddressSpace); auto *co = reinterpret_cast(cursor); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; #elif defined(_LIBUNWIND_TARGET_ARM) - new ((void *)cursor) UnwindCursor( - context, LocalAddressSpace::sThisAddressSpace); + new (reinterpret_cast *>(cursor)) + UnwindCursor( + context, LocalAddressSpace::sThisAddressSpace); auto *co = reinterpret_cast(cursor); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; #elif defined(_LIBUNWIND_TARGET_AARCH64) - new ((void *)cursor) UnwindCursor( - context, LocalAddressSpace::sThisAddressSpace); + new (reinterpret_cast *>(cursor)) + UnwindCursor( + context, LocalAddressSpace::sThisAddressSpace); auto *co = reinterpret_cast(cursor); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index 52439f9b54532c..638f0081430925 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -892,6 +892,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 *p) { return p; } + private: #if defined(_LIBUNWIND_ARM_EHABI) diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp index 94b74b40770c74..a8f48350d2d2b6 100644 --- a/libunwind/src/libunwind.cpp +++ b/libunwind/src/libunwind.cpp @@ -71,8 +71,9 @@ _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( - context, LocalAddressSpace::sThisAddressSpace); + new (reinterpret_cast *>(cursor)) + UnwindCursor( + context, LocalAddressSpace::sThisAddressSpace); #undef REGISTER_KIND AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; co->setInfoBasedOnIPRegister(); From b6e414a83a9af4674008983cc79e6b17410c5c09 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Sun, 3 Feb 2019 22:16:53 +0000 Subject: [PATCH 4/4] Provide a placement new definition for the SEH version of UnwindCursor This fixes compilation after SVN r352966 in SEH mode. llvm-svn: 353010 --- libunwind/src/UnwindCursor.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index 638f0081430925..d5602d4c4ba005 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -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 *p) { return p; } + private: pint_t getLastPC() const { return _dispContext.ControlPc; }