summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Core/Address.cpp23
-rw-r--r--lldb/source/Core/Section.cpp205
-rw-r--r--lldb/source/Expression/DWARFExpression.cpp19
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp2
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h6
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp4
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h4
-rw-r--r--lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h2
-rw-r--r--lldb/source/Plugins/Process/mach-core/ProcessMachCore.h2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp413
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp546
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h139
-rw-r--r--lldb/source/Symbol/Function.cpp8
-rw-r--r--lldb/source/Symbol/LineTable.cpp304
-rw-r--r--lldb/source/Symbol/ObjectFile.cpp52
-rw-r--r--lldb/source/Symbol/Symtab.cpp38
19 files changed, 875 insertions, 907 deletions
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index abde4ac42c9..e4b599dff49 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/source/Core/Address.cpp
@@ -1015,29 +1015,6 @@ lldb_private::operator!= (const Address& a, const Address& rhs)
a.GetOffset() != rhs.GetOffset();
}
-bool
-Address::IsLinkedAddress () const
-{
- SectionSP section_sp (GetSection());
- return section_sp && section_sp->GetLinkedSection();
-}
-
-
-void
-Address::ResolveLinkedAddress ()
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- SectionSP linked_section_sp (section_sp->GetLinkedSection());
- if (linked_section_sp)
- {
- m_offset += section_sp->GetLinkedOffset();
- m_section_wp = linked_section_sp;
- }
- }
-}
-
AddressClass
Address::GetAddressClass () const
{
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index a9481d2ccac..0d924a34a65 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -21,8 +21,8 @@ Section::Section (const ModuleSP &module_sp,
SectionType sect_type,
addr_t file_addr,
addr_t byte_size,
- uint64_t file_offset,
- uint64_t file_size,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
uint32_t flags) :
ModuleChild (module_sp),
UserID (sect_id),
@@ -37,9 +37,7 @@ Section::Section (const ModuleSP &module_sp,
m_children (),
m_fake (false),
m_encrypted (false),
- m_thread_specific (false),
- m_linked_section_wp(),
- m_linked_offset (0)
+ m_thread_specific (false)
{
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
@@ -52,8 +50,8 @@ Section::Section (const lldb::SectionSP &parent_section_sp,
SectionType sect_type,
addr_t file_addr,
addr_t byte_size,
- uint64_t file_offset,
- uint64_t file_size,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
uint32_t flags) :
ModuleChild (module_sp),
UserID (sect_id),
@@ -68,9 +66,7 @@ Section::Section (const lldb::SectionSP &parent_section_sp,
m_children (),
m_fake (false),
m_encrypted (false),
- m_thread_specific (false),
- m_linked_section_wp(),
- m_linked_offset (0)
+ m_thread_specific (false)
{
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
@@ -83,15 +79,6 @@ Section::~Section()
// printf ("Section::~Section(%p)\n", this);
}
-const ConstString&
-Section::GetName() const
-{
- SectionSP linked_section_sp (m_linked_section_wp.lock());
- if (linked_section_sp)
- return linked_section_sp->GetName();
- return m_name;
-}
-
addr_t
Section::GetFileAddress () const
{
@@ -119,43 +106,21 @@ Section::GetOffset () const
return 0;
}
-
-addr_t
-Section::GetLinkedFileAddress () const
-{
- SectionSP linked_section_sp (m_linked_section_wp.lock());
- if (linked_section_sp)
- return linked_section_sp->GetFileAddress() + m_linked_offset;
- return LLDB_INVALID_ADDRESS;
-}
-
-
addr_t
Section::GetLoadBaseAddress (Target *target) const
{
addr_t load_base_addr = LLDB_INVALID_ADDRESS;
- SectionSP linked_section_sp (m_linked_section_wp.lock());
- if (linked_section_sp)
+ SectionSP parent_sp (GetParent ());
+ if (parent_sp)
{
- load_base_addr = linked_section_sp->GetLoadBaseAddress(target);
+ load_base_addr = parent_sp->GetLoadBaseAddress (target);
if (load_base_addr != LLDB_INVALID_ADDRESS)
- load_base_addr += m_linked_offset;
+ load_base_addr += GetOffset();
}
else
{
- SectionSP parent_sp (GetParent ());
- if (parent_sp)
- {
- load_base_addr = parent_sp->GetLoadBaseAddress (target);
- if (load_base_addr != LLDB_INVALID_ADDRESS)
- load_base_addr += GetOffset();
- }
- else
- {
- load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
- }
+ load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
}
-
return load_base_addr;
}
@@ -174,22 +139,13 @@ Section::ResolveContainedAddress (addr_t offset, Address &so_addr) const
return child_section->ResolveContainedAddress (offset - child_offset, so_addr);
}
}
- SectionSP linked_section_sp (m_linked_section_wp.lock());
- if (linked_section_sp)
- {
- so_addr.SetOffset(m_linked_offset + offset);
- so_addr.SetSection(linked_section_sp);
- }
- else
- {
- so_addr.SetOffset(offset);
- so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
-
+ so_addr.SetOffset(offset);
+ so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
+
#ifdef LLDB_CONFIGURATION_DEBUG
- // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections.
- assert(GetModule().get());
+ // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections.
+ assert(GetModule().get());
#endif
- }
return true;
}
@@ -208,21 +164,6 @@ Section::ContainsFileAddress (addr_t vm_addr) const
return false;
}
-bool
-Section::ContainsLinkedFileAddress (addr_t vm_addr) const
-{
- const addr_t linked_file_addr = GetLinkedFileAddress();
- if (linked_file_addr != LLDB_INVALID_ADDRESS)
- {
- if (linked_file_addr <= vm_addr)
- {
- const addr_t offset = vm_addr - linked_file_addr;
- return offset < GetByteSize();
- }
- }
- return false;
-}
-
int
Section::Compare (const Section& a, const Section& b)
{
@@ -261,12 +202,11 @@ Section::Dump (Stream *s, Target *target, uint32_t depth) const
bool resolved = true;
addr_t addr = LLDB_INVALID_ADDRESS;
- SectionSP linked_section_sp (m_linked_section_wp.lock());
if (GetByteSize() == 0)
s->Printf("%39s", "");
else
{
- if (target && linked_section_sp.get() == NULL)
+ if (target)
addr = GetLoadBaseAddress (target);
if (addr == LLDB_INVALID_ADDRESS)
@@ -286,35 +226,6 @@ Section::Dump (Stream *s, Target *target, uint32_t depth) const
s->EOL();
- if (linked_section_sp)
- {
- addr = LLDB_INVALID_ADDRESS;
- resolved = true;
- if (target)
- {
- addr = linked_section_sp->GetLoadBaseAddress(target);
- if (addr != LLDB_INVALID_ADDRESS)
- addr += m_linked_offset;
- }
-
- if (addr == LLDB_INVALID_ADDRESS)
- {
- if (target)
- resolved = false;
- addr = linked_section_sp->GetFileAddress() + m_linked_offset;
- }
-
- int indent = 28 + s->GetIndentLevel();
- s->Printf("%*.*s", indent, indent, "");
- VMRange linked_range(addr, addr + m_byte_size);
- linked_range.Dump (s, 0);
- indent = 3 * (sizeof(uint32_t) * 2 + 2 + 1) + 1;
- s->Printf("%c%*.*s", resolved ? ' ' : '*', indent, indent, "");
-
- linked_section_sp->DumpName(s);
- s->Printf(" + 0x%" PRIx64 "\n", m_linked_offset);
- }
-
if (depth > 0)
m_children.Dump(s, target, false, depth - 1);
}
@@ -371,22 +282,10 @@ Section::Slide (addr_t slide_amount, bool slide_children)
return false;
}
-void
-Section::SetLinkedLocation (const lldb::SectionSP &linked_section_sp, uint64_t linked_offset)
-{
- if (linked_section_sp)
- m_module_wp = linked_section_sp->GetModule();
- m_linked_section_wp = linked_section_sp;
- m_linked_offset = linked_offset;
-}
-
#pragma mark SectionList
SectionList::SectionList () :
m_sections()
-#ifdef LLDB_CONFIGURATION_DEBUG
- , m_finalized(false)
-#endif
{
}
@@ -401,7 +300,6 @@ SectionList::AddSection (const lldb::SectionSP& section_sp)
assert (section_sp.get());
size_t section_index = m_sections.size();
m_sections.push_back(section_sp);
- InvalidateRangeCache();
return section_index;
}
@@ -441,7 +339,6 @@ SectionList::ReplaceSection (user_id_t sect_id, const lldb::SectionSP& sect_sp,
if ((*sect_iter)->GetID() == sect_id)
{
*sect_iter = sect_sp;
- InvalidateRangeCache();
return true;
}
else if (depth > 0)
@@ -575,71 +472,6 @@ SectionList::FindSectionContainingFileAddress (addr_t vm_addr, uint32_t depth) c
return sect_sp;
}
-void
-SectionList::BuildRangeCache() const
-{
- m_range_cache.Clear();
-
- for (collection::size_type idx = 0, last_idx = m_sections.size();
- idx < last_idx;
- ++idx)
- {
- Section *sect = m_sections[idx].get();
-
- addr_t linked_file_address = sect->GetLinkedFileAddress();
-
- if (linked_file_address != LLDB_INVALID_ADDRESS)
- m_range_cache.Append(SectionRangeCache::Entry(linked_file_address, sect->GetByteSize(), idx));
- }
-
- m_range_cache.Sort();
-
-#ifdef LLDB_CONFIGURATION_DEBUG
- m_finalized = true;
-#endif
-}
-
-void
-SectionList::InvalidateRangeCache() const
-{
-#ifdef LLDB_CONFIGURATION_DEBUG
- assert(!m_finalized);
-#endif
- m_range_cache.Clear();
-}
-
-SectionSP
-SectionList::FindSectionContainingLinkedFileAddress (addr_t vm_addr, uint32_t depth) const
-{
- //if (m_range_cache.IsEmpty())
- // BuildRangeCache();
-#ifdef LLDB_CONFIGURATION_DEBUG
- assert(m_finalized);
-#endif
-
- SectionRangeCache::Entry *entry = m_range_cache.FindEntryThatContains(vm_addr);
-
- if (entry)
- return m_sections[entry->data];
-
- if (depth == 0)
- return SectionSP();
-
- for (const_iterator si = m_sections.begin(), se = m_sections.end();
- si != se;
- ++si)
- {
- Section *sect = si->get();
-
- SectionSP sect_sp = sect->GetChildren().FindSectionContainingLinkedFileAddress(vm_addr, depth - 1);
-
- if (sect_sp)
- return sect_sp;
- }
-
- return SectionSP();
-}
-
bool
SectionList::ContainsSection(user_id_t sect_id) const
{
@@ -681,15 +513,12 @@ SectionList::Slide (addr_t slide_amount, bool slide_children)
if ((*pos)->Slide(slide_amount, slide_children))
++count;
}
- InvalidateRangeCache();
return count;
}
void
SectionList::Finalize ()
{
- BuildRangeCache();
-
for (const_iterator si = m_sections.begin(), se = m_sections.end();
si != se;
++si)
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 0be564a1785..27671b20463 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1009,24 +1009,25 @@ GetOpcodeDataSize (const DataExtractor &data, const lldb::offset_t data_offset,
return LLDB_INVALID_OFFSET;
}
-bool
-DWARFExpression::LocationContains_DW_OP_addr (lldb::addr_t file_addr, bool &error) const
+lldb::addr_t
+DWARFExpression::GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const
{
error = false;
if (IsLocationList())
- return false;
+ return LLDB_INVALID_ADDRESS;
lldb::offset_t offset = 0;
+ uint32_t curr_op_addr_idx = 0;
while (m_data.ValidOffset(offset))
{
const uint8_t op = m_data.GetU8(&offset);
if (op == DW_OP_addr)
{
- if (file_addr == LLDB_INVALID_ADDRESS)
- return true;
- addr_t op_file_addr = m_data.GetAddress(&offset);
- if (op_file_addr == file_addr)
- return true;
+ const lldb::addr_t op_file_addr = m_data.GetAddress(&offset);
+ if (curr_op_addr_idx == op_addr_idx)
+ return op_file_addr;
+ else
+ ++curr_op_addr_idx;
}
else
{
@@ -1039,7 +1040,7 @@ DWARFExpression::LocationContains_DW_OP_addr (lldb::addr_t file_addr, bool &erro
offset += op_arg_size;
}
}
- return false;
+ return LLDB_INVALID_ADDRESS;
}
bool
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 42bfefe8d62..37434beac43 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -254,8 +254,6 @@ ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
m_header(),
m_program_headers(),
m_section_headers(),
- m_sections_ap(),
- m_symtab_ap(),
m_filespec_ap(),
m_shstr_data()
{
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 2c1ff6c4d38..ba4057c5f3d 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -153,12 +153,6 @@ private:
/// Collection of symbols from the dynamic table.
DynamicSymbolColl m_dynamic_symbols;
- /// List of sections present in this ELF object file.
- mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
-
- /// Table of all non-dynamic symbols present in this object file.
- mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
-
/// List of file specifications corresponding to the modules (shared
/// libraries) on which this object file depends.
mutable std::auto_ptr<lldb_private::FileSpecList> m_filespec_ap;
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 9ca6d7bc048..0f2a858bb52 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -501,8 +501,6 @@ ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
lldb::offset_t file_offset,
lldb::offset_t length) :
ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
- m_sections_ap(),
- m_symtab_ap(),
m_mach_segments(),
m_mach_sections(),
m_entry_point_address(),
@@ -518,8 +516,6 @@ ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr) :
ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
- m_sections_ap(),
- m_symtab_ap(),
m_mach_segments(),
m_mach_sections(),
m_entry_point_address(),
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index 1d0443731d9..c4a15407c4e 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -146,8 +146,6 @@ public:
protected:
llvm::MachO::mach_header m_header;
- mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
- mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
static const lldb_private::ConstString &GetSegmentNameTEXT();
static const lldb_private::ConstString &GetSegmentNameDATA();
static const lldb_private::ConstString &GetSegmentNameOBJC();
@@ -157,7 +155,7 @@ protected:
llvm::MachO::dysymtab_command m_dysymtab;
std::vector<llvm::MachO::segment_command_64> m_mach_segments;
std::vector<llvm::MachO::section_64> m_mach_sections;
- typedef lldb_private::RangeArray<uint32_t, uint32_t, 1> FileRangeArray;
+ typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
lldb_private::Address m_entry_point_address;
FileRangeArray m_thread_context_offsets;
bool m_thread_context_offsets_valid;
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index aad2696b2ef..814559f5638 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -229,8 +229,6 @@ protected:
typedef SectionHeaderColl::iterator SectionHeaderCollIter;
typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
private:
- mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
- mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
dos_header_t m_dos_header;
coff_header_t m_coff_header;
coff_opt_header_t m_coff_header_opt;
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
index e5564a9dda3..0119613336f 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -130,7 +130,7 @@ private:
// For ProcessMachCore only
//------------------------------------------------------------------
typedef lldb_private::Range<uint32_t, uint32_t> FileRange;
- typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange> VMRangeToFileOffset;
VMRangeToFileOffset m_core_aranges;
lldb::ModuleSP m_core_module_sp;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
index f35ff165f1f..5f3b437d964 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugLine_h_
-#define SymbolFileDWARF_DWARFDebugLine_h_
+#ifndef SymbolFileDWARF_DWARFDebugMacinfo_h_
+#define SymbolFileDWARF_DWARFDebugMacinfo_h_
#include "SymbolFileDWARF.h"
@@ -26,4 +26,4 @@ public:
};
-#endif // SymbolFileDWARF_DWARFDebugLine_h_
+#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
index a21741b2342..10f8cef2594 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
@@ -182,9 +182,9 @@ LogChannelDWARF::ListCategories (Stream *strm)
" line - log the parsing if .debug_line\n"
" pubnames - log the parsing if .debug_pubnames\n"
" pubtypes - log the parsing if .debug_pubtypes\n"
- " lookups - log any lookups that happen by name, regex, or address\n\n"
- " completion - log struct/unions/class type completions\n\n"
- " map - log insertions of object files into DWARF debug maps\n\n",
+ " lookups - log any lookups that happen by name, regex, or address\n"
+ " completion - log struct/unions/class type completions\n"
+ " map - log insertions of object files into DWARF debug maps\n",
SymbolFileDWARF::GetPluginNameStatic());
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ffda80bca19..603d824f315 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -891,28 +891,40 @@ SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompile
assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
- func_range.GetBaseAddress().ResolveLinkedAddress();
-
- const user_id_t func_user_id = MakeUserID(die->GetOffset());
- func_sp.reset(new Function (sc.comp_unit,
- func_user_id, // UserID is the DIE offset
- func_user_id,
- func_name,
- func_type,
- func_range)); // first address range
-
- if (func_sp.get() != NULL)
+ if (FixupAddress (func_range.GetBaseAddress()))
{
- if (frame_base.IsValid())
- func_sp->GetFrameBaseExpression() = frame_base;
- sc.comp_unit->AddFunction(func_sp);
- return func_sp.get();
+ const user_id_t func_user_id = MakeUserID(die->GetOffset());
+ func_sp.reset(new Function (sc.comp_unit,
+ MakeUserID(func_user_id), // UserID is the DIE offset
+ MakeUserID(func_user_id),
+ func_name,
+ func_type,
+ func_range)); // first address range
+
+ if (func_sp.get() != NULL)
+ {
+ if (frame_base.IsValid())
+ func_sp->GetFrameBaseExpression() = frame_base;
+ sc.comp_unit->AddFunction(func_sp);
+ return func_sp.get();
+ }
}
}
}
return NULL;
}
+bool
+SymbolFileDWARF::FixupAddress (Address &addr)
+{
+ SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
+ if (debug_map_symfile)
+ {
+ return debug_map_symfile->LinkOSOAddress(addr);
+ }
+ // This is a normal DWARF file, no address fixups need to happen
+ return true;
+}
lldb::LanguageType
SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
{
@@ -983,15 +995,7 @@ SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpec
struct ParseDWARFLineTableCallbackInfo
{
LineTable* line_table;
- const SectionList *section_list;
- lldb::addr_t prev_sect_file_base_addr;
- lldb::addr_t curr_sect_file_base_addr;
- bool is_oso_for_debug_map;
- bool prev_in_final_executable;
- DWARFDebugLine::Row prev_row;
- SectionSP prev_section_sp;
- SectionSP curr_section_sp;
- llvm::OwningPtr<LineSequence> curr_sequence_ap;
+ std::auto_ptr<LineSequence> sequence_ap;
};
//----------------------------------------------------------------------
@@ -1000,7 +1004,6 @@ struct ParseDWARFLineTableCallbackInfo
static void
ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
{
- LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
if (state.row == DWARFDebugLine::State::StartParsingLineTable)
{
// Just started parsing the line table
@@ -1012,166 +1015,32 @@ ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& sta
else
{
ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
- // We have a new row, lets append it
+ LineTable* line_table = info->line_table;
- if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
+ // If this is our first time here, we need to create a
+ // sequence container.
+ if (!info->sequence_ap.get())
{
- info->prev_section_sp = info->curr_section_sp;
- info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
- // If this is an end sequence entry, then we subtract one from the
- // address to make sure we get an address that is not the end of
- // a section.
- if (state.end_sequence && state.address != 0)
- info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
- else
- info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
-
- if (info->curr_section_sp.get())
- info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
- else
- info->curr_sect_file_base_addr = 0;
+ info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
+ assert(info->sequence_ap.get());
}
- if (info->curr_section_sp.get())
+ line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
+ state.address,
+ state.line,
+ state.column,
+ state.file,
+ state.is_stmt,
+ state.basic_block,
+ state.prologue_end,
+ state.epilogue_begin,
+ state.end_sequence);
+ if (state.end_sequence)
{
- lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
- // Check for the fancy section magic to determine if we
-
- if (info->is_oso_for_debug_map)
- {
- // When this is a debug map object file that contains DWARF
- // (referenced from an N_OSO debug map nlist entry) we will have
- // a file address in the file range for our section from the
- // original .o file, and a load address in the executable that
- // contains the debug map.
- //
- // If the sections for the file range and load range are
- // different, we have a remapped section for the function and
- // this address is resolved. If they are the same, then the
- // function for this address didn't make it into the final
- // executable.
- bool curr_in_final_executable = (bool) info->curr_section_sp->GetLinkedSection ();
-
- // If we are doing DWARF with debug map, then we need to carefully
- // add each line table entry as there may be gaps as functions
- // get moved around or removed.
- if (!info->prev_row.end_sequence && info->prev_section_sp.get())
- {
- if (info->prev_in_final_executable)
- {
- bool terminate_previous_entry = false;
- if (!curr_in_final_executable)
- {
- // Check for the case where the previous line entry
- // in a function made it into the final executable,
- // yet the current line entry falls in a function
- // that didn't. The line table used to be contiguous
- // through this address range but now it isn't. We
- // need to terminate the previous line entry so
- // that we can reconstruct the line range correctly
- // for it and to keep the line table correct.
- terminate_previous_entry = true;
- }
- else if (info->curr_section_sp.get() != info->prev_section_sp.get())
- {
- // Check for cases where the line entries used to be
- // contiguous address ranges, but now they aren't.
- // This can happen when order files specify the
- // ordering of the functions.
- lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
- Section *curr_sect = info->curr_section_sp.get();
- Section *prev_sect = info->prev_section_sp.get();
- assert (curr_sect->GetLinkedSection());
- assert (prev_sect->GetLinkedSection());
- lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
- lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
- lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
- lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
- if (object_file_addr_delta != linked_file_addr_delta)
- terminate_previous_entry = true;
- }
-
- if (terminate_previous_entry)
- {
- line_table->InsertLineEntry (info->prev_section_sp,
- state.address - info->prev_sect_file_base_addr,
- info->prev_row.line,
- info->prev_row.column,
- info->prev_row.file,
- false, // is_stmt
- false, // basic_block
- false, // state.prologue_end
- false, // state.epilogue_begin
- true); // end_sequence);
- }
- }
- }
-
- if (curr_in_final_executable)
- {
- line_table->InsertLineEntry (info->curr_section_sp,
- curr_line_section_offset,
- state.line,
- state.column,
- state.file,
- state.is_stmt,
- state.basic_block,
- state.prologue_end,
- state.epilogue_begin,
- state.end_sequence);
- info->prev_section_sp = info->curr_section_sp;
- }
- else
- {
- // If the current address didn't make it into the final
- // executable, the current section will be the __text
- // segment in the .o file, so we need to clear this so
- // we can catch the next function that did make it into
- // the final executable.
- info->prev_section_sp.reset();
- info->curr_section_sp.reset();
- }
-
- info->prev_in_final_executable = curr_in_final_executable;
- }
- else
- {
- // We are not in an object file that contains DWARF for an
- // N_OSO, this is just a normal DWARF file. The DWARF spec
- // guarantees that the addresses will be in increasing order
- // for a sequence, but the line table for a single compile unit
- // may contain multiple sequences so we append entries to the
- // current sequence until we find its end, then we merge the
- // sequence into the main line table collection.
-
- // If this is our first time here, we need to create a
- // sequence container.
- if (!info->curr_sequence_ap)
- {
- info->curr_sequence_ap.reset(line_table->CreateLineSequenceContainer());
- assert(info->curr_sequence_ap);
- }
- line_table->AppendLineEntryToSequence(info->curr_sequence_ap.get(),
- info->curr_section_sp,
- curr_line_section_offset,
- state.line,
- state.column,
- state.file,
- state.is_stmt,
- state.basic_block,
- state.prologue_end,
- state.epilogue_begin,
- state.end_sequence);
- if (state.end_sequence)
- {
- // First, put the current sequence into the line table.
- line_table->InsertSequence(info->curr_sequence_ap.get());
- // Then, empty it to prepare for the next sequence.
- info->curr_sequence_ap->Clear();
- }
- }
+ // First, put the current sequence into the line table.
+ line_table->InsertSequence(info->sequence_ap.get());
+ // Then, empty it to prepare for the next sequence.
+ info->sequence_ap->Clear();
}
-
- info->prev_row = state;
}
}
@@ -1194,22 +1063,23 @@ SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
if (line_table_ap.get())
{
- ParseDWARFLineTableCallbackInfo info = {
- line_table_ap.get(),
- m_obj_file->GetSectionList(),
- 0,
- 0,
- GetDebugMapSymfile () != NULL,
- false,
- DWARFDebugLine::Row(),
- SectionSP(),
- SectionSP(),
- llvm::OwningPtr<LineSequence>()
- };
+ ParseDWARFLineTableCallbackInfo info;
+ info.line_table = line_table_ap.get();
lldb::offset_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
- sc.comp_unit->SetLineTable(line_table_ap.release());
- return true;
+ if (m_debug_map_symfile)
+ {
+ // We have an object file that has a line table with addresses
+ // that are not linked. We need to link the line table and convert
+ // the addresses that are relative to the .o file into addresses
+ // for the main executable.
+ sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
+ }
+ else
+ {
+ sc.comp_unit->SetLineTable(line_table_ap.release());
+ return true;
+ }
}
}
}
@@ -2672,19 +2542,19 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
LineTable *line_table = sc.comp_unit->GetLineTable();
if (line_table != NULL)
{
- if (so_addr.IsLinkedAddress())
+ // And address that makes it into this function should be in terms
+ // of this debug file if there is no debug map, or it will be an
+ // address in the .o file which needs to be fixed up to be in terms
+ // of the debug map executable. Either way, calling FixupAddress()
+ // will work for us.
+ Address exe_so_addr (so_addr);
+ if (FixupAddress(exe_so_addr))
{
- Address linked_addr (so_addr);
- linked_addr.ResolveLinkedAddress();
- if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
+ if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
{
resolved |= eSymbolContextLineEntry;
}
}
- else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
- {
- resolved |= eSymbolContextLineEntry;
- }
}
}
@@ -6976,14 +6846,13 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
if (info == NULL)
return 0;
- uint32_t cu_idx = UINT32_MAX;
- DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
-
- if (dwarf_cu == NULL)
- return 0;
-
if (sc.function)
{
+ DWARFCompileUnit* dwarf_cu = info->GetCompileUnitContainingDIE(sc.function->GetID()).get();
+
+ if (dwarf_cu == NULL)
+ return 0;
+
const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
@@ -6998,6 +6867,11 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
}
else if (sc.comp_unit)
{
+ DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()).get();
+
+ if (dwarf_cu == NULL)
+ return 0;
+
uint32_t vars_added = 0;
VariableListSP variables (sc.comp_unit->GetVariableList(false));
@@ -7232,10 +7106,10 @@ SymbolFileDWARF::ParseVariableDIE
{
bool op_error = false;
// Check if the location has a DW_OP_addr with any address value...
- addr_t location_has_op_addr = false;
+ lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
if (!location_is_const_value_data)
{
- location_has_op_addr = location.LocationContains_DW_OP_addr (LLDB_INVALID_ADDRESS, op_error);
+ location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
if (op_error)
{
StreamString strm;
@@ -7244,67 +7118,63 @@ SymbolFileDWARF::ParseVariableDIE
}
}
- if (location_has_op_addr)
+ if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
{
if (is_external)
- {
scope = eValueTypeVariableGlobal;
-
- if (GetDebugMapSymfile ())
+ else
+ scope = eValueTypeVariableStatic;
+
+
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
+
+ if (debug_map_symfile)
+ {
+ // When leaving the DWARF in the .o files on darwin,
+ // when we have a global variable that wasn't initialized,
+ // the .o file might not have allocated a virtual
+ // address for the global variable. In this case it will
+ // have created a symbol for the global variable
+ // that is undefined/data and external and the value will
+ // be the byte size of the variable. When we do the
+ // address map in SymbolFileDWARFDebugMap we rely on
+ // having an address, we need to do some magic here
+ // so we can get the correct address for our global
+ // variable. The address for all of these entries
+ // will be zero, and there will be an undefined symbol
+ // in this object file, and the executable will have
+ // a matching symbol with a good address. So here we
+ // dig up the correct address and replace it in the
+ // location for the variable, and set the variable's
+ // symbol context scope to be that of the main executable
+ // so the file address will resolve correctly.
+ bool linked_oso_file_addr = false;
+ if (is_external && location_DW_OP_addr == 0)
{
- // When leaving the DWARF in the .o files on darwin,
- // when we have a global variable that wasn't initialized,
- // the .o file might not have allocated a virtual
- // address for the global variable. In this case it will
- // have created a symbol for the global variable
- // that is undefined/data and external and the value will
- // be the byte size of the variable. When we do the
- // address map in SymbolFileDWARFDebugMap we rely on
- // having an address, we need to do some magic here
- // so we can get the correct address for our global
- // variable. The address for all of these entries
- // will be zero, and there will be an undefined symbol
- // in this object file, and the executable will have
- // a matching symbol with a good address. So here we
- // dig up the correct address and replace it in the
- // location for the variable, and set the variable's
- // symbol context scope to be that of the main executable
- // so the file address will resolve correctly.
- if (location.LocationContains_DW_OP_addr (0, op_error))
+
+ // we have a possible uninitialized extern global
+ ConstString const_name(mangled ? mangled : name);
+ ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
+ if (debug_map_objfile)
{
-
- // we have a possible uninitialized extern global
- Symtab *symtab = m_obj_file->GetSymtab();
- if (symtab)
+ Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
+ if (debug_map_symtab)
{
- ConstString const_name(mangled ? mangled : name);
- Symbol *o_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeAny,
- Symtab::eDebugNo,
- Symtab::eVisibilityExtern);
-
- if (o_symbol)
+ Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
+ eSymbolTypeData,
+ Symtab::eDebugYes,
+ Symtab::eVisibilityExtern);
+ if (exe_symbol)
{
- ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile();
- if (debug_map_objfile)
+ if (exe_symbol->ValueIsAddress())
{
- Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
- Symbol *defined_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeData,
- Symtab::eDebugYes,
- Symtab::eVisibilityExtern);
- if (defined_symbol)
+ const addr_t exe_file_addr = exe_symbol->GetAddress().GetFileAddress();
+ if (exe_file_addr != LLDB_INVALID_ADDRESS)
{
- if (defined_symbol->ValueIsAddress())
+ if (location.Update_DW_OP_addr (exe_file_addr))
{
- const addr_t defined_addr = defined_symbol->GetAddress().GetFileAddress();
- if (defined_addr != LLDB_INVALID_ADDRESS)
- {
- if (location.Update_DW_OP_addr (defined_addr))
- {
- symbol_context_scope = defined_symbol;
- }
- }
+ linked_oso_file_addr = true;
+ symbol_context_scope = exe_symbol;
}
}
}
@@ -7312,10 +7182,23 @@ SymbolFileDWARF::ParseVariableDIE
}
}
}
- }
- else
- {
- scope = eValueTypeVariableStatic;
+
+ if (!linked_oso_file_addr)
+ {
+ // The DW_OP_addr is not zero, but it contains a .o file address which
+ // needs to be linked up correctly.
+ const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
+ if (exe_file_addr != LLDB_INVALID_ADDRESS)
+ {
+ // Update the file address for this variable
+ location.Update_DW_OP_addr (exe_file_addr);
+ }
+ else
+ {
+ // Variable didn't make it into the final executable
+ return var_sp;
+ }
+ }
}
}
else
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 06db2860166..31fb4cc3b3f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -541,6 +541,9 @@ protected:
const DWARFDebugInfoEntry *dst_class_die,
llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures);
+ bool
+ FixupAddress (lldb_private::Address &addr);
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap * m_debug_map_symfile;
clang::TranslationUnitDecl * m_clang_tu_decl;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index bdc2e683d0a..26b2d77a445 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -14,6 +14,8 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Section.h"
+
+//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
#if defined(DEBUG_OSO_DMAP)
#include "lldb/Core/StreamFile.h"
#endif
@@ -21,6 +23,7 @@
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
@@ -35,207 +38,171 @@ using namespace lldb_private;
// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
// (so we can fixup the symbol file id.
-class DebugMapModule : public Module
+
+
+
+const SymbolFileDWARFDebugMap::FileRangeMap &
+SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
{
-public:
- DebugMapModule (const ModuleSP &exe_module_sp,
- uint32_t cu_idx,
- const FileSpec& file_spec,
- const ArchSpec& arch,
- const ConstString *object_name,
- off_t object_offset) :
- Module (file_spec, arch, object_name, object_offset),
- m_exe_module_wp (exe_module_sp),
- m_cu_idx (cu_idx)
- {
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log)
- log->Printf("%p: DebugMapModule::DebugMapModule (exe_module=%p, cu_idx=%u, oso_path='%s/%s', object_name='%s')",
- this,
- exe_module_sp.get(),
- cu_idx,
- file_spec.GetDirectory().GetCString(),
- file_spec.GetFilename().GetCString(),
- object_name ? object_name->GetCString() : "");
- }
+ if (file_range_map_valid)
+ return file_range_map;
- virtual
- ~DebugMapModule ()
+ file_range_map_valid = true;
+
+ Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
+ ObjectFile *oso_objfile = oso_module->GetObjectFile();
+
+ LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+ if (log)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log)
- log->Printf("%p: DebugMapModule::~DebugMapModule ()", this);
+ ConstString object_name (oso_module->GetObjectName());
+ log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s/%s%s%s%s')",
+ this,
+ oso_module->GetFileSpec().GetDirectory().GetCString(),
+ oso_module->GetFileSpec().GetFilename().GetCString(),
+ object_name ? "(" : "",
+ object_name ? object_name.GetCString() : "",
+ object_name ? ")" : "");
}
+
- virtual ObjectFile *
- GetObjectFile ()
+ std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
+ if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
{
- Mutex::Locker locker (m_mutex);
- if (m_did_load_objfile == false)
+ for (auto comp_unit_info : cu_infos)
{
- ModuleSP exe_module_sp (m_exe_module_wp.lock());
- if (exe_module_sp)
+ Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
+ ModuleSP oso_module_sp (oso_objfile->GetModule());
+ Symtab *oso_symtab = oso_objfile->GetSymtab();
+#if defined(DEBUG_OSO_DMAP)
+ StreamFile s(stdout, false);
+ s << "OSO symtab:\n";
+ oso_symtab->Dump(&s, NULL, eSortOrderNone);
+ s << "OSO sections before:\n";
+ oso_objfile->GetSectionList()->Dump(&s, NULL, true, UINT32_MAX);
+#endif
+
+ ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
+ //SectionList *oso_sections = oso_objfile->Sections();
+ // Now we need to make sections that map from zero based object
+ // file addresses to where things eneded up in the main executable.
+
+ assert (comp_unit_info->first_symbol_index != UINT32_MAX);
+ // End index is one past the last valid symbol index
+ const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
+ for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
+ idx < oso_end_idx;
+ ++idx)
{
- ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
- ObjectFile *oso_objfile = Module::GetObjectFile();
- SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
-
- if (exe_objfile && oso_objfile && exe_sym_vendor)
+ Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
+ if (exe_symbol)
{
- SymbolFileDWARFDebugMap *exe_symfile = (SymbolFileDWARFDebugMap *)exe_sym_vendor->GetSymbolFile();
- if (exe_symfile)
+ if (exe_symbol->IsDebug() == false)
+ continue;
+
+ switch (exe_symbol->GetType())
{
- std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
- if (exe_symfile->GetCompUnitInfosForModule(this, cu_infos))
+ default:
+ break;
+
+ case eSymbolTypeCode:
{
- for (auto comp_unit_info : cu_infos)
+ // For each N_FUN, or function that we run into in the debug map
+ // we make a new section that we add to the sections found in the
+ // .o file. This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable.
+
+ // First we find the original symbol in the .o file's symbol table
+ Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
+ eSymbolTypeCode,
+ Symtab::eDebugNo,
+ Symtab::eVisibilityAny);
+ if (oso_fun_symbol)
{
- // Set the ID of the symbol file DWARF to the index of the OSO
- // shifted left by 32 bits to provide a unique prefix for any
- // UserID's that get created in the symbol file.
- //comp_unit_info->exe_sections_sp.reset(new SectionList);
+ // Add the inverse OSO file address to debug map entry mapping
+ exe_symfile->AddOSOFileRange (this,
+ exe_symbol->GetAddress().GetFileAddress(),
+ oso_fun_symbol->GetAddress().GetFileAddress(),
+ std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
- Symtab *exe_symtab = exe_objfile->GetSymtab();
- ModuleSP oso_module_sp (oso_objfile->GetModule());
- Symtab *oso_symtab = oso_objfile->GetSymtab();
- //#define DEBUG_OSO_DMAP // Do not check in with this defined...
-#if defined(DEBUG_OSO_DMAP)
- StreamFile s(stdout);
- s << "OSO symtab:\n";
- oso_symtab->Dump(&s, NULL);
- s << "OSO sections before:\n";
- oso_objfile->GetSectionList()->Dump(&s, NULL, true);
-#endif
-
- ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
- //SectionList *oso_sections = oso_objfile->Sections();
- // Now we need to make sections that map from zero based object
- // file addresses to where things eneded up in the main executable.
-
- assert (comp_unit_info->first_symbol_index != UINT32_MAX);
- // End index is one past the last valid symbol index
- const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
- uint32_t sect_id = 0x10000;
- for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
- idx < oso_end_idx;
- ++idx)
- {
- Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
- if (exe_symbol)
- {
- if (exe_symbol->IsDebug() == false)
- continue;
-
- switch (exe_symbol->GetType())
- {
- default:
- break;
-
- case eSymbolTypeCode:
- {
- // For each N_FUN, or function that we run into in the debug map
- // we make a new section that we add to the sections found in the
- // .o file. This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable.
-
- // First we find the original symbol in the .o file's symbol table
- Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
- if (oso_fun_symbol)
- {
- // If we found the symbol, then we
- SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection());
- SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection());
- if (oso_fun_section)
- {
- // Now we create a section that we will add as a child of the
- // section in which the .o symbol (the N_FUN) exists.
-
- // We use the exe_symbol size because the one in the .o file
- // will just be a symbol with no size, and the exe_symbol
- // size will reflect any size changes (ppc has been known to
- // shrink function sizes when it gets rid of jump islands that
- // aren't needed anymore).
- SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(),
- oso_module_sp, // Module (the .o file)
- sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
- exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
- eSectionTypeDebug,
- oso_fun_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
- exe_symbol->GetByteSize(), // File size (we need the size from the executable)
- 0, 0, 0));
-
- oso_fun_section_sp->SetLinkedLocation (exe_fun_section,
- exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress());
- oso_fun_section->GetChildren().AddSection(oso_fun_section_sp);
- }
- }
- }
- break;
-
- case eSymbolTypeData:
- {
- // For each N_GSYM we remap the address for the global by making
- // a new section that we add to the sections found in the .o file.
- // This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable. We
- // initially set the section size to be 1 byte, but will need to
- // fix up these addresses further after all globals have been
- // parsed to span the gaps, or we can find the global variable
- // sizes from the DWARF info as we are parsing.
-
- // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
- Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(),
- eSymbolTypeData,
- Symtab::eDebugNo,
- Symtab::eVisibilityAny);
-
- if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress())
- {
- // If we found the symbol, then we
- SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection());
- SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection());
- if (oso_gsym_section)
- {
- SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(),
- oso_module_sp, // Module (the .o file)
- sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
- exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
- eSectionTypeDebug,
- oso_gsym_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
- 1, // We don't know the size of the global, just do the main address for now.
- 0, 0, 0));
-
- oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section,
- exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress());
- oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp);
- }
- }
- }
- break;
- }
- }
- }
- oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
- #if defined(DEBUG_OSO_DMAP)
- s << "OSO sections after:\n";
- oso_objfile->GetSectionList()->Dump(&s, NULL, true);
- #endif
}
}
+ break;
+
+ case eSymbolTypeData:
+ {
+ // For each N_GSYM we remap the address for the global by making
+ // a new section that we add to the sections found in the .o file.
+ // This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable. We
+ // initially set the section size to be 1 byte, but will need to
+ // fix up these addresses further after all globals have been
+ // parsed to span the gaps, or we can find the global variable
+ // sizes from the DWARF info as we are parsing.
+
+ // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
+ Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
+ eSymbolTypeData,
+ Symtab::eDebugNo,
+ Symtab::eVisibilityAny);
+
+ if (exe_symbol && oso_gsym_symbol &&
+ exe_symbol->ValueIsAddress() &&
+ oso_gsym_symbol->ValueIsAddress())
+ {
+ // Add the inverse OSO file address to debug map entry mapping
+ exe_symfile->AddOSOFileRange (this,
+ exe_symbol->GetAddress().GetFileAddress(),
+ oso_gsym_symbol->GetAddress().GetFileAddress(),
+ std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
+ }
+ }
+ break;
}
}
}
+
+ exe_symfile->FinalizeOSOFileRanges (this);
+#if defined(DEBUG_OSO_DMAP)
+ s << "OSO sections after:\n";
+ oso_objfile->GetSectionList()->Dump(&s, NULL, true, UINT32_MAX);
+#endif
+ // We don't need the symbols anymore for the .o files
+ oso_objfile->ClearSymtab();
}
- return m_objfile_sp.get();
}
+ return file_range_map;
+}
+
+
+class DebugMapModule : public Module
+{
+public:
+ DebugMapModule (const ModuleSP &exe_module_sp,
+ uint32_t cu_idx,
+ const FileSpec& file_spec,
+ const ArchSpec& arch,
+ const ConstString *object_name,
+ off_t object_offset) :
+ Module (file_spec, arch, object_name, object_offset),
+ m_exe_module_wp (exe_module_sp),
+ m_cu_idx (cu_idx)
+ {
+ }
+
+ virtual
+ ~DebugMapModule ()
+ {
+ }
+
virtual SymbolVendor*
GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL)
@@ -356,14 +323,12 @@ SymbolFileDWARFDebugMap::InitializeObject()
GetClangASTContext().SetExternalSource (ast_source_ap);
}
-
-
void
SymbolFileDWARFDebugMap::InitOSO()
{
if (m_flags.test(kHaveInitializedOSOs))
return;
-
+
m_flags.set(kHaveInitializedOSOs);
// In order to get the abilities of this plug-in, we look at the list of
// N_OSO entries (object files) from the symbol table and make sure that
@@ -376,10 +341,6 @@ SymbolFileDWARFDebugMap::InitOSO()
LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
std::vector<uint32_t> oso_indexes;
-#if defined(DEBUG_OSO_DMAP)
-// StreamFile s(stdout);
-// symtab->Dump(&s, NULL, eSortOrderNone);
-#endif
// When a mach-o symbol is encoded, the n_type field is encoded in bits
// 23:16, and the n_desc field is encoded in bits 15:0.
//
@@ -399,7 +360,31 @@ SymbolFileDWARFDebugMap::InitOSO()
symtab->SortSymbolIndexesByValue(m_func_indexes, true);
symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
+ for (uint32_t sym_idx : m_func_indexes)
+ {
+ const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+ lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+ lldb::addr_t byte_size = symbol->GetByteSize();
+ DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+ m_debug_map.Append(debug_map_entry);
+ }
+ for (uint32_t sym_idx : m_glob_indexes)
+ {
+ const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+ lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+ lldb::addr_t byte_size = symbol->GetByteSize();
+ DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+ m_debug_map.Append(debug_map_entry);
+ }
+ m_debug_map.Sort();
+
+#if defined(DEBUG_OSO_DMAP)
+ StreamFile s(stdout, false);
+ symtab->Dump(&s, NULL, m_func_indexes);
+ symtab->Dump(&s, NULL, m_glob_indexes);
+#endif
m_compile_unit_infos.resize(oso_index_count);
+
// s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__);
// symtab->Dump(&s, oso_indexes);
@@ -643,34 +628,20 @@ SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
FileSpec so_file_spec;
if (GetFileSpecForSO (cu_idx, so_file_spec))
{
- Module *oso_module = GetModuleByOSOIndex (cu_idx);
- if (oso_module)
- {
- // User zero as the ID to match the compile unit at offset
- // zero in each .o file since each .o file can only have
- // one compile unit for now.
- lldb::user_id_t cu_id = 0;
- m_compile_unit_infos[cu_idx].compile_unit_sp.reset (new CompileUnit (oso_module->shared_from_this(),
- NULL,
- so_file_spec,
- cu_id,
- eLanguageTypeUnknown));
- }
-
- if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
- {
- m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
- NULL,
- so_file_spec,
- cu_idx,
- eLanguageTypeUnknown));
- }
+ // User zero as the ID to match the compile unit at offset
+ // zero in each .o file since each .o file can only have
+ // one compile unit for now.
+ lldb::user_id_t cu_id = 0;
+ m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
+ NULL,
+ so_file_spec,
+ cu_id,
+ eLanguageTypeUnknown));
if (m_compile_unit_infos[cu_idx].compile_unit_sp)
{
// Let our symbol vendor know about this compile unit
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx,
- m_compile_unit_infos[cu_idx].compile_unit_sp);
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
}
}
}
@@ -779,7 +750,7 @@ SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
if (oso_dwarf)
- oso_dwarf->ResolveTypeUID (type_uid);
+ return oso_dwarf->ResolveTypeUID (type_uid);
return NULL;
}
@@ -798,30 +769,30 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint3
if (symtab)
{
const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
- sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size());
- if (sc.symbol != NULL)
+ const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
+ if (debug_map_entry)
{
- resolved_flags |= eSymbolContextSymbol;
- uint32_t oso_idx = 0;
- CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
- if (comp_unit_info)
- {
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx);
- if (oso_dwarf && oso_objfile)
- {
- SectionList *oso_section_list = oso_objfile->GetSectionList();
+ sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
- SectionSP oso_symbol_section_sp (oso_section_list->FindSectionContainingLinkedFileAddress (exe_file_addr, UINT32_MAX));
+ if (sc.symbol != NULL)
+ {
+ resolved_flags |= eSymbolContextSymbol;
- if (oso_symbol_section_sp)
+ uint32_t oso_idx = 0;
+ CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
+ if (comp_unit_info)
+ {
+ Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
+ if (oso_module)
{
- const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress();
- Address oso_so_addr (oso_symbol_section_sp, exe_file_addr - linked_file_addr);
- if (oso_so_addr.IsSectionOffset())
- resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+ lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
+ Address oso_so_addr;
+ if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
+ {
+ resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+ }
}
}
}
@@ -1307,6 +1278,24 @@ SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
return lldb::CompUnitSP();
}
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
+{
+ if (oso_dwarf)
+ {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
+ {
+ SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
+ if (oso_symfile == oso_dwarf)
+ {
+ return &m_compile_unit_infos[cu_idx];
+ }
+ }
+ }
+ return NULL;
+}
+
void
SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
@@ -1415,4 +1404,99 @@ SymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::Symb
return NULL;
}
+bool
+SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
+ lldb::addr_t exe_file_addr,
+ lldb::addr_t oso_file_addr,
+ lldb::addr_t oso_byte_size)
+{
+ assert (cu_info);// REMOVE THIS PRIOR TO CHECKIN
+ const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
+ if (debug_map_idx != UINT32_MAX)
+ {
+ DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
+ assert (debug_map_entry);// REMOVE THIS PRIOR TO CHECKIN
+ debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
+ cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
+ return true;
+ }
+ return false;
+}
+
+void
+SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
+{
+ cu_info->file_range_map.Sort();
+#if defined(DEBUG_OSO_DMAP)
+ const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
+ const size_t n = oso_file_range_map.GetSize();
+ printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p)\n", cu_info);
+ for (size_t i=0; i<n; ++i)
+ {
+ const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
+ printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
+ entry.GetRangeBase(), entry.GetRangeEnd(),
+ entry.data, entry.data + entry.GetByteSize());
+ }
+#endif
+}
+
+lldb::addr_t
+SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
+{
+ CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
+ if (cu_info)
+ {
+ const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+ if (oso_range_entry)
+ {
+ const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
+ if (debug_map_entry)
+ {
+ const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
+ const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
+ return exe_file_addr;
+ }
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool
+SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
+{
+ // Make sure this address hasn't been fixed already
+ Module *exe_module = GetObjectFile()->GetModule().get();
+ Module *addr_module = addr.GetModule().get();
+ if (addr_module == exe_module)
+ return true; // Address is already in terms of the main executable module
+
+ CompileUnitInfo *cu_info = GetCompileUnitInfo ((SymbolFileDWARF *)addr_module->GetSymbolVendor()->GetSymbolFile());
+ if (cu_info)
+ {
+ const lldb::addr_t oso_file_addr = addr.GetFileAddress();
+ const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+ if (oso_range_entry)
+ {
+ const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
+ if (debug_map_entry)
+ {
+ const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
+ const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
+ return exe_module->ResolveFileAddress(exe_file_addr, addr);
+ }
+ }
+ }
+ return true;
+}
+
+LineTable *
+SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
+{
+ CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
+ if (cu_info)
+ return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
+ return NULL;
+}
+
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 971d3e1659b..02d0c6205c8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -16,6 +16,7 @@
#include "clang/AST/CharUnits.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Symbol/SymbolFile.h"
#include "UniqueDWARFASTType.h"
@@ -143,6 +144,8 @@ protected:
typedef STD_SHARED_PTR(OSOInfo) OSOInfoSP;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
+
//------------------------------------------------------------------
// Class specific types
//------------------------------------------------------------------
@@ -156,6 +159,9 @@ protected:
uint32_t last_symbol_index;
uint32_t first_symbol_id;
uint32_t last_symbol_id;
+ FileRangeMap file_range_map;
+ bool file_range_map_valid;
+
CompileUnitInfo() :
so_file (),
@@ -165,9 +171,14 @@ protected:
first_symbol_index (UINT32_MAX),
last_symbol_index (UINT32_MAX),
first_symbol_id (UINT32_MAX),
- last_symbol_id (UINT32_MAX)
+ last_symbol_id (UINT32_MAX),
+ file_range_map (),
+ file_range_map_valid (false)
{
}
+
+ const FileRangeMap &
+ GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
};
//------------------------------------------------------------------
@@ -240,6 +251,9 @@ protected:
lldb::CompUnitSP
GetCompileUnit (SymbolFileDWARF *oso_dwarf);
+
+ CompileUnitInfo *
+ GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf);
lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
@@ -258,6 +272,58 @@ protected:
{
return m_unique_ast_type_map;
}
+
+
+ //------------------------------------------------------------------
+ // OSOEntry
+ //------------------------------------------------------------------
+ class OSOEntry
+ {
+ public:
+
+ OSOEntry () :
+ m_exe_sym_idx (UINT32_MAX),
+ m_oso_file_addr (LLDB_INVALID_ADDRESS)
+ {
+ }
+
+ OSOEntry (uint32_t exe_sym_idx,
+ lldb::addr_t oso_file_addr) :
+ m_exe_sym_idx (exe_sym_idx),
+ m_oso_file_addr (oso_file_addr)
+ {
+ }
+
+ uint32_t
+ GetExeSymbolIndex () const
+ {
+ return m_exe_sym_idx;
+ }
+
+ bool
+ operator < (const OSOEntry &rhs) const
+ {
+ return m_exe_sym_idx < rhs.m_exe_sym_idx;
+ }
+
+ lldb::addr_t
+ GetOSOFileAddress () const
+ {
+ return m_oso_file_addr;
+ }
+
+ void
+ SetOSOFileAddress (lldb::addr_t oso_file_addr)
+ {
+ m_oso_file_addr = oso_file_addr;
+ }
+ protected:
+ uint32_t m_exe_sym_idx;
+ lldb::addr_t m_oso_file_addr;
+ };
+
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap;
+
//------------------------------------------------------------------
// Member Variables
//------------------------------------------------------------------
@@ -268,6 +334,77 @@ protected:
std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
+ DebugMap m_debug_map;
+
+ //------------------------------------------------------------------
+ // When an object file from the debug map gets parsed in
+ // SymbolFileDWARF, it needs to tell the debug map about the object
+ // files addresses by calling this function once for each N_FUN,
+ // N_GSYM and N_STSYM and after all entries in the debug map have
+ // been matched up, FinalizeOSOFileRanges() should be called.
+ //------------------------------------------------------------------
+ bool
+ AddOSOFileRange (CompileUnitInfo *cu_info,
+ lldb::addr_t exe_file_addr,
+ lldb::addr_t oso_file_addr,
+ lldb::addr_t oso_byte_size);
+
+ //------------------------------------------------------------------
+ // Called after calling AddOSOFileRange() for each object file debug
+ // map entry to finalize the info for the unlinked compile unit.
+ //------------------------------------------------------------------
+ void
+ FinalizeOSOFileRanges (CompileUnitInfo *cu_info);
+
+ //------------------------------------------------------------------
+ /// Convert \a addr from a .o file address, to an executable address.
+ ///
+ /// @param[in] addr
+ /// A section offset address from a .o file
+ ///
+ /// @return
+ /// Returns true if \a addr was converted to be an executable
+ /// section/offset address, false otherwise.
+ //------------------------------------------------------------------
+ bool
+ LinkOSOAddress (lldb_private::Address &addr);
+
+ //------------------------------------------------------------------
+ /// Convert a .o file "file address" to an executable "file address".
+ ///
+ /// @param[in] oso_symfile
+ /// The DWARF symbol file that contains \a oso_file_addr
+ ///
+ /// @param[in] oso_file_addr
+ /// A .o file "file address" to convert.
+ ///
+ /// @return
+ /// LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
+ /// linked executable, otherwise a valid "file address" from the
+ /// linked executable that contains the debug map.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr);
+
+ //------------------------------------------------------------------
+ /// Given a line table full of lines with "file adresses" that are
+ /// for a .o file represented by \a oso_symfile, link a new line table
+ /// and return it.
+ ///
+ /// @param[in] oso_symfile
+ /// The DWARF symbol file that produced the \a line_table
+ ///
+ /// @param[in] addr
+ /// A section offset address from a .o file
+ ///
+ /// @return
+ /// Returns a valid line table full of linked addresses, or NULL
+ /// if none of the line table adresses exist in the main
+ /// executable.
+ //------------------------------------------------------------------
+ lldb_private::LineTable *
+ LinkOSOLineTable (SymbolFileDWARF *oso_symfile,
+ lldb_private::LineTable *line_table);
};
#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index 34f2ea560a9..64c22efa784 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -392,13 +392,7 @@ Function::CalculateSymbolContextModule ()
{
SectionSP section_sp (m_range.GetBaseAddress().GetSection());
if (section_sp)
- {
- SectionSP linked_section_sp (section_sp->GetLinkedSection());
- if (linked_section_sp)
- return linked_section_sp->GetModule();
- else
- return section_sp->GetModule();
- }
+ return section_sp->GetModule();
return this->GetCompileUnit()->GetModule();
}
diff --git a/lldb/source/Symbol/LineTable.cpp b/lldb/source/Symbol/LineTable.cpp
index 6784ac0b2df..479d8cb09e8 100644
--- a/lldb/source/Symbol/LineTable.cpp
+++ b/lldb/source/Symbol/LineTable.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/Address.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -22,7 +23,6 @@ using namespace lldb_private;
//----------------------------------------------------------------------
LineTable::LineTable(CompileUnit* comp_unit) :
m_comp_unit(comp_unit),
- m_section_list(),
m_entries()
{
}
@@ -37,8 +37,7 @@ LineTable::~LineTable()
void
LineTable::InsertLineEntry
(
- const SectionSP& section_sp,
- lldb::addr_t section_offset,
+ lldb::addr_t file_addr,
uint32_t line,
uint16_t column,
uint16_t file_idx,
@@ -49,21 +48,7 @@ LineTable::InsertLineEntry
bool is_terminal_entry
)
{
- SectionSP line_section_sp;
- SectionSP linked_section_sp (section_sp->GetLinkedSection());
- if (linked_section_sp)
- {
- section_offset += section_sp->GetLinkedOffset();
- line_section_sp = linked_section_sp;
- }
- else
- {
- line_section_sp = section_sp;
- }
- assert(line_section_sp.get());
-
- uint32_t sect_idx = m_section_list.AddUniqueSection (line_section_sp);
- Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+ Entry entry(file_addr, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
entry_collection::iterator begin_pos = m_entries.begin();
entry_collection::iterator end_pos = m_entries.end();
@@ -85,7 +70,7 @@ LineSequence::LineSequence()
void
LineTable::LineSequenceImpl::Clear()
{
- m_seq_entries.clear();
+ m_entries.clear();
}
LineSequence* LineTable::CreateLineSequenceContainer ()
@@ -97,8 +82,7 @@ void
LineTable::AppendLineEntryToSequence
(
LineSequence* sequence,
- const SectionSP& section_sp,
- lldb::addr_t section_offset,
+ lldb::addr_t file_addr,
uint32_t line,
uint16_t column,
uint16_t file_idx,
@@ -111,9 +95,8 @@ LineTable::AppendLineEntryToSequence
{
assert(sequence != NULL);
LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
- uint32_t sect_idx = m_section_list.AddUniqueSection (section_sp);
- Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
- seq->m_seq_entries.push_back (entry);
+ Entry entry(file_addr, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+ seq->m_entries.push_back (entry);
}
void
@@ -121,17 +104,17 @@ LineTable::InsertSequence (LineSequence* sequence)
{
assert(sequence != NULL);
LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
- if (seq->m_seq_entries.empty())
+ if (seq->m_entries.empty())
return;
- Entry& entry = seq->m_seq_entries.front();
-
+ Entry& entry = seq->m_entries.front();
+
// If the first entry address in this sequence is greater than or equal to
// the address of the last item in our entry collection, just append.
if (m_entries.empty() || !Entry::EntryAddressLessThan(entry, m_entries.back()))
{
m_entries.insert(m_entries.end(),
- seq->m_seq_entries.begin(),
- seq->m_seq_entries.end());
+ seq->m_entries.begin(),
+ seq->m_entries.end());
return;
}
@@ -149,7 +132,7 @@ LineTable::InsertSequence (LineSequence* sequence)
assert(prev_pos->is_terminal_entry);
}
#endif
- m_entries.insert(pos, seq->m_seq_entries.begin(), seq->m_seq_entries.end());
+ m_entries.insert(pos, seq->m_entries.begin(), seq->m_entries.end());
}
//----------------------------------------------------------------------
@@ -161,37 +144,23 @@ LineTable::Entry::LessThanBinaryPredicate::LessThanBinaryPredicate(LineTable *li
bool
LineTable::Entry::LessThanBinaryPredicate::operator() (const LineTable::Entry& a, const LineTable::Entry& b) const
{
- if (a.sect_idx == b.sect_idx)
- {
- #define LT_COMPARE(a,b) if (a != b) return a < b
- LT_COMPARE (a.sect_offset, b.sect_offset);
- // b and a reversed on purpose below.
- LT_COMPARE (b.is_terminal_entry, a.is_terminal_entry);
- LT_COMPARE (a.line, b.line);
- LT_COMPARE (a.column, b.column);
- LT_COMPARE (a.is_start_of_statement, b.is_start_of_statement);
- LT_COMPARE (a.is_start_of_basic_block, b.is_start_of_basic_block);
- // b and a reversed on purpose below.
- LT_COMPARE (b.is_prologue_end, a.is_prologue_end);
- LT_COMPARE (a.is_epilogue_begin, b.is_epilogue_begin);
- LT_COMPARE (a.file_idx, b.file_idx);
- return false;
- #undef LT_COMPARE
- }
-
- const Section *a_section = m_line_table->GetSectionForEntryIndex (a.sect_idx);
- const Section *b_section = m_line_table->GetSectionForEntryIndex (b.sect_idx);
- return Section::Compare(*a_section, *b_section) < 0;
+ #define LT_COMPARE(a,b) if (a != b) return a < b
+ LT_COMPARE (a.file_addr, b.file_addr);
+ // b and a reversed on purpose below.
+ LT_COMPARE (b.is_terminal_entry, a.is_terminal_entry);
+ LT_COMPARE (a.line, b.line);
+ LT_COMPARE (a.column, b.column);
+ LT_COMPARE (a.is_start_of_statement, b.is_start_of_statement);
+ LT_COMPARE (a.is_start_of_basic_block, b.is_start_of_basic_block);
+ // b and a reversed on purpose below.
+ LT_COMPARE (b.is_prologue_end, a.is_prologue_end);
+ LT_COMPARE (a.is_epilogue_begin, b.is_epilogue_begin);
+ LT_COMPARE (a.file_idx, b.file_idx);
+ return false;
+ #undef LT_COMPARE
}
-Section *
-LineTable::GetSectionForEntryIndex (uint32_t idx)
-{
- if (idx < m_section_list.GetSize())
- return m_section_list.GetSectionAtIndex(idx).get();
- return NULL;
-}
uint32_t
LineTable::GetSize() const
@@ -218,69 +187,69 @@ LineTable::FindLineEntryByAddress (const Address &so_addr, LineEntry& line_entry
*index_ptr = UINT32_MAX;
bool success = false;
- uint32_t sect_idx = m_section_list.FindSectionIndex (so_addr.GetSection().get());
- if (sect_idx != UINT32_MAX)
+
+ if (so_addr.GetModule().get() == m_comp_unit->GetModule().get())
{
Entry search_entry;
- search_entry.sect_idx = sect_idx;
- search_entry.sect_offset = so_addr.GetOffset();
-
- entry_collection::const_iterator begin_pos = m_entries.begin();
- entry_collection::const_iterator end_pos = m_entries.end();
- entry_collection::const_iterator pos = lower_bound(begin_pos, end_pos, search_entry, Entry::EntryAddressLessThan);
- if (pos != end_pos)
+ search_entry.file_addr = so_addr.GetFileAddress();
+ if (search_entry.file_addr != LLDB_INVALID_ADDRESS)
{
- if (pos != begin_pos)
+ entry_collection::const_iterator begin_pos = m_entries.begin();
+ entry_collection::const_iterator end_pos = m_entries.end();
+ entry_collection::const_iterator pos = lower_bound(begin_pos, end_pos, search_entry, Entry::EntryAddressLessThan);
+ if (pos != end_pos)
{
- if (pos->sect_offset != search_entry.sect_offset)
- --pos;
- else if (pos->sect_offset == search_entry.sect_offset)
+ if (pos != begin_pos)
{
- // If this is a termination entry, it should't match since
- // entries with the "is_terminal_entry" member set to true
- // are termination entries that define the range for the
- // previous entry.
- if (pos->is_terminal_entry)
+ if (pos->file_addr != search_entry.file_addr)
+ --pos;
+ else if (pos->file_addr == search_entry.file_addr)
{
- // The matching entry is a terminal entry, so we skip
- // ahead to the next entry to see if there is another
- // entry following this one whose section/offset matches.
- ++pos;
- if (pos != end_pos)
+ // If this is a termination entry, it should't match since
+ // entries with the "is_terminal_entry" member set to true
+ // are termination entries that define the range for the
+ // previous entry.
+ if (pos->is_terminal_entry)
{
- if (pos->sect_offset != search_entry.sect_offset)
- pos = end_pos;
+ // The matching entry is a terminal entry, so we skip
+ // ahead to the next entry to see if there is another
+ // entry following this one whose section/offset matches.
+ ++pos;
+ if (pos != end_pos)
+ {
+ if (pos->file_addr != search_entry.file_addr)
+ pos = end_pos;
+ }
}
- }
-
- if (pos != end_pos)
- {
- // While in the same section/offset backup to find the first
- // line entry that matches the address in case there are
- // multiple
- while (pos != begin_pos)
+
+ if (pos != end_pos)
{
- entry_collection::const_iterator prev_pos = pos - 1;
- if (prev_pos->sect_idx == search_entry.sect_idx &&
- prev_pos->sect_offset == search_entry.sect_offset &&
- prev_pos->is_terminal_entry == false)
- --pos;
- else
- break;
+ // While in the same section/offset backup to find the first
+ // line entry that matches the address in case there are
+ // multiple
+ while (pos != begin_pos)
+ {
+ entry_collection::const_iterator prev_pos = pos - 1;
+ if (prev_pos->file_addr == search_entry.file_addr &&
+ prev_pos->is_terminal_entry == false)
+ --pos;
+ else
+ break;
+ }
}
}
- }
- }
-
- // Make sure we have a valid match and that the match isn't a terminating
- // entry for a previous line...
- if (pos != end_pos && pos->is_terminal_entry == false)
- {
- uint32_t match_idx = std::distance (begin_pos, pos);
- success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry);
- if (index_ptr != NULL && success)
- *index_ptr = match_idx;
+ }
+
+ // Make sure we have a valid match and that the match isn't a terminating
+ // entry for a previous line...
+ if (pos != end_pos && pos->is_terminal_entry == false)
+ {
+ uint32_t match_idx = std::distance (begin_pos, pos);
+ success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry);
+ if (index_ptr != NULL && success)
+ *index_ptr = match_idx;
+ }
}
}
}
@@ -294,32 +263,24 @@ LineTable::ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry)
if (idx < m_entries.size())
{
const Entry& entry = m_entries[idx];
- line_entry.range.GetBaseAddress().SetSection(m_section_list.GetSectionAtIndex (entry.sect_idx));
- line_entry.range.GetBaseAddress().SetOffset(entry.sect_offset);
- if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
+ ModuleSP module_sp (m_comp_unit->GetModule());
+ if (module_sp && module_sp->ResolveFileAddress(entry.file_addr, line_entry.range.GetBaseAddress()))
{
- const Entry& next_entry = m_entries[idx+1];
- if (next_entry.sect_idx == entry.sect_idx)
- {
- line_entry.range.SetByteSize(next_entry.sect_offset - entry.sect_offset);
- }
+ if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
+ line_entry.range.SetByteSize(m_entries[idx+1].file_addr - entry.file_addr);
else
- {
- Address next_line_addr(m_section_list.GetSectionAtIndex (next_entry.sect_idx), next_entry.sect_offset);
- line_entry.range.SetByteSize(next_line_addr.GetFileAddress() - line_entry.range.GetBaseAddress().GetFileAddress());
- }
+ line_entry.range.SetByteSize(0);
+
+ line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
+ line_entry.line = entry.line;
+ line_entry.column = entry.column;
+ line_entry.is_start_of_statement = entry.is_start_of_statement;
+ line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
+ line_entry.is_prologue_end = entry.is_prologue_end;
+ line_entry.is_epilogue_begin = entry.is_epilogue_begin;
+ line_entry.is_terminal_entry = entry.is_terminal_entry;
+ return true;
}
- else
- line_entry.range.SetByteSize(0);
- line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
- line_entry.line = entry.line;
- line_entry.column = entry.column;
- line_entry.is_start_of_statement = entry.is_start_of_statement;
- line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
- line_entry.is_prologue_end = entry.is_prologue_end;
- line_entry.is_epilogue_begin = entry.is_epilogue_begin;
- line_entry.is_terminal_entry = entry.is_terminal_entry;
- return true;
}
return false;
}
@@ -503,7 +464,6 @@ LineTable::GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool
const size_t count = m_entries.size();
LineEntry line_entry;
- std::vector<addr_t> section_base_file_addrs (m_section_list.GetSize(), LLDB_INVALID_ADDRESS);
FileAddressRanges::Entry range (LLDB_INVALID_ADDRESS, 0);
for (size_t idx = 0; idx < count; ++idx)
{
@@ -513,23 +473,89 @@ LineTable::GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool
{
if (range.GetRangeBase() != LLDB_INVALID_ADDRESS)
{
- if (section_base_file_addrs[entry.sect_idx] == LLDB_INVALID_ADDRESS)
- section_base_file_addrs[entry.sect_idx] = m_section_list.GetSectionAtIndex (entry.sect_idx)->GetFileAddress();
- range.SetRangeEnd(section_base_file_addrs[entry.sect_idx] + entry.sect_offset);
+ range.SetRangeEnd(entry.file_addr);
file_ranges.Append(range);
range.Clear(LLDB_INVALID_ADDRESS);
}
}
else if (range.GetRangeBase() == LLDB_INVALID_ADDRESS)
{
- if (section_base_file_addrs[entry.sect_idx] == LLDB_INVALID_ADDRESS)
- section_base_file_addrs[entry.sect_idx] = m_section_list.GetSectionAtIndex (entry.sect_idx)->GetFileAddress();
- range.SetRangeBase(section_base_file_addrs[entry.sect_idx] + entry.sect_offset);
+ range.SetRangeBase(entry.file_addr);
}
}
return file_ranges.GetSize() - initial_count;
}
+LineTable *
+LineTable::LinkLineTable (const FileRangeMap &file_range_map)
+{
+ std::auto_ptr<LineTable> line_table_ap (new LineTable (m_comp_unit));
+ LineSequenceImpl sequence;
+ const size_t count = m_entries.size();
+ LineEntry line_entry;
+ const FileRangeMap::Entry *file_range_entry = NULL;
+ const FileRangeMap::Entry *prev_file_range_entry = NULL;
+ lldb::addr_t prev_file_addr = LLDB_INVALID_ADDRESS;
+ bool prev_entry_was_linked = false;
+ for (size_t idx = 0; idx < count; ++idx)
+ {
+ const Entry& entry = m_entries[idx];
+
+ const bool end_sequence = entry.is_terminal_entry;
+ const lldb::addr_t lookup_file_addr = entry.file_addr - (end_sequence ? 1 : 0);
+ if (file_range_entry == NULL || !file_range_entry->Contains(lookup_file_addr))
+ {
+ prev_file_range_entry = file_range_entry;
+ file_range_entry = file_range_map.FindEntryThatContains(lookup_file_addr);
+ }
+
+ if (file_range_entry)
+ {
+ // This entry has an address remapping and it needs to have its address relinked
+ sequence.m_entries.push_back(entry);
+ // Fix tha addresss
+ const lldb::addr_t linked_file_addr = entry.file_addr - file_range_entry->GetRangeBase() + file_range_entry->data;
+// if (linked_file_addr == 0x000000000128b7d5)
+// puts("remove this");
+ sequence.m_entries.back().file_addr = linked_file_addr;
+ }
+ else if (prev_entry_was_linked)
+ {
+ // This entry doesn't have a remapping and it needs to be removed.
+ // Watch out in case we need to terminate a previous entry needs to
+ // be terminated now that one line entry in a sequence is not longer valid.
+ if (!entry.is_terminal_entry &&
+ !sequence.m_entries.empty() &&
+ !sequence.m_entries.back().is_terminal_entry)
+ {
+ assert (prev_file_addr != LLDB_INVALID_ADDRESS);
+ sequence.m_entries.push_back(sequence.m_entries.back());
+ const lldb::addr_t linked_file_addr = std::min<lldb::addr_t>(entry.file_addr,prev_file_range_entry->GetRangeEnd()) - prev_file_range_entry->GetRangeBase() + prev_file_range_entry->data;
+ sequence.m_entries.back().file_addr = linked_file_addr;
+ sequence.m_entries.back().is_terminal_entry = true;
+ }
+ }
+
+ // If we have items in the sequence and the last entry is a terminal entry,
+ // insert this sequence into our new line table.
+ if (!sequence.m_entries.empty() && sequence.m_entries.back().is_terminal_entry)
+ {
+ line_table_ap->InsertSequence (&sequence);
+ sequence.Clear();
+ prev_entry_was_linked = false;
+ prev_file_addr = LLDB_INVALID_ADDRESS;
+ }
+ else
+ {
+ prev_entry_was_linked = file_range_entry != NULL;
+ prev_file_addr = entry.file_addr;
+ }
+ }
+ if (line_table_ap->m_entries.empty())
+ return NULL;
+ return line_table_ap.release();
+}
+
diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp
index a3574a52c20..4ad515b94d8 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -200,8 +200,10 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_data (),
m_unwind_table (*this),
m_process_wp(),
- m_memory_addr (LLDB_INVALID_ADDRESS)
-{
+ m_memory_addr (LLDB_INVALID_ADDRESS),
+ m_sections_ap (),
+ m_symtab_ap ()
+{
if (file_spec_ptr)
m_file = *file_spec_ptr;
if (data_sp)
@@ -209,12 +211,16 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
+ const ConstString object_name (module_sp->GetObjectName());
if (m_file)
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n",
+ log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s%s%s%s), file = %s/%s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
+ module_sp.get(),
module_sp->GetFileSpec().GetFilename().AsCString(),
+ object_name ? "(" : "",
+ object_name ? object_name.GetCString() : "",
+ object_name ? ")" : "",
m_file.GetDirectory().AsCString(),
m_file.GetFilename().AsCString(),
m_file_offset,
@@ -222,10 +228,13 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
}
else
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n",
+ log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s%s%s%s), file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
+ module_sp.get(),
module_sp->GetFileSpec().GetFilename().AsCString(),
+ object_name ? "(" : "",
+ object_name ? object_name.GetCString() : "",
+ object_name ? ")" : "",
m_file_offset,
m_length);
}
@@ -246,17 +255,23 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_data (),
m_unwind_table (*this),
m_process_wp (process_sp),
- m_memory_addr (header_addr)
-{
+ m_memory_addr (header_addr),
+ m_sections_ap (),
+ m_symtab_ap ()
+{
if (header_data_sp)
m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, process = %p, header_addr = 0x%" PRIx64 "\n",
+ const ConstString object_name (module_sp->GetObjectName());
+ log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s%s%s%s), process = %p, header_addr = 0x%" PRIx64,
this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
+ module_sp.get(),
module_sp->GetFileSpec().GetFilename().AsCString(),
+ object_name ? "(" : "",
+ object_name ? object_name.GetCString() : "",
+ object_name ? ")" : "",
process_sp.get(),
m_memory_addr);
}
@@ -519,3 +534,20 @@ ObjectFile::SplitArchivePathWithObject (const char *path_with_object, FileSpec &
return false;
}
+void
+ObjectFile::ClearSymtab ()
+{
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
+ {
+ lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ if (log)
+ {
+ log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p",
+ this,
+ m_symtab_ap.get());
+ }
+ m_symtab_ap.reset();
+ }
+}
diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp
index ee660fb733d..37c204d1890 100644
--- a/lldb/source/Symbol/Symtab.cpp
+++ b/lldb/source/Symbol/Symtab.cpp
@@ -11,6 +11,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Section.h"
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -882,13 +883,13 @@ Symtab::CalculateSymbolSize (Symbol *symbol)
if (!m_addr_indexes_computed)
InitAddressIndexes();
const size_t num_addr_indexes = m_addr_indexes.size();
+ const lldb::addr_t symbol_file_addr = symbol->GetAddress().GetFileAddress();
SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress (this,
- symbol->GetAddress().GetFileAddress(),
+ symbol_file_addr,
&m_addr_indexes.front(),
num_addr_indexes);
if (info.match_index_ptr != NULL)
{
- const lldb::addr_t curr_file_addr = symbol->GetAddress().GetFileAddress();
// We can figure out the address range of all symbols except the
// last one by taking the delta between the current symbol and
// the next symbol
@@ -899,15 +900,32 @@ Symtab::CalculateSymbolSize (Symbol *symbol)
{
Symbol *next_symbol = SymbolAtIndex(m_addr_indexes[addr_index]);
if (next_symbol == NULL)
- break;
-
- const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
- if (next_file_addr > curr_file_addr)
{
- byte_size = next_file_addr - curr_file_addr;
- symbol->SetByteSize(byte_size);
- symbol->SetSizeIsSynthesized(true);
- break;
+ // No next symbol take the size to be the remaining bytes in the section
+ // in which the symbol resides
+ SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (symbol_file_addr));
+ if (section_sp)
+ {
+ const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
+ if (end_section_file_addr > symbol_file_addr)
+ {
+ byte_size = end_section_file_addr - symbol_file_addr;
+ symbol->SetByteSize(byte_size);
+ symbol->SetSizeIsSynthesized(true);
+ break;
+ }
+ }
+ }
+ else
+ {
+ const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
+ if (next_file_addr > symbol_file_addr)
+ {
+ byte_size = next_file_addr - symbol_file_addr;
+ symbol->SetByteSize(byte_size);
+ symbol->SetSizeIsSynthesized(true);
+ break;
+ }
}
}
}
OpenPOWER on IntegriCloud