From 9098f1d3d96e36e3892c63d295de591791cc8849 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 13 Feb 2014 04:19:32 +0000 Subject: [PATCH] Change the ABI CallFrameAddressIsValid methods for i386 and x86_64. They were enforcing 16-byte alignment on stack frames for Darwin x86 programs. But we've found that trap handlers typically don't have the stack pointer aligned correctly when a trap happens and lldb wasn't backtracing all the way through. This method is only used as a safety guard to prevent lldb's unwinder from using a bogus address as a stack frame - we'll still enforce word-size alignment on stack frames so that should be fine. Also rolled back akaylor's changes from August 2013 in r188952 which changed the i386 ABI plugin to relax the CallFrameAddressIsValid offsets for non-Darwin targets where only 4-byte alignment is enforced. Now Darwin is the same as those environments. llvm-svn: 201292 --- .../ABI/MacOSX-i386/ABIMacOSX_i386.cpp | 22 +++-------- .../Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h | 37 +++++++++---------- .../Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h | 16 ++++++-- .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 2 +- 4 files changed, 37 insertions(+), 40 deletions(-) diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index f360a182e065..8596381b3cbc 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -235,22 +235,12 @@ ABIMacOSX_i386::GetRedZoneSize () const ABISP ABIMacOSX_i386::CreateInstance (const ArchSpec &arch) { - static ABISP g_abi_mac_sp; - static ABISP g_abi_other_sp; - if (arch.GetTriple().getArch() == llvm::Triple::x86) - { - if (arch.GetTriple().isOSDarwin()) - { - if (!g_abi_mac_sp) - g_abi_mac_sp.reset (new ABIMacOSX_i386(true)); - return g_abi_mac_sp; - } - else - { - if (!g_abi_other_sp) - g_abi_other_sp.reset (new ABIMacOSX_i386(false)); - return g_abi_other_sp; - } + static ABISP g_abi_sp; + if (arch.GetTriple().getArch() == llvm::Triple::x86) + { + if (!g_abi_sp) + g_abi_sp.reset (new ABIMacOSX_i386); + return g_abi_sp; } return ABISP(); } diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h index a2eee280fa38..43784a5c9111 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h @@ -71,24 +71,25 @@ public: return true; } + // The Darwin i386 ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size (4-bytes). + // Whitelisting the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. + // + // If we were to enforce 16-byte alignment, we also need to relax to 4-byte + // alignment for non-darwin i386 targets. virtual bool CallFrameAddressIsValid (lldb::addr_t cfa) { - // Darwin call frame addresses must be 16-byte aligned, but other OS's - // only need 4-byte alignment. Otherwise the ABI matches, so we have - // this one minor override here. - if (target_is_darwin) - { - // Make sure the stack call frame addresses are are 16 byte aligned - if (cfa & (16ull - 1ull)) - return false; // Not 16 byte aligned - } - else - { - // Make sure the stack call frame addresses are are 4 byte aligned - if (cfa & (4ull - 1ull)) - return false; // Not 4 byte aligned - } + // Make sure the stack call frame addresses are are 4 byte aligned + if (cfa & (4ull - 1ull)) + return false; // Not 4 byte aligned if (cfa == 0) return false; // Zero is not a valid stack address return true; @@ -139,11 +140,7 @@ protected: RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info); private: - ABIMacOSX_i386(bool is_darwin) : lldb_private::ABI(), - target_is_darwin(is_darwin) - { } // Call CreateInstance instead. - - bool target_is_darwin; + ABIMacOSX_i386() : lldb_private::ABI() { } // Call CreateInstance instead. }; diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h index 5ccb6e5fa744..7fd1b6c4b0f3 100644 --- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h +++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h @@ -68,12 +68,22 @@ public: return true; } + // The SysV x86_64 ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size (8-bytes). + // Whitelisting the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. virtual bool CallFrameAddressIsValid (lldb::addr_t cfa) { - // Make sure the stack call frame addresses are 16 byte aligned - if (cfa & (16ull - 1ull)) - return false; // Not 16 byte aligned + // Make sure the stack call frame addresses are 8 byte aligned + if (cfa & (8ull - 1ull)) + return false; // Not 8 byte aligned if (cfa == 0) return false; // Zero is not a valid stack address return true; diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index c84aec1c17fd..286b1ef62d9a 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -482,7 +482,7 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData (const lldb::ModuleSP module, const l Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); if (log) log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: " - "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%ld, tls_block=0x%" PRIx64 "\n", + "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n", mod->GetObjectName().AsCString(""), link_map, tp, (int64_t)modid, tls_block); return tls_block;