summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2010-10-25 11:12:07 +0000
committerJason Molenda <jmolenda@apple.com>2010-10-25 11:12:07 +0000
commitab4f1924db7175fd04c78034684ff854d3b58255 (patch)
tree56ee59a62fe3eadb6ab70ea9e989950a0045f10d /lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
parent829b21fb02948e73a08bb3938153e0884a5f0b6d (diff)
downloadbcm5719-llvm-ab4f1924db7175fd04c78034684ff854d3b58255.tar.gz
bcm5719-llvm-ab4f1924db7175fd04c78034684ff854d3b58255.zip
Check in the native lldb unwinder.
Not yet enabled as the default unwinder but there are no known backtrace problems with the code at this point. Added 'log enable lldb unwind' to help diagnose backtrace problems; this output needs a little refining but it's a good first step. eh_frame information is currently read unconditionally - the code is structured to allow this to be delayed until it's actually needed. There is a performance hit when you have to parse the eh_frame information for any largeish executable/library so it's necessary to avoid if possible. It's confusing having both the UnwindPlan::RegisterLocation struct and the RegisterConextLLDB::RegisterLocation struct, I need to rename one of them. The writing of registers isn't done in the RegisterConextLLDB subclass yet; neither is the running of complex DWARF expressions from eh_frame (e.g. used for _sigtramp on Mac OS X). llvm-svn: 117256
Diffstat (limited to 'lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h')
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h177
1 files changed, 177 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
new file mode 100644
index 00000000000..41e43538e6d
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -0,0 +1,177 @@
+//===-- RegisterContextLLDB.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_RegisterContextLLDB_h_
+#define lldb_RegisterContextLLDB_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+class RegisterContextLLDB : public lldb_private::RegisterContext
+{
+public:
+ RegisterContextLLDB (lldb_private::Thread &thread,
+ const lldb::RegisterContextSP& next_frame,
+ lldb_private::SymbolContext& sym_ctx,
+ int frame_number);
+
+ ///
+ // pure virtual functions from the base class that we must implement
+ ///
+
+ virtual
+ ~RegisterContextLLDB () { }
+
+ virtual void
+ Invalidate ();
+
+ virtual size_t
+ GetRegisterCount ();
+
+ virtual const lldb::RegisterInfo *
+ GetRegisterInfoAtIndex (uint32_t reg);
+
+ virtual size_t
+ GetRegisterSetCount ();
+
+ virtual const lldb::RegisterSet *
+ GetRegisterSet (uint32_t reg_set);
+
+ virtual bool
+ ReadRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data);
+
+ virtual bool
+ ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
+
+ virtual bool
+ WriteRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data, uint32_t data_offset = 0);
+
+ virtual bool
+ WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
+
+ virtual uint32_t
+ ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
+
+ bool
+ IsValid () const;
+
+ bool
+ GetCFA (lldb::addr_t& cfa);
+
+ bool
+ GetStartPC (lldb::addr_t& start_pc);
+
+ bool
+ GetPC (lldb::addr_t& start_pc);
+
+private:
+
+ typedef enum FrameType
+ {
+ eNormalFrame,
+ eSigtrampFrame,
+ eDebuggerFrame, // a debugger inferior function call frame; we get caller's registers from debugger
+ eNotAValidFrame // this frame is invalid for some reason - most likely it is past the top (end) of the stack
+ };
+
+ enum RegisterLocationTypes
+ {
+ eRegisterNotSaved = 0, // register was not preserved by callee. If volatile reg, is unavailable
+ eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location)
+ eRegisterInRegister, // register is available in a (possible other) register (register_number)
+ eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space
+ eRegisterValueInferred // register val was computed (and is in register_value)
+ };
+
+ struct RegisterLocation
+ {
+ int type;
+ union
+ {
+ lldb::addr_t target_memory_location;
+ uint32_t register_number; // in eRegisterKindLLDB register numbering system
+ void* host_memory_location;
+ uint64_t register_value; // eRegisterValueInferred - e.g. stack pointer == cfa + offset
+ } location;
+ };
+
+
+ void
+ InitializeZerothFrame ();
+
+ void
+ InitializeNonZerothFrame();
+
+ // Provide a location for where THIS function saved the CALLER's register value
+ // Or a frame "below" this one savedit, i.e. a function called by this one, preserved a register that this
+ // function didn't modify/use.
+ //
+ // The RegisterLocation type may be set to eRegisterNotAvailable -- this will happen for a volatile register
+ // bieng queried mid-stack. Instead of floating frame 0's contents of that register up the stack (which may
+ // or may not be the value of that reg when the function was executing), we won't return any value.
+ //
+ // If a non-volatile register (a "preserved" register) is requested mid-stack and no frames "below" the requested
+ // stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same
+ // as the requesting frame's.
+ //
+ bool
+ SavedLocationForRegister (uint32_t lldb_regnum, RegisterLocation &regloc);
+
+ bool
+ ReadRegisterBytesFromRegisterLocation (uint32_t regnum, RegisterLocation regloc, lldb_private::DataExtractor &data);
+
+ bool
+ WriteRegisterBytesFromRegisterLocation (uint32_t regnum, RegisterLocation regloc, lldb_private::Scalar value);
+
+ // Get the contents of a general purpose (address-size) register for this frame
+ // (usually retrieved from the m_next_frame)
+ // m_base_reg_ectx and m_next_frame should both be initialized appropriately before calling.
+ bool
+ ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value);
+
+ void
+ GetUnwindPlansForFrame (lldb_private::Address current_pc);
+
+ lldb_private::Thread& m_thread;
+ lldb::RegisterContextSP m_next_frame;
+
+ lldb_private::RegisterContext *m_base_reg_ctx; // RegisterContext of frame 0 (live register values only)
+
+ ///
+ // The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above)
+ // i.e. where THIS frame saved them
+ ///
+
+ lldb_private::UnwindPlan *m_fast_unwind_plan; // may be NULL
+ lldb_private::UnwindPlan *m_full_unwind_plan;
+ bool m_zeroth_frame; // Is this the bottom-most, i.e. currently executing, frame?
+ bool m_all_registers_available; // Can we retrieve all regs or just nonvolatile regs?
+ int m_frame_type; // enum FrameType
+ int m_current_offset; // how far into the function we've executed; -1 if unknown
+ lldb_private::SymbolContext& m_sym_ctx;
+
+ int m_frame_number; // What stack frame level this frame is - used for debug logging
+
+ lldb::addr_t m_cfa;
+ lldb_private::Address m_start_pc;
+
+ std::map<uint32_t, RegisterLocation> m_registers; // where to find reg values for this frame
+
+ //------------------------------------------------------------------
+ // For RegisterContextLLDB only
+ //------------------------------------------------------------------
+
+ DISALLOW_COPY_AND_ASSIGN (RegisterContextLLDB);
+};
+
+#endif // lldb_RegisterContextLLDB_h_
OpenPOWER on IntegriCloud