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.

<rdar://problem/15982682> 

llvm-svn: 201292
This commit is contained in:
Jason Molenda 2014-02-13 04:19:32 +00:00
parent 2b97f9b211
commit 9098f1d3d9
4 changed files with 37 additions and 40 deletions

View File

@ -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();
}

View File

@ -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.
};

View File

@ -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;

View File

@ -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;