summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp670
1 files changed, 411 insertions, 259 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 0ed6843823b..4e1b41c74aa 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -13,10 +13,14 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Section.h"
+#if defined(DEBUG_OSO_DMAP)
#include "lldb/Core/StreamFile.h"
+#endif
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
@@ -27,6 +31,248 @@
using namespace lldb;
using namespace lldb_private;
+// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()"
+// (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
+{
+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 ObjectFile *
+ GetObjectFile ()
+ {
+ Mutex::Locker locker (m_mutex);
+ if (m_did_load_objfile == false)
+ {
+ ModuleSP exe_module_sp (m_exe_module_wp.lock());
+ if (exe_module_sp)
+ {
+ 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)
+ {
+ SymbolFileDWARFDebugMap *exe_symfile = (SymbolFileDWARFDebugMap *)exe_sym_vendor->GetSymbolFile();
+ if (exe_symfile)
+ {
+ SymbolFileDWARFDebugMap::CompileUnitInfo *comp_unit_info = exe_symfile->GetCompUnitInfo (this);
+ if (comp_unit_info)
+ {
+ // 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);
+
+ 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
+ }
+ }
+ }
+ }
+ }
+ return m_objfile_sp.get();
+ }
+
+ virtual SymbolVendor*
+ GetSymbolVendor(bool can_create = true)
+ {
+ // Scope for locker
+ if (m_symfile_ap.get() || can_create == false)
+ return m_symfile_ap.get();
+
+ ModuleSP exe_module_sp (m_exe_module_wp.lock());
+ if (exe_module_sp)
+ {
+ // Now get the object file outside of a locking scope
+ ObjectFile *oso_objfile = GetObjectFile ();
+ if (oso_objfile)
+ {
+ Mutex::Locker locker (m_mutex);
+ SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create);
+ if (symbol_vendor)
+ {
+ // Set a a pointer to this class to set our OSO DWARF file know
+ // that the DWARF is being used along with a debug map and that
+ // it will have the remapped sections that we do below.
+ SymbolFileDWARF *oso_symfile = (SymbolFileDWARF *)symbol_vendor->GetSymbolFile();
+
+ if (!oso_symfile)
+ return NULL;
+
+ ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
+ SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
+
+ if (exe_objfile && exe_sym_vendor)
+ {
+ if (oso_symfile->GetNumCompileUnits() == 1)
+ {
+ oso_symfile->SetDebugMapModule(exe_module_sp);
+ // 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.
+ oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
+ }
+ else
+ {
+ oso_symfile->SetID (UINT64_MAX);
+ }
+ }
+ return symbol_vendor;
+ }
+ }
+ }
+ return NULL;
+ }
+
+protected:
+ ModuleWP m_exe_module_wp;
+ const uint32_t m_cu_idx;
+};
+
void
SymbolFileDWARFDebugMap::Initialize()
{
@@ -93,7 +339,7 @@ SymbolFileDWARFDebugMap::InitializeObject()
void
-SymbolFileDWARFDebugMap::InitOSO ()
+SymbolFileDWARFDebugMap::InitOSO()
{
if (m_flags.test(kHaveInitializedOSOs))
return;
@@ -110,9 +356,10 @@ 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.
//
@@ -138,24 +385,30 @@ SymbolFileDWARFDebugMap::InitOSO ()
for (uint32_t i=0; i<oso_index_count; ++i)
{
- m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1);
- if (m_compile_unit_infos[i].so_symbol->GetSiblingIndex() == 0)
- m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 2);
- m_compile_unit_infos[i].oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]);
- uint32_t sibling_idx = m_compile_unit_infos[i].so_symbol->GetSiblingIndex();
+ const Symbol *so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1);
+ const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]);
+ assert (so_symbol);
+ assert (oso_symbol);
+ assert (so_symbol->GetType() == eSymbolTypeSourceFile);
+ assert (oso_symbol->GetType() == eSymbolTypeObjectFile);
+ m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), true);
+ m_compile_unit_infos[i].oso_file.SetFile(oso_symbol->GetName().AsCString(), true);
+ uint32_t sibling_idx = so_symbol->GetSiblingIndex();
// The sibling index can't be less that or equal to the current index "i"
if (sibling_idx <= i)
{
- m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", m_compile_unit_infos[i].so_symbol->GetID());
+ m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
}
else
{
- m_compile_unit_infos[i].last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
- m_compile_unit_infos[i].first_symbol_index = symtab->GetIndexForSymbol(m_compile_unit_infos[i].so_symbol);
- m_compile_unit_infos[i].last_symbol_index = symtab->GetIndexForSymbol(m_compile_unit_infos[i].last_symbol);
+ const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
+ m_compile_unit_infos[i].first_symbol_index = symtab->GetIndexForSymbol(so_symbol);
+ m_compile_unit_infos[i].last_symbol_index = symtab->GetIndexForSymbol(last_symbol);
+ m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
+ m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
if (log)
- log->Printf("Initialized OSO 0x%8.8x: file=%s", i, m_compile_unit_infos[i].oso_symbol->GetName().GetCString());
+ log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
}
}
}
@@ -176,19 +429,33 @@ SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_inf
{
if (comp_unit_info->oso_module_sp.get() == NULL && comp_unit_info->symbol_file_supported)
{
- Symbol *oso_symbol = comp_unit_info->oso_symbol;
- if (oso_symbol)
+ if (!comp_unit_info->oso_file.Exists())
{
- FileSpec oso_file_spec(oso_symbol->GetMangled().GetName().AsCString(), true);
- // Always create a new module for .o files. Why? Because we
- // use the debug map, to add new sections to each .o file and
- // even though a .o file might not have changed, the sections
- // that get added to the .o file can change.
- comp_unit_info->oso_module_sp.reset (new Module (oso_file_spec,
- m_obj_file->GetModule()->GetArchitecture(),
- NULL,
- 0));
+ char path[PATH_MAX*2];
+ comp_unit_info->oso_file.GetPath(path, sizeof(path));
+ if (ObjectFile::SplitArchivePathWithObject (path,
+ comp_unit_info->oso_file,
+ comp_unit_info->oso_object))
+ {
+ comp_unit_info->oso_file.GetPath(path, sizeof(path));
+ //printf ("resolved archive '%s' and object '%s'\n", path, comp_unit_info->oso_object.GetCString());
+ }
+ else
+ {
+ comp_unit_info->symbol_file_supported = false;
+ return false;
+ }
}
+ // Always create a new module for .o files. Why? Because we
+ // use the debug map, to add new sections to each .o file and
+ // even though a .o file might not have changed, the sections
+ // that get added to the .o file can change.
+ comp_unit_info->oso_module_sp.reset (new DebugMapModule (GetObjectFile()->GetModule(),
+ GetCompUnitInfoIndex(comp_unit_info),
+ comp_unit_info->oso_file,
+ m_obj_file->GetModule()->GetArchitecture(),
+ comp_unit_info->oso_object ? &comp_unit_info->oso_object : NULL,
+ 0));
}
return comp_unit_info->oso_module_sp.get();
}
@@ -199,19 +466,11 @@ SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec
{
if (oso_idx < m_compile_unit_infos.size())
{
- if (!m_compile_unit_infos[oso_idx].so_file)
+ if (m_compile_unit_infos[oso_idx].so_file)
{
-
- if (m_compile_unit_infos[oso_idx].so_symbol == NULL)
- return false;
-
- std::string so_path (m_compile_unit_infos[oso_idx].so_symbol->GetMangled().GetName().AsCString());
- if (m_compile_unit_infos[oso_idx].so_symbol[1].GetType() == eSymbolTypeSourceFile)
- so_path += m_compile_unit_infos[oso_idx].so_symbol[1].GetMangled().GetName().AsCString();
- m_compile_unit_infos[oso_idx].so_file.SetFile(so_path.c_str(), true);
+ file_spec = m_compile_unit_infos[oso_idx].so_file;
+ return true;
}
- file_spec = m_compile_unit_infos[oso_idx].so_file;
- return true;
}
return false;
}
@@ -270,182 +529,13 @@ SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
SymbolFileDWARF *
SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
{
- if (comp_unit_info->oso_symbol_vendor == NULL && comp_unit_info->symbol_file_supported)
+ Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
+ if (oso_module)
{
- ObjectFile *oso_objfile = GetObjectFileByCompUnitInfo (comp_unit_info);
-
- if (oso_objfile)
- {
- comp_unit_info->oso_symbol_vendor = oso_objfile->GetModule()->GetSymbolVendor();
-// SymbolFileDWARF *oso_dwarf = new SymbolFileDWARF(oso_objfile);
-// comp_unit_info->oso_dwarf_sp.reset (oso_dwarf);
- if (comp_unit_info->oso_symbol_vendor)
- {
- // Set a a pointer to this class to set our OSO DWARF file know
- // that the DWARF is being used along with a debug map and that
- // it will have the remapped sections that we do below.
- SymbolFileDWARF *oso_symfile = (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile();
-
- if (!oso_symfile)
- return NULL;
-
- if (oso_symfile->GetNumCompileUnits() != 1)
- {
- oso_symfile->GetObjectFile()->GetModule()->ReportError ("DWARF for object file '%s' contains multiple translation units!",
- oso_symfile->GetObjectFile()->GetFileSpec().GetFilename().AsCString());
- comp_unit_info->symbol_file_supported = false;
- comp_unit_info->oso_module_sp.reset();
- comp_unit_info->oso_compile_unit_sp.reset();
- comp_unit_info->oso_symbol_vendor = NULL;
- return NULL;
- }
-
- oso_symfile->SetDebugMapSymfile(this);
- // 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.
- oso_symfile->SetID (((uint64_t)GetCompUnitInfoIndex(comp_unit_info) + 1ull) << 32ull);
- comp_unit_info->debug_map_sections_sp.reset(new SectionList);
-
- Symtab *exe_symtab = m_obj_file->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.
- uint32_t oso_start_idx = exe_symtab->GetIndexForSymbol (comp_unit_info->oso_symbol);
- assert (oso_start_idx != UINT32_MAX);
- oso_start_idx += 1;
- const uint32_t oso_end_idx = comp_unit_info->so_symbol->GetSiblingIndex();
- uint32_t sect_id = 0x10000;
- for (uint32_t idx = oso_start_idx; 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);
- comp_unit_info->debug_map_sections_sp->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);
- comp_unit_info->debug_map_sections_sp->AddSection(oso_gsym_section_sp);
- }
- }
- }
- break;
- }
- }
- }
- oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
- comp_unit_info->debug_map_sections_sp->Finalize();
-#if defined(DEBUG_OSO_DMAP)
- s << "OSO sections after:\n";
- oso_objfile->GetSectionList()->Dump(&s, NULL, true);
-#endif
- }
- }
+ SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
+ if (sym_vendor)
+ return (SymbolFileDWARF *)sym_vendor->GetSymbolFile();
}
- if (comp_unit_info->oso_symbol_vendor)
- return (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile();
return NULL;
}
@@ -468,16 +558,19 @@ SymbolFileDWARFDebugMap::CalculateAbilities ()
SymbolFile::VariableTypes |
SymbolFile::LineTables;
- for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx)
- {
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- if (oso_dwarf)
- {
- uint32_t oso_abilities = oso_dwarf->GetAbilities();
- if ((oso_abilities & dwarf_abilities) == dwarf_abilities)
- return oso_abilities;
- }
- }
+ InitOSO();
+ if (!m_compile_unit_infos.empty())
+ return dwarf_abilities;
+// for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx)
+// {
+// SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
+// if (oso_dwarf)
+// {
+// uint32_t oso_abilities = oso_dwarf->GetAbilities();
+// if ((oso_abilities & dwarf_abilities) == dwarf_abilities)
+// return oso_abilities;
+// }
+// }
}
return 0;
}
@@ -501,30 +594,34 @@ SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL &&
m_compile_unit_infos[cu_idx].symbol_file_supported)
{
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (cu_idx);
- if (oso_dwarf)
+ FileSpec so_file_spec;
+ if (GetFileSpecForSO (cu_idx, so_file_spec))
{
- // There is only one compile unit for N_OSO entry right now, so
- // it will always exist at index zero.
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp = m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetCompileUnitAtIndex (0);
- }
+ 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].oso_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].oso_compile_unit_sp.get() == NULL)
- {
- // We weren't able to get the DWARF for this N_OSO entry (the
- // .o file may be missing or not at the specified path), make
- // one up as best we can from the debug map. We set the uid
- // of the compile unit to the symbol index with the MSBit set
- // so that it doesn't collide with any uid values from the DWARF
- Symbol *so_symbol = m_compile_unit_infos[cu_idx].so_symbol;
- if (so_symbol)
+ if (!m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
{
m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
NULL,
- so_symbol->GetMangled().GetName().AsCString(),
+ so_file_spec,
cu_idx,
eLanguageTypeUnknown));
-
+ }
+
+ if (m_compile_unit_infos[cu_idx].oso_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].oso_compile_unit_sp);
@@ -549,6 +646,28 @@ SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
return NULL;
}
+
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompUnitInfo (const lldb_private::Module *module)
+{
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t i=0; i<cu_count; ++i)
+ {
+ if (module == m_compile_unit_infos[i].oso_module_sp.get())
+ return &m_compile_unit_infos[i];
+ }
+ return NULL;
+}
+
+lldb::LanguageType
+SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
+{
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitLanguage (sc);
+ return eLanguageTypeUnknown;
+}
+
size_t
SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
{
@@ -602,7 +721,7 @@ SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
{
SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
if (oso_dwarf)
- return oso_dwarf->ParseTypes (sc);
+ return oso_dwarf->ParseVariablesForContext (sc);
return 0;
}
@@ -669,24 +788,31 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint3
uint32_t
SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
{
- uint32_t initial = sc_list.GetSize();
+ const uint32_t initial = sc_list.GetSize();
const uint32_t cu_count = GetNumCompileUnits();
- FileSpec so_file_spec;
for (uint32_t i=0; i<cu_count; ++i)
{
- if (GetFileSpecForSO (i, so_file_spec))
+ // If we are checking for inlines, then we need to look through all
+ // compile units no matter if "file_spec" matches.
+ bool resolve = check_inlines;
+
+ if (!resolve)
{
- // By passing false to the comparison we will be able to match
- // and files given a filename only. If both file_spec and
- // so_file_spec have directories, we will still do a full match.
- if (FileSpec::Compare (file_spec, so_file_spec, false) == 0)
+ FileSpec so_file_spec;
+ if (GetFileSpecForSO (i, so_file_spec))
{
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
- if (oso_dwarf)
- oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
+ // Match the full path if the incoming file_spec has a directory (not just a basename)
+ const bool full_match = file_spec.GetDirectory();
+ resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
}
}
+ if (resolve)
+ {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
+ if (oso_dwarf)
+ oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
+ }
}
return sc_list.GetSize() - initial;
}
@@ -825,10 +951,10 @@ SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr,
{
const user_id_t symbol_id = *symbol_idx_ptr;
- if (symbol_id < comp_unit_info->so_symbol->GetID())
+ if (symbol_id < comp_unit_info->first_symbol_id)
return -1;
- if (symbol_id <= comp_unit_info->last_symbol->GetID())
+ if (symbol_id <= comp_unit_info->last_symbol_id)
return 0;
return 1;
@@ -1113,23 +1239,49 @@ SymbolFileDWARFDebugMap::GetPluginVersion()
return 1;
}
-void
-SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
+lldb::CompUnitSP
+SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
{
- const uint32_t cu_count = GetNumCompileUnits();
- for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
+ if (oso_dwarf)
{
- if (m_compile_unit_infos[cu_idx].oso_symbol_vendor &&
- m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetSymbolFile() == oso_dwarf)
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
{
- if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
+ SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
+ if (oso_symfile == oso_dwarf)
{
- assert (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == cu_sp.get());
+ if (!m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
+ m_compile_unit_infos[cu_idx].oso_compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
+
+ return m_compile_unit_infos[cu_idx].oso_compile_unit_sp;
}
- else
+ }
+ }
+ assert(!"this shouldn't happen");
+ return lldb::CompUnitSP();
+}
+
+
+void
+SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
+{
+ 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)
{
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp = cu_sp;
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
+ if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
+ {
+ assert (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == cu_sp.get());
+ }
+ else
+ {
+ m_compile_unit_infos[cu_idx].oso_compile_unit_sp = cu_sp;
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
+ }
}
}
}
OpenPOWER on IntegriCloud