diff --git a/lldb/include/lldb/Target/ABI.h b/lldb/include/lldb/Target/ABI.h index eb0ae288310f..16f8ee7fc7d7 100644 --- a/lldb/include/lldb/Target/ABI.h +++ b/lldb/include/lldb/Target/ABI.h @@ -46,7 +46,6 @@ public: GetArgumentValues (Thread &thread, ValueList &values) const = 0; -public: lldb::ValueObjectSP GetReturnValueObject (Thread &thread, ClangASTType &type, @@ -72,12 +71,22 @@ public: virtual bool RegisterIsVolatile (const RegisterInfo *reg_info) = 0; + // Should return true if your ABI uses frames when doing stack backtraces. This + // means a frame pointer is used that points to the previous stack frame in some + // way or another. virtual bool StackUsesFrames () = 0; + // Should take a look at a call frame address (CFA) which is just the stack + // pointer value upon entry to a function. ABIs usually impose alignment + // restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed. + // This function should return true if "cfa" is valid call frame address for + // the ABI, and false otherwise. This is used by the generic stack frame unwinding + // code to help determine when a stack ends. virtual bool CallFrameAddressIsValid (lldb::addr_t cfa) = 0; + // Validates a possible PC value and returns true if an opcode can be at "pc". virtual bool CodeAddressIsValid (lldb::addr_t pc) = 0; @@ -93,7 +102,15 @@ public: virtual const RegisterInfo * GetRegisterInfoArray (uint32_t &count) = 0; - + // Some architectures (e.g. x86) will push the return address on the stack and decrement + // the stack pointer when making a function call. This means that every stack frame will + // have a unique CFA. + // Other architectures (e.g. arm) pass the return address in a register so it is possible + // to have a frame on a backtrace that does not push anything on the stack or change the + // CFA. + virtual bool + FunctionCallsChangeCFA () = 0; + bool GetRegisterInfoByName (const ConstString &name, RegisterInfo &info); diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h index 5e781be9a912..c1edb6edd624 100644 --- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h +++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h @@ -93,6 +93,12 @@ public: return pc & ~(lldb::addr_t)1; } + virtual bool + FunctionCallsChangeCFA () + { + return false; + } + virtual const lldb_private::RegisterInfo * GetRegisterInfoArray (uint32_t &count); diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h index 6dcfff52ab83..4cc94ab0348c 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h @@ -93,7 +93,13 @@ public: // Just make sure the address is a valid 32 bit address. return pc <= UINT32_MAX; } - + + virtual bool + FunctionCallsChangeCFA () + { + return true; + } + virtual const lldb_private::RegisterInfo * GetRegisterInfoArray (uint32_t &count); 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 9efc24499486..d0fd38589e6a 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 @@ -91,7 +91,13 @@ public: // aren't fixed width... return true; } - + + virtual bool + FunctionCallsChangeCFA () + { + return true; + } + virtual const lldb_private::RegisterInfo * GetRegisterInfoArray (uint32_t &count); //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index 96b812901a42..e922add20ce4 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -604,7 +604,7 @@ RegisterContextLLDB::InitializeNonZerothFrame() repeating_frames = true; } } - if (repeating_frames) + if (repeating_frames && abi->FunctionCallsChangeCFA()) { if (log) {