diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp | 88 |
1 files changed, 76 insertions, 12 deletions
diff --git a/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp b/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp index e2ae19e..b36be8e 100644 --- a/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp @@ -9,6 +9,10 @@ #include "lldb/Expression/DWARFExpression.h" +// C Includes +#include <inttypes.h> + +// C++ Includes #include <vector> #include "lldb/Core/DataEncoder.h" @@ -28,20 +32,18 @@ #include "lldb/lldb-private-log.h" -#include "lldb/Symbol/ClangASTType.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/Type.h" - #include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/StackID.h" +#include "lldb/Target/Thread.h" using namespace lldb; using namespace lldb_private; +// TODO- why is this also defined (in a better way) in DWARFDefines.cpp? const char * DW_OP_value_to_name (uint32_t val) { @@ -220,6 +222,7 @@ DW_OP_value_to_name (uint32_t val) // DWARFExpression constructor //---------------------------------------------------------------------- DWARFExpression::DWARFExpression() : + m_module_wp(), m_data(), m_reg_kind (eRegisterKindDWARF), m_loclist_slide (LLDB_INVALID_ADDRESS) @@ -227,6 +230,7 @@ DWARFExpression::DWARFExpression() : } DWARFExpression::DWARFExpression(const DWARFExpression& rhs) : + m_module_wp(rhs.m_module_wp), m_data(rhs.m_data), m_reg_kind (rhs.m_reg_kind), m_loclist_slide(rhs.m_loclist_slide) @@ -234,11 +238,14 @@ DWARFExpression::DWARFExpression(const DWARFExpression& rhs) : } -DWARFExpression::DWARFExpression(const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) : +DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) : + m_module_wp(), m_data(data, data_offset, data_length), m_reg_kind (eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) { + if (module_sp) + m_module_wp = module_sp; } //---------------------------------------------------------------------- @@ -262,11 +269,12 @@ DWARFExpression::SetOpcodeData (const DataExtractor& data) } void -DWARFExpression::CopyOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) +DWARFExpression::CopyOpcodeData (lldb::ModuleSP module_sp, const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) { const uint8_t *bytes = data.PeekData(data_offset, data_length); if (bytes) { + m_module_wp = module_sp; m_data.SetData(DataBufferSP(new DataBufferHeap(bytes, data_length))); m_data.SetByteOrder(data.GetByteOrder()); m_data.SetAddressByteSize(data.GetAddressByteSize()); @@ -274,8 +282,9 @@ DWARFExpression::CopyOpcodeData (const DataExtractor& data, lldb::offset_t data_ } void -DWARFExpression::SetOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) +DWARFExpression::SetOpcodeData (lldb::ModuleSP module_sp, const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) { + m_module_wp = module_sp; m_data.SetData(data, data_offset, data_length); } @@ -588,6 +597,9 @@ DWARFExpression::DumpLocation (Stream *s, lldb::offset_t offset, lldb::offset_t // case DW_OP_APPLE_array_ref: // s->PutCString("DW_OP_APPLE_array_ref"); // break; + case DW_OP_GNU_push_tls_address: + s->PutCString("DW_OP_GNU_push_tls_address"); // 0xe0 + break; case DW_OP_APPLE_uninit: s->PutCString("DW_OP_APPLE_uninit"); // 0xF0 break; @@ -919,7 +931,8 @@ GetOpcodeDataSize (const DataExtractor &data, const lldb::offset_t data_offset, case DW_OP_form_tls_address: // 0x9b DWARF3 case DW_OP_call_frame_cfa: // 0x9c DWARF3 case DW_OP_stack_value: // 0x9f DWARF4 - return 0; + case DW_OP_GNU_push_tls_address: // 0xe0 GNU extension + return 0; // Opcodes with a single 1 byte arguments case DW_OP_const1u: // 0x08 1 1-byte constant @@ -1221,6 +1234,8 @@ DWARFExpression::Evaluate Error *error_ptr ) const { + ModuleSP module_sp = m_module_wp.lock(); + if (IsLocationList()) { lldb::offset_t offset = 0; @@ -1268,7 +1283,7 @@ DWARFExpression::Evaluate if (length > 0 && lo_pc <= pc && pc < hi_pc) { - return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr); + return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, module_sp, m_data, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr); } offset += length; } @@ -1280,7 +1295,7 @@ DWARFExpression::Evaluate } // Not a location list, just a single expression. - return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr); + return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, module_sp, m_data, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr); } @@ -1292,6 +1307,7 @@ DWARFExpression::Evaluate ClangExpressionVariableList *expr_locals, ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx, + lldb::ModuleSP opcode_ctx, const DataExtractor& opcodes, const lldb::offset_t opcodes_offset, const lldb::offset_t opcodes_length, @@ -1347,7 +1363,7 @@ DWARFExpression::Evaluate if (log && log->GetVerbose()) { size_t count = stack.size(); - log->Printf("Stack before operation has %lu values:", count); + log->Printf("Stack before operation has %zu values:", count); for (size_t i=0; i<count; ++i) { StreamString new_value; @@ -2659,6 +2675,54 @@ DWARFExpression::Evaluate return false; } break; + + //---------------------------------------------------------------------- + // OPCODE: DW_OP_GNU_push_tls_address + // OPERANDS: none + // DESCRIPTION: Pops a TLS offset from the stack, converts it to + // an absolute value, and pushes it back on. + //---------------------------------------------------------------------- + case DW_OP_GNU_push_tls_address: + { + if (stack.size() < 1) + { + if (error_ptr) + error_ptr->SetErrorString("DW_OP_GNU_push_tls_address needs an argument."); + return false; + } + + if (!exe_ctx || !opcode_ctx) + { + if (error_ptr) + error_ptr->SetErrorString("No context to evaluate TLS within."); + return false; + } + + Thread *thread = exe_ctx->GetThreadPtr(); + if (!thread) + { + if (error_ptr) + error_ptr->SetErrorString("No thread to evaluate TLS within."); + return false; + } + + // Lookup the TLS block address for this thread and module. + addr_t tls_addr = thread->GetThreadLocalData (opcode_ctx); + + if (tls_addr == LLDB_INVALID_ADDRESS) + { + if (error_ptr) + error_ptr->SetErrorString ("No TLS data currently exists for this thread."); + return false; + } + + // Convert the TLS offset into the absolute address. + Scalar tmp = stack.back().ResolveValue(exe_ctx); + stack.back() = tmp + tls_addr; + stack.back().SetValueType (Value::eValueTypeLoadAddress); + } + break; + default: if (log) log->Printf("Unhandled opcode %s in DWARFExpression.", DW_OP_value_to_name(op)); @@ -2675,7 +2739,7 @@ DWARFExpression::Evaluate else if (log && log->GetVerbose()) { size_t count = stack.size(); - log->Printf("Stack after operation has %lu values:", count); + log->Printf("Stack after operation has %zu values:", count); for (size_t i=0; i<count; ++i) { StreamString new_value; |