diff options
27 files changed, 411 insertions, 295 deletions
diff --git a/lldb/include/lldb/Core/DataExtractor.h b/lldb/include/lldb/Core/DataExtractor.h index b6ac6e93d08..1e14fff7039 100644 --- a/lldb/include/lldb/Core/DataExtractor.h +++ b/lldb/include/lldb/Core/DataExtractor.h @@ -1024,7 +1024,7 @@ public: /// The number of bytes that this object now contains. //------------------------------------------------------------------ uint32_t - SetData (const DataExtractor& data, uint32_t offset = 0, uint32_t length = UINT_MAX); + SetData (const DataExtractor& data, uint32_t offset = 0, uint32_t length = UINT32_MAX); //------------------------------------------------------------------ /// Adopt a subset of shared data in \a data_sp. @@ -1052,7 +1052,7 @@ public: /// The number of bytes that this object now contains. //------------------------------------------------------------------ uint32_t - SetData (lldb::DataBufferSP& data_sp, uint32_t offset = 0, uint32_t length = UINT_MAX); + SetData (lldb::DataBufferSP& data_sp, uint32_t offset = 0, uint32_t length = UINT32_MAX); //------------------------------------------------------------------ /// Set the byte_order value. diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h index 26b489f2f81..fae70c8ca38 100644 --- a/lldb/include/lldb/Core/Module.h +++ b/lldb/include/lldb/Core/Module.h @@ -208,7 +208,7 @@ public: /// /// @param[in] max_matches /// Allow the number of matches to be limited to \a - /// max_matches. Specify UINT_MAX to get all possible matches. + /// max_matches. Specify UINT32_MAX to get all possible matches. /// /// @param[in] variable_list /// A list of variables that gets the matches appended to (if @@ -233,7 +233,7 @@ public: /// /// @param[in] max_matches /// Allow the number of matches to be limited to \a - /// max_matches. Specify UINT_MAX to get all possible matches. + /// max_matches. Specify UINT32_MAX to get all possible matches. /// /// @param[in] variable_list /// A list of variables that gets the matches appended to (if @@ -262,7 +262,7 @@ public: /// /// @param[in] max_matches /// Allow the number of matches to be limited to \a - /// max_matches. Specify UINT_MAX to get all possible matches. + /// max_matches. Specify UINT32_MAX to get all possible matches. /// /// @param[in] encoding /// Limit the search to specific types, or get all types if @@ -298,7 +298,7 @@ public: /// /// @param[in] max_matches /// Allow the number of matches to be limited to \a - /// max_matches. Specify UINT_MAX to get all possible matches. + /// max_matches. Specify UINT32_MAX to get all possible matches. /// /// @param[in] encoding /// Limit the search to specific types, or get all types if diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 35f9851fadf..47ff65d3a94 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -177,7 +177,7 @@ public: /// /// @param[in] max_matches /// Allow the number of matches to be limited to \a - /// max_matches. Specify UINT_MAX to get all possible matches. + /// max_matches. Specify UINT32_MAX to get all possible matches. /// /// @param[in] variable_list /// A list of variables that gets the matches appended to (if @@ -205,7 +205,7 @@ public: /// /// @param[in] max_matches /// Allow the number of matches to be limited to \a - /// max_matches. Specify UINT_MAX to get all possible matches. + /// max_matches. Specify UINT32_MAX to get all possible matches. /// /// @param[in] variable_list /// A list of variables that gets the matches appended to (if @@ -287,7 +287,7 @@ public: /// /// @param[in] max_matches /// Allow the number of matches to be limited to \a - /// max_matches. Specify UINT_MAX to get all possible matches. + /// max_matches. Specify UINT32_MAX to get all possible matches. /// /// @param[in] encoding /// Limit the search to specific types, or get all types if diff --git a/lldb/include/lldb/Core/Section.h b/lldb/include/lldb/Core/Section.h index f698a5a0778..54331a664cb 100644 --- a/lldb/include/lldb/Core/Section.h +++ b/lldb/include/lldb/Core/Section.h @@ -61,10 +61,10 @@ public: GetSharedPointer (const Section *section, bool check_children) const; lldb::SectionSP - FindSectionContainingFileAddress (lldb::addr_t addr, uint32_t depth = UINT_MAX) const; + FindSectionContainingFileAddress (lldb::addr_t addr, uint32_t depth = UINT32_MAX) const; lldb::SectionSP - FindSectionContainingLinkedFileAddress (lldb::addr_t vm_addr) const; + FindSectionContainingLinkedFileAddress (lldb::addr_t vm_addr, uint32_t depth) const; bool GetSectionData (const DataExtractor& module_data, DataExtractor& section_data) const; @@ -81,7 +81,7 @@ public: GetNumSections (uint32_t depth) const; bool - ReplaceSection (lldb::user_id_t sect_id, lldb::SectionSP& sect_sp, uint32_t depth = UINT_MAX); + ReplaceSection (lldb::user_id_t sect_id, lldb::SectionSP& sect_sp, uint32_t depth = UINT32_MAX); lldb::SectionSP GetSectionAtIndex (uint32_t idx) const; diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h index 170bec51d7b..b988d2e9426 100644 --- a/lldb/include/lldb/Expression/DWARFExpression.h +++ b/lldb/include/lldb/Expression/DWARFExpression.h @@ -57,15 +57,10 @@ public: /// /// @param[in] data_length /// The byte length of the location expression. - /// - /// @param[in] loclist_base_addr_ptr - /// If non-NULL, the address of the location list in the target - /// process's .debug_loc section. //------------------------------------------------------------------ DWARFExpression(const DataExtractor& data, uint32_t data_offset, - uint32_t data_length, - const Address* loclist_base_addr_ptr); + uint32_t data_length); //------------------------------------------------------------------ /// Copy constructor @@ -86,9 +81,18 @@ public: /// /// @param[in] level /// The level of verbosity to use. + /// + /// @param[in] location_list_base_addr + /// If this is a location list based expression, this is the + /// address of the object that owns it. NOTE: this value is + /// different from the DWARF version of the location list base + /// address which is compile unit relative. This base address + /// is the address of the object that owns the location list. //------------------------------------------------------------------ void - GetDescription (Stream *s, lldb::DescriptionLevel level) const; + GetDescription (Stream *s, + lldb::DescriptionLevel level, + lldb::addr_t location_list_base_addr) const; //------------------------------------------------------------------ /// Return true if the location expression contains data @@ -115,11 +119,11 @@ public: /// True if IsLocationList() is true and the address was found; /// false otherwise. //------------------------------------------------------------------ +// bool +// LocationListContainsLoadAddress (Process* process, const Address &addr) const; +// bool - LocationListContainsLoadAddress (Process* process, const Address &addr) const; - - bool - LocationListContainsLoadAddress (Process* process, lldb::addr_t load_addr) const; + LocationListContainsAddress (lldb::addr_t loclist_base_addr, lldb::addr_t addr) const; //------------------------------------------------------------------ /// Make the expression parser read its location information from a @@ -128,13 +132,9 @@ public: /// @param[in] data /// A data extractor configured to read the DWARF location expression's /// bytecode. - /// - /// @param[in] loclist_base_addr_ptr - /// If non-NULL, the address of the location list in the target - /// process's .debug_loc section. //------------------------------------------------------------------ void - SetOpcodeData(const DataExtractor& data, const Address* loclist_base_addr_ptr); + SetOpcodeData(const DataExtractor& data); //------------------------------------------------------------------ /// Make the expression parser read its location information from a @@ -149,23 +149,22 @@ public: /// /// @param[in] data_length /// The byte length of the location expression. - /// - /// @param[in] loclist_base_addr_ptr - /// If non-NULL, the address of the location list in the target - /// process's .debug_loc section. //------------------------------------------------------------------ void - SetOpcodeData(const DataExtractor& data, uint32_t data_offset, uint32_t data_length, const Address* loclist_base_addr_ptr); + SetOpcodeData(const DataExtractor& data, uint32_t data_offset, uint32_t data_length); //------------------------------------------------------------------ - /// Make the expression parser refer to a location list + /// Tells the expression that it refers to a location list. /// - /// @param[in] base_addr - /// The address of the location list in the target process's .debug_loc - /// section. + /// @param[in] slide + /// This value should be a slide that is applied to any values + /// in the location list data so the values become zero based + /// offsets into the object that owns the location list. We need + /// to make location lists relative to the objects that own them + /// so we can relink addresses on the fly. //------------------------------------------------------------------ void - SetLocationListBaseAddress(Address& base_addr); + SetLocationListSlide (lldb::addr_t slide); //------------------------------------------------------------------ /// Return the call-frame-info style register kind @@ -190,6 +189,7 @@ public: bool Evaluate (ExecutionContextScope *exe_scope, clang::ASTContext *ast_context, + lldb::addr_t loclist_base_load_addr, const Value* initial_value_ptr, Value& result, Error *error_ptr) const; @@ -201,6 +201,7 @@ public: bool Evaluate (ExecutionContext *exe_ctx, clang::ASTContext *ast_context, + lldb::addr_t loclist_base_load_addr, const Value* initial_value_ptr, Value& result, Error *error_ptr) const; @@ -318,7 +319,9 @@ protected: DataExtractor m_data; ///< A data extractor capable of reading opcode bytes int m_reg_kind; ///< One of the defines that starts with LLDB_REGKIND_ - Address m_loclist_base_addr; ///< Base address needed for location lists + lldb::addr_t m_loclist_slide; ///< A value used to slide the location list offsets so that + ///< they are relative to the object that owns the location list + ///< (the function for frame base and variable location lists) ClangExpressionVariableList *m_expr_locals; ///< The locals used by this expression. See Evaluate() ClangExpressionDeclMap *m_decl_map; ///< The external variables used by this expression. See Evaluate() }; diff --git a/lldb/include/lldb/Symbol/Symtab.h b/lldb/include/lldb/Symbol/Symtab.h index 1d804433465..b036d47e765 100644 --- a/lldb/include/lldb/Symbol/Symtab.h +++ b/lldb/include/lldb/Symbol/Symtab.h @@ -49,8 +49,8 @@ public: const Symbol * SymbolAtIndex (uint32_t idx) const; Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx); // const Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx) const; - uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT_MAX) const; - uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT_MAX) const; + uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const; + uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const; uint32_t AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& matches); uint32_t AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches); uint32_t AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, lldb::SymbolType symbol_type, std::vector<uint32_t>& matches); diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index ea7e73a51fc..e79937bfbf4 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -309,91 +309,6 @@ public: } void - DumpVariable (CommandReturnObject &result, ExecutionContext *exe_ctx, Variable *variable) - { - if (variable) - { - Stream &s = result.GetOutputStream(); - DWARFExpression &expr = variable->LocationExpression(); - Value expr_result; - Error expr_error; - Type *variable_type = variable->GetType(); - bool expr_success = expr.Evaluate(exe_ctx, NULL, NULL, expr_result, &expr_error); - - if (m_options.debug) - s.Printf ("Variable{0x%8.8x}: ", variable->GetID()); - - if (!expr_success) - s.Printf ("%s = ERROR: %s\n", variable->GetName().AsCString(NULL), expr_error.AsCString()); - else - { - Value::ValueType expr_value_type = expr_result.GetValueType(); - switch (expr_value_type) - { - case Value::eValueTypeScalar: - s.Printf ("%s = ", variable->GetName().AsCString(NULL)); - if (variable_type) - { - DataExtractor data; - if (expr_result.ResolveValue (exe_ctx, NULL).GetData (data)) - variable_type->DumpValue (exe_ctx, &s, data, 0, m_options.show_types, m_options.show_summary, m_options.debug); - } - break; - - case Value::eValueTypeFileAddress: - case Value::eValueTypeLoadAddress: - case Value::eValueTypeHostAddress: - { - s.Printf ("%s = ", variable->GetName().AsCString(NULL)); - lldb::addr_t addr = LLDB_INVALID_ADDRESS; - lldb::AddressType addr_type = eAddressTypeLoad; - - if (expr_value_type == Value::eValueTypeFileAddress) - { - lldb::addr_t file_addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS); - SymbolContext var_sc; - variable->CalculateSymbolContext(&var_sc); - if (var_sc.module_sp) - { - ObjectFile *objfile = var_sc.module_sp->GetObjectFile(); - if (objfile) - { - Address so_addr(file_addr, objfile->GetSectionList()); - addr = so_addr.GetLoadAddress(exe_ctx->process); - } - if (addr == LLDB_INVALID_ADDRESS) - { - result.GetErrorStream().Printf ("error: %s is not loaded\n", - var_sc.module_sp->GetFileSpec().GetFilename().AsCString()); - } - } - else - { - result.GetErrorStream().Printf ("error: unable to resolve the variable address 0x%llx\n", file_addr); - } - } - else - { - if (expr_value_type == Value::eValueTypeHostAddress) - addr_type = eAddressTypeHost; - addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS); - } - - if (addr != LLDB_INVALID_ADDRESS) - { - if (m_options.debug) - s.Printf("@ 0x%8.8llx, value = ", addr); - variable_type->DumpValueInMemory (exe_ctx, &s, addr, addr_type, m_options.show_types, m_options.show_summary, m_options.debug); - } - } - break; - } - s.EOL(); - } - } - } - - void DumpValueObject (CommandReturnObject &result, ExecutionContextScope *exe_scope, ValueObject *valobj, diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp index a86695d46e7..b506879d50a 100644 --- a/lldb/source/Core/Section.cpp +++ b/lldb/source/Core/Section.cpp @@ -641,7 +641,7 @@ SectionList::FindSectionContainingFileAddress (addr_t vm_addr, uint32_t depth) c SectionSP -SectionList::FindSectionContainingLinkedFileAddress (addr_t vm_addr) const +SectionList::FindSectionContainingLinkedFileAddress (addr_t vm_addr, uint32_t depth) const { SectionSP sect_sp; const_iterator sect_iter; @@ -652,7 +652,10 @@ SectionList::FindSectionContainingLinkedFileAddress (addr_t vm_addr) const if (sect->ContainsLinkedFileAddress (vm_addr)) { sect_sp = *sect_iter; - break; + } + else if (depth > 0) + { + sect_sp = sect->GetChildren().FindSectionContainingLinkedFileAddress (vm_addr, depth - 1); } } return sect_sp; diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp index fef94dc3dad..9a432ab381c 100644 --- a/lldb/source/Core/ValueObjectVariable.cpp +++ b/lldb/source/Core/ValueObjectVariable.cpp @@ -103,9 +103,17 @@ ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope) Variable *variable = m_variable_sp.get(); DWARFExpression &expr = variable->LocationExpression(); - Value old_value(m_value); + lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS; ExecutionContext exe_ctx (exe_scope); - if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, m_value, &m_error)) + if (expr.IsLocationList()) + { + SymbolContext sc; + variable->CalculateSymbolContext (&sc); + if (sc.function) + loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.process); + } + Value old_value(m_value); + if (expr.Evaluate (&exe_ctx, GetClangAST(), loclist_base_load_addr, NULL, m_value, &m_error)) { m_value.SetContext(Value::eContextTypeDCVariable, variable); diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 37d13a98a52..e3e5d9467f4 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -830,9 +830,17 @@ ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx, std::auto_ptr<Value> var_location(new Value); + lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS; + + if (var_location_expr.IsLocationList()) + { + SymbolContext var_sc; + var->CalculateSymbolContext (&var_sc); + loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.process); + } Error err; - if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, NULL, *var_location.get(), &err)) + if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, loclist_base_load_addr, NULL, *var_location.get(), &err)) { if (log) log->Printf("Error evaluating location: %s", err.AsCString()); diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 77e1581ceaf..a29994ef4b0 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/StreamString.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" +#include "lldb/Core/VMRange.h" #include "lldb/Expression/ClangExpressionDeclMap.h" #include "lldb/Expression/ClangExpressionVariable.h" @@ -216,7 +217,7 @@ DW_OP_value_to_name (uint32_t val) DWARFExpression::DWARFExpression() : m_data(), m_reg_kind (eRegisterKindDWARF), - m_loclist_base_addr(), + m_loclist_slide (LLDB_INVALID_ADDRESS), m_expr_locals (NULL), m_decl_map (NULL) { @@ -225,22 +226,20 @@ DWARFExpression::DWARFExpression() : DWARFExpression::DWARFExpression(const DWARFExpression& rhs) : m_data(rhs.m_data), m_reg_kind (rhs.m_reg_kind), - m_loclist_base_addr(rhs.m_loclist_base_addr), + m_loclist_slide(rhs.m_loclist_slide), m_expr_locals (rhs.m_expr_locals), m_decl_map (rhs.m_decl_map) { } -DWARFExpression::DWARFExpression(const DataExtractor& data, uint32_t data_offset, uint32_t data_length, const Address* loclist_base_addr_ptr) : +DWARFExpression::DWARFExpression(const DataExtractor& data, uint32_t data_offset, uint32_t data_length) : m_data(data, data_offset, data_length), m_reg_kind (eRegisterKindDWARF), - m_loclist_base_addr(), + m_loclist_slide(LLDB_INVALID_ADDRESS), m_expr_locals (NULL), m_decl_map (NULL) { - if (loclist_base_addr_ptr) - m_loclist_base_addr = *loclist_base_addr_ptr; } //---------------------------------------------------------------------- @@ -271,23 +270,15 @@ DWARFExpression::SetExpressionDeclMap (ClangExpressionDeclMap *decl_map) } void -DWARFExpression::SetOpcodeData (const DataExtractor& data, const Address* loclist_base_addr_ptr) +DWARFExpression::SetOpcodeData (const DataExtractor& data) { m_data = data; - if (loclist_base_addr_ptr != NULL) - m_loclist_base_addr = *loclist_base_addr_ptr; - else - m_loclist_base_addr.Clear(); } void -DWARFExpression::SetOpcodeData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length, const Address* loclist_base_addr_ptr) +DWARFExpression::SetOpcodeData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length) { m_data.SetData(data, data_offset, data_length); - if (loclist_base_addr_ptr != NULL) - m_loclist_base_addr = *loclist_base_addr_ptr; - else - m_loclist_base_addr.Clear(); } void @@ -561,9 +552,9 @@ DWARFExpression::DumpLocation (Stream *s, uint32_t offset, uint32_t length, lldb } void -DWARFExpression::SetLocationListBaseAddress(Address& base_addr) +DWARFExpression::SetLocationListSlide (addr_t slide) { - m_loclist_base_addr = base_addr; + m_loclist_slide = slide; } int @@ -581,18 +572,18 @@ DWARFExpression::SetRegisterKind (int reg_kind) bool DWARFExpression::IsLocationList() const { - return m_loclist_base_addr.IsSectionOffset(); + return m_loclist_slide != LLDB_INVALID_ADDRESS; } void -DWARFExpression::GetDescription (Stream *s, lldb::DescriptionLevel level) const +DWARFExpression::GetDescription (Stream *s, lldb::DescriptionLevel level, addr_t location_list_base_addr) const { if (IsLocationList()) { // We have a location list uint32_t offset = 0; uint32_t count = 0; - Address base_addr(m_loclist_base_addr); + addr_t curr_base_addr = location_list_base_addr; while (m_data.ValidOffset(offset)) { lldb::addr_t begin_addr_offset = m_data.GetAddress(&offset); @@ -601,9 +592,8 @@ DWARFExpression::GetDescription (Stream *s, lldb::DescriptionLevel level) const { if (count > 0) s->PutCString(", "); - AddressRange addr_range(base_addr, end_addr_offset - begin_addr_offset); - addr_range.GetBaseAddress().SetOffset(base_addr.GetOffset() + begin_addr_offset); - addr_range.Dump (s, NULL, Address::DumpStyleFileAddress); + VMRange addr_range(curr_base_addr + begin_addr_offset, curr_base_addr + end_addr_offset); + addr_range.Dump(s, 0, 8); s->PutChar('{'); uint32_t location_length = m_data.GetU16(&offset); DumpLocation (s, offset, location_length, level); @@ -620,6 +610,7 @@ DWARFExpression::GetDescription (Stream *s, lldb::DescriptionLevel level) const if (m_data.GetAddressByteSize() == 4 && begin_addr_offset == 0xFFFFFFFFull || m_data.GetAddressByteSize() == 8 && begin_addr_offset == 0xFFFFFFFFFFFFFFFFull) { + curr_base_addr = end_addr_offset + location_list_base_addr; // We have a new base address if (count > 0) s->PutCString(", "); @@ -685,25 +676,60 @@ ReadRegisterValueAsScalar return false; } -bool -DWARFExpression::LocationListContainsLoadAddress (Process* process, const Address &addr) const -{ - return LocationListContainsLoadAddress(process, addr.GetLoadAddress(process)); -} +//bool +//DWARFExpression::LocationListContainsLoadAddress (Process* process, const Address &addr) const +//{ +// return LocationListContainsLoadAddress(process, addr.GetLoadAddress(process)); +//} +// +//bool +//DWARFExpression::LocationListContainsLoadAddress (Process* process, addr_t load_addr) const +//{ +// if (load_addr == LLDB_INVALID_ADDRESS) +// return false; +// +// if (IsLocationList()) +// { +// uint32_t offset = 0; +// +// addr_t loc_list_base_addr = m_loclist_slide.GetLoadAddress(process); +// +// if (loc_list_base_addr == LLDB_INVALID_ADDRESS) +// return false; +// +// while (m_data.ValidOffset(offset)) +// { +// // We need to figure out what the value is for the location. +// addr_t lo_pc = m_data.GetAddress(&offset); +// addr_t hi_pc = m_data.GetAddress(&offset); +// if (lo_pc == 0 && hi_pc == 0) +// break; +// else +// { +// lo_pc += loc_list_base_addr; +// hi_pc += loc_list_base_addr; +// +// if (lo_pc <= load_addr && load_addr < hi_pc) +// return true; +// +// offset += m_data.GetU16(&offset); +// } +// } +// } +// return false; +//} bool -DWARFExpression::LocationListContainsLoadAddress (Process* process, addr_t load_addr) const +DWARFExpression::LocationListContainsAddress (lldb::addr_t loclist_base_addr, lldb::addr_t addr) const { - if (load_addr == LLDB_INVALID_ADDRESS) + if (addr == LLDB_INVALID_ADDRESS) return false; if (IsLocationList()) { uint32_t offset = 0; - addr_t loc_list_base_addr = m_loclist_base_addr.GetLoadAddress(process); - - if (loc_list_base_addr == LLDB_INVALID_ADDRESS) + if (loclist_base_addr == LLDB_INVALID_ADDRESS) return false; while (m_data.ValidOffset(offset)) @@ -715,10 +741,10 @@ DWARFExpression::LocationListContainsLoadAddress (Process* process, addr_t load_ break; else { - lo_pc += loc_list_base_addr; - hi_pc += loc_list_base_addr; + lo_pc += loclist_base_addr - m_loclist_slide; + hi_pc += loclist_base_addr - m_loclist_slide; - if (lo_pc <= load_addr && load_addr < hi_pc) + if (lo_pc <= addr && addr < hi_pc) return true; offset += m_data.GetU16(&offset); @@ -733,13 +759,14 @@ DWARFExpression::Evaluate ( ExecutionContextScope *exe_scope, clang::ASTContext *ast_context, + lldb::addr_t loclist_base_load_addr, const Value* initial_value_ptr, Value& result, Error *error_ptr ) const { ExecutionContext exe_ctx (exe_scope); - return Evaluate(&exe_ctx, ast_context, initial_value_ptr, result, error_ptr); + return Evaluate(&exe_ctx, ast_context, loclist_base_load_addr, initial_value_ptr, result, error_ptr); } bool @@ -747,6 +774,7 @@ DWARFExpression::Evaluate ( ExecutionContext *exe_ctx, clang::ASTContext *ast_context, + lldb::addr_t loclist_base_load_addr, const Value* initial_value_ptr, Value& result, Error *error_ptr @@ -757,43 +785,39 @@ DWARFExpression::Evaluate uint32_t offset = 0; addr_t pc = exe_ctx->frame->GetRegisterContext()->GetPC(); - if (pc == LLDB_INVALID_ADDRESS) + if (loclist_base_load_addr != LLDB_INVALID_ADDRESS) { - if (error_ptr) - error_ptr->SetErrorString("Invalid PC in frame."); - return false; - } - - addr_t loc_list_base_addr = m_loclist_base_addr.GetLoadAddress(exe_ctx->process); - - if (loc_list_base_addr == LLDB_INVALID_ADDRESS) - { - if (error_ptr) - error_ptr->SetErrorString("Out of scope."); - return false; - } - - while (m_data.ValidOffset(offset)) - { - // We need to figure out what the value is for the location. - addr_t lo_pc = m_data.GetAddress(&offset); - addr_t hi_pc = m_data.GetAddress(&offset); - if (lo_pc == 0 && hi_pc == 0) + if (pc == LLDB_INVALID_ADDRESS) { - break; + if (error_ptr) + error_ptr->SetErrorString("Invalid PC in frame."); + return false; } - else - { - lo_pc += loc_list_base_addr; - hi_pc += loc_list_base_addr; - uint16_t length = m_data.GetU16(&offset); + addr_t curr_loclist_base_load_addr = loclist_base_load_addr; - if (length > 0 && lo_pc <= pc && pc < hi_pc) + while (m_data.ValidOffset(offset)) + { + // We need to figure out what the value is for the location. + addr_t lo_pc = m_data.GetAddress(&offset); + addr_t hi_pc = m_data.GetAddress(&offset); + if (lo_pc == 0 && hi_pc == 0) + { + break; + } + else { - return DWARFExpression::Evaluate (exe_ctx, ast_context, m_data, m_expr_locals, m_decl_map, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr); + lo_pc += curr_loclist_base_load_addr - m_loclist_slide; + hi_pc += curr_loclist_base_load_addr - m_loclist_slide; + + uint16_t length = m_data.GetU16(&offset); + + if (length > 0 && lo_pc <= pc && pc < hi_pc) + { + return DWARFExpression::Evaluate (exe_ctx, ast_context, m_data, m_expr_locals, m_decl_map, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr); + } + offset += length; } - offset += length; } } if (error_ptr) diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp index e5b3ca25574..e1c4eb39250 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp @@ -1152,8 +1152,8 @@ RegisterContextMach_arm::NumSupportedHardwareBreakpoints () #if defined (__arm__) // Set the init value to something that will let us know that we need to // autodetect how many breakpoints are supported dynamically... - static uint32_t g_num_supported_hw_breakpoints = UINT_MAX - if (g_num_supported_hw_breakpoints == UINT_MAX) + static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX; + if (g_num_supported_hw_breakpoints == UINT32_MAX) { // Set this to zero in case we can't tell if there are any HW breakpoints g_num_supported_hw_breakpoints = 0; @@ -1282,8 +1282,8 @@ RegisterContextMach_arm::NumSupportedHardwareWatchpoints () #if defined (__arm__) // Set the init value to something that will let us know that we need to // autodetect how many watchpoints are supported dynamically... - static uint32_t g_num_supported_hw_watchpoints = UINT_MAX; - if (g_num_supported_hw_watchpoints == UINT_MAX) + static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX; + if (g_num_supported_hw_watchpoints == UINT32_MAX) { // Set this to zero in case we can't tell if there are any HW breakpoints g_num_supported_hw_watchpoints = 0; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 8a21e1ec555..d75b5fc4cf4 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -355,7 +355,7 @@ DWARFCompileUnit::SetDIERelations() // the running average ends up being in the stdout log. static size_t g_total_cu_debug_info_size = 0; static size_t g_total_num_dies = 0; - static size_t g_min_bytes_per_die = UINT_MAX; + static size_t g_min_bytes_per_die = UINT32_MAX; static size_t g_max_bytes_per_die = 0; const size_t num_dies = m_die_array.size(); const size_t cu_debug_info_size = GetDebugInfoSize(); @@ -555,7 +555,9 @@ DWARFCompileUnit::Index lldb_private::UniqueCStringMap<dw_offset_t>& method_name_to_function_die, lldb_private::UniqueCStringMap<dw_offset_t>& selector_name_to_function_die, lldb_private::UniqueCStringMap<dw_offset_t>& name_to_type_die, - lldb_private::UniqueCStringMap<dw_offset_t>& name_to_global_die + lldb_private::UniqueCStringMap<dw_offset_t>& name_to_global_die, + const DWARFDebugRanges *debug_ranges, + DWARFDebugAranges *aranges ) { const DataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data(); @@ -599,6 +601,10 @@ DWARFCompileUnit::Index bool has_address = false; bool has_location = false; bool is_global_or_static_variable = false; + dw_addr_t lo_pc = DW_INVALID_ADDRESS; + dw_addr_t hi_pc = DW_INVALID_ADDRESS; + DWARFDebugRanges::RangeList ranges; + dw_offset_t specification_die_offset = DW_INVALID_OFFSET; const size_t num_attributes = die.GetAttributes(m_dwarf2Data, this, attributes); if (num_attributes > 0) @@ -634,7 +640,36 @@ DWARFCompileUnit::Index break; case DW_AT_low_pc: + has_address = true; + if (tag == DW_TAG_subprogram && attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) + { + lo_pc = form_value.Unsigned(); + } + break; + + case DW_AT_high_pc: + has_address = true; + if (tag == DW_TAG_subprogram && attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) + { + hi_pc = form_value.Unsigned(); + } + break; + case DW_AT_ranges: + if (tag == DW_TAG_subprogram && attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) + { + if (debug_ranges) + { + debug_ranges->FindRanges(form_value.Unsigned(), ranges); + // All DW_AT_ranges are relative to the base address of the + // compile unit. We add the compile unit base address to make + // sure all the addresses are properly fixed up. + ranges.AddOffset(GetBaseAddress()); + } + } + has_address = true; + break; + case DW_AT_entry_pc: has_address = true; break; @@ -693,6 +728,22 @@ DWARFCompileUnit::Index break; } } + + if (tag == DW_TAG_subprogram) + { + if (lo_pc != DW_INVALID_ADDRESS && hi_pc != DW_INVALID_ADDRESS) + { + aranges->AppendRange (m_offset, lo_pc, hi_pc); + } + else + { + for (size_t i=0, num_ranges = ranges.Size(); i<num_ranges; ++i) + { + const DWARFDebugRanges::Range *range = ranges.RangeAtIndex (i); + aranges->AppendRange (m_offset, range->begin_offset, range->end_offset); + } + } + } } switch (tag) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index d269537ce69..0e097dd5c86 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -26,7 +26,7 @@ public: DWARFDebugInfoEntry** function_die, DWARFDebugInfoEntry** block_die); - size_t AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& matching_dies, uint32_t depth = UINT_MAX) const; + size_t AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& matching_dies, uint32_t depth = UINT32_MAX) const; void Clear(); bool Verify(lldb_private::Stream *s) const; void Dump(lldb_private::Stream *s) const; @@ -147,7 +147,9 @@ public: lldb_private::UniqueCStringMap<dw_offset_t>& method_name_to_function_die, lldb_private::UniqueCStringMap<dw_offset_t>& selector_name_to_function_die, lldb_private::UniqueCStringMap<dw_offset_t>& name_to_type_die, - lldb_private::UniqueCStringMap<dw_offset_t>& name_to_global_die); + lldb_private::UniqueCStringMap<dw_offset_t>& name_to_global_die, + const DWARFDebugRanges* debug_ranges, + DWARFDebugAranges *aranges); protected: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp index c51a2dde34d..9c5f05ec5be 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp @@ -45,7 +45,7 @@ DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, uint32_t* of else { if (prev_abbr_code + 1 != abbrevDeclaration.Code()) - m_idx_offset = UINT_MAX; // Out of order indexes, we can't do O(1) lookups... + m_idx_offset = UINT32_MAX; // Out of order indexes, we can't do O(1) lookups... } prev_abbr_code = abbrevDeclaration.Code(); } @@ -69,7 +69,7 @@ DWARFAbbreviationDeclarationSet::Dump(Stream *s) const const DWARFAbbreviationDeclaration* DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const { - if (m_idx_offset == UINT_MAX) + if (m_idx_offset == UINT32_MAX) { DWARFAbbreviationDeclarationCollConstIter pos; DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp index 39c5a7fd189..1c8ef58c3c5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp @@ -35,7 +35,6 @@ DWARFDebugAranges::DWARFDebugAranges() : //---------------------------------------------------------------------- static bool RangeLessThan (const DWARFDebugAranges::Range& range1, const DWARFDebugAranges::Range& range2) { -// printf("RangeLessThan -- 0x%8.8x < 0x%8.8x ? %d\n", range1.lo_pc, range1.lo_pc, range1.lo_pc < range2.lo_pc); return range1.lo_pc < range2.lo_pc; } @@ -274,6 +273,54 @@ DWARFDebugAranges::InsertRange(const DWARFDebugAranges::Range& range) } +void +DWARFDebugAranges::AppendRange (dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc) +{ + if (!m_aranges.empty()) + { + if (m_aranges.back().offset == offset && m_aranges.back().hi_pc == low_pc) + { + m_aranges.back().hi_pc = high_pc; + return; + } + } + m_aranges.push_back (DWARFDebugAranges::Range(low_pc, high_pc, offset)); +} + +void +DWARFDebugAranges::Sort() +{ + // Sort our address range entries + std::stable_sort (m_aranges.begin(), m_aranges.end(), RangeLessThan); + + // Merge any entries that have the same offset and same start/end address + RangeColl::iterator pos = m_aranges.begin(); + RangeColl::iterator end = m_aranges.end(); + while (pos != end) + { + RangeColl::iterator next_pos = pos + 1; + if (next_pos != end && + pos->offset == next_pos->offset && + pos->hi_pc == next_pos->lo_pc) + { + // We have found an entry whose end address it he same as the + // next entry's start address and the offsets are the same so + // we can merge these two entries. + pos->hi_pc = next_pos->hi_pc; + // Erase the next entry that wasn't needed + pos = m_aranges.erase (next_pos); + // Now recompute the end of the collection + end = m_aranges.end(); + } + else + { + // Two entries have either different offsets or there are gaps + // in the address range, move along, nothing to see here. + pos = next_pos; + } + } +} + //---------------------------------------------------------------------- // FindAddress //---------------------------------------------------------------------- diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h index f3db949bf26..0861376fc66 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -59,8 +59,13 @@ public: bool GetMaxRange(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const; bool Extract(const lldb_private::DataExtractor &debug_aranges_data); bool Generate(SymbolFileDWARF* dwarf2Data); - void InsertRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc); - void InsertRange(const DWARFDebugAranges::Range& range); + void InsertRange (dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc); + void InsertRange (const DWARFDebugAranges::Range& range); + + // Use append range multiple times and then call sort + void AppendRange (dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc); + void Sort(); + const Range* RangeAtIndex(uint32_t idx) const { if (idx < m_aranges.size()) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index fcb0ccf1189..abe26ef0b38 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -868,7 +868,7 @@ typedef struct DumpInfo strm(init_strm), die_offset(off), recurse_depth(depth), - found_depth(UINT_MAX), + found_depth(UINT32_MAX), found_die(false), ancestors() { @@ -959,7 +959,7 @@ static dw_offset_t DumpCallback // We have already found our DIE and are printing it's children. Obey // our recurse depth and return an invalid offset if we get done // dumping all the the children - if (dumpInfo->recurse_depth == UINT_MAX || curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth) + if (dumpInfo->recurse_depth == UINT32_MAX || curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth) die->Dump(dwarf2Data, cu, s, 0); } else if (dumpInfo->die_offset > die->GetOffset()) @@ -1076,7 +1076,7 @@ DWARFDebugInfo::Dump else { s->Printf(" for DIE entry at .debug_info[0x%8.8x]", die_offset); - if (recurse_depth != UINT_MAX) + if (recurse_depth != UINT32_MAX) s->Printf(" recursing %u levels deep.", recurse_depth); s->EOL(); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 19eef06d3d1..50a7e9ba5ed 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -56,7 +56,7 @@ DWARFDebugInfoEntry::Attributes::FindAttributeIndex(dw_attr_t attr) const if (pos->attr == attr) return std::distance(beg, pos); } - return UINT_MAX; + return UINT32_MAX; } void @@ -69,14 +69,14 @@ DWARFDebugInfoEntry::Attributes::Append(const DWARFCompileUnit *cu, dw_offset_t bool DWARFDebugInfoEntry::Attributes::ContainsAttribute(dw_attr_t attr) const { - return FindAttributeIndex(attr) != UINT_MAX; + return FindAttributeIndex(attr) != UINT32_MAX; } bool DWARFDebugInfoEntry::Attributes::RemoveAttribute(dw_attr_t attr) { uint32_t attr_index = FindAttributeIndex(attr); - if (attr_index != UINT_MAX) + if (attr_index != UINT32_MAX) { m_infos.erase(m_infos.begin() + attr_index); return true; @@ -584,9 +584,9 @@ DWARFDebugInfoEntry::Compare if (a_attr_count != b_attr_count) { uint32_t is_decl_index = a_attrs.FindAttributeIndex(DW_AT_declaration); - uint32_t a_name_index = UINT_MAX; - uint32_t b_name_index = UINT_MAX; - if (is_decl_index != UINT_MAX) + uint32_t a_name_index = UINT32_MAX; + uint32_t b_name_index = UINT32_MAX; + if (is_decl_index != UINT32_MAX) { if (a_attr_count == 2) { @@ -597,13 +597,13 @@ DWARFDebugInfoEntry::Compare else { is_decl_index = b_attrs.FindAttributeIndex(DW_AT_declaration); - if (is_decl_index != UINT_MAX && a_attr_count == 2) + if (is_decl_index != UINT32_MAX && a_attr_count == 2) { a_name_index = a_attrs.FindAttributeIndex(DW_AT_name); b_name_index = b_attrs.FindAttributeIndex(DW_AT_name); } } - if (a_name_index != UINT_MAX && b_name_index != UINT_MAX) + if (a_name_index != UINT32_MAX && b_name_index != UINT32_MAX) { if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, a_name_index, a_form_value) && b_attrs.ExtractFormValueAtIndex(dwarf2Data, b_name_index, b_form_value)) @@ -794,6 +794,7 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges dw_addr_t lo_pc = DW_INVALID_ADDRESS; dw_addr_t hi_pc = DW_INVALID_ADDRESS; std::vector<dw_offset_t> die_offsets; + bool set_frame_base_loclist_addr = false; if (m_abbrevDecl) { const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); @@ -892,18 +893,26 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges { uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); uint32_t block_length = form_value.Unsigned(); - frame_base->SetOpcodeData(debug_info_data, block_offset, block_length, NULL); + frame_base->SetOpcodeData(debug_info_data, block_offset, block_length); } else { - const DataExtractor& debug_loc_data = dwarf2Data->get_debug_loc_data(); + const DataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data(); const dw_offset_t debug_loc_offset = form_value.Unsigned(); size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); if (loc_list_length > 0) { - Address base_address(cu->GetBaseAddress(), dwarf2Data->GetObjectFile()->GetSectionList()); - frame_base->SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address); + frame_base->SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length); + if (lo_pc != DW_INVALID_ADDRESS) + { + assert (lo_pc >= cu->GetBaseAddress()); + frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress()); + } + else + { + set_frame_base_loclist_addr = true; + } } } } @@ -928,6 +937,12 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges ranges.AddRange(lo_pc, lo_pc); } } + + if (set_frame_base_loclist_addr) + { + assert (ranges.LowestAddress(0) >= cu->GetBaseAddress()); + frame_base->SetLocationListSlide(ranges.LowestAddress(0) - cu->GetBaseAddress()); + } if (ranges.Size() == 0 || (name == NULL) || (mangled == NULL)) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp index 2b3f39b24f3..ed658032b63 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -1008,7 +1008,7 @@ static bool FindMatchingAddress (const DWARFDebugLine::Row& row1, const DWARFDeb uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const { - uint32_t index = UINT_MAX; + uint32_t index = UINT32_MAX; if (!rows.empty()) { // Use the lower_bound algorithm to perform a binary search since we know @@ -1036,7 +1036,7 @@ DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc if (index > 0) --index; else - index = UINT_MAX; + index = UINT32_MAX; } } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index c8fef6504f2..0dbd479c5ab 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -418,19 +418,29 @@ SymbolFileDWARF::DebugAbbrev() const DWARFDebugAranges* SymbolFileDWARF::DebugAranges() { - if (m_aranges.get() == NULL) - { - Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); - m_aranges.reset(new DWARFDebugAranges()); - if (m_aranges.get()) - { - const DataExtractor &debug_aranges_data = get_debug_aranges_data(); - if (debug_aranges_data.GetByteSize() > 0) - m_aranges->Extract(debug_aranges_data); - else - m_aranges->Generate(this); - } - } + // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files + // and we are already parsing all of the DWARF because the .debug_pubnames + // is useless (it only mentions symbols that are externally visible), so + // don't use the .debug_aranges section, we should be using a debug aranges + // we got from SymbolFileDWARF::Index(). + + if (!m_indexed) + Index(); + + +// if (m_aranges.get() == NULL) +// { +// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); +// m_aranges.reset(new DWARFDebugAranges()); +// if (m_aranges.get()) +// { +// const DataExtractor &debug_aranges_data = get_debug_aranges_data(); +// if (debug_aranges_data.GetByteSize() > 0) +// m_aranges->Extract(debug_aranges_data); +// else +// m_aranges->Generate(this); +// } +// } return m_aranges.get(); } @@ -1492,7 +1502,7 @@ SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_i if (dc_cu.get()) { // Figure out the compile unit index if we weren't given one - if (cu_idx == UINT_MAX) + if (cu_idx == UINT32_MAX) DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx); m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx); @@ -1507,7 +1517,7 @@ SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* f sc.Clear(); // Check if the symbol vendor already knows about this compile unit? sc.module_sp = m_obj_file->GetModule()->GetSP(); - sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); + sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX); sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get(); if (sc.function == NULL) @@ -1669,7 +1679,7 @@ SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); found_line = sc.line_entry.line; - while (line_idx != UINT_MAX) + while (line_idx != UINT32_MAX) { sc.function = NULL; sc.block = NULL; @@ -1742,6 +1752,8 @@ SymbolFileDWARF::Index () DWARFDebugInfo* debug_info = DebugInfo(); if (debug_info) { + m_aranges.reset(new DWARFDebugAranges()); + uint32_t cu_idx = 0; const uint32_t num_compile_units = GetNumCompileUnits(); for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) @@ -1755,7 +1767,9 @@ SymbolFileDWARF::Index () m_method_name_to_function_die, m_selector_name_to_function_die, m_name_to_global_die, - m_name_to_type_die); + m_name_to_type_die, + DebugRanges(), + m_aranges.get()); // Keep memory down by clearing DIEs if this generate function // caused them to be parsed @@ -1769,6 +1783,7 @@ SymbolFileDWARF::Index () m_selector_name_to_function_die.Sort(); m_name_to_global_die.Sort(); m_name_to_type_die.Sort(); + m_aranges->Sort(); } } @@ -1804,10 +1819,10 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint sc.module_sp = m_obj_file->GetModule()->GetSP(); assert (sc.module_sp); - sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); + sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX); assert(sc.comp_unit != NULL); - ParseVariables(sc, cu_sp.get(), die, false, false, &variables); + ParseVariables(sc, cu_sp.get(), LLDB_INVALID_ADDRESS, die, false, false, &variables); if (variables.GetSize() - original_size >= max_matches) break; @@ -1854,10 +1869,10 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append assert (sc.module_sp); - sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); + sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX); assert(sc.comp_unit != NULL); - ParseVariables(sc, cu_sp.get(), die, false, false, &variables); + ParseVariables(sc, cu_sp.get(), LLDB_INVALID_ADDRESS, die, false, false, &variables); if (variables.GetSize() - original_size >= max_matches) break; @@ -3308,7 +3323,11 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) if (sc.function) { const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); - return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true); + + dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS); + assert (func_lo_pc != DW_INVALID_ADDRESS); + + return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true); } else if (sc.comp_unit) { @@ -3328,7 +3347,7 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) const size_t num_globals = dwarf_cu->GetNumGlobals(); for (size_t idx=0; idx<num_globals; ++idx) { - VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx))); + VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx), LLDB_INVALID_ADDRESS)); if (var_sp) { variables->AddVariable(var_sp); @@ -3348,7 +3367,8 @@ SymbolFileDWARF::ParseVariableDIE ( const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, - const DWARFDebugInfoEntry *die + const DWARFDebugInfoEntry *die, + const lldb::addr_t func_low_pc ) { @@ -3393,7 +3413,7 @@ SymbolFileDWARF::ParseVariableDIE uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); uint32_t block_length = form_value.Unsigned(); - location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL); + location.SetOpcodeData(get_debug_info_data(), block_offset, block_length); } else { @@ -3403,8 +3423,9 @@ SymbolFileDWARF::ParseVariableDIE size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); if (loc_list_length > 0) { - Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList()); - location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address); + location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length); + assert (func_low_pc != LLDB_INVALID_ADDRESS); + location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress()); } } } @@ -3489,6 +3510,7 @@ SymbolFileDWARF::ParseVariables ( const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, + const lldb::addr_t func_low_pc, const DWARFDebugInfoEntry *orig_die, bool parse_siblings, bool parse_children, @@ -3565,7 +3587,7 @@ SymbolFileDWARF::ParseVariables (tag == DW_TAG_constant) || (tag == DW_TAG_formal_parameter && sc.function)) { - VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die)); + VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc)); if (var_sp) { variables->AddVariable(var_sp); @@ -3578,7 +3600,7 @@ SymbolFileDWARF::ParseVariables if (!skip_children && parse_children && die->HasChildren()) { - vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true); + vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true); //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index fc4325a5447..2d86359f010 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -218,7 +218,7 @@ protected: bool ParseCompileUnit(DWARFCompileUnit* cu, lldb::CompUnitSP& compile_unit_sp); DWARFCompileUnit* GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid); DWARFCompileUnit* GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu); - lldb_private::CompileUnit* GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx = UINT_MAX); + lldb_private::CompileUnit* GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx = UINT32_MAX); bool GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, lldb_private::SymbolContext& sc); lldb_private::Function * ParseCompileUnitFunction (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die); size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc, @@ -234,11 +234,13 @@ protected: lldb::VariableSP ParseVariableDIE( const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, - const DWARFDebugInfoEntry *die); + const DWARFDebugInfoEntry *die, + const lldb::addr_t func_low_pc); size_t ParseVariables( const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, + const lldb::addr_t func_low_pc, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 0140dd2dc70..b99a30ce476 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -617,30 +617,15 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint3 { SectionList *oso_section_list = oso_objfile->GetSectionList(); + SectionSP oso_symbol_section_sp (oso_section_list->FindSectionContainingLinkedFileAddress (exe_file_addr, UINT32_MAX)); - SectionSP oso_section_sp(oso_section_list->FindSectionByName(exe_so_addr.GetSection()->GetName())); - if (oso_section_sp) + if (oso_symbol_section_sp) { - SectionSP oso_symbol_section_sp (oso_section_sp->GetChildren().FindSectionContainingLinkedFileAddress (exe_file_addr)); - - if (oso_symbol_section_sp) - { - const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress(); - Address oso_so_addr (oso_symbol_section_sp.get(), exe_file_addr - linked_file_addr); - if (oso_so_addr.IsSectionOffset()) - resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); - } + const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress(); + Address oso_so_addr (oso_symbol_section_sp.get(), exe_file_addr - linked_file_addr); + if (oso_so_addr.IsSectionOffset()) + resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); } - // Map the load address from in the executable back to a - // section/offset address in the .o file so we can do - // lookups in the .o DWARF. -// Address oso_so_addr (exe_load_addr, false, comp_unit_info->debug_map_sections_sp.get()); -// -// // Make sure we were able to resolve this back to a .o -// // section offset address, and if so, resolve the context -// // for everything that was asked for. -// if (oso_so_addr.IsSectionOffset()) -// resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); } } } diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp index 33098f8bb22..b263e57851d 100644 --- a/lldb/source/Symbol/CompileUnit.cpp +++ b/lldb/source/Symbol/CompileUnit.cpp @@ -331,7 +331,7 @@ CompileUnit::ResolveSymbolContext // we will use this for our subsequent line exact matches below. found_line = sc.line_entry.line; - while (line_idx != UINT_MAX) + while (line_idx != UINT32_MAX) { sc_list.Append(sc); line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_indexes.front(), found_line, true, &sc.line_entry); @@ -350,7 +350,7 @@ CompileUnit::ResolveSymbolContext // we will use this for our subsequent line exact matches below. found_line = sc.line_entry.line; - while (line_idx != UINT_MAX) + while (line_idx != UINT32_MAX) { sc_list.Append(sc); line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_indexes, found_line, true, &sc.line_entry); diff --git a/lldb/source/Symbol/LineTable.cpp b/lldb/source/Symbol/LineTable.cpp index 6b11f2449c5..55c13f3aa10 100644 --- a/lldb/source/Symbol/LineTable.cpp +++ b/lldb/source/Symbol/LineTable.cpp @@ -294,7 +294,7 @@ LineTable::FindLineEntryIndexByFileIndex const size_t count = m_entries.size(); std::vector<uint32_t>::const_iterator begin_pos = file_indexes.begin(); std::vector<uint32_t>::const_iterator end_pos = file_indexes.end(); - size_t best_match = UINT_MAX; + size_t best_match = UINT32_MAX; for (size_t idx = start_idx; idx < count; ++idx) { @@ -329,20 +329,20 @@ LineTable::FindLineEntryIndexByFileIndex } } - if (best_match != UINT_MAX) + if (best_match != UINT32_MAX) { if (line_entry_ptr) ConvertEntryAtIndexToLineEntry (best_match, *line_entry_ptr); return best_match; } - return UINT_MAX; + return UINT32_MAX; } uint32_t LineTable::FindLineEntryIndexByFileIndex (uint32_t start_idx, uint32_t file_idx, uint32_t line, bool exact, LineEntry* line_entry_ptr) { const size_t count = m_entries.size(); - size_t best_match = UINT_MAX; + size_t best_match = UINT32_MAX; for (size_t idx = start_idx; idx < count; ++idx) { @@ -377,13 +377,13 @@ LineTable::FindLineEntryIndexByFileIndex (uint32_t start_idx, uint32_t file_idx, } } - if (best_match != UINT_MAX) + if (best_match != UINT32_MAX) { if (line_entry_ptr) ConvertEntryAtIndexToLineEntry (best_match, *line_entry_ptr); return best_match; } - return UINT_MAX; + return UINT32_MAX; } void diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index a5c74e60f1a..3aafa2bd919 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -94,7 +94,15 @@ Variable::Dump(Stream *s, bool show_context) const if (m_location.IsValid()) { s->PutCString(", location = "); - m_location.GetDescription(s, lldb::eDescriptionLevelBrief); + lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; + if (m_location.IsLocationList()) + { + SymbolContext variable_sc; + m_owner_scope->CalculateSymbolContext(&variable_sc); + if (variable_sc.function) + loclist_base_addr = variable_sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); + } + m_location.GetDescription(s, lldb::eDescriptionLevelBrief, loclist_base_addr); } if (m_external) @@ -130,6 +138,7 @@ Variable::IsInScope (StackFrame *frame) switch (m_scope) { case eValueTypeVariableGlobal: + case eValueTypeVariableStatic: // Globals and statics are always in scope. return true; @@ -140,27 +149,40 @@ Variable::IsInScope (StackFrame *frame) // address range? if (m_location.IsLocationList()) { + SymbolContext sc; + CalculateSymbolContext(&sc); + + // Currently we only support functions that have things with + // locations lists. If this expands, we will need to add support + assert (sc.function); + Process *process = &frame->GetThread().GetProcess(); + addr_t loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (process); + if (loclist_base_load_addr == LLDB_INVALID_ADDRESS) + return false; // It is a location list. We just need to tell if the location // list contains the current address when converted to a load // address - return m_location.LocationListContainsLoadAddress (&frame->GetThread().GetProcess(), frame->GetRegisterContext()->GetPC()); + return m_location.LocationListContainsAddress (loclist_base_load_addr, frame->GetFrameCodeAddress().GetLoadAddress (process)); } else { // We don't have a location list, we just need to see if the block // that this variable was defined in is currently - Block *frame_block = frame->GetSymbolContext(eSymbolContextBlock).block; + Block *frame_block = frame->GetFrameBlock(); if (frame_block) { SymbolContext variable_sc; CalculateSymbolContext (&variable_sc); - if (variable_sc.function && variable_sc.block) - return variable_sc.block->FindBlockByID(frame_block->GetID()) != NULL; + if (frame_block == variable_sc.block) + return true; + + return frame_block->Contains (variable_sc.block); } } break; default: + assert (!"Unhandled case"); break; } return false; diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 874f46bc832..e90c73895ca 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -486,7 +486,11 @@ StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) m_flags.Set(GOT_FRAME_BASE); ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this); Value expr_value; - if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0) + addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; + if (m_sc.function->GetFrameBaseExpression().IsLocationList()) + loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess()); + + if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false) { // We should really have an error if evaluate returns, but in case // we don't, lets set the error to something at least. |