[Lldb-commits] [lldb] r280751 - *** This commit represents a complete reformatting of the LLDB source code
Kate Stone via lldb-commits
lldb-commits at lists.llvm.org
Tue Sep 6 13:58:36 PDT 2016
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Tue Sep 6 15:57:50 2016
@@ -15,10 +15,10 @@
#include "DWARFDebugAranges.h"
-#include "lldb/Core/RangeMap.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Section.h"
@@ -41,1550 +41,1401 @@
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()"
+// 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.
const SymbolFileDWARFDebugMap::FileRangeMap &
-SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
-{
- if (file_range_map_valid)
- return file_range_map;
-
- file_range_map_valid = true;
-
- Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
- if (!oso_module)
- return file_range_map;
-
- ObjectFile *oso_objfile = oso_module->GetObjectFile();
- if (!oso_objfile)
- return file_range_map;
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log)
- {
- ConstString object_name (oso_module->GetObjectName());
- log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
- static_cast<void*>(this),
- oso_module->GetSpecificationDescription().c_str());
- }
-
- std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
- if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
- {
- for (auto comp_unit_info : cu_infos)
- {
- Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
- ModuleSP oso_module_sp (oso_objfile->GetModule());
- Symtab *oso_symtab = oso_objfile->GetSymtab();
-
- ///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 ended 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)
- {
- 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(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
- eSymbolTypeCode,
- Symtab::eDebugNo,
- Symtab::eVisibilityAny);
- if (oso_fun_symbol)
- {
- // Add the inverse OSO file address to debug map entry mapping
- exe_symfile->AddOSOFileRange (this,
- exe_symbol->GetAddressRef().GetFileAddress(),
- exe_symbol->GetByteSize(),
- oso_fun_symbol->GetAddressRef().GetFileAddress(),
- oso_fun_symbol->GetByteSize());
-
- }
- }
- 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(lldb::eLanguageTypeUnknown, 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->GetAddressRef().GetFileAddress(),
- exe_symbol->GetByteSize(),
- oso_gsym_symbol->GetAddressRef().GetFileAddress(),
- oso_gsym_symbol->GetByteSize());
- }
- }
- break;
- }
- }
- }
-
- exe_symfile->FinalizeOSOFileRanges (this);
- // We don't need the symbols anymore for the .o files
- oso_objfile->ClearSymtab();
- }
- }
+SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
+ SymbolFileDWARFDebugMap *exe_symfile) {
+ if (file_range_map_valid)
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,
- const TimeValue *object_mod_time_ptr) :
- Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr),
- m_exe_module_wp (exe_module_sp),
- m_cu_idx (cu_idx)
- {
- }
-
- ~DebugMapModule() override = default;
-
- SymbolVendor*
- GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) override
- {
- // 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)
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
- if (symbol_vendor)
- {
- // Set 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 = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(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)
- {
- 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);
- }
- return symbol_vendor;
- }
- }
- }
- return NULL;
- }
-
-protected:
- ModuleWP m_exe_module_wp;
- const uint32_t m_cu_idx;
-};
-void
-SymbolFileDWARFDebugMap::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
-
-void
-SymbolFileDWARFDebugMap::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-lldb_private::ConstString
-SymbolFileDWARFDebugMap::GetPluginNameStatic()
-{
- static ConstString g_name("dwarf-debugmap");
- return g_name;
-}
-
-const char *
-SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
-{
- return "DWARF and DWARF3 debug symbol file reader (debug map).";
-}
-
-SymbolFile*
-SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
-{
- return new SymbolFileDWARFDebugMap (obj_file);
-}
-
-SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
- SymbolFile(ofile),
- m_flags(),
- m_compile_unit_infos(),
- m_func_indexes(),
- m_glob_indexes(),
- m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
-{
-}
-
-SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
-{
-}
-
-void
-SymbolFileDWARFDebugMap::InitializeObject()
-{
-}
-
-void
-SymbolFileDWARFDebugMap::InitOSO()
-{
- if (m_flags.test(kHaveInitializedOSOs))
- return;
-
- m_flags.set(kHaveInitializedOSOs);
-
- // If the object file has been stripped, there is no sense in looking further
- // as all of the debug symbols for the debug map will not be available
- if (m_obj_file->IsStripped())
- return;
-
- // Also make sure the file type is some sort of executable. Core files, debug
- // info files (dSYM), object files (.o files), and stub libraries all can
- switch (m_obj_file->GetType())
- {
- case ObjectFile::eTypeInvalid:
- case ObjectFile::eTypeCoreFile:
- case ObjectFile::eTypeDebugInfo:
- case ObjectFile::eTypeObjectFile:
- case ObjectFile::eTypeStubLibrary:
- case ObjectFile::eTypeUnknown:
- case ObjectFile::eTypeJIT:
- return;
-
- case ObjectFile::eTypeExecutable:
- case ObjectFile::eTypeDynamicLinker:
- case ObjectFile::eTypeSharedLibrary:
- break;
- }
-
- // 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
- // these files exist and also contain valid DWARF. If we get any of that
- // then we return the abilities of the first N_OSO's DWARF.
-
- Symtab* symtab = m_obj_file->GetSymtab();
- if (symtab)
- {
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
-
- std::vector<uint32_t> oso_indexes;
- // 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.
- //
- // To find all N_OSO entries that are part of the DWARF + debug map
- // we find only object file symbols with the flags value as follows:
- // bits 23:16 == 0x66 (N_OSO)
- // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
- const uint32_t k_oso_symbol_flags_value = 0x660001u;
-
- const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
-
- if (oso_index_count > 0)
- {
- symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
- symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);
-
- 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->GetAddressRef().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->GetAddressRef().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();
+ file_range_map_valid = true;
- m_compile_unit_infos.resize(oso_index_count);
+ Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this);
+ if (!oso_module)
+ return file_range_map;
- for (uint32_t i=0; i<oso_index_count; ++i)
- {
- const uint32_t so_idx = oso_indexes[i] - 1;
- const uint32_t oso_idx = oso_indexes[i];
- const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
- const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
- if (so_symbol &&
- oso_symbol &&
- so_symbol->GetType() == eSymbolTypeSourceFile &&
- oso_symbol->GetType() == eSymbolTypeObjectFile)
- {
- m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
- m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
- TimeValue oso_mod_time;
- oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0));
- m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
- 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 == UINT32_MAX)
- {
- 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
- {
- const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
- m_compile_unit_infos[i].first_symbol_index = so_idx;
- m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
- 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, oso_symbol->GetName().GetCString());
- }
- }
- else
- {
- if (oso_symbol == NULL)
- m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx);
- else if (so_symbol == NULL)
- m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx);
- else if (so_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx);
- else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx);
- }
- }
- }
- }
-}
+ ObjectFile *oso_objfile = oso_module->GetObjectFile();
+ if (!oso_objfile)
+ return file_range_map;
-Module *
-SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
-{
- const uint32_t cu_count = GetNumCompileUnits();
- if (oso_idx < cu_count)
- return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
- return NULL;
-}
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+ if (log) {
+ ConstString object_name(oso_module->GetObjectName());
+ log->Printf(
+ "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
+ static_cast<void *>(this),
+ oso_module->GetSpecificationDescription().c_str());
+ }
+
+ std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
+ if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
+ for (auto comp_unit_info : cu_infos) {
+ Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
+ ModuleSP oso_module_sp(oso_objfile->GetModule());
+ Symtab *oso_symtab = oso_objfile->GetSymtab();
+
+ /// 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 ended 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) {
+ Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
+ if (exe_symbol) {
+ if (exe_symbol->IsDebug() == false)
+ continue;
-Module *
-SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
-{
- if (!comp_unit_info->oso_sp)
- {
- auto pos = m_oso_map.find (comp_unit_info->oso_path);
- if (pos != m_oso_map.end())
- {
- comp_unit_info->oso_sp = pos->second;
- }
- else
- {
- ObjectFile *obj_file = GetObjectFile();
- comp_unit_info->oso_sp.reset (new OSOInfo());
- m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
- const char *oso_path = comp_unit_info->oso_path.GetCString();
- FileSpec oso_file (oso_path, false);
- ConstString oso_object;
- if (oso_file.Exists())
- {
- TimeValue oso_mod_time (oso_file.GetModificationTime());
- if (oso_mod_time != comp_unit_info->oso_mod_time)
- {
- obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored",
- oso_file.GetPath().c_str(),
- oso_mod_time.GetAsSecondsSinceJan1_1970(),
- comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
- return NULL;
- }
+ switch (exe_symbol->GetType()) {
+ default:
+ break;
- }
- else
- {
- const bool must_exist = true;
-
- if (!ObjectFile::SplitArchivePathWithObject (oso_path,
- oso_file,
- oso_object,
- must_exist))
- {
- return NULL;
- }
- }
- // 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.
- ArchSpec oso_arch;
- // Only adopt the architecture from the module (not the vendor or OS)
- // since .o files for "i386-apple-ios" will historically show up as "i386-apple-macosx"
- // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
- // load command...
- oso_arch.SetTriple(m_obj_file->GetModule()->GetArchitecture().GetTriple().getArchName().str().c_str());
- comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
- GetCompUnitInfoIndex(comp_unit_info),
- oso_file,
- oso_arch,
- oso_object ? &oso_object : NULL,
- 0,
- oso_object ? &comp_unit_info->oso_mod_time : NULL));
- }
+ 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(lldb::eLanguageTypeUnknown,
+ Mangled::ePreferMangled),
+ eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
+ if (oso_fun_symbol) {
+ // Add the inverse OSO file address to debug map entry mapping
+ exe_symfile->AddOSOFileRange(
+ this, exe_symbol->GetAddressRef().GetFileAddress(),
+ exe_symbol->GetByteSize(),
+ oso_fun_symbol->GetAddressRef().GetFileAddress(),
+ oso_fun_symbol->GetByteSize());
+ }
+ } 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(lldb::eLanguageTypeUnknown,
+ 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->GetAddressRef().GetFileAddress(),
+ exe_symbol->GetByteSize(),
+ oso_gsym_symbol->GetAddressRef().GetFileAddress(),
+ oso_gsym_symbol->GetByteSize());
+ }
+ } break;
+ }
+ }
+ }
+
+ exe_symfile->FinalizeOSOFileRanges(this);
+ // We don't need the symbols anymore for the .o files
+ oso_objfile->ClearSymtab();
}
- if (comp_unit_info->oso_sp)
- return comp_unit_info->oso_sp->module_sp.get();
- return NULL;
+ }
+ return file_range_map;
}
-bool
-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)
- {
- file_spec = m_compile_unit_infos[oso_idx].so_file;
- return true;
+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,
+ const TimeValue *object_mod_time_ptr)
+ : Module(file_spec, arch, object_name, object_offset,
+ object_mod_time_ptr),
+ m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {}
+
+ ~DebugMapModule() override = default;
+
+ SymbolVendor *
+ GetSymbolVendor(bool can_create = true,
+ lldb_private::Stream *feedback_strm = NULL) override {
+ // 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) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ SymbolVendor *symbol_vendor =
+ Module::GetSymbolVendor(can_create, feedback_strm);
+ if (symbol_vendor) {
+ // Set 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 =
+ SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(
+ 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) {
+ 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);
+ }
+ return symbol_vendor;
}
+ }
}
- return false;
-}
-
-ObjectFile *
-SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
-{
- Module *oso_module = GetModuleByOSOIndex (oso_idx);
- if (oso_module)
- return oso_module->GetObjectFile();
- return NULL;
-}
-
-SymbolFileDWARF *
-SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
-{
- CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
- if (comp_unit_info)
- return GetSymbolFileByCompUnitInfo (comp_unit_info);
return NULL;
-}
+ }
-ObjectFile *
-SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
-{
- Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
- if (oso_module)
- return oso_module->GetObjectFile();
- return NULL;
-}
+protected:
+ ModuleWP m_exe_module_wp;
+ const uint32_t m_cu_idx;
+};
-uint32_t
-SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
-{
- if (!m_compile_unit_infos.empty())
- {
- const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
- const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
- if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
- return comp_unit_info - first_comp_unit_info;
- }
- return UINT32_MAX;
+void SymbolFileDWARFDebugMap::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void SymbolFileDWARFDebugMap::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginNameStatic() {
+ static ConstString g_name("dwarf-debugmap");
+ return g_name;
+}
+
+const char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() {
+ return "DWARF and DWARF3 debug symbol file reader (debug map).";
+}
+
+SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) {
+ return new SymbolFileDWARFDebugMap(obj_file);
+}
+
+SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile)
+ : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(),
+ m_glob_indexes(),
+ m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
+
+SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
+
+void SymbolFileDWARFDebugMap::InitializeObject() {}
+
+void SymbolFileDWARFDebugMap::InitOSO() {
+ if (m_flags.test(kHaveInitializedOSOs))
+ return;
+
+ m_flags.set(kHaveInitializedOSOs);
+
+ // If the object file has been stripped, there is no sense in looking further
+ // as all of the debug symbols for the debug map will not be available
+ if (m_obj_file->IsStripped())
+ return;
+
+ // Also make sure the file type is some sort of executable. Core files, debug
+ // info files (dSYM), object files (.o files), and stub libraries all can
+ switch (m_obj_file->GetType()) {
+ case ObjectFile::eTypeInvalid:
+ case ObjectFile::eTypeCoreFile:
+ case ObjectFile::eTypeDebugInfo:
+ case ObjectFile::eTypeObjectFile:
+ case ObjectFile::eTypeStubLibrary:
+ case ObjectFile::eTypeUnknown:
+ case ObjectFile::eTypeJIT:
+ return;
+
+ case ObjectFile::eTypeExecutable:
+ case ObjectFile::eTypeDynamicLinker:
+ case ObjectFile::eTypeSharedLibrary:
+ break;
+ }
+
+ // 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
+ // these files exist and also contain valid DWARF. If we get any of that
+ // then we return the abilities of the first N_OSO's DWARF.
+
+ Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+
+ std::vector<uint32_t> oso_indexes;
+ // 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.
+ //
+ // To find all N_OSO entries that are part of the DWARF + debug map
+ // we find only object file symbols with the flags value as follows:
+ // bits 23:16 == 0x66 (N_OSO)
+ // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
+ const uint32_t k_oso_symbol_flags_value = 0x660001u;
+
+ const uint32_t oso_index_count =
+ symtab->AppendSymbolIndexesWithTypeAndFlagsValue(
+ eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
+
+ if (oso_index_count > 0) {
+ symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes,
+ Symtab::eVisibilityAny,
+ m_func_indexes);
+ symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes,
+ Symtab::eVisibilityAny,
+ m_glob_indexes);
+
+ 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->GetAddressRef().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->GetAddressRef().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();
+
+ m_compile_unit_infos.resize(oso_index_count);
+
+ for (uint32_t i = 0; i < oso_index_count; ++i) {
+ const uint32_t so_idx = oso_indexes[i] - 1;
+ const uint32_t oso_idx = oso_indexes[i];
+ const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
+ const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
+ if (so_symbol && oso_symbol &&
+ so_symbol->GetType() == eSymbolTypeSourceFile &&
+ oso_symbol->GetType() == eSymbolTypeObjectFile) {
+ m_compile_unit_infos[i].so_file.SetFile(
+ so_symbol->GetName().AsCString(), false);
+ m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
+ TimeValue oso_mod_time;
+ oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0));
+ m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
+ 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 == UINT32_MAX) {
+ 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 {
+ const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
+ m_compile_unit_infos[i].first_symbol_index = so_idx;
+ m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
+ 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,
+ oso_symbol->GetName().GetCString());
+ }
+ } else {
+ if (oso_symbol == NULL)
+ m_obj_file->GetModule()->ReportError(
+ "N_OSO symbol[%u] can't be found, please file a bug and attach "
+ "the binary listed in this error",
+ oso_idx);
+ else if (so_symbol == NULL)
+ m_obj_file->GetModule()->ReportError(
+ "N_SO not found for N_OSO symbol[%u], please file a bug and "
+ "attach the binary listed in this error",
+ oso_idx);
+ else if (so_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError(
+ "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
+ "please file a bug and attach the binary listed in this error",
+ so_symbol->GetType(), oso_idx);
+ else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError(
+ "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
+ "please file a bug and attach the binary listed in this error",
+ oso_symbol->GetType(), oso_idx);
+ }
+ }
+ }
+ }
+}
+
+Module *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
+ const uint32_t cu_count = GetNumCompileUnits();
+ if (oso_idx < cu_count)
+ return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
+ return NULL;
+}
+
+Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
+ CompileUnitInfo *comp_unit_info) {
+ if (!comp_unit_info->oso_sp) {
+ auto pos = m_oso_map.find(comp_unit_info->oso_path);
+ if (pos != m_oso_map.end()) {
+ comp_unit_info->oso_sp = pos->second;
+ } else {
+ ObjectFile *obj_file = GetObjectFile();
+ comp_unit_info->oso_sp.reset(new OSOInfo());
+ m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
+ const char *oso_path = comp_unit_info->oso_path.GetCString();
+ FileSpec oso_file(oso_path, false);
+ ConstString oso_object;
+ if (oso_file.Exists()) {
+ TimeValue oso_mod_time(oso_file.GetModificationTime());
+ if (oso_mod_time != comp_unit_info->oso_mod_time) {
+ obj_file->GetModule()->ReportError(
+ "debug map object file '%s' has changed (actual time is "
+ "0x%" PRIx64 ", debug map time is 0x%" PRIx64
+ ") since this executable was linked, file will be ignored",
+ oso_file.GetPath().c_str(),
+ oso_mod_time.GetAsSecondsSinceJan1_1970(),
+ comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
+ return NULL;
+ }
+
+ } else {
+ const bool must_exist = true;
+
+ if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file,
+ oso_object, must_exist)) {
+ return NULL;
+ }
+ }
+ // 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.
+ ArchSpec oso_arch;
+ // Only adopt the architecture from the module (not the vendor or OS)
+ // since .o files for "i386-apple-ios" will historically show up as
+ // "i386-apple-macosx"
+ // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
+ // load command...
+ oso_arch.SetTriple(m_obj_file->GetModule()
+ ->GetArchitecture()
+ .GetTriple()
+ .getArchName()
+ .str()
+ .c_str());
+ comp_unit_info->oso_sp->module_sp.reset(new DebugMapModule(
+ obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file,
+ oso_arch, oso_object ? &oso_object : NULL, 0,
+ oso_object ? &comp_unit_info->oso_mod_time : NULL));
+ }
+ }
+ if (comp_unit_info->oso_sp)
+ return comp_unit_info->oso_sp->module_sp.get();
+ return NULL;
+}
+
+bool 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) {
+ file_spec = m_compile_unit_infos[oso_idx].so_file;
+ return true;
+ }
+ }
+ return false;
+}
+
+ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) {
+ Module *oso_module = GetModuleByOSOIndex(oso_idx);
+ if (oso_module)
+ return oso_module->GetObjectFile();
+ return NULL;
}
SymbolFileDWARF *
-SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
-{
- if (oso_idx < m_compile_unit_infos.size())
- return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
- return NULL;
+SymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) {
+ CompileUnitInfo *comp_unit_info = GetCompUnitInfo(sc);
+ if (comp_unit_info)
+ return GetSymbolFileByCompUnitInfo(comp_unit_info);
+ return NULL;
+}
+
+ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo(
+ CompileUnitInfo *comp_unit_info) {
+ Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
+ if (oso_module)
+ return oso_module->GetObjectFile();
+ return NULL;
+}
+
+uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex(
+ const CompileUnitInfo *comp_unit_info) {
+ if (!m_compile_unit_infos.empty()) {
+ const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
+ const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
+ if (first_comp_unit_info <= comp_unit_info &&
+ comp_unit_info <= last_comp_unit_info)
+ return comp_unit_info - first_comp_unit_info;
+ }
+ return UINT32_MAX;
}
SymbolFileDWARF *
-SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
-{
- if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
- return (SymbolFileDWARF *)sym_file;
- return NULL;
+SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) {
+ if (oso_idx < m_compile_unit_infos.size())
+ return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
+ return NULL;
}
SymbolFileDWARF *
-SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
-{
- Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
- if (oso_module)
- {
- SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
- if (sym_vendor)
- return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
- }
- return NULL;
-}
-
-uint32_t
-SymbolFileDWARFDebugMap::CalculateAbilities ()
-{
- // 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
- // these files exist and also contain valid DWARF. If we get any of that
- // then we return the abilities of the first N_OSO's DWARF.
-
- const uint32_t oso_index_count = GetNumCompileUnits();
- if (oso_index_count > 0)
- {
- InitOSO();
- if (!m_compile_unit_infos.empty())
- {
- return SymbolFile::CompileUnits |
- SymbolFile::Functions |
- SymbolFile::Blocks |
- SymbolFile::GlobalVariables |
- SymbolFile::LocalVariables |
- SymbolFile::VariableTypes |
- SymbolFile::LineTables ;
+SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
+ if (sym_file &&
+ sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
+ return (SymbolFileDWARF *)sym_file;
+ return NULL;
+}
+
+SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
+ CompileUnitInfo *comp_unit_info) {
+ Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
+ if (oso_module) {
+ SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
+ if (sym_vendor)
+ return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile());
+ }
+ return NULL;
+}
+
+uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
+ // 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
+ // these files exist and also contain valid DWARF. If we get any of that
+ // then we return the abilities of the first N_OSO's DWARF.
+
+ const uint32_t oso_index_count = GetNumCompileUnits();
+ if (oso_index_count > 0) {
+ InitOSO();
+ if (!m_compile_unit_infos.empty()) {
+ return SymbolFile::CompileUnits | SymbolFile::Functions |
+ SymbolFile::Blocks | SymbolFile::GlobalVariables |
+ SymbolFile::LocalVariables | SymbolFile::VariableTypes |
+ SymbolFile::LineTables;
+ }
+ }
+ return 0;
+}
+
+uint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() {
+ InitOSO();
+ return m_compile_unit_infos.size();
+}
+
+CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
+ CompUnitSP comp_unit_sp;
+ const uint32_t cu_count = GetNumCompileUnits();
+
+ if (cu_idx < cu_count) {
+ Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
+ if (oso_module) {
+ FileSpec so_file_spec;
+ if (GetFileSpecForSO(cu_idx, so_file_spec)) {
+ // 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, eLazyBoolCalculate));
+
+ 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);
}
+ }
}
- return 0;
-}
+ comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
+ }
-uint32_t
-SymbolFileDWARFDebugMap::GetNumCompileUnits()
-{
- InitOSO ();
- return m_compile_unit_infos.size();
-}
-
-CompUnitSP
-SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
-{
- CompUnitSP comp_unit_sp;
- const uint32_t cu_count = GetNumCompileUnits();
-
- if (cu_idx < cu_count)
- {
- Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
- if (oso_module)
- {
- FileSpec so_file_spec;
- if (GetFileSpecForSO (cu_idx, so_file_spec))
- {
- // 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, eLazyBoolCalculate));
-
- 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);
- }
- }
- }
- comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
- }
-
- return comp_unit_sp;
+ return comp_unit_sp;
}
SymbolFileDWARFDebugMap::CompileUnitInfo *
-SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
-{
- const uint32_t cu_count = GetNumCompileUnits();
- for (uint32_t i=0; i<cu_count; ++i)
- {
- if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
- return &m_compile_unit_infos[i];
- }
- return NULL;
-}
-
-size_t
-SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
-{
- const uint32_t cu_count = GetNumCompileUnits();
- for (uint32_t i=0; i<cu_count; ++i)
- {
- if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
- cu_infos.push_back (&m_compile_unit_infos[i]);
- }
- return cu_infos.size();
+SymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t i = 0; i < cu_count; ++i) {
+ if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
+ return &m_compile_unit_infos[i];
+ }
+ return NULL;
+}
+
+size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
+ const lldb_private::Module *module,
+ std::vector<CompileUnitInfo *> &cu_infos) {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t i = 0; i < cu_count; ++i) {
+ if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i]))
+ cu_infos.push_back(&m_compile_unit_infos[i]);
+ }
+ return cu_infos.size();
}
lldb::LanguageType
-SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitLanguage (sc);
- return eLanguageTypeUnknown;
+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)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitFunctions (sc);
- return 0;
+SymbolFileDWARFDebugMap::ParseCompileUnitFunctions(const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitFunctions(sc);
+ return 0;
+}
+
+bool SymbolFileDWARFDebugMap::ParseCompileUnitLineTable(
+ const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitLineTable(sc);
+ return false;
+}
+
+bool SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros(
+ const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitDebugMacros(sc);
+ return false;
+}
+
+bool SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles(
+ const SymbolContext &sc, FileSpecList &support_files) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitSupportFiles(sc, support_files);
+ return false;
+}
+
+bool SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(
+ const lldb_private::SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCompileUnitIsOptimized(sc);
+ return false;
+}
+
+bool SymbolFileDWARFDebugMap::ParseImportedModules(
+ const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseImportedModules(sc, imported_modules);
+ return false;
+}
+
+size_t SymbolFileDWARFDebugMap::ParseFunctionBlocks(const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseFunctionBlocks(sc);
+ return 0;
+}
+
+size_t SymbolFileDWARFDebugMap::ParseTypes(const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseTypes(sc);
+ return 0;
}
-bool
-SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitLineTable (sc);
- return false;
+size_t
+SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->ParseVariablesForContext(sc);
+ return 0;
+}
+
+Type *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)
+ return oso_dwarf->ResolveTypeUID(type_uid);
+ return NULL;
+}
+
+bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
+ bool success = false;
+ if (compiler_type) {
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) {
+ oso_dwarf->CompleteType(compiler_type);
+ success = true;
+ return true;
+ }
+ return false;
+ });
+ }
+ return success;
}
-bool
-SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitDebugMacros (sc);
- return false;
+uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
+ const Address &exe_so_addr, uint32_t resolve_scope, SymbolContext &sc) {
+ uint32_t resolved_flags = 0;
+ Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab) {
+ const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
+
+ const DebugMap::Entry *debug_map_entry =
+ m_debug_map.FindEntryThatContains(exe_file_addr);
+ if (debug_map_entry) {
+
+ sc.symbol =
+ symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
+
+ if (sc.symbol != NULL) {
+ resolved_flags |= eSymbolContextSymbol;
+
+ uint32_t oso_idx = 0;
+ CompileUnitInfo *comp_unit_info =
+ GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx);
+ if (comp_unit_info) {
+ comp_unit_info->GetFileRangeMap(this);
+ Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
+ if (oso_module) {
+ 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);
+ }
+ }
+ }
+ }
+ }
+ }
+ return resolved_flags;
+}
+
+uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
+ const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ uint32_t resolve_scope, SymbolContextList &sc_list) {
+ const uint32_t initial = sc_list.GetSize();
+ const uint32_t cu_count = GetNumCompileUnits();
+
+ for (uint32_t i = 0; i < cu_count; ++i) {
+ // 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) {
+ FileSpec so_file_spec;
+ if (GetFileSpecForSO(i, so_file_spec)) {
+ // Match the full path if the incoming file_spec has a directory (not
+ // just a basename)
+ const bool full_match = (bool)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;
+}
+
+uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ const std::vector<uint32_t>
+ &indexes, // Indexes into the symbol table that match "name"
+ uint32_t max_matches,
+ VariableList &variables) {
+ const uint32_t original_size = variables.GetSize();
+ const size_t match_count = indexes.size();
+ for (size_t i = 0; i < match_count; ++i) {
+ uint32_t oso_idx;
+ CompileUnitInfo *comp_unit_info =
+ GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx);
+ if (comp_unit_info) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
+ if (oso_dwarf) {
+ if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true,
+ max_matches, variables))
+ if (variables.GetSize() > max_matches)
+ break;
+ }
+ }
+ }
+ return variables.GetSize() - original_size;
}
-bool
-SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
- return false;
-}
+uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches, VariableList &variables) {
-bool
-SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
- if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitIsOptimized(sc);
- return false;
-}
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ variables.Clear();
-bool
-SymbolFileDWARFDebugMap::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseImportedModules(sc, imported_modules);
- return false;
-}
+ // Remember how many variables are in the list before we search in case
+ // we are appending the results to a variable list.
+ const uint32_t original_size = variables.GetSize();
-size_t
-SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseFunctionBlocks (sc);
- return 0;
-}
+ uint32_t total_matches = 0;
-size_t
-SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseTypes (sc);
- return 0;
-}
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ const uint32_t oso_matches = oso_dwarf->FindGlobalVariables(
+ name, parent_decl_ctx, true, max_matches, variables);
+ if (oso_matches > 0) {
+ total_matches += oso_matches;
-size_t
-SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
-{
- SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->ParseVariablesForContext (sc);
- return 0;
-}
+ // Are we getting all matches?
+ if (max_matches == UINT32_MAX)
+ return false; // Yep, continue getting everything
-Type*
-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)
- return oso_dwarf->ResolveTypeUID (type_uid);
- return NULL;
-}
+ // If we have found enough matches, lets get out
+ if (max_matches >= total_matches)
+ return true;
-bool
-SymbolFileDWARFDebugMap::CompleteType (CompilerType& compiler_type)
-{
- bool success = false;
- if (compiler_type)
- {
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- if (oso_dwarf->HasForwardDeclForClangType (compiler_type))
- {
- oso_dwarf->CompleteType (compiler_type);
- success = true;
- return true;
- }
- return false;
- });
+ // Update the max matches for any subsequent calls to find globals
+ // in any other object files with DWARF
+ max_matches -= oso_matches;
}
- return success;
-}
-uint32_t
-SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
-{
- uint32_t resolved_flags = 0;
- Symtab* symtab = m_obj_file->GetSymtab();
- if (symtab)
- {
- const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
-
- const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
- if (debug_map_entry)
- {
-
- sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
-
- if (sc.symbol != NULL)
- {
- resolved_flags |= eSymbolContextSymbol;
-
- uint32_t oso_idx = 0;
- CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
- if (comp_unit_info)
- {
- comp_unit_info->GetFileRangeMap(this);
- Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
- if (oso_module)
- {
- 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);
- }
- }
- }
- }
- }
- }
- return resolved_flags;
+ return false;
+ });
+
+ // Return the number of variable that were appended to the list
+ return variables.GetSize() - original_size;
}
uint32_t
-SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
-{
- const uint32_t initial = sc_list.GetSize();
- const uint32_t cu_count = GetNumCompileUnits();
+SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression ®ex,
+ bool append, uint32_t max_matches,
+ VariableList &variables) {
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ variables.Clear();
+
+ // Remember how many variables are in the list before we search in case
+ // we are appending the results to a variable list.
+ const uint32_t original_size = variables.GetSize();
+
+ uint32_t total_matches = 0;
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ const uint32_t oso_matches =
+ oso_dwarf->FindGlobalVariables(regex, true, max_matches, variables);
+ if (oso_matches > 0) {
+ total_matches += oso_matches;
+
+ // Are we getting all matches?
+ if (max_matches == UINT32_MAX)
+ return false; // Yep, continue getting everything
- for (uint32_t i=0; i<cu_count; ++i)
- {
- // 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)
- {
- FileSpec so_file_spec;
- if (GetFileSpecForSO (i, so_file_spec))
- {
- // Match the full path if the incoming file_spec has a directory (not just a basename)
- const bool full_match = (bool)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;
-}
+ // If we have found enough matches, lets get out
+ if (max_matches >= total_matches)
+ return true;
-uint32_t
-SymbolFileDWARFDebugMap::PrivateFindGlobalVariables
-(
- const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- const std::vector<uint32_t> &indexes, // Indexes into the symbol table that match "name"
- uint32_t max_matches,
- VariableList& variables
-)
-{
- const uint32_t original_size = variables.GetSize();
- const size_t match_count = indexes.size();
- for (size_t i=0; i<match_count; ++i)
- {
- uint32_t oso_idx;
- CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
- if (comp_unit_info)
- {
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- if (oso_dwarf)
- {
- if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, max_matches, variables))
- if (variables.GetSize() > max_matches)
- break;
- }
- }
+ // Update the max matches for any subsequent calls to find globals
+ // in any other object files with DWARF
+ max_matches -= oso_matches;
}
- return variables.GetSize() - original_size;
-}
-
-uint32_t
-SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- bool append,
- uint32_t max_matches,
- VariableList& variables)
-{
-
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
-
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
- const uint32_t original_size = variables.GetSize();
- uint32_t total_matches = 0;
-
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
- parent_decl_ctx,
- true,
- max_matches,
- variables);
- if (oso_matches > 0)
- {
- total_matches += oso_matches;
-
- // Are we getting all matches?
- if (max_matches == UINT32_MAX)
- return false; // Yep, continue getting everything
-
- // If we have found enough matches, lets get out
- if (max_matches >= total_matches)
- return true;
-
- // Update the max matches for any subsequent calls to find globals
- // in any other object files with DWARF
- max_matches -= oso_matches;
- }
-
- return false;
- });
+ return false;
+ });
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
+ // Return the number of variable that were appended to the list
+ return variables.GetSize() - original_size;
}
-uint32_t
-SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
-{
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
-
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
- const uint32_t original_size = variables.GetSize();
+int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex(
+ uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
+ const uint32_t symbol_idx = *symbol_idx_ptr;
- uint32_t total_matches = 0;
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
- true,
- max_matches,
- variables);
- if (oso_matches > 0)
- {
- total_matches += oso_matches;
-
- // Are we getting all matches?
- if (max_matches == UINT32_MAX)
- return false; // Yep, continue getting everything
-
- // If we have found enough matches, lets get out
- if (max_matches >= total_matches)
- return true;
-
- // Update the max matches for any subsequent calls to find globals
- // in any other object files with DWARF
- max_matches -= oso_matches;
- }
-
- return false;
- });
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
-}
-
-int
-SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
-{
- const uint32_t symbol_idx = *symbol_idx_ptr;
-
- if (symbol_idx < comp_unit_info->first_symbol_index)
- return -1;
-
- if (symbol_idx <= comp_unit_info->last_symbol_index)
- return 0;
-
- return 1;
-}
-
-int
-SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
-{
- const user_id_t symbol_id = *symbol_idx_ptr;
-
- if (symbol_id < comp_unit_info->first_symbol_id)
- return -1;
-
- if (symbol_id <= comp_unit_info->last_symbol_id)
- return 0;
-
- return 1;
-}
-
-SymbolFileDWARFDebugMap::CompileUnitInfo*
-SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
-{
- const uint32_t oso_index_count = m_compile_unit_infos.size();
- CompileUnitInfo *comp_unit_info = NULL;
- if (oso_index_count)
- {
- comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx,
- &m_compile_unit_infos[0],
- m_compile_unit_infos.size(),
- sizeof(CompileUnitInfo),
- (ComparisonFunction)SymbolContainsSymbolWithIndex);
- }
-
- if (oso_idx_ptr)
- {
- if (comp_unit_info != NULL)
- *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
- else
- *oso_idx_ptr = UINT32_MAX;
- }
- return comp_unit_info;
-}
-
-SymbolFileDWARFDebugMap::CompileUnitInfo*
-SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
-{
- const uint32_t oso_index_count = m_compile_unit_infos.size();
- CompileUnitInfo *comp_unit_info = NULL;
- if (oso_index_count)
- {
- comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id,
- &m_compile_unit_infos[0],
- m_compile_unit_infos.size(),
- sizeof(CompileUnitInfo),
- (ComparisonFunction)SymbolContainsSymbolWithID);
- }
-
- if (oso_idx_ptr)
- {
- if (comp_unit_info != NULL)
- *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
- else
- *oso_idx_ptr = UINT32_MAX;
- }
- return comp_unit_info;
-}
-
-static void
-RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
-{
- // We found functions in .o files. Not all functions in the .o files
- // will have made it into the final output file. The ones that did
- // make it into the final output file will have a section whose module
- // matches the module from the ObjectFile for this SymbolFile. When
- // the modules don't match, then we have something that was in a
- // .o file, but doesn't map to anything in the final executable.
- uint32_t i=start_idx;
- while (i < sc_list.GetSize())
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(i, sc);
- if (sc.function)
- {
- const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
- if (section_sp->GetModule() != module_sp)
- {
- sc_list.RemoveContextAtIndex(i);
- continue;
- }
- }
- ++i;
- }
+ if (symbol_idx < comp_unit_info->first_symbol_index)
+ return -1;
+
+ if (symbol_idx <= comp_unit_info->last_symbol_index)
+ return 0;
+
+ return 1;
}
-uint32_t
-SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask,
- bool include_inlines,
- bool append,
- SymbolContextList& sc_list)
-{
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
- name.GetCString());
-
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
- else
- sc_list.Clear();
+int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID(
+ user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
+ const user_id_t symbol_id = *symbol_idx_ptr;
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- uint32_t sc_idx = sc_list.GetSize();
- if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, true, sc_list))
- {
- RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
- }
- return false;
- });
+ if (symbol_id < comp_unit_info->first_symbol_id)
+ return -1;
+
+ if (symbol_id <= comp_unit_info->last_symbol_id)
+ return 0;
- return sc_list.GetSize() - initial_size;
+ return 1;
}
-uint32_t
-SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
-{
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
- regex.GetText());
-
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex(
+ uint32_t symbol_idx, uint32_t *oso_idx_ptr) {
+ const uint32_t oso_index_count = m_compile_unit_infos.size();
+ CompileUnitInfo *comp_unit_info = NULL;
+ if (oso_index_count) {
+ comp_unit_info = (CompileUnitInfo *)bsearch(
+ &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
+ sizeof(CompileUnitInfo),
+ (ComparisonFunction)SymbolContainsSymbolWithIndex);
+ }
+
+ if (oso_idx_ptr) {
+ if (comp_unit_info != NULL)
+ *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
else
- sc_list.Clear();
+ *oso_idx_ptr = UINT32_MAX;
+ }
+ return comp_unit_info;
+}
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- uint32_t sc_idx = sc_list.GetSize();
-
- if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
- {
- RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
- }
- return false;
- });
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID(
+ user_id_t symbol_id, uint32_t *oso_idx_ptr) {
+ const uint32_t oso_index_count = m_compile_unit_infos.size();
+ CompileUnitInfo *comp_unit_info = NULL;
+ if (oso_index_count) {
+ comp_unit_info = (CompileUnitInfo *)::bsearch(
+ &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
+ sizeof(CompileUnitInfo),
+ (ComparisonFunction)SymbolContainsSymbolWithID);
+ }
+
+ if (oso_idx_ptr) {
+ if (comp_unit_info != NULL)
+ *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
+ else
+ *oso_idx_ptr = UINT32_MAX;
+ }
+ return comp_unit_info;
+}
+
+static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
+ SymbolContextList &sc_list,
+ uint32_t start_idx) {
+ // We found functions in .o files. Not all functions in the .o files
+ // will have made it into the final output file. The ones that did
+ // make it into the final output file will have a section whose module
+ // matches the module from the ObjectFile for this SymbolFile. When
+ // the modules don't match, then we have something that was in a
+ // .o file, but doesn't map to anything in the final executable.
+ uint32_t i = start_idx;
+ while (i < sc_list.GetSize()) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(i, sc);
+ if (sc.function) {
+ const SectionSP section_sp(
+ sc.function->GetAddressRange().GetBaseAddress().GetSection());
+ if (section_sp->GetModule() != module_sp) {
+ sc_list.RemoveContextAtIndex(i);
+ continue;
+ }
+ }
+ ++i;
+ }
+}
+
+uint32_t SymbolFileDWARFDebugMap::FindFunctions(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
+ name.GetCString());
+
+ uint32_t initial_size = 0;
+ if (append)
+ initial_size = sc_list.GetSize();
+ else
+ sc_list.Clear();
+
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ uint32_t sc_idx = sc_list.GetSize();
+ if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
+ include_inlines, true, sc_list)) {
+ RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ sc_idx);
+ }
+ return false;
+ });
- return sc_list.GetSize() - initial_size;
+ return sc_list.GetSize() - initial_size;
}
-size_t
-SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope,
- uint32_t type_mask,
- TypeList &type_list)
-{
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
- type_mask);
-
- uint32_t initial_size = type_list.GetSize();
- SymbolFileDWARF *oso_dwarf = NULL;
- if (sc_scope)
- {
- SymbolContext sc;
- sc_scope->CalculateSymbolContext(&sc);
-
- CompileUnitInfo *cu_info = GetCompUnitInfo (sc);
- if (cu_info)
- {
- oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info);
- if (oso_dwarf)
- oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
- }
+uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression ®ex,
+ bool include_inlines,
+ bool append,
+ SymbolContextList &sc_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
+ regex.GetText());
+
+ uint32_t initial_size = 0;
+ if (append)
+ initial_size = sc_list.GetSize();
+ else
+ sc_list.Clear();
+
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ uint32_t sc_idx = sc_list.GetSize();
+
+ if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) {
+ RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ sc_idx);
}
- else
- {
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
- return false;
- });
- }
- return type_list.GetSize() - initial_size;
+ return false;
+ });
+
+ return sc_list.GetSize() - initial_size;
}
-TypeSP
-SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
-{
- TypeSP type_sp;
+size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ TypeList &type_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
+ type_mask);
+
+ uint32_t initial_size = type_list.GetSize();
+ SymbolFileDWARF *oso_dwarf = NULL;
+ if (sc_scope) {
+ SymbolContext sc;
+ sc_scope->CalculateSymbolContext(&sc);
+
+ CompileUnitInfo *cu_info = GetCompUnitInfo(sc);
+ if (cu_info) {
+ oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info);
+ if (oso_dwarf)
+ oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
+ }
+ } else {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
- return ((bool)type_sp);
+ oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
+ return false;
});
- return type_sp;
+ }
+ return type_list.GetSize() - initial_size;
}
-bool
-SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
-{
- if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
- {
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
- {
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
- return true;
- }
- return false;
- });
- }
- return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
+TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext(
+ const DWARFDeclContext &die_decl_ctx) {
+ TypeSP type_sp;
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+ return ((bool)type_sp);
+ });
+ return type_sp;
+}
+
+bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
+ SymbolFileDWARF *skip_dwarf_oso) {
+ if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ if (skip_dwarf_oso != oso_dwarf &&
+ oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) {
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
+ return true;
+ }
+ return false;
+ });
+ }
+ return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
}
-TypeSP
-SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
- const ConstString &type_name,
- bool must_be_implementation)
-{
- // If we have a debug map, we will have an Objective C symbol whose name is
- // the type name and whose type is eSymbolTypeObjCClass. If we can find that
- // symbol and find its containing parent, we can locate the .o file that will
- // contain the implementation definition since it will be scoped inside the N_SO
- // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
- SymbolFileDWARF *oso_dwarf = NULL;
- TypeSP type_sp;
- ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
- if (module_objfile)
- {
- Symtab *symtab = module_objfile->GetSymtab();
- if (symtab)
- {
- Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny);
- if (objc_class_symbol)
- {
- // Get the N_SO symbol that contains the objective C class symbol as this
- // should be the .o file that contains the real definition...
- const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
-
- if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile)
- {
- const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol);
- if (source_file_symbol_idx != UINT32_MAX)
- {
- CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL);
- if (compile_unit_info)
- {
- oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info);
- if (oso_dwarf)
- {
- TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation));
- if (type_sp)
- {
- return type_sp;
- }
- }
- }
- }
+TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const ConstString &type_name,
+ bool must_be_implementation) {
+ // If we have a debug map, we will have an Objective C symbol whose name is
+ // the type name and whose type is eSymbolTypeObjCClass. If we can find that
+ // symbol and find its containing parent, we can locate the .o file that will
+ // contain the implementation definition since it will be scoped inside the
+ // N_SO
+ // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
+ SymbolFileDWARF *oso_dwarf = NULL;
+ TypeSP type_sp;
+ ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
+ if (module_objfile) {
+ Symtab *symtab = module_objfile->GetSymtab();
+ if (symtab) {
+ Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
+ type_name, eSymbolTypeObjCClass, Symtab::eDebugAny,
+ Symtab::eVisibilityAny);
+ if (objc_class_symbol) {
+ // Get the N_SO symbol that contains the objective C class symbol as
+ // this
+ // should be the .o file that contains the real definition...
+ const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
+
+ if (source_file_symbol &&
+ source_file_symbol->GetType() == eSymbolTypeSourceFile) {
+ const uint32_t source_file_symbol_idx =
+ symtab->GetIndexForSymbol(source_file_symbol);
+ if (source_file_symbol_idx != UINT32_MAX) {
+ CompileUnitInfo *compile_unit_info =
+ GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx,
+ NULL);
+ if (compile_unit_info) {
+ oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info);
+ if (oso_dwarf) {
+ TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name, must_be_implementation));
+ if (type_sp) {
+ return type_sp;
}
+ }
}
+ }
}
+ }
}
+ }
- // Only search all .o files for the definition if we don't need the implementation
- // because otherwise, with a valid debug map we should have the ObjC class symbol and
- // the code above should have found it.
- if (must_be_implementation == false)
- {
- TypeSP type_sp;
-
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
- return (bool)type_sp;
- });
-
- return type_sp;
- }
- return TypeSP();
+ // Only search all .o files for the definition if we don't need the
+ // implementation
+ // because otherwise, with a valid debug map we should have the ObjC class
+ // symbol and
+ // the code above should have found it.
+ if (must_be_implementation == false) {
+ TypeSP type_sp;
+
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name, must_be_implementation);
+ return (bool)type_sp;
+ });
+
+ return type_sp;
+ }
+ return TypeSP();
}
-uint32_t
-SymbolFileDWARFDebugMap::FindTypes
-(
- const SymbolContext& sc,
- const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- bool append,
+uint32_t SymbolFileDWARFDebugMap::FindTypes(
+ const SymbolContext &sc, const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx, bool append,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap& types
-)
-{
- if (!append)
- types.Clear();
-
- const uint32_t initial_types_size = types.GetSize();
- SymbolFileDWARF *oso_dwarf;
-
- if (sc.comp_unit)
- {
- oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
- }
- else
- {
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
- if (types.GetSize() >= max_matches)
- return true;
- else
- return false;
- });
- }
+ TypeMap &types) {
+ if (!append)
+ types.Clear();
+
+ const uint32_t initial_types_size = types.GetSize();
+ SymbolFileDWARF *oso_dwarf;
- return types.GetSize() - initial_types_size;
+ if (sc.comp_unit) {
+ oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ return oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append,
+ max_matches, searched_symbol_files, types);
+ } else {
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, max_matches,
+ searched_symbol_files, types);
+ if (types.GetSize() >= max_matches)
+ return true;
+ else
+ return false;
+ });
+ }
+
+ return types.GetSize() - initial_types_size;
}
//
-//uint32_t
-//SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+// uint32_t
+// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const
+// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding
+// encoding, lldb::user_id_t udt_uid, TypeList& types)
//{
// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
// if (oso_dwarf)
-// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
+// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding,
+// udt_uid, types);
// return 0;
//}
+CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx) {
+ CompilerDeclContext matching_namespace;
+ SymbolFileDWARF *oso_dwarf;
-CompilerDeclContext
-SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc,
- const lldb_private::ConstString &name,
- const CompilerDeclContext *parent_decl_ctx)
-{
- CompilerDeclContext matching_namespace;
- SymbolFileDWARF *oso_dwarf;
-
- if (sc.comp_unit)
- {
- oso_dwarf = GetSymbolFile (sc);
- if (oso_dwarf)
- matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);
- }
- else
- {
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);
+ if (sc.comp_unit) {
+ oso_dwarf = GetSymbolFile(sc);
+ if (oso_dwarf)
+ matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx);
+ } else {
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx);
- return (bool)matching_namespace;
- });
- }
+ return (bool)matching_namespace;
+ });
+ }
- return matching_namespace;
+ return matching_namespace;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-SymbolFileDWARFDebugMap::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-SymbolFileDWARFDebugMap::GetPluginVersion()
-{
- return 1;
-}
+uint32_t SymbolFileDWARFDebugMap::GetPluginVersion() { return 1; }
lldb::CompUnitSP
-SymbolFileDWARFDebugMap::GetCompileUnit (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)
- {
- if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
- m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
-
- return m_compile_unit_infos[cu_idx].compile_unit_sp;
- }
- }
- }
- assert(!"this shouldn't happen");
- return lldb::CompUnitSP();
+SymbolFileDWARFDebugMap::GetCompileUnit(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) {
+ if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
+ m_compile_unit_infos[cu_idx].compile_unit_sp =
+ ParseCompileUnitAtIndex(cu_idx);
+
+ return m_compile_unit_infos[cu_idx].compile_unit_sp;
+ }
+ }
+ }
+ assert(!"this shouldn't happen");
+ 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;
+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)
-{
- 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)
- {
- if (m_compile_unit_infos[cu_idx].compile_unit_sp)
- {
- assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
- }
- else
- {
- m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
- }
- }
+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) {
+ if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
+ assert(m_compile_unit_infos[cu_idx].compile_unit_sp.get() ==
+ cu_sp.get());
+ } else {
+ m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
+ cu_idx, cu_sp);
}
+ }
}
+ }
}
CompilerDeclContext
-SymbolFileDWARFDebugMap::GetDeclContextForUID (lldb::user_id_t type_uid)
-{
- const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- if (oso_dwarf)
- return oso_dwarf->GetDeclContextForUID (type_uid);
- return CompilerDeclContext();
+SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) {
+ const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
+ if (oso_dwarf)
+ return oso_dwarf->GetDeclContextForUID(type_uid);
+ return CompilerDeclContext();
}
CompilerDeclContext
-SymbolFileDWARFDebugMap::GetDeclContextContainingUID (lldb::user_id_t type_uid)
-{
- const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- if (oso_dwarf)
- return oso_dwarf->GetDeclContextContainingUID (type_uid);
- return CompilerDeclContext();
-}
-
-void
-SymbolFileDWARFDebugMap::ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx)
-{
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->ParseDeclsForContext (decl_ctx);
- return true; // Keep iterating
- });
-}
-
-bool
-SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
- lldb::addr_t exe_file_addr,
- lldb::addr_t exe_byte_size,
- lldb::addr_t oso_file_addr,
- lldb::addr_t oso_byte_size)
-{
- 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);
- debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
- addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
- if (range_size == 0)
- {
- range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
- if (range_size == 0)
- range_size = 1;
- }
- cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
- return true;
+SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
+ const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
+ if (oso_dwarf)
+ return oso_dwarf->GetDeclContextContainingUID(type_uid);
+ return CompilerDeclContext();
+}
+
+void SymbolFileDWARFDebugMap::ParseDeclsForContext(
+ lldb_private::CompilerDeclContext decl_ctx) {
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ oso_dwarf->ParseDeclsForContext(decl_ctx);
+ return true; // Keep iterating
+ });
+}
+
+bool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info,
+ lldb::addr_t exe_file_addr,
+ lldb::addr_t exe_byte_size,
+ lldb::addr_t oso_file_addr,
+ lldb::addr_t oso_byte_size) {
+ 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);
+ debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
+ addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
+ if (range_size == 0) {
+ range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
+ if (range_size == 0)
+ range_size = 1;
}
- return false;
+ cu_info->file_range_map.Append(
+ FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
+ return true;
+ }
+ return false;
}
-void
-SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
-{
- cu_info->file_range_map.Sort();
+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) %s\n",
- cu_info,
- cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
- 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());
- }
+ 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) %s\n",
+ cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
+ 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 (GetSymbolFileAsSymbolFileDWARF(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;
+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(GetSymbolFileAsSymbolFileDWARF(
+ 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;
}
size_t
-SymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges)
-{
- size_t num_line_entries_added = 0;
- if (debug_aranges && dwarf2Data)
- {
- CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
- if (compile_unit_info)
- {
- const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this);
- for (size_t idx = 0;
- idx < file_range_map.GetSize();
- idx++)
- {
- const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx);
- if (entry)
- {
- debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
- num_line_entries_added++;
- }
- }
+SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data,
+ DWARFDebugAranges *debug_aranges) {
+ size_t num_line_entries_added = 0;
+ if (debug_aranges && dwarf2Data) {
+ CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
+ if (compile_unit_info) {
+ const FileRangeMap &file_range_map =
+ compile_unit_info->GetFileRangeMap(this);
+ for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) {
+ const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx);
+ if (entry) {
+ debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(),
+ entry->GetRangeEnd());
+ num_line_entries_added++;
}
+ }
}
- return num_line_entries_added;
+ }
+ return num_line_entries_added;
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h Tue Sep 6 15:57:50 2016
@@ -10,9 +10,8 @@
#ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
-
-#include <vector>
#include <bitset>
+#include <vector>
#include "lldb/Core/RangeMap.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -23,398 +22,355 @@ class SymbolFileDWARF;
class DWARFDebugAranges;
class DWARFDeclContext;
-class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile
-{
+class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile {
public:
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::SymbolFile *
- CreateInstance (lldb_private::ObjectFile* obj_file);
-
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolFileDWARFDebugMap (lldb_private::ObjectFile* ofile);
- ~SymbolFileDWARFDebugMap () override;
-
- uint32_t CalculateAbilities () override;
- void InitializeObject() override;
-
- //------------------------------------------------------------------
- // Compile Unit function calls
- //------------------------------------------------------------------
- uint32_t GetNumCompileUnits () override;
- lldb::CompUnitSP ParseCompileUnitAtIndex (uint32_t index) override;
-
- lldb::LanguageType ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc) override;
- size_t ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc) override;
- bool ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc) override;
- bool ParseCompileUnitDebugMacros (const lldb_private::SymbolContext& sc) override;
- bool ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files) override;
- bool
- ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
- bool ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) override;
- size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override;
- size_t ParseTypes (const lldb_private::SymbolContext& sc) override;
- size_t ParseVariablesForContext (const lldb_private::SymbolContext& sc) override;
-
- lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid) override;
- lldb_private::CompilerDeclContext GetDeclContextForUID (lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext GetDeclContextContainingUID (lldb::user_id_t uid) override;
- void ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) override;
-
- bool CompleteType (lldb_private::CompilerType& compiler_type) override;
- uint32_t ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc) override;
- uint32_t ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list) override;
- uint32_t FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override;
- uint32_t FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override;
- uint32_t FindFunctions (const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override;
- uint32_t FindFunctions (const lldb_private::RegularExpression& regex, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override;
- uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap& types) override;
- lldb_private::CompilerDeclContext
- FindNamespace (const lldb_private::SymbolContext& sc,
- const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
- size_t GetTypes (lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
- lldb_private::TypeList &type_list) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFileDWARFDebugMap(lldb_private::ObjectFile *ofile);
+ ~SymbolFileDWARFDebugMap() override;
+
+ uint32_t CalculateAbilities() override;
+ void InitializeObject() override;
+
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
+ uint32_t GetNumCompileUnits() override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
+ lldb::LanguageType
+ ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
+ size_t
+ ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
+ bool
+ ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
+ bool ParseCompileUnitSupportFiles(
+ const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) override;
+ bool
+ ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
+ bool ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
+ size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
+ size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
+ size_t
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
+
+ lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUID(lldb::user_id_t uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUID(lldb::user_id_t uid) override;
+ void
+ ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+
+ bool CompleteType(lldb_private::CompilerType &compiler_type) override;
+ uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) override;
+ uint32_t
+ ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
+ bool check_inlines, uint32_t resolve_scope,
+ lldb_private::SymbolContextList &sc_list) override;
+ uint32_t
+ FindGlobalVariables(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
+ uint32_t FindGlobalVariables(const lldb_private::RegularExpression ®ex,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
+ uint32_t
+ FindFunctions(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) override;
+ uint32_t FindFunctions(const lldb_private::RegularExpression ®ex,
+ bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) override;
+ uint32_t
+ FindTypes(const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ lldb_private::TypeMap &types) override;
+ lldb_private::CompilerDeclContext FindNamespace(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+ size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- enum
- {
- kHaveInitializedOSOs = (1 << 0),
- kNumFlags
- };
-
- friend class DebugMapModule;
- friend struct DIERef;
- friend class DWARFASTParserClang;
- friend class DWARFCompileUnit;
- friend class SymbolFileDWARF;
- struct OSOInfo
- {
- lldb::ModuleSP module_sp;
-
- OSOInfo() :
- module_sp ()
- {
- }
- };
-
- typedef std::shared_ptr<OSOInfo> OSOInfoSP;
-
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
-
- //------------------------------------------------------------------
- // Class specific types
- //------------------------------------------------------------------
- struct CompileUnitInfo
- {
- lldb_private::FileSpec so_file;
- lldb_private::ConstString oso_path;
- lldb_private::TimeValue oso_mod_time;
- OSOInfoSP oso_sp;
- lldb::CompUnitSP compile_unit_sp;
- uint32_t first_symbol_index;
- 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 (),
- oso_path (),
- oso_mod_time (),
- oso_sp (),
- compile_unit_sp (),
- first_symbol_index (UINT32_MAX),
- last_symbol_index (UINT32_MAX),
- first_symbol_id (UINT32_MAX),
- last_symbol_id (UINT32_MAX),
- file_range_map (),
- file_range_map_valid (false)
- {
- }
-
- const FileRangeMap &
- GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
- };
-
- //------------------------------------------------------------------
- // Protected Member Functions
- //------------------------------------------------------------------
- void
- InitOSO ();
-
- static uint32_t
- GetOSOIndexFromUserID (lldb::user_id_t uid)
- {
- return (uint32_t)((uid >> 32ull) - 1ull);
+ enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
+
+ friend class DebugMapModule;
+ friend struct DIERef;
+ friend class DWARFASTParserClang;
+ friend class DWARFCompileUnit;
+ friend class SymbolFileDWARF;
+ struct OSOInfo {
+ lldb::ModuleSP module_sp;
+
+ OSOInfo() : module_sp() {}
+ };
+
+ typedef std::shared_ptr<OSOInfo> OSOInfoSP;
+
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t,
+ lldb::addr_t>
+ FileRangeMap;
+
+ //------------------------------------------------------------------
+ // Class specific types
+ //------------------------------------------------------------------
+ struct CompileUnitInfo {
+ lldb_private::FileSpec so_file;
+ lldb_private::ConstString oso_path;
+ lldb_private::TimeValue oso_mod_time;
+ OSOInfoSP oso_sp;
+ lldb::CompUnitSP compile_unit_sp;
+ uint32_t first_symbol_index;
+ 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(), oso_path(), oso_mod_time(), oso_sp(), compile_unit_sp(),
+ first_symbol_index(UINT32_MAX), last_symbol_index(UINT32_MAX),
+ first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX),
+ file_range_map(), file_range_map_valid(false) {}
+
+ const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
+ };
+
+ //------------------------------------------------------------------
+ // Protected Member Functions
+ //------------------------------------------------------------------
+ void InitOSO();
+
+ static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
+ return (uint32_t)((uid >> 32ull) - 1ull);
+ }
+
+ static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file);
+
+ bool GetFileSpecForSO(uint32_t oso_idx, lldb_private::FileSpec &file_spec);
+
+ CompileUnitInfo *GetCompUnitInfo(const lldb_private::SymbolContext &sc);
+
+ size_t GetCompUnitInfosForModule(const lldb_private::Module *oso_module,
+ std::vector<CompileUnitInfo *> &cu_infos);
+
+ lldb_private::Module *
+ GetModuleByCompUnitInfo(CompileUnitInfo *comp_unit_info);
+
+ lldb_private::Module *GetModuleByOSOIndex(uint32_t oso_idx);
+
+ lldb_private::ObjectFile *
+ GetObjectFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
+
+ lldb_private::ObjectFile *GetObjectFileByOSOIndex(uint32_t oso_idx);
+
+ uint32_t GetCompUnitInfoIndex(const CompileUnitInfo *comp_unit_info);
+
+ SymbolFileDWARF *GetSymbolFile(const lldb_private::SymbolContext &sc);
+
+ SymbolFileDWARF *GetSymbolFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
+
+ SymbolFileDWARF *GetSymbolFileByOSOIndex(uint32_t oso_idx);
+
+ // If closure returns "false", iteration continues. If it returns
+ // "true", iteration terminates.
+ void ForEachSymbolFile(std::function<bool(SymbolFileDWARF *)> closure) {
+ for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size();
+ oso_idx < num_oso_idxs; ++oso_idx) {
+ if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) {
+ if (closure(oso_dwarf))
+ return;
+ }
}
-
- static SymbolFileDWARF *
- GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file);
-
- bool
- GetFileSpecForSO (uint32_t oso_idx, lldb_private::FileSpec &file_spec);
-
- CompileUnitInfo *
- GetCompUnitInfo (const lldb_private::SymbolContext& sc);
-
- size_t
- GetCompUnitInfosForModule (const lldb_private::Module *oso_module,
- std::vector<CompileUnitInfo *>& cu_infos);
-
- lldb_private::Module *
- GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info);
-
- lldb_private::Module *
- GetModuleByOSOIndex (uint32_t oso_idx);
-
- lldb_private::ObjectFile *
- GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
-
- lldb_private::ObjectFile *
- GetObjectFileByOSOIndex (uint32_t oso_idx);
-
- uint32_t
- GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info);
-
- SymbolFileDWARF *
- GetSymbolFile (const lldb_private::SymbolContext& sc);
-
- SymbolFileDWARF *
- GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
-
- SymbolFileDWARF *
- GetSymbolFileByOSOIndex (uint32_t oso_idx);
-
- // If closure returns "false", iteration continues. If it returns
- // "true", iteration terminates.
- void
- ForEachSymbolFile (std::function<bool (SymbolFileDWARF *)> closure)
- {
- for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size();
- oso_idx < num_oso_idxs;
- ++oso_idx)
- {
- if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx))
- {
- if (closure(oso_dwarf))
- return;
- }
- }
+ }
+
+ CompileUnitInfo *GetCompileUnitInfoForSymbolWithIndex(uint32_t symbol_idx,
+ uint32_t *oso_idx_ptr);
+
+ CompileUnitInfo *GetCompileUnitInfoForSymbolWithID(lldb::user_id_t symbol_id,
+ uint32_t *oso_idx_ptr);
+
+ static int
+ SymbolContainsSymbolWithIndex(uint32_t *symbol_idx_ptr,
+ const CompileUnitInfo *comp_unit_info);
+
+ static int SymbolContainsSymbolWithID(lldb::user_id_t *symbol_idx_ptr,
+ const CompileUnitInfo *comp_unit_info);
+
+ uint32_t PrivateFindGlobalVariables(
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches,
+ lldb_private::VariableList &variables);
+
+ void SetCompileUnit(SymbolFileDWARF *oso_dwarf,
+ const lldb::CompUnitSP &cu_sp);
+
+ lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf);
+
+ CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf);
+
+ lldb::TypeSP
+ FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
+
+ bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso);
+
+ lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ bool must_be_implementation);
+
+ UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() {
+ 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;
}
- CompileUnitInfo *
- GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr);
-
- CompileUnitInfo *
- GetCompileUnitInfoForSymbolWithID (lldb::user_id_t symbol_id, uint32_t *oso_idx_ptr);
-
- static int
- SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
-
- static int
- SymbolContainsSymbolWithID (lldb::user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
-
- uint32_t
- PrivateFindGlobalVariables (const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- const std::vector<uint32_t> &name_symbol_indexes,
- uint32_t max_matches,
- lldb_private::VariableList& variables);
-
-
- void
- SetCompileUnit (SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp);
-
- lldb::CompUnitSP
- GetCompileUnit (SymbolFileDWARF *oso_dwarf);
-
- CompileUnitInfo *
- GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf);
-
- lldb::TypeSP
- FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
-
- bool
- Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso);
-
- lldb::TypeSP
- FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
- const lldb_private::ConstString &type_name,
- bool must_be_implementation);
-
-
- UniqueDWARFASTTypeMap &
- GetUniqueDWARFASTTypeMap ()
- {
- return m_unique_ast_type_map;
+ 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;
}
-
-
- //------------------------------------------------------------------
- // 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
- //------------------------------------------------------------------
- std::bitset<kNumFlags> m_flags;
- std::vector<CompileUnitInfo> m_compile_unit_infos;
- std::vector<uint32_t> m_func_indexes; // Sorted by address
- std::vector<uint32_t> m_glob_indexes;
- 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 exe_byte_size,
- 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 addresses" 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 addresses exist in the main
- /// executable.
- //------------------------------------------------------------------
- lldb_private::LineTable *
- LinkOSOLineTable (SymbolFileDWARF *oso_symfile,
- lldb_private::LineTable *line_table);
-
- size_t
- AddOSOARanges (SymbolFileDWARF* dwarf2Data,
- DWARFDebugAranges* debug_aranges);
+
+ 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
+ //------------------------------------------------------------------
+ std::bitset<kNumFlags> m_flags;
+ std::vector<CompileUnitInfo> m_compile_unit_infos;
+ std::vector<uint32_t> m_func_indexes; // Sorted by address
+ std::vector<uint32_t> m_glob_indexes;
+ 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 exe_byte_size, 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 addresses" 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 addresses exist in the main
+ /// executable.
+ //------------------------------------------------------------------
+ lldb_private::LineTable *
+ LinkOSOLineTable(SymbolFileDWARF *oso_symfile,
+ lldb_private::LineTable *line_table);
+
+ size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data,
+ DWARFDebugAranges *debug_aranges);
};
#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp Tue Sep 6 15:57:50 2016
@@ -20,120 +20,103 @@
using namespace lldb;
using namespace lldb_private;
-SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile, DWARFCompileUnit* dwarf_cu) :
- SymbolFileDWARF(objfile.get()),
- m_obj_file_sp(objfile),
- m_base_dwarf_cu(dwarf_cu)
-{
- SetID(((lldb::user_id_t)dwarf_cu->GetOffset())<<32);
-}
-
-void
-SymbolFileDWARFDwo::LoadSectionData (lldb::SectionType sect_type, DWARFDataExtractor& data)
-{
- const SectionList* section_list = m_obj_file->GetSectionList(false /* update_module_section_list */);
- if (section_list)
- {
- SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
- if (section_sp)
- {
- // See if we memory mapped the DWARF segment?
- if (m_dwarf_data.GetByteSize())
- {
- data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize());
- return;
- }
+SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
+ DWARFCompileUnit *dwarf_cu)
+ : SymbolFileDWARF(objfile.get()), m_obj_file_sp(objfile),
+ m_base_dwarf_cu(dwarf_cu) {
+ SetID(((lldb::user_id_t)dwarf_cu->GetOffset()) << 32);
+}
+
+void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
+ DWARFDataExtractor &data) {
+ const SectionList *section_list =
+ m_obj_file->GetSectionList(false /* update_module_section_list */);
+ if (section_list) {
+ SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
+ if (section_sp) {
+ // See if we memory mapped the DWARF segment?
+ if (m_dwarf_data.GetByteSize()) {
+ data.SetData(m_dwarf_data, section_sp->GetOffset(),
+ section_sp->GetFileSize());
+ return;
+ }
- if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
- return;
+ if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
+ return;
- data.Clear();
- }
+ data.Clear();
}
+ }
- SymbolFileDWARF::LoadSectionData(sect_type, data);
+ SymbolFileDWARF::LoadSectionData(sect_type, data);
}
lldb::CompUnitSP
-SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
-{
- assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible compile unit");
- return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX);
+SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx) {
+ assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit "
+ "called with incompatible compile "
+ "unit");
+ return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX);
}
-DWARFCompileUnit*
-SymbolFileDWARFDwo::GetCompileUnit()
-{
- // Only dwo files with 1 compile unit is supported
- if (GetNumCompileUnits() == 1)
- return DebugInfo()->GetCompileUnitAtIndex(0);
- else
- return nullptr;
+DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() {
+ // Only dwo files with 1 compile unit is supported
+ if (GetNumCompileUnits() == 1)
+ return DebugInfo()->GetCompileUnitAtIndex(0);
+ else
+ return nullptr;
}
-DWARFCompileUnit*
-SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
-{
- return GetCompileUnit();
+DWARFCompileUnit *
+SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
+ return GetCompileUnit();
}
-SymbolFileDWARF::DIEToTypePtr&
-SymbolFileDWARFDwo::GetDIEToType()
-{
- return GetBaseSymbolFile()->GetDIEToType();
+SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() {
+ return GetBaseSymbolFile()->GetDIEToType();
}
-SymbolFileDWARF::DIEToVariableSP&
-SymbolFileDWARFDwo::GetDIEToVariable()
-{
- return GetBaseSymbolFile()->GetDIEToVariable();
+SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() {
+ return GetBaseSymbolFile()->GetDIEToVariable();
}
-SymbolFileDWARF::DIEToClangType&
-SymbolFileDWARFDwo::GetForwardDeclDieToClangType()
-{
- return GetBaseSymbolFile()->GetForwardDeclDieToClangType();
+SymbolFileDWARF::DIEToClangType &
+SymbolFileDWARFDwo::GetForwardDeclDieToClangType() {
+ return GetBaseSymbolFile()->GetForwardDeclDieToClangType();
}
-SymbolFileDWARF::ClangTypeToDIE&
-SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie()
-{
- return GetBaseSymbolFile()->GetForwardDeclClangTypeToDie();
+SymbolFileDWARF::ClangTypeToDIE &
+SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() {
+ return GetBaseSymbolFile()->GetForwardDeclClangTypeToDie();
}
-UniqueDWARFASTTypeMap&
-SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap()
-{
- return GetBaseSymbolFile()->GetUniqueDWARFASTTypeMap();
+UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {
+ return GetBaseSymbolFile()->GetUniqueDWARFASTTypeMap();
}
-lldb::TypeSP
-SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
-{
- return GetBaseSymbolFile()->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext(
+ const DWARFDeclContext &die_decl_ctx) {
+ return GetBaseSymbolFile()->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
}
-SymbolFileDWARF*
-SymbolFileDWARFDwo::GetBaseSymbolFile()
-{
- return m_base_dwarf_cu->GetSymbolFileDWARF();
+SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() {
+ return m_base_dwarf_cu->GetSymbolFileDWARF();
}
DWARFExpression::LocationListFormat
-SymbolFileDWARFDwo::GetLocationListFormat() const
-{
- return DWARFExpression::SplitDwarfLocationList;
+SymbolFileDWARFDwo::GetLocationListFormat() const {
+ return DWARFExpression::SplitDwarfLocationList;
}
-TypeSystem*
-SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language)
-{
- return GetBaseSymbolFile()->GetTypeSystemForLanguage(language);
+TypeSystem *
+SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
+ return GetBaseSymbolFile()->GetTypeSystemForLanguage(language);
}
DWARFDIE
-SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref)
-{
- lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset);
- return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset);
+SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
+ lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset);
+ return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset);
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h Tue Sep 6 15:57:50 2016
@@ -16,64 +16,56 @@
// Project includes
#include "SymbolFileDWARF.h"
-class SymbolFileDWARFDwo : public SymbolFileDWARF
-{
+class SymbolFileDWARFDwo : public SymbolFileDWARF {
public:
- SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit* dwarf_cu);
+ SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit *dwarf_cu);
- ~SymbolFileDWARFDwo() override = default;
-
- lldb::CompUnitSP
- ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) override;
+ ~SymbolFileDWARFDwo() override = default;
- DWARFCompileUnit*
- GetCompileUnit();
+ lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx) override;
- DWARFCompileUnit*
- GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override;
+ DWARFCompileUnit *GetCompileUnit();
- lldb_private::DWARFExpression::LocationListFormat
- GetLocationListFormat() const override;
+ DWARFCompileUnit *
+ GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override;
- lldb_private::TypeSystem*
- GetTypeSystemForLanguage(lldb::LanguageType language) override;
+ lldb_private::DWARFExpression::LocationListFormat
+ GetLocationListFormat() const override;
- DWARFDIE
- GetDIE(const DIERef &die_ref) override;
+ lldb_private::TypeSystem *
+ GetTypeSystemForLanguage(lldb::LanguageType language) override;
- std::unique_ptr<SymbolFileDWARFDwo>
- GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) override
- {
- return nullptr;
- }
+ DWARFDIE
+ GetDIE(const DIERef &die_ref) override;
+
+ std::unique_ptr<SymbolFileDWARFDwo>
+ GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu,
+ const DWARFDebugInfoEntry &cu_die) override {
+ return nullptr;
+ }
protected:
- void
- LoadSectionData (lldb::SectionType sect_type, lldb_private::DWARFDataExtractor& data) override;
+ void LoadSectionData(lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data) override;
+
+ DIEToTypePtr &GetDIEToType() override;
- DIEToTypePtr&
- GetDIEToType() override;
+ DIEToVariableSP &GetDIEToVariable() override;
- DIEToVariableSP&
- GetDIEToVariable() override;
-
- DIEToClangType&
- GetForwardDeclDieToClangType() override;
+ DIEToClangType &GetForwardDeclDieToClangType() override;
- ClangTypeToDIE&
- GetForwardDeclClangTypeToDie() override;
+ ClangTypeToDIE &GetForwardDeclClangTypeToDie() override;
- UniqueDWARFASTTypeMap&
- GetUniqueDWARFASTTypeMap() override;
+ UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() override;
- lldb::TypeSP
- FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) override;
+ lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(
+ const DWARFDeclContext &die_decl_ctx) override;
- SymbolFileDWARF*
- GetBaseSymbolFile();
+ SymbolFileDWARF *GetBaseSymbolFile();
- lldb::ObjectFileSP m_obj_file_sp;
- DWARFCompileUnit* m_base_dwarf_cu;
+ lldb::ObjectFileSP m_obj_file_sp;
+ DWARFCompileUnit *m_base_dwarf_cu;
};
#endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp Tue Sep 6 15:57:50 2016
@@ -15,73 +15,63 @@
// Project includes
#include "lldb/Symbol/Declaration.h"
-bool
-UniqueDWARFASTTypeList::Find (const DWARFDIE &die,
- const lldb_private::Declaration &decl,
- const int32_t byte_size,
- UniqueDWARFASTType &entry) const
-{
- for (const UniqueDWARFASTType &udt : m_collection)
- {
- // Make sure the tags match
- if (udt.m_die.Tag() == die.Tag())
- {
- // Validate byte sizes of both types only if both are valid.
- if (udt.m_byte_size < 0 || byte_size < 0 || udt.m_byte_size == byte_size)
- {
- // Make sure the file and line match
- if (udt.m_declaration == decl)
+bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
+ const lldb_private::Declaration &decl,
+ const int32_t byte_size,
+ UniqueDWARFASTType &entry) const {
+ for (const UniqueDWARFASTType &udt : m_collection) {
+ // Make sure the tags match
+ if (udt.m_die.Tag() == die.Tag()) {
+ // Validate byte sizes of both types only if both are valid.
+ if (udt.m_byte_size < 0 || byte_size < 0 ||
+ udt.m_byte_size == byte_size) {
+ // Make sure the file and line match
+ if (udt.m_declaration == decl) {
+ // The type has the same name, and was defined on the same
+ // file and line. Now verify all of the parent DIEs match.
+ DWARFDIE parent_arg_die = die.GetParent();
+ DWARFDIE parent_pos_die = udt.m_die.GetParent();
+ bool match = true;
+ bool done = false;
+ while (!done && match && parent_arg_die && parent_pos_die) {
+ const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
+ const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
+ if (parent_arg_tag == parent_pos_tag) {
+ switch (parent_arg_tag) {
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_namespace: {
+ const char *parent_arg_die_name = parent_arg_die.GetName();
+ if (parent_arg_die_name ==
+ NULL) // Anonymous (i.e. no-name) struct
{
- // The type has the same name, and was defined on the same
- // file and line. Now verify all of the parent DIEs match.
- DWARFDIE parent_arg_die = die.GetParent();
- DWARFDIE parent_pos_die = udt.m_die.GetParent();
- bool match = true;
- bool done = false;
- while (!done && match && parent_arg_die && parent_pos_die)
- {
- const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
- const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
- if (parent_arg_tag == parent_pos_tag)
- {
- switch (parent_arg_tag)
- {
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_namespace:
- {
- const char *parent_arg_die_name = parent_arg_die.GetName();
- if (parent_arg_die_name == NULL) // Anonymous (i.e. no-name) struct
- {
- match = false;
- }
- else
- {
- const char *parent_pos_die_name = parent_pos_die.GetName();
- if (parent_pos_die_name == NULL || ((parent_arg_die_name != parent_pos_die_name) && strcmp (parent_arg_die_name, parent_pos_die_name)))
- match = false;
- }
- }
- break;
-
- case DW_TAG_compile_unit:
- done = true;
- break;
- }
- }
- parent_arg_die = parent_arg_die.GetParent();
- parent_pos_die = parent_pos_die.GetParent();
- }
-
- if (match)
- {
- entry = udt;
- return true;
- }
+ match = false;
+ } else {
+ const char *parent_pos_die_name = parent_pos_die.GetName();
+ if (parent_pos_die_name == NULL ||
+ ((parent_arg_die_name != parent_pos_die_name) &&
+ strcmp(parent_arg_die_name, parent_pos_die_name)))
+ match = false;
}
+ } break;
+
+ case DW_TAG_compile_unit:
+ done = true;
+ break;
+ }
}
+ parent_arg_die = parent_arg_die.GetParent();
+ parent_pos_die = parent_pos_die.GetParent();
+ }
+
+ if (match) {
+ entry = udt;
+ return true;
+ }
}
+ }
}
- return false;
+ }
+ return false;
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h Tue Sep 6 15:57:50 2016
@@ -18,139 +18,93 @@
#include "llvm/ADT/DenseMap.h"
// Project includes
-#include "lldb/Symbol/Declaration.h"
#include "DWARFDIE.h"
+#include "lldb/Symbol/Declaration.h"
-class UniqueDWARFASTType
-{
+class UniqueDWARFASTType {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- UniqueDWARFASTType () :
- m_type_sp (),
- m_die (),
- m_declaration (),
- m_byte_size (-1) // Set to negative value to make sure we have a valid value
- {
- }
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ UniqueDWARFASTType()
+ : m_type_sp(), m_die(), m_declaration(),
+ m_byte_size(
+ -1) // Set to negative value to make sure we have a valid value
+ {}
+
+ UniqueDWARFASTType(lldb::TypeSP &type_sp, const DWARFDIE &die,
+ const lldb_private::Declaration &decl, int32_t byte_size)
+ : m_type_sp(type_sp), m_die(die), m_declaration(decl),
+ m_byte_size(byte_size) {}
+
+ UniqueDWARFASTType(const UniqueDWARFASTType &rhs)
+ : m_type_sp(rhs.m_type_sp), m_die(rhs.m_die),
+ m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {}
+
+ ~UniqueDWARFASTType() {}
+
+ UniqueDWARFASTType &operator=(const UniqueDWARFASTType &rhs) {
+ if (this != &rhs) {
+ m_type_sp = rhs.m_type_sp;
+ m_die = rhs.m_die;
+ m_declaration = rhs.m_declaration;
+ m_byte_size = rhs.m_byte_size;
+ }
+ return *this;
+ }
+
+ lldb::TypeSP m_type_sp;
+ DWARFDIE m_die;
+ lldb_private::Declaration m_declaration;
+ int32_t m_byte_size;
+};
- UniqueDWARFASTType (lldb::TypeSP &type_sp,
- const DWARFDIE &die,
- const lldb_private::Declaration &decl,
- int32_t byte_size) :
- m_type_sp (type_sp),
- m_die (die),
- m_declaration (decl),
- m_byte_size (byte_size)
- {
- }
-
- UniqueDWARFASTType (const UniqueDWARFASTType &rhs) :
- m_type_sp (rhs.m_type_sp),
- m_die (rhs.m_die),
- m_declaration (rhs.m_declaration),
- m_byte_size (rhs.m_byte_size)
- {
- }
+class UniqueDWARFASTTypeList {
+public:
+ UniqueDWARFASTTypeList() : m_collection() {}
- ~UniqueDWARFASTType()
- {
- }
+ ~UniqueDWARFASTTypeList() {}
- UniqueDWARFASTType &
- operator= (const UniqueDWARFASTType &rhs)
- {
- if (this != &rhs)
- {
- m_type_sp = rhs.m_type_sp;
- m_die = rhs.m_die;
- m_declaration = rhs.m_declaration;
- m_byte_size = rhs.m_byte_size;
- }
- return *this;
- }
+ uint32_t GetSize() { return (uint32_t)m_collection.size(); }
- lldb::TypeSP m_type_sp;
- DWARFDIE m_die;
- lldb_private::Declaration m_declaration;
- int32_t m_byte_size;
-};
+ void Append(const UniqueDWARFASTType &entry) {
+ m_collection.push_back(entry);
+ }
+
+ bool Find(const DWARFDIE &die, const lldb_private::Declaration &decl,
+ const int32_t byte_size, UniqueDWARFASTType &entry) const;
-class UniqueDWARFASTTypeList
-{
-public:
- UniqueDWARFASTTypeList () :
- m_collection()
- {
- }
-
- ~UniqueDWARFASTTypeList ()
- {
- }
-
- uint32_t
- GetSize()
- {
- return (uint32_t)m_collection.size();
- }
-
- void
- Append (const UniqueDWARFASTType &entry)
- {
- m_collection.push_back (entry);
- }
-
- bool
- Find (const DWARFDIE &die,
- const lldb_private::Declaration &decl,
- const int32_t byte_size,
- UniqueDWARFASTType &entry) const;
-
protected:
- typedef std::vector<UniqueDWARFASTType> collection;
- collection m_collection;
+ typedef std::vector<UniqueDWARFASTType> collection;
+ collection m_collection;
};
-class UniqueDWARFASTTypeMap
-{
+class UniqueDWARFASTTypeMap {
public:
- UniqueDWARFASTTypeMap () :
- m_collection ()
- {
- }
-
- ~UniqueDWARFASTTypeMap ()
- {
- }
+ UniqueDWARFASTTypeMap() : m_collection() {}
- void
- Insert (const lldb_private::ConstString &name,
- const UniqueDWARFASTType &entry)
- {
- m_collection[name.GetCString()].Append (entry);
- }
+ ~UniqueDWARFASTTypeMap() {}
- bool
- Find (const lldb_private::ConstString &name,
- const DWARFDIE &die,
- const lldb_private::Declaration &decl,
- const int32_t byte_size,
- UniqueDWARFASTType &entry) const
- {
- const char *unique_name_cstr = name.GetCString();
- collection::const_iterator pos = m_collection.find (unique_name_cstr);
- if (pos != m_collection.end())
- {
- return pos->second.Find (die, decl, byte_size, entry);
- }
- return false;
+ void Insert(const lldb_private::ConstString &name,
+ const UniqueDWARFASTType &entry) {
+ m_collection[name.GetCString()].Append(entry);
+ }
+
+ bool Find(const lldb_private::ConstString &name, const DWARFDIE &die,
+ const lldb_private::Declaration &decl, const int32_t byte_size,
+ UniqueDWARFASTType &entry) const {
+ const char *unique_name_cstr = name.GetCString();
+ collection::const_iterator pos = m_collection.find(unique_name_cstr);
+ if (pos != m_collection.end()) {
+ return pos->second.Find(die, decl, byte_size, entry);
}
+ return false;
+ }
protected:
- // A unique name string should be used
- typedef llvm::DenseMap<const char *, UniqueDWARFASTTypeList> collection;
- collection m_collection;
+ // A unique name string should be used
+ typedef llvm::DenseMap<const char *, UniqueDWARFASTTypeList> collection;
+ collection m_collection;
};
-#endif // lldb_UniqueDWARFASTType_h_
+#endif // lldb_UniqueDWARFASTType_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp Tue Sep 6 15:57:50 2016
@@ -34,204 +34,199 @@ using namespace lldb_private;
using namespace llvm;
using namespace llvm::pdb;
-namespace
-{
-int
-TranslateUdtKind(PDB_UdtType pdb_kind)
-{
- switch (pdb_kind)
- {
- case PDB_UdtType::Class:
- return clang::TTK_Class;
- case PDB_UdtType::Struct:
- return clang::TTK_Struct;
- case PDB_UdtType::Union:
- return clang::TTK_Union;
- case PDB_UdtType::Interface:
- return clang::TTK_Interface;
- }
+namespace {
+int TranslateUdtKind(PDB_UdtType pdb_kind) {
+ switch (pdb_kind) {
+ case PDB_UdtType::Class:
return clang::TTK_Class;
-}
-
-lldb::Encoding
-TranslateBuiltinEncoding(PDB_BuiltinType type)
-{
- switch (type)
- {
- case PDB_BuiltinType::Float:
- return lldb::eEncodingIEEE754;
- case PDB_BuiltinType::Int:
- case PDB_BuiltinType::Long:
- case PDB_BuiltinType::Char:
- return lldb::eEncodingSint;
- case PDB_BuiltinType::Bool:
- case PDB_BuiltinType::UInt:
- case PDB_BuiltinType::ULong:
- case PDB_BuiltinType::HResult:
- return lldb::eEncodingUint;
- default:
- return lldb::eEncodingInvalid;
- }
+ case PDB_UdtType::Struct:
+ return clang::TTK_Struct;
+ case PDB_UdtType::Union:
+ return clang::TTK_Union;
+ case PDB_UdtType::Interface:
+ return clang::TTK_Interface;
+ }
+ return clang::TTK_Class;
+}
+
+lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
+ switch (type) {
+ case PDB_BuiltinType::Float:
+ return lldb::eEncodingIEEE754;
+ case PDB_BuiltinType::Int:
+ case PDB_BuiltinType::Long:
+ case PDB_BuiltinType::Char:
+ return lldb::eEncodingSint;
+ case PDB_BuiltinType::Bool:
+ case PDB_BuiltinType::UInt:
+ case PDB_BuiltinType::ULong:
+ case PDB_BuiltinType::HResult:
+ return lldb::eEncodingUint;
+ default:
+ return lldb::eEncodingInvalid;
+ }
}
}
-PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast)
-{
-}
+PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {}
-PDBASTParser::~PDBASTParser()
-{
-}
+PDBASTParser::~PDBASTParser() {}
// DebugInfoASTParser interface
-lldb::TypeSP
-PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type)
-{
- // PDB doesn't maintain enough information to robustly rebuild the entire
- // tree, and this is most problematic when it comes to figure out the
- // right DeclContext to put a type in. So for now, everything goes in
- // the translation unit decl as a fully qualified type.
- clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl();
- Declaration decl;
-
- if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type))
- {
- AccessType access = lldb::eAccessPublic;
- PDB_UdtType udt_kind = udt->getUdtKind();
-
- if (udt_kind == PDB_UdtType::Class)
- access = lldb::eAccessPrivate;
-
- CompilerType clang_type =
- m_ast.CreateRecordType(tu_decl_ctx, access, udt->getName().c_str(), TranslateUdtKind(udt_kind),
- lldb::eLanguageTypeC_plus_plus, nullptr);
-
- m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
-
- return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(udt->getName()),
- udt->getLength(), nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
- clang_type, Type::eResolveStateForward);
- }
- else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type))
- {
- std::string name = enum_type->getName();
- lldb::Encoding encoding = TranslateBuiltinEncoding(enum_type->getBuiltinType());
- uint64_t bytes = enum_type->getLength();
- CompilerType builtin_type = m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8);
-
- CompilerType ast_enum = m_ast.CreateEnumerationType(name.c_str(), tu_decl_ctx, decl, builtin_type);
- auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
- while (auto enum_value = enum_values->getNext())
- {
- if (enum_value->getDataKind() != PDB_DataKind::Constant)
- continue;
- AddEnumValue(ast_enum, *enum_value);
- }
-
- return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ast_enum, Type::eResolveStateFull);
- }
- else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type))
- {
- Type *target_type = m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
- std::string name = type_def->getName();
- uint64_t bytes = type_def->getLength();
- if (!target_type)
- return nullptr;
- CompilerType target_ast_type = target_type->GetFullCompilerType();
- CompilerDeclContext target_decl_ctx = m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
- CompilerType ast_typedef = m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
- return std::make_shared<Type>(type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes,
- nullptr, target_type->GetID(), Type::eEncodingIsTypedefUID, decl, ast_typedef,
- Type::eResolveStateFull);
- }
- else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type))
- {
- auto arg_enum = func_sig->getArguments();
- uint32_t num_args = arg_enum->getChildCount();
- std::vector<CompilerType> arg_list(num_args);
- while (auto arg = arg_enum->getNext())
- {
- Type *arg_type = m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId());
- // If there's some error looking up one of the dependent types of this function signature, bail.
- if (!arg_type)
- return nullptr;
- CompilerType arg_ast_type = arg_type->GetFullCompilerType();
- arg_list.push_back(arg_ast_type);
- }
- auto pdb_return_type = func_sig->getReturnType();
- Type *return_type = m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
- // If there's some error looking up one of the dependent types of this function signature, bail.
- if (!return_type)
- return nullptr;
- CompilerType return_ast_type = return_type->GetFullCompilerType();
- uint32_t type_quals = 0;
- if (func_sig->isConstType())
- type_quals |= clang::Qualifiers::Const;
- if (func_sig->isVolatileType())
- type_quals |= clang::Qualifiers::Volatile;
- CompilerType func_sig_ast_type =
- m_ast.CreateFunctionType(return_ast_type, &arg_list[0], num_args, false, type_quals);
-
- return std::make_shared<Type>(func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_sig_ast_type,
- Type::eResolveStateFull);
- }
- else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type))
- {
- uint32_t num_elements = array_type->getCount();
- uint32_t element_uid = array_type->getElementType()->getSymIndexId();
- uint32_t bytes = array_type->getLength();
-
- Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
- CompilerType element_ast_type = element_type->GetFullCompilerType();
- CompilerType array_ast_type = m_ast.CreateArrayType(element_ast_type, num_elements, false);
- return std::make_shared<Type>(array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), bytes, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl, array_ast_type,
- Type::eResolveStateFull);
- }
- return nullptr;
-}
-
-bool
-PDBASTParser::AddEnumValue(CompilerType enum_type, const PDBSymbolData &enum_value) const
-{
- Declaration decl;
- Variant v = enum_value.getValue();
- std::string name = enum_value.getName();
- int64_t raw_value;
- switch (v.Type)
- {
- case PDB_VariantType::Int8:
- raw_value = v.Value.Int8;
- break;
- case PDB_VariantType::Int16:
- raw_value = v.Value.Int16;
- break;
- case PDB_VariantType::Int32:
- raw_value = v.Value.Int32;
- break;
- case PDB_VariantType::Int64:
- raw_value = v.Value.Int64;
- break;
- case PDB_VariantType::UInt8:
- raw_value = v.Value.UInt8;
- break;
- case PDB_VariantType::UInt16:
- raw_value = v.Value.UInt16;
- break;
- case PDB_VariantType::UInt32:
- raw_value = v.Value.UInt32;
- break;
- case PDB_VariantType::UInt64:
- raw_value = v.Value.UInt64;
- break;
- default:
- return false;
- }
- CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
- uint32_t byte_size = m_ast.getASTContext()->getTypeSize(ClangUtil::GetQualType(underlying_type));
- return m_ast.AddEnumerationValueToEnumerationType(enum_type.GetOpaqueQualType(), underlying_type, decl,
- name.c_str(), raw_value, byte_size * 8);
+lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
+ // PDB doesn't maintain enough information to robustly rebuild the entire
+ // tree, and this is most problematic when it comes to figure out the
+ // right DeclContext to put a type in. So for now, everything goes in
+ // the translation unit decl as a fully qualified type.
+ clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl();
+ Declaration decl;
+
+ if (auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type)) {
+ AccessType access = lldb::eAccessPublic;
+ PDB_UdtType udt_kind = udt->getUdtKind();
+
+ if (udt_kind == PDB_UdtType::Class)
+ access = lldb::eAccessPrivate;
+
+ CompilerType clang_type = m_ast.CreateRecordType(
+ tu_decl_ctx, access, udt->getName().c_str(), TranslateUdtKind(udt_kind),
+ lldb::eLanguageTypeC_plus_plus, nullptr);
+
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+
+ return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(),
+ ConstString(udt->getName()), udt->getLength(),
+ nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, decl, clang_type,
+ Type::eResolveStateForward);
+ } else if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type)) {
+ std::string name = enum_type->getName();
+ lldb::Encoding encoding =
+ TranslateBuiltinEncoding(enum_type->getBuiltinType());
+ uint64_t bytes = enum_type->getLength();
+ CompilerType builtin_type =
+ m_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, bytes * 8);
+
+ CompilerType ast_enum = m_ast.CreateEnumerationType(
+ name.c_str(), tu_decl_ctx, decl, builtin_type);
+ auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
+ while (auto enum_value = enum_values->getNext()) {
+ if (enum_value->getDataKind() != PDB_DataKind::Constant)
+ continue;
+ AddEnumValue(ast_enum, *enum_value);
+ }
+
+ return std::make_shared<Type>(type.getSymIndexId(), m_ast.GetSymbolFile(),
+ ConstString(name), bytes, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ ast_enum, Type::eResolveStateFull);
+ } else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type)) {
+ Type *target_type =
+ m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
+ std::string name = type_def->getName();
+ uint64_t bytes = type_def->getLength();
+ if (!target_type)
+ return nullptr;
+ CompilerType target_ast_type = target_type->GetFullCompilerType();
+ CompilerDeclContext target_decl_ctx =
+ m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
+ CompilerType ast_typedef =
+ m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
+ return std::make_shared<Type>(
+ type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
+ bytes, nullptr, target_type->GetID(), Type::eEncodingIsTypedefUID, decl,
+ ast_typedef, Type::eResolveStateFull);
+ } else if (auto func_sig = llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
+ auto arg_enum = func_sig->getArguments();
+ uint32_t num_args = arg_enum->getChildCount();
+ std::vector<CompilerType> arg_list(num_args);
+ while (auto arg = arg_enum->getNext()) {
+ Type *arg_type =
+ m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId());
+ // If there's some error looking up one of the dependent types of this
+ // function signature, bail.
+ if (!arg_type)
+ return nullptr;
+ CompilerType arg_ast_type = arg_type->GetFullCompilerType();
+ arg_list.push_back(arg_ast_type);
+ }
+ auto pdb_return_type = func_sig->getReturnType();
+ Type *return_type =
+ m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
+ // If there's some error looking up one of the dependent types of this
+ // function signature, bail.
+ if (!return_type)
+ return nullptr;
+ CompilerType return_ast_type = return_type->GetFullCompilerType();
+ uint32_t type_quals = 0;
+ if (func_sig->isConstType())
+ type_quals |= clang::Qualifiers::Const;
+ if (func_sig->isVolatileType())
+ type_quals |= clang::Qualifiers::Volatile;
+ CompilerType func_sig_ast_type = m_ast.CreateFunctionType(
+ return_ast_type, &arg_list[0], num_args, false, type_quals);
+
+ return std::make_shared<Type>(
+ func_sig->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), 0,
+ nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ func_sig_ast_type, Type::eResolveStateFull);
+ } else if (auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type)) {
+ uint32_t num_elements = array_type->getCount();
+ uint32_t element_uid = array_type->getElementType()->getSymIndexId();
+ uint32_t bytes = array_type->getLength();
+
+ Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
+ CompilerType element_ast_type = element_type->GetFullCompilerType();
+ CompilerType array_ast_type =
+ m_ast.CreateArrayType(element_ast_type, num_elements, false);
+ return std::make_shared<Type>(
+ array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
+ bytes, nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ array_ast_type, Type::eResolveStateFull);
+ }
+ return nullptr;
+}
+
+bool PDBASTParser::AddEnumValue(CompilerType enum_type,
+ const PDBSymbolData &enum_value) const {
+ Declaration decl;
+ Variant v = enum_value.getValue();
+ std::string name = enum_value.getName();
+ int64_t raw_value;
+ switch (v.Type) {
+ case PDB_VariantType::Int8:
+ raw_value = v.Value.Int8;
+ break;
+ case PDB_VariantType::Int16:
+ raw_value = v.Value.Int16;
+ break;
+ case PDB_VariantType::Int32:
+ raw_value = v.Value.Int32;
+ break;
+ case PDB_VariantType::Int64:
+ raw_value = v.Value.Int64;
+ break;
+ case PDB_VariantType::UInt8:
+ raw_value = v.Value.UInt8;
+ break;
+ case PDB_VariantType::UInt16:
+ raw_value = v.Value.UInt16;
+ break;
+ case PDB_VariantType::UInt32:
+ raw_value = v.Value.UInt32;
+ break;
+ case PDB_VariantType::UInt64:
+ raw_value = v.Value.UInt64;
+ break;
+ default:
+ return false;
+ }
+ CompilerType underlying_type =
+ m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
+ uint32_t byte_size = m_ast.getASTContext()->getTypeSize(
+ ClangUtil::GetQualType(underlying_type));
+ return m_ast.AddEnumerationValueToEnumerationType(
+ enum_type.GetOpaqueQualType(), underlying_type, decl, name.c_str(),
+ raw_value, byte_size * 8);
}
Modified: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.h Tue Sep 6 15:57:50 2016
@@ -14,45 +14,39 @@
#include "lldb/Symbol/ClangASTImporter.h"
-namespace clang
-{
+namespace clang {
class CharUnits;
class CXXRecordDecl;
class FieldDecl;
class RecordDecl;
}
-namespace lldb_private
-{
+namespace lldb_private {
class ClangASTContext;
class CompilerType;
}
-namespace llvm
-{
-namespace pdb
-{
+namespace llvm {
+namespace pdb {
class PDBSymbol;
class PDBSymbolData;
class PDBSymbolTypeBuiltin;
}
}
-class PDBASTParser
-{
+class PDBASTParser {
public:
- PDBASTParser(lldb_private::ClangASTContext &ast);
- ~PDBASTParser();
+ PDBASTParser(lldb_private::ClangASTContext &ast);
+ ~PDBASTParser();
- lldb::TypeSP
- CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type);
+ lldb::TypeSP CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type);
private:
- bool
- AddEnumValue(lldb_private::CompilerType enum_type, const llvm::pdb::PDBSymbolData &data) const;
+ bool AddEnumValue(lldb_private::CompilerType enum_type,
+ const llvm::pdb::PDBSymbolData &data) const;
- lldb_private::ClangASTContext &m_ast;
- lldb_private::ClangASTImporter m_ast_importer;
+ lldb_private::ClangASTContext &m_ast;
+ lldb_private::ClangASTImporter m_ast_importer;
};
#endif // SymbolFileDWARF_DWARFASTParserClang_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp Tue Sep 6 15:57:50 2016
@@ -42,692 +42,661 @@
using namespace lldb_private;
using namespace llvm::pdb;
-namespace
-{
-lldb::LanguageType
-TranslateLanguage(PDB_Lang lang)
-{
- switch (lang)
- {
- case PDB_Lang::Cpp:
- return lldb::LanguageType::eLanguageTypeC_plus_plus;
- case PDB_Lang::C:
- return lldb::LanguageType::eLanguageTypeC;
- default:
- return lldb::LanguageType::eLanguageTypeUnknown;
- }
- }
-
- bool
- ShouldAddLine(uint32_t requested_line, uint32_t actual_line, uint32_t addr_length)
- {
- return ((requested_line == 0 || actual_line == requested_line) && addr_length > 0);
- }
+namespace {
+lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
+ switch (lang) {
+ case PDB_Lang::Cpp:
+ return lldb::LanguageType::eLanguageTypeC_plus_plus;
+ case PDB_Lang::C:
+ return lldb::LanguageType::eLanguageTypeC;
+ default:
+ return lldb::LanguageType::eLanguageTypeUnknown;
+ }
}
-void
-SymbolFilePDB::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
- DebuggerInitialize);
+bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
+ uint32_t addr_length) {
+ return ((requested_line == 0 || actual_line == requested_line) &&
+ addr_length > 0);
+}
}
-void
-SymbolFilePDB::Terminate()
-{
- PluginManager::UnregisterPlugin(CreateInstance);
+void SymbolFilePDB::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
}
-void
-SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger)
-{
+void SymbolFilePDB::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-SymbolFilePDB::GetPluginNameStatic()
-{
- static ConstString g_name("pdb");
- return g_name;
+void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {}
+
+lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() {
+ static ConstString g_name("pdb");
+ return g_name;
}
-const char *
-SymbolFilePDB::GetPluginDescriptionStatic()
-{
- return "Microsoft PDB debug symbol file reader.";
+const char *SymbolFilePDB::GetPluginDescriptionStatic() {
+ return "Microsoft PDB debug symbol file reader.";
}
lldb_private::SymbolFile *
-SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file)
-{
- return new SymbolFilePDB(obj_file);
+SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
+ return new SymbolFilePDB(obj_file);
}
SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
- : SymbolFile(object_file), m_cached_compile_unit_count(0)
-{
-}
+ : SymbolFile(object_file), m_cached_compile_unit_count(0) {}
-SymbolFilePDB::~SymbolFilePDB()
-{
-}
+SymbolFilePDB::~SymbolFilePDB() {}
-uint32_t
-SymbolFilePDB::CalculateAbilities()
-{
- if (!m_session_up)
- {
- // Lazily load and match the PDB file, but only do this once.
- std::string exePath = m_obj_file->GetFileSpec().GetPath();
- auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath), m_session_up);
- if (error)
- {
- llvm::consumeError(std::move(error));
- return 0;
- }
+uint32_t SymbolFilePDB::CalculateAbilities() {
+ if (!m_session_up) {
+ // Lazily load and match the PDB file, but only do this once.
+ std::string exePath = m_obj_file->GetFileSpec().GetPath();
+ auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
+ m_session_up);
+ if (error) {
+ llvm::consumeError(std::move(error));
+ return 0;
}
- return CompileUnits | LineTables;
+ }
+ return CompileUnits | LineTables;
}
-void
-SymbolFilePDB::InitializeObject()
-{
- lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
- m_session_up->setLoadAddress(obj_load_address);
-
- TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(type_system, clang_type_system->GetTranslationUnitDecl());
-}
+void SymbolFilePDB::InitializeObject() {
+ lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
+ m_session_up->setLoadAddress(obj_load_address);
-uint32_t
-SymbolFilePDB::GetNumCompileUnits()
-{
- if (m_cached_compile_unit_count == 0)
- {
- auto global = m_session_up->getGlobalScope();
- auto compilands = global->findAllChildren<PDBSymbolCompiland>();
- m_cached_compile_unit_count = compilands->getChildCount();
-
- // The linker can inject an additional "dummy" compilation unit into the PDB.
- // Ignore this special compile unit for our purposes, if it is there. It is
- // always the last one.
- auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
- std::string name = last_cu->getName();
- if (name == "* Linker *")
- --m_cached_compile_unit_count;
- }
- return m_cached_compile_unit_count;
+ TypeSystem *type_system =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ ClangASTContext *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(
+ type_system, clang_type_system->GetTranslationUnitDecl());
}
-lldb::CompUnitSP
-SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index)
-{
+uint32_t SymbolFilePDB::GetNumCompileUnits() {
+ if (m_cached_compile_unit_count == 0) {
auto global = m_session_up->getGlobalScope();
auto compilands = global->findAllChildren<PDBSymbolCompiland>();
- auto cu = compilands->getChildAtIndex(index);
+ m_cached_compile_unit_count = compilands->getChildCount();
- uint32_t id = cu->getSymIndexId();
+ // The linker can inject an additional "dummy" compilation unit into the
+ // PDB.
+ // Ignore this special compile unit for our purposes, if it is there. It is
+ // always the last one.
+ auto last_cu = compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
+ std::string name = last_cu->getName();
+ if (name == "* Linker *")
+ --m_cached_compile_unit_count;
+ }
+ return m_cached_compile_unit_count;
+}
+
+lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
+ auto global = m_session_up->getGlobalScope();
+ auto compilands = global->findAllChildren<PDBSymbolCompiland>();
+ auto cu = compilands->getChildAtIndex(index);
- return ParseCompileUnitForSymIndex(id);
+ uint32_t id = cu->getSymIndexId();
+
+ return ParseCompileUnitForSymIndex(id);
}
lldb::LanguageType
-SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc)
-{
- // What fields should I expect to be filled out on the SymbolContext? Is it
- // safe to assume that `sc.comp_unit` is valid?
- if (!sc.comp_unit)
- return lldb::eLanguageTypeUnknown;
-
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
- if (!cu)
- return lldb::eLanguageTypeUnknown;
- auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
- if (!details)
- return lldb::eLanguageTypeUnknown;
- return TranslateLanguage(details->getLanguage());
-}
+SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) {
+ // What fields should I expect to be filled out on the SymbolContext? Is it
+ // safe to assume that `sc.comp_unit` is valid?
+ if (!sc.comp_unit)
+ return lldb::eLanguageTypeUnknown;
+
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
+ sc.comp_unit->GetID());
+ if (!cu)
+ return lldb::eLanguageTypeUnknown;
+ auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ if (!details)
+ return lldb::eLanguageTypeUnknown;
+ return TranslateLanguage(details->getLanguage());
+}
+
+size_t SymbolFilePDB::ParseCompileUnitFunctions(
+ const lldb_private::SymbolContext &sc) {
+ // TODO: Implement this
+ return size_t();
+}
+
+bool SymbolFilePDB::ParseCompileUnitLineTable(
+ const lldb_private::SymbolContext &sc) {
+ return ParseCompileUnitLineTable(sc, 0);
+}
+
+bool SymbolFilePDB::ParseCompileUnitDebugMacros(
+ const lldb_private::SymbolContext &sc) {
+ // PDB doesn't contain information about macros
+ return false;
+}
+
+bool SymbolFilePDB::ParseCompileUnitSupportFiles(
+ const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) {
+ if (!sc.comp_unit)
+ return false;
-size_t
-SymbolFilePDB::ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc)
-{
- // TODO: Implement this
- return size_t();
-}
-
-bool
-SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc)
-{
- return ParseCompileUnitLineTable(sc, 0);
-}
-
-bool
-SymbolFilePDB::ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc)
-{
- // PDB doesn't contain information about macros
+ // In theory this is unnecessary work for us, because all of this information
+ // is easily
+ // (and quickly) accessible from DebugInfoPDB, so caching it a second time
+ // seems like a waste.
+ // Unfortunately, there's no good way around this short of a moderate
+ // refactor, since SymbolVendor
+ // depends on being able to cache this list.
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
+ sc.comp_unit->GetID());
+ if (!cu)
+ return false;
+ auto files = m_session_up->getSourceFilesForCompiland(*cu);
+ if (!files || files->getChildCount() == 0)
return false;
-}
-bool
-SymbolFilePDB::ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc,
- lldb_private::FileSpecList &support_files)
-{
- if (!sc.comp_unit)
- return false;
-
- // In theory this is unnecessary work for us, because all of this information is easily
- // (and quickly) accessible from DebugInfoPDB, so caching it a second time seems like a waste.
- // Unfortunately, there's no good way around this short of a moderate refactor, since SymbolVendor
- // depends on being able to cache this list.
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
- if (!cu)
- return false;
- auto files = m_session_up->getSourceFilesForCompiland(*cu);
- if (!files || files->getChildCount() == 0)
- return false;
-
- while (auto file = files->getNext())
- {
- FileSpec spec(file->getFileName(), false);
- support_files.Append(spec);
- }
- return true;
+ while (auto file = files->getNext()) {
+ FileSpec spec(file->getFileName(), false);
+ support_files.Append(spec);
+ }
+ return true;
}
-bool
-SymbolFilePDB::ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules)
-{
- // PDB does not yet support module debug info
- return false;
+bool SymbolFilePDB::ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) {
+ // PDB does not yet support module debug info
+ return false;
}
size_t
-SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc)
-{
- // TODO: Implement this
- return size_t();
+SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) {
+ // TODO: Implement this
+ return size_t();
}
-size_t
-SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc)
-{
- // TODO: Implement this
- return size_t();
+size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) {
+ // TODO: Implement this
+ return size_t();
}
size_t
-SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc)
-{
- // TODO: Implement this
- return size_t();
-}
-
-lldb_private::Type *
-SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid)
-{
- auto find_result = m_types.find(type_uid);
- if (find_result != m_types.end())
- return find_result->second.get();
-
- TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- if (!clang_type_system)
- return nullptr;
- PDBASTParser *pdb = llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser());
- if (!pdb)
- return nullptr;
-
- auto pdb_type = m_session_up->getSymbolById(type_uid);
- if (pdb_type == nullptr)
- return nullptr;
-
- lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
- m_types.insert(std::make_pair(type_uid, result));
- return result.get();
-}
-
-bool
-SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type)
-{
- // TODO: Implement this
- return false;
+SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
+ // TODO: Implement this
+ return size_t();
}
-lldb_private::CompilerDecl
-SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid)
-{
- return lldb_private::CompilerDecl();
-}
+lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+ auto find_result = m_types.find(type_uid);
+ if (find_result != m_types.end())
+ return find_result->second.get();
+
+ TypeSystem *type_system =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ ClangASTContext *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return nullptr;
+ PDBASTParser *pdb =
+ llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser());
+ if (!pdb)
+ return nullptr;
-lldb_private::CompilerDeclContext
-SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid)
-{
- // PDB always uses the translation unit decl context for everything. We can improve this later
- // but it's not easy because PDB doesn't provide a high enough level of type fidelity in this area.
- return *m_tu_decl_ctx_up;
-}
+ auto pdb_type = m_session_up->getSymbolById(type_uid);
+ if (pdb_type == nullptr)
+ return nullptr;
-lldb_private::CompilerDeclContext
-SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid)
-{
- return *m_tu_decl_ctx_up;
+ lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
+ m_types.insert(std::make_pair(type_uid, result));
+ return result.get();
}
-void
-SymbolFilePDB::ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx)
-{
+bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
+ // TODO: Implement this
+ return false;
}
-uint32_t
-SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope,
- lldb_private::SymbolContext &sc)
-{
- return uint32_t();
+lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
+ return lldb_private::CompilerDecl();
}
-uint32_t
-SymbolFilePDB::ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
- uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list)
-{
- if (resolve_scope & lldb::eSymbolContextCompUnit)
- {
- // Locate all compilation units with line numbers referencing the specified file. For example, if
- // `file_spec` is <vector>, then this should return all source files and header files that reference
- // <vector>, either directly or indirectly.
- auto compilands =
- m_session_up->findCompilandsForSourceFile(file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
-
- // For each one, either find get its previously parsed data, or parse it afresh and add it to
- // the symbol context list.
- while (auto compiland = compilands->getNext())
- {
- // If we're not checking inlines, then don't add line information for this file unless the FileSpec
- // matches.
- if (!check_inlines)
- {
- // `getSourceFileName` returns the basename of the original source file used to generate this compiland.
- // It does not return the full path. Currently the only way to get that is to do a basename lookup to
- // get the IPDBSourceFile, but this is ambiguous in the case of two source files with the same name
- // contributing to the same compiland. This is a moderately extreme edge case, so we consider this ok
- // for now, although we need to find a long term solution.
- std::string source_file = compiland->getSourceFileName();
- auto pdb_file = m_session_up->findOneSourceFile(compiland.get(), source_file,
- PDB_NameSearchFlags::NS_CaseInsensitive);
- source_file = pdb_file->getFileName();
- FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
- if (!file_spec.FileEquals(this_spec))
- continue;
- }
-
- SymbolContext sc;
- auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId());
- sc.comp_unit = cu.get();
- sc.module_sp = cu->GetModule();
- sc_list.Append(sc);
-
- // If we were asked to resolve line entries, add all entries to the line table that match the requested
- // line (or all lines if `line` == 0)
- if (resolve_scope & lldb::eSymbolContextLineEntry)
- ParseCompileUnitLineTable(sc, line);
- }
- }
- return sc_list.GetSize();
+lldb_private::CompilerDeclContext
+SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
+ // PDB always uses the translation unit decl context for everything. We can
+ // improve this later
+ // but it's not easy because PDB doesn't provide a high enough level of type
+ // fidelity in this area.
+ return *m_tu_decl_ctx_up;
}
-uint32_t
-SymbolFilePDB::FindGlobalVariables(const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches, lldb_private::VariableList &variables)
-{
- return uint32_t();
+lldb_private::CompilerDeclContext
+SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
+ return *m_tu_decl_ctx_up;
}
+void SymbolFilePDB::ParseDeclsForContext(
+ lldb_private::CompilerDeclContext decl_ctx) {}
+
uint32_t
-SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex, bool append, uint32_t max_matches,
- lldb_private::VariableList &variables)
-{
- return uint32_t();
+SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) {
+ return uint32_t();
+}
+
+uint32_t SymbolFilePDB::ResolveSymbolContext(
+ const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
+ uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) {
+ if (resolve_scope & lldb::eSymbolContextCompUnit) {
+ // Locate all compilation units with line numbers referencing the specified
+ // file. For example, if
+ // `file_spec` is <vector>, then this should return all source files and
+ // header files that reference
+ // <vector>, either directly or indirectly.
+ auto compilands = m_session_up->findCompilandsForSourceFile(
+ file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
+
+ // For each one, either find get its previously parsed data, or parse it
+ // afresh and add it to
+ // the symbol context list.
+ while (auto compiland = compilands->getNext()) {
+ // If we're not checking inlines, then don't add line information for this
+ // file unless the FileSpec
+ // matches.
+ if (!check_inlines) {
+ // `getSourceFileName` returns the basename of the original source file
+ // used to generate this compiland.
+ // It does not return the full path. Currently the only way to get that
+ // is to do a basename lookup to
+ // get the IPDBSourceFile, but this is ambiguous in the case of two
+ // source files with the same name
+ // contributing to the same compiland. This is a moderately extreme
+ // edge case, so we consider this ok
+ // for now, although we need to find a long term solution.
+ std::string source_file = compiland->getSourceFileName();
+ auto pdb_file = m_session_up->findOneSourceFile(
+ compiland.get(), source_file,
+ PDB_NameSearchFlags::NS_CaseInsensitive);
+ source_file = pdb_file->getFileName();
+ FileSpec this_spec(source_file, false, FileSpec::ePathSyntaxWindows);
+ if (!file_spec.FileEquals(this_spec))
+ continue;
+ }
+
+ SymbolContext sc;
+ auto cu = ParseCompileUnitForSymIndex(compiland->getSymIndexId());
+ sc.comp_unit = cu.get();
+ sc.module_sp = cu->GetModule();
+ sc_list.Append(sc);
+
+ // If we were asked to resolve line entries, add all entries to the line
+ // table that match the requested
+ // line (or all lines if `line` == 0)
+ if (resolve_scope & lldb::eSymbolContextLineEntry)
+ ParseCompileUnitLineTable(sc, line);
+ }
+ }
+ return sc_list.GetSize();
}
-uint32_t
-SymbolFilePDB::FindFunctions(const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask,
- bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list)
-{
- return uint32_t();
+uint32_t SymbolFilePDB::FindGlobalVariables(
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
+ uint32_t max_matches, lldb_private::VariableList &variables) {
+ return uint32_t();
}
uint32_t
-SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list)
-{
- return uint32_t();
+SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) {
+ return uint32_t();
}
-void
-SymbolFilePDB::GetMangledNamesForFunction(const std::string &scope_qualified_name,
- std::vector<lldb_private::ConstString> &mangled_names)
-{
+uint32_t SymbolFilePDB::FindFunctions(
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) {
+ return uint32_t();
}
uint32_t
-SymbolFilePDB::FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types)
-{
- if (!append)
- types.Clear();
- if (!name)
- return 0;
-
- searched_symbol_files.clear();
- searched_symbol_files.insert(this);
-
- std::string name_str = name.AsCString();
-
- // If this might be a regex, we have to return EVERY symbol and process them one by one, which is going
- // to destroy performance on large PDB files. So try really hard not to use a regex match.
- if (name_str.find_first_of("[]?*.-+\\") != std::string::npos)
- FindTypesByRegex(name_str, max_matches, types);
- else
- FindTypesByName(name_str, max_matches, types);
- return types.GetSize();
-}
-
-void
-SymbolFilePDB::FindTypesByRegex(const std::string ®ex, uint32_t max_matches, lldb_private::TypeMap &types)
-{
- // When searching by regex, we need to go out of our way to limit the search space as much as possible, since
- // the way this is implemented is by searching EVERYTHING in the PDB and manually doing a regex compare. PDB
- // library isn't optimized for regex searches or searches across multiple symbol types at the same time, so the
- // best we can do is to search enums, then typedefs, then classes one by one, and do a regex compare against all
- // of them.
- PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, PDB_SymType::UDT};
- auto global = m_session_up->getGlobalScope();
- std::unique_ptr<IPDBEnumSymbols> results;
+SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex,
+ bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) {
+ return uint32_t();
+}
+
+void SymbolFilePDB::GetMangledNamesForFunction(
+ const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names) {}
+
+uint32_t SymbolFilePDB::FindTypes(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
+ uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ lldb_private::TypeMap &types) {
+ if (!append)
+ types.Clear();
+ if (!name)
+ return 0;
- std::regex re(regex);
+ searched_symbol_files.clear();
+ searched_symbol_files.insert(this);
- uint32_t matches = 0;
+ std::string name_str = name.AsCString();
- for (auto tag : tags_to_search)
- {
- results = global->findAllChildren(tag);
- while (auto result = results->getNext())
- {
- if (max_matches > 0 && matches >= max_matches)
- break;
-
- std::string type_name;
- if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
- type_name = enum_type->getName();
- else if (auto typedef_type = llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
- type_name = typedef_type->getName();
- else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
- type_name = class_type->getName();
- else
- {
- // We're only looking for types that have names. Skip symbols, as well as
- // unnamed types such as arrays, pointers, etc.
- continue;
- }
-
- if (!std::regex_match(type_name, re))
- continue;
-
- // This should cause the type to get cached and stored in the `m_types` lookup.
- if (!ResolveTypeUID(result->getSymIndexId()))
- continue;
-
- auto iter = m_types.find(result->getSymIndexId());
- if (iter == m_types.end())
- continue;
- types.Insert(iter->second);
- ++matches;
- }
+ // If this might be a regex, we have to return EVERY symbol and process them
+ // one by one, which is going
+ // to destroy performance on large PDB files. So try really hard not to use a
+ // regex match.
+ if (name_str.find_first_of("[]?*.-+\\") != std::string::npos)
+ FindTypesByRegex(name_str, max_matches, types);
+ else
+ FindTypesByName(name_str, max_matches, types);
+ return types.GetSize();
+}
+
+void SymbolFilePDB::FindTypesByRegex(const std::string ®ex,
+ uint32_t max_matches,
+ lldb_private::TypeMap &types) {
+ // When searching by regex, we need to go out of our way to limit the search
+ // space as much as possible, since
+ // the way this is implemented is by searching EVERYTHING in the PDB and
+ // manually doing a regex compare. PDB
+ // library isn't optimized for regex searches or searches across multiple
+ // symbol types at the same time, so the
+ // best we can do is to search enums, then typedefs, then classes one by one,
+ // and do a regex compare against all
+ // of them.
+ PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
+ PDB_SymType::UDT};
+ auto global = m_session_up->getGlobalScope();
+ std::unique_ptr<IPDBEnumSymbols> results;
+
+ std::regex re(regex);
+
+ uint32_t matches = 0;
+
+ for (auto tag : tags_to_search) {
+ results = global->findAllChildren(tag);
+ while (auto result = results->getNext()) {
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+
+ std::string type_name;
+ if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
+ type_name = enum_type->getName();
+ else if (auto typedef_type =
+ llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
+ type_name = typedef_type->getName();
+ else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
+ type_name = class_type->getName();
+ else {
+ // We're only looking for types that have names. Skip symbols, as well
+ // as
+ // unnamed types such as arrays, pointers, etc.
+ continue;
+ }
+
+ if (!std::regex_match(type_name, re))
+ continue;
+
+ // This should cause the type to get cached and stored in the `m_types`
+ // lookup.
+ if (!ResolveTypeUID(result->getSymIndexId()))
+ continue;
+
+ auto iter = m_types.find(result->getSymIndexId());
+ if (iter == m_types.end())
+ continue;
+ types.Insert(iter->second);
+ ++matches;
}
+ }
}
-void
-SymbolFilePDB::FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types)
-{
- auto global = m_session_up->getGlobalScope();
- std::unique_ptr<IPDBEnumSymbols> results;
- results = global->findChildren(PDB_SymType::None, name.c_str(), PDB_NameSearchFlags::NS_Default);
-
- uint32_t matches = 0;
-
- while (auto result = results->getNext())
- {
- if (max_matches > 0 && matches >= max_matches)
- break;
- switch (result->getSymTag())
- {
- case PDB_SymType::Enum:
- case PDB_SymType::UDT:
- case PDB_SymType::Typedef:
- break;
- default:
- // We're only looking for types that have names. Skip symbols, as well as
- // unnamed types such as arrays, pointers, etc.
- continue;
- }
-
- // This should cause the type to get cached and stored in the `m_types` lookup.
- if (!ResolveTypeUID(result->getSymIndexId()))
- continue;
-
- auto iter = m_types.find(result->getSymIndexId());
- if (iter == m_types.end())
- continue;
- types.Insert(iter->second);
- ++matches;
+void SymbolFilePDB::FindTypesByName(const std::string &name,
+ uint32_t max_matches,
+ lldb_private::TypeMap &types) {
+ auto global = m_session_up->getGlobalScope();
+ std::unique_ptr<IPDBEnumSymbols> results;
+ results = global->findChildren(PDB_SymType::None, name.c_str(),
+ PDB_NameSearchFlags::NS_Default);
+
+ uint32_t matches = 0;
+
+ while (auto result = results->getNext()) {
+ if (max_matches > 0 && matches >= max_matches)
+ break;
+ switch (result->getSymTag()) {
+ case PDB_SymType::Enum:
+ case PDB_SymType::UDT:
+ case PDB_SymType::Typedef:
+ break;
+ default:
+ // We're only looking for types that have names. Skip symbols, as well as
+ // unnamed types such as arrays, pointers, etc.
+ continue;
}
-}
-size_t
-SymbolFilePDB::FindTypes(const std::vector<lldb_private::CompilerContext> &contexts, bool append,
- lldb_private::TypeMap &types)
-{
- return 0;
-}
-
-lldb_private::TypeList *
-SymbolFilePDB::GetTypeList()
-{
- return nullptr;
-}
-
-size_t
-SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask,
- lldb_private::TypeList &type_list)
-{
- return size_t();
+ // This should cause the type to get cached and stored in the `m_types`
+ // lookup.
+ if (!ResolveTypeUID(result->getSymIndexId()))
+ continue;
+
+ auto iter = m_types.find(result->getSymIndexId());
+ if (iter == m_types.end())
+ continue;
+ types.Insert(iter->second);
+ ++matches;
+ }
+}
+
+size_t SymbolFilePDB::FindTypes(
+ const std::vector<lldb_private::CompilerContext> &contexts, bool append,
+ lldb_private::TypeMap &types) {
+ return 0;
+}
+
+lldb_private::TypeList *SymbolFilePDB::GetTypeList() { return nullptr; }
+
+size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) {
+ return size_t();
}
lldb_private::TypeSystem *
-SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language)
-{
- auto type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- return type_system;
-}
+SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
+ auto type_system =
+ m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system)
+ type_system->SetSymbolFile(this);
+ return type_system;
+}
+
+lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx) {
+ return lldb_private::CompilerDeclContext();
+}
+
+lldb_private::ConstString SymbolFilePDB::GetPluginName() {
+ static ConstString g_name("pdb");
+ return g_name;
+}
+
+uint32_t SymbolFilePDB::GetPluginVersion() { return 1; }
+
+IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; }
+
+const IPDBSession &SymbolFilePDB::GetPDBSession() const {
+ return *m_session_up;
+}
+
+lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id) {
+ auto found_cu = m_comp_units.find(id);
+ if (found_cu != m_comp_units.end())
+ return found_cu->second;
+
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id);
+
+ // `getSourceFileName` returns the basename of the original source file used
+ // to generate this compiland. It does
+ // not return the full path. Currently the only way to get that is to do a
+ // basename lookup to get the
+ // IPDBSourceFile, but this is ambiguous in the case of two source files with
+ // the same name contributing to the
+ // same compiland. This is a moderately extreme edge case, so we consider this
+ // ok for now, although we need to find
+ // a long term solution.
+ auto file =
+ m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(),
+ PDB_NameSearchFlags::NS_CaseInsensitive);
+ std::string path = file->getFileName();
+
+ lldb::LanguageType lang;
+ auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
+ if (!details)
+ lang = lldb::eLanguageTypeC_plus_plus;
+ else
+ lang = TranslateLanguage(details->getLanguage());
+
+ // Don't support optimized code for now, DebugInfoPDB does not return this
+ // information.
+ LazyBool optimized = eLazyBoolNo;
+ auto result = std::make_shared<CompileUnit>(
+ m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized);
+ m_comp_units.insert(std::make_pair(id, result));
+ return result;
+}
+
+bool SymbolFilePDB::ParseCompileUnitLineTable(
+ const lldb_private::SymbolContext &sc, uint32_t match_line) {
+ auto global = m_session_up->getGlobalScope();
+ auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(
+ sc.comp_unit->GetID());
+
+ // LineEntry needs the *index* of the file into the list of support files
+ // returned by
+ // ParseCompileUnitSupportFiles. But the underlying SDK gives us a globally
+ // unique
+ // idenfitifier in the namespace of the PDB. So, we have to do a mapping so
+ // that we
+ // can hand out indices.
+ llvm::DenseMap<uint32_t, uint32_t> index_map;
+ BuildSupportFileIdToSupportFileIndexMap(*cu, index_map);
+ auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
+
+ // Find contributions to `cu` from all source and header files.
+ std::string path = sc.comp_unit->GetPath();
+ auto files = m_session_up->getSourceFilesForCompiland(*cu);
+
+ // For each source and header file, create a LineSequence for contributions to
+ // the cu
+ // from that file, and add the sequence.
+ while (auto file = files->getNext()) {
+ std::unique_ptr<LineSequence> sequence(
+ line_table->CreateLineSequenceContainer());
+ auto lines = m_session_up->findLineNumbers(*cu, *file);
+ int entry_count = lines->getChildCount();
+
+ uint64_t prev_addr;
+ uint32_t prev_length;
+ uint32_t prev_line;
+ uint32_t prev_source_idx;
+
+ for (int i = 0; i < entry_count; ++i) {
+ auto line = lines->getChildAtIndex(i);
+
+ uint64_t lno = line->getLineNumber();
+ uint64_t addr = line->getVirtualAddress();
+ uint32_t length = line->getLength();
+ uint32_t source_id = line->getSourceFileId();
+ uint32_t col = line->getColumnNumber();
+ uint32_t source_idx = index_map[source_id];
+
+ // There was a gap between the current entry and the previous entry if the
+ // addresses don't perfectly line
+ // up.
+ bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
+
+ // Before inserting the current entry, insert a terminal entry at the end
+ // of the previous entry's address
+ // range if the current entry resulted in a gap from the previous entry.
+ if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) {
+ line_table->AppendLineEntryToSequence(
+ sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
+ }
+
+ if (ShouldAddLine(match_line, lno, length)) {
+ bool is_statement = line->isStatement();
+ bool is_prologue = false;
+ bool is_epilogue = false;
+ auto func =
+ m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
+ if (func) {
+ auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
+ is_prologue = (addr == prologue->getVirtualAddress());
-lldb_private::CompilerDeclContext
-SymbolFilePDB::FindNamespace(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx)
-{
- return lldb_private::CompilerDeclContext();
-}
-
-lldb_private::ConstString
-SymbolFilePDB::GetPluginName()
-{
- static ConstString g_name("pdb");
- return g_name;
-}
-
-uint32_t
-SymbolFilePDB::GetPluginVersion()
-{
- return 1;
-}
-
-IPDBSession &
-SymbolFilePDB::GetPDBSession()
-{
- return *m_session_up;
-}
-
-const IPDBSession &
-SymbolFilePDB::GetPDBSession() const
-{
- return *m_session_up;
-}
-
-lldb::CompUnitSP
-SymbolFilePDB::ParseCompileUnitForSymIndex(uint32_t id)
-{
- auto found_cu = m_comp_units.find(id);
- if (found_cu != m_comp_units.end())
- return found_cu->second;
-
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(id);
-
- // `getSourceFileName` returns the basename of the original source file used to generate this compiland. It does
- // not return the full path. Currently the only way to get that is to do a basename lookup to get the
- // IPDBSourceFile, but this is ambiguous in the case of two source files with the same name contributing to the
- // same compiland. This is a moderately extreme edge case, so we consider this ok for now, although we need to find
- // a long term solution.
- auto file =
- m_session_up->findOneSourceFile(cu.get(), cu->getSourceFileName(), PDB_NameSearchFlags::NS_CaseInsensitive);
- std::string path = file->getFileName();
-
- lldb::LanguageType lang;
- auto details = cu->findOneChild<PDBSymbolCompilandDetails>();
- if (!details)
- lang = lldb::eLanguageTypeC_plus_plus;
- else
- lang = TranslateLanguage(details->getLanguage());
-
- // Don't support optimized code for now, DebugInfoPDB does not return this information.
- LazyBool optimized = eLazyBoolNo;
- auto result = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, path.c_str(), id, lang, optimized);
- m_comp_units.insert(std::make_pair(id, result));
- return result;
-}
-
-bool
-SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line)
-{
- auto global = m_session_up->getGlobalScope();
- auto cu = m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(sc.comp_unit->GetID());
-
- // LineEntry needs the *index* of the file into the list of support files returned by
- // ParseCompileUnitSupportFiles. But the underlying SDK gives us a globally unique
- // idenfitifier in the namespace of the PDB. So, we have to do a mapping so that we
- // can hand out indices.
- llvm::DenseMap<uint32_t, uint32_t> index_map;
- BuildSupportFileIdToSupportFileIndexMap(*cu, index_map);
- auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
-
- // Find contributions to `cu` from all source and header files.
- std::string path = sc.comp_unit->GetPath();
- auto files = m_session_up->getSourceFilesForCompiland(*cu);
-
- // For each source and header file, create a LineSequence for contributions to the cu
- // from that file, and add the sequence.
- while (auto file = files->getNext())
- {
- std::unique_ptr<LineSequence> sequence(line_table->CreateLineSequenceContainer());
- auto lines = m_session_up->findLineNumbers(*cu, *file);
- int entry_count = lines->getChildCount();
-
- uint64_t prev_addr;
- uint32_t prev_length;
- uint32_t prev_line;
- uint32_t prev_source_idx;
-
- for (int i = 0; i < entry_count; ++i)
- {
- auto line = lines->getChildAtIndex(i);
-
- uint64_t lno = line->getLineNumber();
- uint64_t addr = line->getVirtualAddress();
- uint32_t length = line->getLength();
- uint32_t source_id = line->getSourceFileId();
- uint32_t col = line->getColumnNumber();
- uint32_t source_idx = index_map[source_id];
-
- // There was a gap between the current entry and the previous entry if the addresses don't perfectly line
- // up.
- bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
-
- // Before inserting the current entry, insert a terminal entry at the end of the previous entry's address
- // range if the current entry resulted in a gap from the previous entry.
- if (is_gap && ShouldAddLine(match_line, prev_line, prev_length))
- {
- line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
- prev_source_idx, false, false, false, false, true);
- }
-
- if (ShouldAddLine(match_line, lno, length))
- {
- bool is_statement = line->isStatement();
- bool is_prologue = false;
- bool is_epilogue = false;
- auto func = m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
- if (func)
- {
- auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
- is_prologue = (addr == prologue->getVirtualAddress());
-
- auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
- is_epilogue = (addr == epilogue->getVirtualAddress());
- }
-
- line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, source_idx, is_statement, false,
- is_prologue, is_epilogue, false);
- }
-
- prev_addr = addr;
- prev_length = length;
- prev_line = lno;
- prev_source_idx = source_idx;
+ auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
+ is_epilogue = (addr == epilogue->getVirtualAddress());
}
- if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length))
- {
- // The end is always a terminal entry, so insert it regardless.
- line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
- prev_source_idx, false, false, false, false, true);
- }
+ line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col,
+ source_idx, is_statement, false,
+ is_prologue, is_epilogue, false);
+ }
+
+ prev_addr = addr;
+ prev_length = length;
+ prev_line = lno;
+ prev_source_idx = source_idx;
+ }
- line_table->InsertSequence(sequence.release());
+ if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) {
+ // The end is always a terminal entry, so insert it regardless.
+ line_table->AppendLineEntryToSequence(
+ sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
}
- sc.comp_unit->SetLineTable(line_table.release());
- return true;
+ line_table->InsertSequence(sequence.release());
+ }
+
+ sc.comp_unit->SetLineTable(line_table.release());
+ return true;
}
-void
-SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(const PDBSymbolCompiland &cu,
- llvm::DenseMap<uint32_t, uint32_t> &index_map) const
-{
- // This is a hack, but we need to convert the source id into an index into the support
- // files array. We don't want to do path comparisons to avoid basename / full path
- // issues that may or may not even be a problem, so we use the globally unique source
- // file identifiers. Ideally we could use the global identifiers everywhere, but LineEntry
- // currently assumes indices.
- auto source_files = m_session_up->getSourceFilesForCompiland(cu);
- int index = 0;
-
- while (auto file = source_files->getNext())
- {
- uint32_t source_id = file->getUniqueId();
- index_map[source_id] = index++;
- }
+void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(
+ const PDBSymbolCompiland &cu,
+ llvm::DenseMap<uint32_t, uint32_t> &index_map) const {
+ // This is a hack, but we need to convert the source id into an index into the
+ // support
+ // files array. We don't want to do path comparisons to avoid basename / full
+ // path
+ // issues that may or may not even be a problem, so we use the globally unique
+ // source
+ // file identifiers. Ideally we could use the global identifiers everywhere,
+ // but LineEntry
+ // currently assumes indices.
+ auto source_files = m_session_up->getSourceFilesForCompiland(cu);
+ int index = 0;
+
+ while (auto file = source_files->getNext()) {
+ uint32_t source_id = file->getUniqueId();
+ index_map[source_id] = index++;
+ }
}
Modified: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h Tue Sep 6 15:57:50 2016
@@ -17,188 +17,174 @@
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDB.h"
-class SymbolFilePDB : public lldb_private::SymbolFile
-{
+class SymbolFilePDB : public lldb_private::SymbolFile {
public:
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static void
- DebuggerInitialize(lldb_private::Debugger &debugger);
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolFilePDB(lldb_private::ObjectFile *ofile);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFilePDB(lldb_private::ObjectFile *ofile);
- ~SymbolFilePDB() override;
+ ~SymbolFilePDB() override;
- uint32_t
- CalculateAbilities() override;
+ uint32_t CalculateAbilities() override;
- void
- InitializeObject() override;
+ void InitializeObject() override;
- //------------------------------------------------------------------
- // Compile Unit function calls
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
- uint32_t
- GetNumCompileUnits() override;
+ uint32_t GetNumCompileUnits() override;
- lldb::CompUnitSP
- ParseCompileUnitAtIndex(uint32_t index) override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- lldb::LanguageType
- ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
+ lldb::LanguageType
+ ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
+ size_t
+ ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
+ bool
+ ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitSupportFiles(const lldb_private::SymbolContext &sc,
- lldb_private::FileSpecList &support_files) override;
+ bool ParseCompileUnitSupportFiles(
+ const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) override;
- bool
- ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ bool ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
- size_t
- ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
+ size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseTypes(const lldb_private::SymbolContext &sc) override;
+ size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
+ size_t
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
- lldb_private::Type *
- ResolveTypeUID(lldb::user_id_t type_uid) override;
+ lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
- bool
- CompleteType(lldb_private::CompilerType &compiler_type) override;
+ bool CompleteType(lldb_private::CompilerType &compiler_type) override;
- lldb_private::CompilerDecl
- GetDeclForUID(lldb::user_id_t uid) override;
+ lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext
- GetDeclContextForUID(lldb::user_id_t uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUID(lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUID(lldb::user_id_t uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUID(lldb::user_id_t uid) override;
- void
- ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+ void
+ ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
- uint32_t
- ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope,
- lldb_private::SymbolContext &sc) override;
+ uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) override;
- uint32_t
- ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
- uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) override;
+ uint32_t
+ ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
+ bool check_inlines, uint32_t resolve_scope,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t
- FindGlobalVariables(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches, lldb_private::VariableList &variables) override;
+ uint32_t
+ FindGlobalVariables(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- FindGlobalVariables(const lldb_private::RegularExpression ®ex, bool append, uint32_t max_matches,
- lldb_private::VariableList &variables) override;
+ uint32_t FindGlobalVariables(const lldb_private::RegularExpression ®ex,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask, bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ uint32_t
+ FindFunctions(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t
- FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ uint32_t FindFunctions(const lldb_private::RegularExpression ®ex,
+ bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) override;
- void
- GetMangledNamesForFunction(const std::string &scope_qualified_name,
- std::vector<lldb_private::ConstString> &mangled_names) override;
+ void GetMangledNamesForFunction(
+ const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names) override;
- uint32_t
- FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override;
+ uint32_t
+ FindTypes(const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ lldb_private::TypeMap &types) override;
- size_t
- FindTypes(const std::vector<lldb_private::CompilerContext> &context, bool append,
- lldb_private::TypeMap &types) override;
+ size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
+ bool append, lldb_private::TypeMap &types) override;
- lldb_private::TypeList *
- GetTypeList() override;
+ lldb_private::TypeList *GetTypeList() override;
- size_t
- GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask,
- lldb_private::TypeList &type_list) override;
+ size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) override;
- lldb_private::TypeSystem *
- GetTypeSystemForLanguage(lldb::LanguageType language) override;
+ lldb_private::TypeSystem *
+ GetTypeSystemForLanguage(lldb::LanguageType language) override;
- lldb_private::CompilerDeclContext
- FindNamespace(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+ lldb_private::CompilerDeclContext FindNamespace(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
- lldb_private::ConstString
- GetPluginName() override;
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- llvm::pdb::IPDBSession &
- GetPDBSession();
+ llvm::pdb::IPDBSession &GetPDBSession();
- const llvm::pdb::IPDBSession &
- GetPDBSession() const;
+ const llvm::pdb::IPDBSession &GetPDBSession() const;
private:
- lldb::CompUnitSP
- ParseCompileUnitForSymIndex(uint32_t id);
+ lldb::CompUnitSP ParseCompileUnitForSymIndex(uint32_t id);
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line);
+ bool ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc,
+ uint32_t match_line);
- void
- BuildSupportFileIdToSupportFileIndexMap(const llvm::pdb::PDBSymbolCompiland &cu,
- llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
+ void BuildSupportFileIdToSupportFileIndexMap(
+ const llvm::pdb::PDBSymbolCompiland &cu,
+ llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
- void
- FindTypesByRegex(const std::string ®ex, uint32_t max_matches, lldb_private::TypeMap &types);
+ void FindTypesByRegex(const std::string ®ex, uint32_t max_matches,
+ lldb_private::TypeMap &types);
- void
- FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types);
+ void FindTypesByName(const std::string &name, uint32_t max_matches,
+ lldb_private::TypeMap &types);
- llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
- llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
+ llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
+ llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
- std::vector<lldb::TypeSP> m_builtin_types;
- std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
- uint32_t m_cached_compile_unit_count;
- std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up;
+ std::vector<lldb::TypeSP> m_builtin_types;
+ std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
+ uint32_t m_cached_compile_unit_count;
+ std::unique_ptr<lldb_private::CompilerDeclContext> m_tu_decl_ctx_up;
};
#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp Tue Sep 6 15:57:50 2016
@@ -24,312 +24,251 @@
using namespace lldb;
using namespace lldb_private;
-void
-SymbolFileSymtab::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void SymbolFileSymtab::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-SymbolFileSymtab::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void SymbolFileSymtab::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-SymbolFileSymtab::GetPluginNameStatic()
-{
- static ConstString g_name("symtab");
- return g_name;
+lldb_private::ConstString SymbolFileSymtab::GetPluginNameStatic() {
+ static ConstString g_name("symtab");
+ return g_name;
}
-const char *
-SymbolFileSymtab::GetPluginDescriptionStatic()
-{
- return "Reads debug symbols from an object file's symbol table.";
+const char *SymbolFileSymtab::GetPluginDescriptionStatic() {
+ return "Reads debug symbols from an object file's symbol table.";
}
-
-SymbolFile*
-SymbolFileSymtab::CreateInstance (ObjectFile* obj_file)
-{
- return new SymbolFileSymtab(obj_file);
+SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFile *obj_file) {
+ return new SymbolFileSymtab(obj_file);
}
-size_t
-SymbolFileSymtab::GetTypes (SymbolContextScope *sc_scope, uint32_t type_mask, lldb_private::TypeList &type_list)
-{
- return 0;
+size_t SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) {
+ return 0;
}
-SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) :
- SymbolFile(obj_file),
- m_source_indexes(),
- m_func_indexes(),
- m_code_indexes(),
- m_objc_class_name_to_index ()
-{
-}
-
-SymbolFileSymtab::~SymbolFileSymtab()
-{
-}
-
-uint32_t
-SymbolFileSymtab::CalculateAbilities ()
-{
- uint32_t abilities = 0;
- if (m_obj_file)
- {
- const Symtab *symtab = m_obj_file->GetSymtab();
- if (symtab)
- {
- //----------------------------------------------------------------------
- // The snippet of code below will get the indexes the module symbol
- // table entries that are code, data, or function related (debug info),
- // sort them by value (address) and dump the sorted symbols.
- //----------------------------------------------------------------------
- if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes))
- {
- abilities |= CompileUnits;
- }
-
- if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes))
- {
- symtab->SortSymbolIndexesByValue(m_func_indexes, true);
- abilities |= Functions;
- }
+SymbolFileSymtab::SymbolFileSymtab(ObjectFile *obj_file)
+ : SymbolFile(obj_file), m_source_indexes(), m_func_indexes(),
+ m_code_indexes(), m_objc_class_name_to_index() {}
- if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes))
- {
- symtab->SortSymbolIndexesByValue(m_code_indexes, true);
- abilities |= Functions;
- }
+SymbolFileSymtab::~SymbolFileSymtab() {}
- if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes))
- {
- symtab->SortSymbolIndexesByValue(m_data_indexes, true);
- abilities |= GlobalVariables;
- }
-
- lldb_private::Symtab::IndexCollection objc_class_indexes;
- if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes))
- {
- symtab->AppendSymbolNamesToMap (objc_class_indexes,
- true,
- true,
- m_objc_class_name_to_index);
- m_objc_class_name_to_index.Sort();
- }
- }
+uint32_t SymbolFileSymtab::CalculateAbilities() {
+ uint32_t abilities = 0;
+ if (m_obj_file) {
+ const Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab) {
+ //----------------------------------------------------------------------
+ // The snippet of code below will get the indexes the module symbol
+ // table entries that are code, data, or function related (debug info),
+ // sort them by value (address) and dump the sorted symbols.
+ //----------------------------------------------------------------------
+ if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile,
+ m_source_indexes)) {
+ abilities |= CompileUnits;
+ }
+
+ if (symtab->AppendSymbolIndexesWithType(
+ eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny,
+ m_func_indexes)) {
+ symtab->SortSymbolIndexesByValue(m_func_indexes, true);
+ abilities |= Functions;
+ }
+
+ if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo,
+ Symtab::eVisibilityAny,
+ m_code_indexes)) {
+ symtab->SortSymbolIndexesByValue(m_code_indexes, true);
+ abilities |= Functions;
+ }
+
+ if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData,
+ m_data_indexes)) {
+ symtab->SortSymbolIndexesByValue(m_data_indexes, true);
+ abilities |= GlobalVariables;
+ }
+
+ lldb_private::Symtab::IndexCollection objc_class_indexes;
+ if (symtab->AppendSymbolIndexesWithType(eSymbolTypeObjCClass,
+ objc_class_indexes)) {
+ symtab->AppendSymbolNamesToMap(objc_class_indexes, true, true,
+ m_objc_class_name_to_index);
+ m_objc_class_name_to_index.Sort();
+ }
}
- return abilities;
+ }
+ return abilities;
}
-uint32_t
-SymbolFileSymtab::GetNumCompileUnits()
-{
- // If we don't have any source file symbols we will just have one compile unit for
- // the entire object file
- if (m_source_indexes.empty())
- return 0;
-
- // If we have any source file symbols we will logically organize the object symbols
- // using these.
- return m_source_indexes.size();
-}
-
-CompUnitSP
-SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
-{
- CompUnitSP cu_sp;
-
- // If we don't have any source file symbols we will just have one compile unit for
- // the entire object file
- if (idx < m_source_indexes.size())
- {
- const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
- if (cu_symbol)
- cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0,
- eLanguageTypeUnknown, eLazyBoolNo));
- }
- return cu_sp;
+uint32_t SymbolFileSymtab::GetNumCompileUnits() {
+ // If we don't have any source file symbols we will just have one compile unit
+ // for
+ // the entire object file
+ if (m_source_indexes.empty())
+ return 0;
+
+ // If we have any source file symbols we will logically organize the object
+ // symbols
+ // using these.
+ return m_source_indexes.size();
+}
+
+CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) {
+ CompUnitSP cu_sp;
+
+ // If we don't have any source file symbols we will just have one compile unit
+ // for
+ // the entire object file
+ if (idx < m_source_indexes.size()) {
+ const Symbol *cu_symbol =
+ m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
+ if (cu_symbol)
+ cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL,
+ cu_symbol->GetName().AsCString(), 0,
+ eLanguageTypeUnknown, eLazyBoolNo));
+ }
+ return cu_sp;
}
lldb::LanguageType
-SymbolFileSymtab::ParseCompileUnitLanguage (const SymbolContext& sc)
-{
- return eLanguageTypeUnknown;
+SymbolFileSymtab::ParseCompileUnitLanguage(const SymbolContext &sc) {
+ return eLanguageTypeUnknown;
}
+size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) {
+ size_t num_added = 0;
+ // We must at least have a valid compile unit
+ assert(sc.comp_unit != NULL);
+ const Symtab *symtab = m_obj_file->GetSymtab();
+ const Symbol *curr_symbol = NULL;
+ const Symbol *next_symbol = NULL;
+ // const char *prefix = m_obj_file->SymbolPrefix();
+ // if (prefix == NULL)
+ // prefix == "";
+ //
+ // const uint32_t prefix_len = strlen(prefix);
+
+ // If we don't have any source file symbols we will just have one compile unit
+ // for
+ // the entire object file
+ if (m_source_indexes.empty()) {
+ // The only time we will have a user ID of zero is when we don't have
+ // and source file symbols and we declare one compile unit for the
+ // entire object file
+ if (!m_func_indexes.empty()) {
+ }
-size_t
-SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
-{
- size_t num_added = 0;
- // We must at least have a valid compile unit
- assert (sc.comp_unit != NULL);
- const Symtab *symtab = m_obj_file->GetSymtab();
- const Symbol *curr_symbol = NULL;
- const Symbol *next_symbol = NULL;
-// const char *prefix = m_obj_file->SymbolPrefix();
-// if (prefix == NULL)
-// prefix == "";
-//
-// const uint32_t prefix_len = strlen(prefix);
-
- // If we don't have any source file symbols we will just have one compile unit for
- // the entire object file
- if (m_source_indexes.empty())
- {
- // The only time we will have a user ID of zero is when we don't have
- // and source file symbols and we declare one compile unit for the
- // entire object file
- if (!m_func_indexes.empty())
- {
-
- }
-
- if (!m_code_indexes.empty())
- {
-// StreamFile s(stdout);
-// symtab->Dump(&s, m_code_indexes);
-
- uint32_t idx = 0; // Index into the indexes
- const uint32_t num_indexes = m_code_indexes.size();
- for (idx = 0; idx < num_indexes; ++idx)
- {
- uint32_t symbol_idx = m_code_indexes[idx];
- curr_symbol = symtab->SymbolAtIndex(symbol_idx);
- if (curr_symbol)
- {
- // Union of all ranges in the function DIE (if the function is discontiguous)
- AddressRange func_range(curr_symbol->GetAddress(), 0);
- if (func_range.GetBaseAddress().IsSectionOffset())
- {
- uint32_t symbol_size = curr_symbol->GetByteSize();
- if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
- func_range.SetByteSize(symbol_size);
- else if (idx + 1 < num_indexes)
- {
- next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
- if (next_symbol)
- {
- func_range.SetByteSize(next_symbol->GetAddressRef().GetOffset() - curr_symbol->GetAddressRef().GetOffset());
- }
- }
-
- FunctionSP func_sp(new Function(sc.comp_unit,
- symbol_idx, // UserID is the DIE offset
- LLDB_INVALID_UID, // We don't have any type info for this function
- curr_symbol->GetMangled(), // Linker/mangled name
- NULL, // no return type for a code symbol...
- func_range)); // first address range
-
- if (func_sp.get() != NULL)
- {
- sc.comp_unit->AddFunction(func_sp);
- ++num_added;
- }
- }
- }
+ if (!m_code_indexes.empty()) {
+ // StreamFile s(stdout);
+ // symtab->Dump(&s, m_code_indexes);
+
+ uint32_t idx = 0; // Index into the indexes
+ const uint32_t num_indexes = m_code_indexes.size();
+ for (idx = 0; idx < num_indexes; ++idx) {
+ uint32_t symbol_idx = m_code_indexes[idx];
+ curr_symbol = symtab->SymbolAtIndex(symbol_idx);
+ if (curr_symbol) {
+ // Union of all ranges in the function DIE (if the function is
+ // discontiguous)
+ AddressRange func_range(curr_symbol->GetAddress(), 0);
+ if (func_range.GetBaseAddress().IsSectionOffset()) {
+ uint32_t symbol_size = curr_symbol->GetByteSize();
+ if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
+ func_range.SetByteSize(symbol_size);
+ else if (idx + 1 < num_indexes) {
+ next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
+ if (next_symbol) {
+ func_range.SetByteSize(
+ next_symbol->GetAddressRef().GetOffset() -
+ curr_symbol->GetAddressRef().GetOffset());
+ }
+ }
+
+ FunctionSP func_sp(
+ new Function(sc.comp_unit,
+ symbol_idx, // UserID is the DIE offset
+ LLDB_INVALID_UID, // We don't have any type info
+ // for this function
+ curr_symbol->GetMangled(), // Linker/mangled name
+ NULL, // no return type for a code symbol...
+ func_range)); // first address range
+
+ if (func_sp.get() != NULL) {
+ sc.comp_unit->AddFunction(func_sp);
+ ++num_added;
}
-
+ }
}
+ }
}
- else
- {
- // We assume we
- }
- return num_added;
+ } else {
+ // We assume we
+ }
+ return num_added;
}
-bool
-SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
-{
- return false;
+bool SymbolFileSymtab::ParseCompileUnitLineTable(const SymbolContext &sc) {
+ return false;
}
-bool
-SymbolFileSymtab::ParseCompileUnitDebugMacros (const SymbolContext &sc)
-{
- return false;
+bool SymbolFileSymtab::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
+ return false;
}
-bool
-SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
-{
- return false;
+bool SymbolFileSymtab::ParseCompileUnitSupportFiles(
+ const SymbolContext &sc, FileSpecList &support_files) {
+ return false;
}
-bool
-SymbolFileSymtab::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules)
-{
- return false;
+bool SymbolFileSymtab::ParseImportedModules(
+ const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
+ return false;
}
-size_t
-SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
-{
- return 0;
+size_t SymbolFileSymtab::ParseFunctionBlocks(const SymbolContext &sc) {
+ return 0;
}
+size_t SymbolFileSymtab::ParseTypes(const SymbolContext &sc) { return 0; }
-size_t
-SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
-{
- return 0;
+size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) {
+ return 0;
}
+Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) {
+ return NULL;
+}
-size_t
-SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
-{
- return 0;
+bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) {
+ return false;
}
-Type*
-SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
-{
- return NULL;
-}
-
-bool
-SymbolFileSymtab::CompleteType (lldb_private::CompilerType& compiler_type)
-{
- return false;
-}
-
-uint32_t
-SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
-{
- if (m_obj_file->GetSymtab() == NULL)
- return 0;
-
- uint32_t resolved_flags = 0;
- if (resolve_scope & eSymbolContextSymbol)
- {
- sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
- if (sc.symbol)
- resolved_flags |= eSymbolContextSymbol;
- }
- return resolved_flags;
+uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr,
+ uint32_t resolve_scope,
+ SymbolContext &sc) {
+ if (m_obj_file->GetSymtab() == NULL)
+ return 0;
+
+ uint32_t resolved_flags = 0;
+ if (resolve_scope & eSymbolContextSymbol) {
+ sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(
+ so_addr.GetFileAddress());
+ if (sc.symbol)
+ resolved_flags |= eSymbolContextSymbol;
+ }
+ return resolved_flags;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-SymbolFileSymtab::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString SymbolFileSymtab::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-SymbolFileSymtab::GetPluginVersion()
-{
- return 1;
-}
+uint32_t SymbolFileSymtab::GetPluginVersion() { return 1; }
Modified: lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h Tue Sep 6 15:57:50 2016
@@ -19,112 +19,96 @@
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Symtab.h"
-class SymbolFileSymtab : public lldb_private::SymbolFile
-{
+class SymbolFileSymtab : public lldb_private::SymbolFile {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolFileSymtab(lldb_private::ObjectFile* obj_file);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFileSymtab(lldb_private::ObjectFile *obj_file);
- ~SymbolFileSymtab() override;
+ ~SymbolFileSymtab() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::SymbolFile*
- CreateInstance (lldb_private::ObjectFile* obj_file);
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
- uint32_t
- CalculateAbilities() override;
+ uint32_t CalculateAbilities() override;
- //------------------------------------------------------------------
- // Compile Unit function calls
- //------------------------------------------------------------------
- uint32_t
- GetNumCompileUnits() override;
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
+ uint32_t GetNumCompileUnits() override;
- lldb::CompUnitSP
- ParseCompileUnitAtIndex(uint32_t index) override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- lldb::LanguageType
- ParseCompileUnitLanguage(const lldb_private::SymbolContext& sc) override;
+ lldb::LanguageType
+ ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseCompileUnitFunctions(const lldb_private::SymbolContext& sc) override;
+ size_t
+ ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext& sc) override;
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitDebugMacros(const lldb_private::SymbolContext& sc) override;
+ bool
+ ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitSupportFiles(const lldb_private::SymbolContext& sc,
- lldb_private::FileSpecList &support_files) override;
-
- bool
- ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ bool ParseCompileUnitSupportFiles(
+ const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) override;
- size_t
- ParseFunctionBlocks(const lldb_private::SymbolContext& sc) override;
+ bool ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
- size_t
- ParseTypes(const lldb_private::SymbolContext& sc) override;
+ size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseVariablesForContext(const lldb_private::SymbolContext& sc) override;
+ size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
- lldb_private::Type*
- ResolveTypeUID(lldb::user_id_t type_uid) override;
+ size_t
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
- bool
- CompleteType(lldb_private::CompilerType& compiler_type) override;
+ lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
- uint32_t
- ResolveSymbolContext(const lldb_private::Address& so_addr,
- uint32_t resolve_scope,
- lldb_private::SymbolContext& sc) override;
+ bool CompleteType(lldb_private::CompilerType &compiler_type) override;
- size_t
- GetTypes(lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
- lldb_private::TypeList &type_list) override;
+ uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) override;
- uint32_t
- GetPluginVersion() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
protected:
- typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap;
+ typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap;
+
+ lldb_private::Symtab::IndexCollection m_source_indexes;
+ lldb_private::Symtab::IndexCollection m_func_indexes;
+ lldb_private::Symtab::IndexCollection m_code_indexes;
+ lldb_private::Symtab::IndexCollection m_data_indexes;
+ lldb_private::Symtab::NameToIndexMap m_objc_class_name_to_index;
+ TypeMap m_objc_class_types;
- lldb_private::Symtab::IndexCollection m_source_indexes;
- lldb_private::Symtab::IndexCollection m_func_indexes;
- lldb_private::Symtab::IndexCollection m_code_indexes;
- lldb_private::Symtab::IndexCollection m_data_indexes;
- lldb_private::Symtab::NameToIndexMap m_objc_class_name_to_index;
- TypeMap m_objc_class_types;
-
private:
- DISALLOW_COPY_AND_ASSIGN (SymbolFileSymtab);
+ DISALLOW_COPY_AND_ASSIGN(SymbolFileSymtab);
};
#endif // liblldb_SymbolFileSymtab_h_
Modified: lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp Tue Sep 6 15:57:50 2016
@@ -27,48 +27,33 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// SymbolVendorELF constructor
//----------------------------------------------------------------------
-SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) :
- SymbolVendor (module_sp)
-{
-}
+SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp)
+ : SymbolVendor(module_sp) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-SymbolVendorELF::~SymbolVendorELF()
-{
-}
+SymbolVendorELF::~SymbolVendorELF() {}
-void
-SymbolVendorELF::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void SymbolVendorELF::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-SymbolVendorELF::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void SymbolVendorELF::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-SymbolVendorELF::GetPluginNameStatic()
-{
- static ConstString g_name("ELF");
- return g_name;
+lldb_private::ConstString SymbolVendorELF::GetPluginNameStatic() {
+ static ConstString g_name("ELF");
+ return g_name;
}
-const char *
-SymbolVendorELF::GetPluginDescriptionStatic()
-{
- return "Symbol vendor for ELF that looks for dSYM files that match executables.";
+const char *SymbolVendorELF::GetPluginDescriptionStatic() {
+ return "Symbol vendor for ELF that looks for dSYM files that match "
+ "executables.";
}
-
-
//----------------------------------------------------------------------
// CreateInstance
//
@@ -76,122 +61,108 @@ SymbolVendorELF::GetPluginDescriptionSta
// vendors to allow for complex debug information file setups, and to
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
-SymbolVendor*
-SymbolVendorELF::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
-{
- if (!module_sp)
- return NULL;
-
- ObjectFile *obj_file = module_sp->GetObjectFile();
- if (!obj_file)
- return NULL;
-
- static ConstString obj_file_elf("elf");
- ConstString obj_name = obj_file->GetPluginName();
- if (obj_name != obj_file_elf)
- return NULL;
-
- lldb_private::UUID uuid;
- if (!obj_file->GetUUID (&uuid))
- return NULL;
-
- // Get the .gnu_debuglink file (if specified).
- FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
-
- // If the module specified a filespec, use it first.
- FileSpec debug_symbol_fspec (module_sp->GetSymbolFileFileSpec());
- if (debug_symbol_fspec)
- file_spec_list.Insert (0, debug_symbol_fspec);
-
- // If we have no debug symbol files, then nothing to do.
- if (file_spec_list.IsEmpty())
- return NULL;
-
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "SymbolVendorELF::CreateInstance (module = %s)",
- module_sp->GetFileSpec().GetPath().c_str());
-
- for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx)
- {
- ModuleSpec module_spec;
- const FileSpec fspec = file_spec_list.GetFileSpecAtIndex (idx);
-
- module_spec.GetFileSpec() = obj_file->GetFileSpec();
- module_spec.GetFileSpec().ResolvePath();
- module_spec.GetSymbolFileSpec() = fspec;
- module_spec.GetUUID() = uuid;
- FileSpec dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
- if (dsym_fspec)
- {
- DataBufferSP dsym_file_data_sp;
- lldb::offset_t dsym_file_data_offset = 0;
- ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset);
- if (dsym_objfile_sp)
- {
- // This objfile is for debugging purposes. Sadly, ObjectFileELF won't be able
- // to figure this out consistently as the symbol file may not have stripped the
- // code sections, etc.
- dsym_objfile_sp->SetType (ObjectFile::eTypeDebugInfo);
-
- SymbolVendorELF* symbol_vendor = new SymbolVendorELF(module_sp);
- if (symbol_vendor)
- {
- // Get the module unified section list and add our debug sections to that.
- SectionList *module_section_list = module_sp->GetSectionList();
- SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
-
- static const SectionType g_sections[] =
- {
- eSectionTypeDWARFDebugAbbrev,
- eSectionTypeDWARFDebugAddr,
- eSectionTypeDWARFDebugAranges,
- eSectionTypeDWARFDebugFrame,
- eSectionTypeDWARFDebugInfo,
- eSectionTypeDWARFDebugLine,
- eSectionTypeDWARFDebugLoc,
- eSectionTypeDWARFDebugMacInfo,
- eSectionTypeDWARFDebugPubNames,
- eSectionTypeDWARFDebugPubTypes,
- eSectionTypeDWARFDebugRanges,
- eSectionTypeDWARFDebugStr,
- eSectionTypeDWARFDebugStrOffsets,
- eSectionTypeELFSymbolTable,
- };
- for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
- {
- SectionType section_type = g_sections[idx];
- SectionSP section_sp (objfile_section_list->FindSectionByType (section_type, true));
- if (section_sp)
- {
- SectionSP module_section_sp (module_section_list->FindSectionByType (section_type, true));
- if (module_section_sp)
- module_section_list->ReplaceSection (module_section_sp->GetID(), section_sp);
- else
- module_section_list->AddSection (section_sp);
- }
- }
-
- symbol_vendor->AddSymbolFileRepresentation (dsym_objfile_sp);
- return symbol_vendor;
- }
+SymbolVendor *
+SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm) {
+ if (!module_sp)
+ return NULL;
+
+ ObjectFile *obj_file = module_sp->GetObjectFile();
+ if (!obj_file)
+ return NULL;
+
+ static ConstString obj_file_elf("elf");
+ ConstString obj_name = obj_file->GetPluginName();
+ if (obj_name != obj_file_elf)
+ return NULL;
+
+ lldb_private::UUID uuid;
+ if (!obj_file->GetUUID(&uuid))
+ return NULL;
+
+ // Get the .gnu_debuglink file (if specified).
+ FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
+
+ // If the module specified a filespec, use it first.
+ FileSpec debug_symbol_fspec(module_sp->GetSymbolFileFileSpec());
+ if (debug_symbol_fspec)
+ file_spec_list.Insert(0, debug_symbol_fspec);
+
+ // If we have no debug symbol files, then nothing to do.
+ if (file_spec_list.IsEmpty())
+ return NULL;
+
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolVendorELF::CreateInstance (module = %s)",
+ module_sp->GetFileSpec().GetPath().c_str());
+
+ for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx) {
+ ModuleSpec module_spec;
+ const FileSpec fspec = file_spec_list.GetFileSpecAtIndex(idx);
+
+ module_spec.GetFileSpec() = obj_file->GetFileSpec();
+ module_spec.GetFileSpec().ResolvePath();
+ module_spec.GetSymbolFileSpec() = fspec;
+ module_spec.GetUUID() = uuid;
+ FileSpec dsym_fspec = Symbols::LocateExecutableSymbolFile(module_spec);
+ if (dsym_fspec) {
+ DataBufferSP dsym_file_data_sp;
+ lldb::offset_t dsym_file_data_offset = 0;
+ ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
+ module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(),
+ dsym_file_data_sp, dsym_file_data_offset);
+ if (dsym_objfile_sp) {
+ // This objfile is for debugging purposes. Sadly, ObjectFileELF won't be
+ // able
+ // to figure this out consistently as the symbol file may not have
+ // stripped the
+ // code sections, etc.
+ dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
+
+ SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
+ if (symbol_vendor) {
+ // Get the module unified section list and add our debug sections to
+ // that.
+ SectionList *module_section_list = module_sp->GetSectionList();
+ SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
+
+ static const SectionType g_sections[] = {
+ eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
+ eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugFrame,
+ eSectionTypeDWARFDebugInfo, eSectionTypeDWARFDebugLine,
+ eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugMacInfo,
+ eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes,
+ eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugStr,
+ eSectionTypeDWARFDebugStrOffsets, eSectionTypeELFSymbolTable,
+ };
+ for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
+ ++idx) {
+ SectionType section_type = g_sections[idx];
+ SectionSP section_sp(
+ objfile_section_list->FindSectionByType(section_type, true));
+ if (section_sp) {
+ SectionSP module_section_sp(
+ module_section_list->FindSectionByType(section_type, true));
+ if (module_section_sp)
+ module_section_list->ReplaceSection(module_section_sp->GetID(),
+ section_sp);
+ else
+ module_section_list->AddSection(section_sp);
}
+ }
+
+ symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
+ return symbol_vendor;
}
+ }
}
- return NULL;
+ }
+ return NULL;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-SymbolVendorELF::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-SymbolVendorELF::GetPluginVersion()
-{
- return 1;
-}
+ConstString SymbolVendorELF::GetPluginName() { return GetPluginNameStatic(); }
+uint32_t SymbolVendorELF::GetPluginVersion() { return 1; }
Modified: lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h (original)
+++ lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h Tue Sep 6 15:57:50 2016
@@ -14,48 +14,42 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/lldb-private.h"
-class SymbolVendorELF : public lldb_private::SymbolVendor
-{
+class SymbolVendorELF : public lldb_private::SymbolVendor {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolVendorELF (const lldb::ModuleSP &module_sp);
-
- ~SymbolVendorELF() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::SymbolVendor*
- CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolVendorELF(const lldb::ModuleSP &module_sp);
+
+ ~SymbolVendorELF() override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolVendor *
+ CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
private:
- DISALLOW_COPY_AND_ASSIGN (SymbolVendorELF);
+ DISALLOW_COPY_AND_ASSIGN(SymbolVendorELF);
};
#endif // liblldb_SymbolVendorELF_h_
Modified: lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp Tue Sep 6 15:57:50 2016
@@ -28,88 +28,69 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// SymbolVendorMacOSX constructor
//----------------------------------------------------------------------
-SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp) :
- SymbolVendor (module_sp)
-{
-}
+SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp)
+ : SymbolVendor(module_sp) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-SymbolVendorMacOSX::~SymbolVendorMacOSX()
-{
-}
-
+SymbolVendorMacOSX::~SymbolVendorMacOSX() {}
-static bool
-UUIDsMatch(Module *module, ObjectFile *ofile, lldb_private::Stream *feedback_strm)
-{
- if (module && ofile)
- {
- // Make sure the UUIDs match
- lldb_private::UUID dsym_uuid;
-
- if (!ofile->GetUUID(&dsym_uuid))
- {
- if (feedback_strm)
- {
- feedback_strm->PutCString("warning: failed to get the uuid for object file: '");
- ofile->GetFileSpec().Dump(feedback_strm);
- feedback_strm->PutCString("\n");
- }
- return false;
- }
+static bool UUIDsMatch(Module *module, ObjectFile *ofile,
+ lldb_private::Stream *feedback_strm) {
+ if (module && ofile) {
+ // Make sure the UUIDs match
+ lldb_private::UUID dsym_uuid;
+
+ if (!ofile->GetUUID(&dsym_uuid)) {
+ if (feedback_strm) {
+ feedback_strm->PutCString(
+ "warning: failed to get the uuid for object file: '");
+ ofile->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->PutCString("\n");
+ }
+ return false;
+ }
- if (dsym_uuid == module->GetUUID())
- return true;
+ if (dsym_uuid == module->GetUUID())
+ return true;
- // Emit some warning messages since the UUIDs do not match!
- if (feedback_strm)
- {
- feedback_strm->PutCString("warning: UUID mismatch detected between modules:\n ");
- module->GetUUID().Dump(feedback_strm);
- feedback_strm->PutChar(' ');
- module->GetFileSpec().Dump(feedback_strm);
- feedback_strm->PutCString("\n ");
- dsym_uuid.Dump(feedback_strm);
- feedback_strm->PutChar(' ');
- ofile->GetFileSpec().Dump(feedback_strm);
- feedback_strm->EOL();
- }
+ // Emit some warning messages since the UUIDs do not match!
+ if (feedback_strm) {
+ feedback_strm->PutCString(
+ "warning: UUID mismatch detected between modules:\n ");
+ module->GetUUID().Dump(feedback_strm);
+ feedback_strm->PutChar(' ');
+ module->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->PutCString("\n ");
+ dsym_uuid.Dump(feedback_strm);
+ feedback_strm->PutChar(' ');
+ ofile->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->EOL();
}
- return false;
+ }
+ return false;
}
-void
-SymbolVendorMacOSX::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void SymbolVendorMacOSX::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-SymbolVendorMacOSX::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void SymbolVendorMacOSX::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-SymbolVendorMacOSX::GetPluginNameStatic()
-{
- static ConstString g_name("macosx");
- return g_name;
+lldb_private::ConstString SymbolVendorMacOSX::GetPluginNameStatic() {
+ static ConstString g_name("macosx");
+ return g_name;
}
-const char *
-SymbolVendorMacOSX::GetPluginDescriptionStatic()
-{
- return "Symbol vendor for MacOSX that looks for dSYM files that match executables.";
+const char *SymbolVendorMacOSX::GetPluginDescriptionStatic() {
+ return "Symbol vendor for MacOSX that looks for dSYM files that match "
+ "executables.";
}
-
-
//----------------------------------------------------------------------
// CreateInstance
//
@@ -117,186 +98,190 @@ SymbolVendorMacOSX::GetPluginDescription
// vendors to allow for complex debug information file setups, and to
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
-SymbolVendor*
-SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
-{
- if (!module_sp)
- return NULL;
-
- ObjectFile * obj_file = module_sp->GetObjectFile();
- if (!obj_file)
- return NULL;
-
- static ConstString obj_file_macho("mach-o");
- ConstString obj_name = obj_file->GetPluginName();
- if (obj_name != obj_file_macho)
- return NULL;
-
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "SymbolVendorMacOSX::CreateInstance (module = %s)",
- module_sp->GetFileSpec().GetPath().c_str());
- SymbolVendorMacOSX* symbol_vendor = new SymbolVendorMacOSX(module_sp);
- if (symbol_vendor)
- {
- char path[PATH_MAX];
- path[0] = '\0';
-
- // Try and locate the dSYM file on Mac OS X
- Timer scoped_timer2 ("SymbolVendorMacOSX::CreateInstance () locate dSYM",
- "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
- module_sp->GetFileSpec().GetPath().c_str());
-
- // First check to see if the module has a symbol file in mind already.
- // If it does, then we MUST use that.
- FileSpec dsym_fspec (module_sp->GetSymbolFileFileSpec());
-
- ObjectFileSP dsym_objfile_sp;
- if (!dsym_fspec)
- {
- // No symbol file was specified in the module, lets try and find
- // one ourselves.
- FileSpec file_spec = obj_file->GetFileSpec();
- if (!file_spec)
- file_spec = module_sp->GetFileSpec();
-
- ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
- module_spec.GetUUID() = module_sp->GetUUID();
- dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
- if (module_spec.GetSourceMappingList().GetSize())
- module_sp->GetSourceMappingList().Append (module_spec.GetSourceMappingList (), true);
- }
-
- if (dsym_fspec)
- {
- DataBufferSP dsym_file_data_sp;
- lldb::offset_t dsym_file_data_offset = 0;
- dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset);
- if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm))
- {
- // We need a XML parser if we hope to parse a plist...
- if (XMLDocument::XMLEnabled())
- {
- char dsym_path[PATH_MAX];
- if (module_sp->GetSourceMappingList().IsEmpty() && dsym_fspec.GetPath(dsym_path, sizeof(dsym_path)))
- {
- lldb_private::UUID dsym_uuid;
- if (dsym_objfile_sp->GetUUID(&dsym_uuid))
- {
- std::string uuid_str = dsym_uuid.GetAsString ();
- if (!uuid_str.empty())
- {
- char *resources = strstr (dsym_path, "/Contents/Resources/");
- if (resources)
- {
- char dsym_uuid_plist_path[PATH_MAX];
- resources[strlen("/Contents/Resources/")] = '\0';
- snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), "%s%s.plist", dsym_path, uuid_str.c_str());
- FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false);
- if (dsym_uuid_plist_spec.Exists())
- {
- ApplePropertyList plist(dsym_uuid_plist_path);
- if (plist)
- {
- std::string DBGBuildSourcePath;
- std::string DBGSourcePath;
-
- plist.GetValueAsString("DBGBuildSourcePath", DBGBuildSourcePath);
- plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
- if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty())
- {
- if (DBGSourcePath[0] == '~')
- {
- FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_sp->GetSourceMappingList().Append (ConstString(DBGBuildSourcePath), ConstString(DBGSourcePath), true);
- }
-
- // DBGSourcePathRemapping is a dictionary in the plist with
- // keys which are DBGBuildSourcePath file paths and
- // values which are DBGSourcePath file paths
-
- StructuredData::ObjectSP plist_sp = plist.GetStructuredData();
- if (plist_sp.get()
- && plist_sp->GetAsDictionary()
- && plist_sp->GetAsDictionary()->HasKey("DBGSourcePathRemapping")
- && plist_sp->GetAsDictionary()->GetValueForKey("DBGSourcePathRemapping")->GetAsDictionary())
- {
-
- // In an early version of DBGSourcePathRemapping, the DBGSourcePath
- // values were incorrect. If we have a newer style
- // DBGSourcePathRemapping, there will be a DBGVersion key in the plist
- // (we don't care about the value at this point).
- //
- // If this is an old style DBGSourcePathRemapping, ignore the
- // value half of the key-value remappings and use reuse the original
- // gloal DBGSourcePath string.
- bool new_style_source_remapping_dictionary = false;
- std::string original_DBGSourcePath_value = DBGSourcePath;
- if (plist_sp->GetAsDictionary()->HasKey("DBGVersion"))
- {
- new_style_source_remapping_dictionary = true;
- }
-
- StructuredData::Dictionary *remappings_dict = plist_sp->GetAsDictionary()->GetValueForKey("DBGSourcePathRemapping")->GetAsDictionary();
- remappings_dict->ForEach ([&module_sp, new_style_source_remapping_dictionary, original_DBGSourcePath_value](ConstString key, StructuredData::Object *object) -> bool
- {
- if (object && object->GetAsString())
- {
-
- // key is DBGBuildSourcePath
- // object is DBGSourcePath
- std::string DBGSourcePath = object->GetStringValue();
- if (new_style_source_remapping_dictionary == false && !original_DBGSourcePath_value.empty())
- {
- DBGSourcePath = original_DBGSourcePath_value;
- }
- if (DBGSourcePath[0] == '~')
- {
- FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_sp->GetSourceMappingList().Append (key, ConstString(DBGSourcePath), true);
- }
- return true;
- });
-
- }
- }
- }
- }
- }
+SymbolVendor *
+SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm) {
+ if (!module_sp)
+ return NULL;
+
+ ObjectFile *obj_file = module_sp->GetObjectFile();
+ if (!obj_file)
+ return NULL;
+
+ static ConstString obj_file_macho("mach-o");
+ ConstString obj_name = obj_file->GetPluginName();
+ if (obj_name != obj_file_macho)
+ return NULL;
+
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolVendorMacOSX::CreateInstance (module = %s)",
+ module_sp->GetFileSpec().GetPath().c_str());
+ SymbolVendorMacOSX *symbol_vendor = new SymbolVendorMacOSX(module_sp);
+ if (symbol_vendor) {
+ char path[PATH_MAX];
+ path[0] = '\0';
+
+ // Try and locate the dSYM file on Mac OS X
+ Timer scoped_timer2(
+ "SymbolVendorMacOSX::CreateInstance () locate dSYM",
+ "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
+ module_sp->GetFileSpec().GetPath().c_str());
+
+ // First check to see if the module has a symbol file in mind already.
+ // If it does, then we MUST use that.
+ FileSpec dsym_fspec(module_sp->GetSymbolFileFileSpec());
+
+ ObjectFileSP dsym_objfile_sp;
+ if (!dsym_fspec) {
+ // No symbol file was specified in the module, lets try and find
+ // one ourselves.
+ FileSpec file_spec = obj_file->GetFileSpec();
+ if (!file_spec)
+ file_spec = module_sp->GetFileSpec();
+
+ ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
+ module_spec.GetUUID() = module_sp->GetUUID();
+ dsym_fspec = Symbols::LocateExecutableSymbolFile(module_spec);
+ if (module_spec.GetSourceMappingList().GetSize())
+ module_sp->GetSourceMappingList().Append(
+ module_spec.GetSourceMappingList(), true);
+ }
+
+ if (dsym_fspec) {
+ DataBufferSP dsym_file_data_sp;
+ lldb::offset_t dsym_file_data_offset = 0;
+ dsym_objfile_sp = ObjectFile::FindPlugin(
+ module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(),
+ dsym_file_data_sp, dsym_file_data_offset);
+ if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm)) {
+ // We need a XML parser if we hope to parse a plist...
+ if (XMLDocument::XMLEnabled()) {
+ char dsym_path[PATH_MAX];
+ if (module_sp->GetSourceMappingList().IsEmpty() &&
+ dsym_fspec.GetPath(dsym_path, sizeof(dsym_path))) {
+ lldb_private::UUID dsym_uuid;
+ if (dsym_objfile_sp->GetUUID(&dsym_uuid)) {
+ std::string uuid_str = dsym_uuid.GetAsString();
+ if (!uuid_str.empty()) {
+ char *resources = strstr(dsym_path, "/Contents/Resources/");
+ if (resources) {
+ char dsym_uuid_plist_path[PATH_MAX];
+ resources[strlen("/Contents/Resources/")] = '\0';
+ snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path),
+ "%s%s.plist", dsym_path, uuid_str.c_str());
+ FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false);
+ if (dsym_uuid_plist_spec.Exists()) {
+ ApplePropertyList plist(dsym_uuid_plist_path);
+ if (plist) {
+ std::string DBGBuildSourcePath;
+ std::string DBGSourcePath;
+
+ plist.GetValueAsString("DBGBuildSourcePath",
+ DBGBuildSourcePath);
+ plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
+ if (!DBGBuildSourcePath.empty() &&
+ !DBGSourcePath.empty()) {
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str(),
+ true);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_sp->GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath),
+ ConstString(DBGSourcePath), true);
+ }
+
+ // DBGSourcePathRemapping is a dictionary in the plist
+ // with
+ // keys which are DBGBuildSourcePath file paths and
+ // values which are DBGSourcePath file paths
+
+ StructuredData::ObjectSP plist_sp =
+ plist.GetStructuredData();
+ if (plist_sp.get() && plist_sp->GetAsDictionary() &&
+ plist_sp->GetAsDictionary()->HasKey(
+ "DBGSourcePathRemapping") &&
+ plist_sp->GetAsDictionary()
+ ->GetValueForKey("DBGSourcePathRemapping")
+ ->GetAsDictionary()) {
+
+ // In an early version of DBGSourcePathRemapping, the
+ // DBGSourcePath
+ // values were incorrect. If we have a newer style
+ // DBGSourcePathRemapping, there will be a DBGVersion
+ // key in the plist
+ // (we don't care about the value at this point).
+ //
+ // If this is an old style DBGSourcePathRemapping,
+ // ignore the
+ // value half of the key-value remappings and use reuse
+ // the original
+ // gloal DBGSourcePath string.
+ bool new_style_source_remapping_dictionary = false;
+ std::string original_DBGSourcePath_value =
+ DBGSourcePath;
+ if (plist_sp->GetAsDictionary()->HasKey("DBGVersion")) {
+ new_style_source_remapping_dictionary = true;
}
+
+ StructuredData::Dictionary *remappings_dict =
+ plist_sp->GetAsDictionary()
+ ->GetValueForKey("DBGSourcePathRemapping")
+ ->GetAsDictionary();
+ remappings_dict->ForEach(
+ [&module_sp, new_style_source_remapping_dictionary,
+ original_DBGSourcePath_value](
+ ConstString key,
+ StructuredData::Object *object) -> bool {
+ if (object && object->GetAsString()) {
+
+ // key is DBGBuildSourcePath
+ // object is DBGSourcePath
+ std::string DBGSourcePath =
+ object->GetStringValue();
+ if (new_style_source_remapping_dictionary ==
+ false &&
+ !original_DBGSourcePath_value.empty()) {
+ DBGSourcePath = original_DBGSourcePath_value;
+ }
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(
+ DBGSourcePath.c_str(), true);
+ DBGSourcePath =
+ resolved_source_path.GetPath();
+ }
+ module_sp->GetSourceMappingList().Append(
+ key, ConstString(DBGSourcePath), true);
+ }
+ return true;
+ });
+ }
}
+ }
}
-
- symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
- return symbol_vendor;
+ }
}
+ }
}
- // Just create our symbol vendor using the current objfile as this is either
- // an executable with no dSYM (that we could locate), an executable with
- // a dSYM that has a UUID that doesn't match.
- symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this());
+ symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
+ return symbol_vendor;
+ }
}
- return symbol_vendor;
-}
-
+ // Just create our symbol vendor using the current objfile as this is either
+ // an executable with no dSYM (that we could locate), an executable with
+ // a dSYM that has a UUID that doesn't match.
+ symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this());
+ }
+ return symbol_vendor;
+}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-SymbolVendorMacOSX::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-SymbolVendorMacOSX::GetPluginVersion()
-{
- return 1;
+ConstString SymbolVendorMacOSX::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t SymbolVendorMacOSX::GetPluginVersion() { return 1; }
Modified: lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h (original)
+++ lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h Tue Sep 6 15:57:50 2016
@@ -10,49 +10,42 @@
#ifndef liblldb_SymbolVendorMacOSX_h_
#define liblldb_SymbolVendorMacOSX_h_
-#include "lldb/lldb-private.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/lldb-private.h"
-class SymbolVendorMacOSX : public lldb_private::SymbolVendor
-{
+class SymbolVendorMacOSX : public lldb_private::SymbolVendor {
public:
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::SymbolVendor*
- CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm);
-
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- SymbolVendorMacOSX (const lldb::ModuleSP &module_sp);
-
- virtual
- ~SymbolVendorMacOSX();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual lldb_private::ConstString
- GetPluginName();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolVendor *
+ CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolVendorMacOSX(const lldb::ModuleSP &module_sp);
+
+ virtual ~SymbolVendorMacOSX();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual lldb_private::ConstString GetPluginName();
- virtual uint32_t
- GetPluginVersion();
+ virtual uint32_t GetPluginVersion();
private:
- DISALLOW_COPY_AND_ASSIGN (SymbolVendorMacOSX);
+ DISALLOW_COPY_AND_ASSIGN(SymbolVendorMacOSX);
};
-#endif // liblldb_SymbolVendorMacOSX_h_
+#endif // liblldb_SymbolVendorMacOSX_h_
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp Tue Sep 6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- AppleGetItemInfoHandler.cpp -------------------------------*- C++ -*-===//
+//===-- AppleGetItemInfoHandler.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,8 +33,10 @@
using namespace lldb;
using namespace lldb_private;
-const char *AppleGetItemInfoHandler::g_get_item_info_function_name = "__lldb_backtrace_recording_get_item_info";
-const char *AppleGetItemInfoHandler::g_get_item_info_function_code = " \n\
+const char *AppleGetItemInfoHandler::g_get_item_info_function_name =
+ "__lldb_backtrace_recording_get_item_info";
+const char *AppleGetItemInfoHandler::g_get_item_info_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
/* \n\
@@ -97,294 +100,304 @@ extern \"C\"
";
AppleGetItemInfoHandler::AppleGetItemInfoHandler(Process *process)
- : m_process(process),
- m_get_item_info_impl_code(),
+ : m_process(process), m_get_item_info_impl_code(),
m_get_item_info_function_mutex(),
m_get_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_item_info_retbuffer_mutex()
-{
-}
+ m_get_item_info_retbuffer_mutex() {}
-AppleGetItemInfoHandler::~AppleGetItemInfoHandler ()
-{
-}
+AppleGetItemInfoHandler::~AppleGetItemInfoHandler() {}
-void
-AppleGetItemInfoHandler::Detach()
-{
-
- if (m_process && m_process->IsAlive() && m_get_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS)
- {
- std::unique_lock<std::mutex> lock(m_get_item_info_retbuffer_mutex, std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_item_info_return_buffer_addr);
- }
+void AppleGetItemInfoHandler::Detach() {
+
+ if (m_process && m_process->IsAlive() &&
+ m_get_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS) {
+ std::unique_lock<std::mutex> lock(m_get_item_info_retbuffer_mutex,
+ std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_item_info_return_buffer_addr);
+ }
}
// Compile our __lldb_backtrace_recording_get_item_info() function (from the
-// source above in g_get_item_info_function_code) if we don't find that function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for testing.)
+// source above in g_get_item_info_function_code) if we don't find that function
+// in the inferior
+// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
+// testing.)
+//
+// Insert the __lldb_backtrace_recording_get_item_info into the inferior process
+// if needed.
//
-// Insert the __lldb_backtrace_recording_get_item_info into the inferior process if needed.
+// Write the get_item_info_arglist into the inferior's memory space to prepare
+// for the call.
//
-// Write the get_item_info_arglist into the inferior's memory space to prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process, which can be used to
+// Returns the address of the arguments written down in the inferior process,
+// which can be used to
// make the function call.
-lldb::addr_t
-AppleGetItemInfoHandler::SetupGetItemInfoFunction(Thread &thread, ValueList &get_item_info_arglist)
-{
- ExecutionContext exe_ctx(thread.shared_from_this());
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *get_item_info_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_item_info_function_mutex);
-
- // First stage is to make the UtilityFunction to hold our injected function:
-
- if (!m_get_item_info_impl_code.get())
- {
- if (g_get_item_info_function_code != NULL)
- {
- Error error;
- m_get_item_info_impl_code.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_get_item_info_function_code,
- eLanguageTypeObjC,
- g_get_item_info_function_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get utility function: %s.", error.AsCString());
- return args_addr;
- }
-
- if (!m_get_item_info_impl_code->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install get-item-info introspection.");
- diagnostics.Dump(log);
- }
- m_get_item_info_impl_code.reset();
- return args_addr;
- }
- }
- else
- {
- if (log)
- log->Printf("No get-item-info introspection code found.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Next make the runner function for our implementation utility function.
- Error error;
-
- TypeSystem *type_system = thread.GetProcess()->GetTarget().GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
- CompilerType get_item_info_return_type = type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
-
- get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(get_item_info_return_type,
- get_item_info_arglist,
- thread.shared_from_this(),
- error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("Error Inserting get-item-info function: \"%s\".", error.AsCString());
- return args_addr;
- }
- }
- else
- {
- // If it's already made, then we can just retrieve the caller:
- get_item_info_caller = m_get_item_info_impl_code->GetFunctionCaller();
- if (!get_item_info_caller)
- {
- if (log)
- log->Printf ("Failed to get get-item-info introspection caller.");
- m_get_item_info_impl_code.reset();
- return args_addr;
- }
+lldb::addr_t AppleGetItemInfoHandler::SetupGetItemInfoFunction(
+ Thread &thread, ValueList &get_item_info_arglist) {
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+ lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *get_item_info_caller = nullptr;
+
+ // Scope for mutex locker:
+ {
+ std::lock_guard<std::mutex> guard(m_get_item_info_function_mutex);
+
+ // First stage is to make the UtilityFunction to hold our injected function:
+
+ if (!m_get_item_info_impl_code.get()) {
+ if (g_get_item_info_function_code != NULL) {
+ Error error;
+ m_get_item_info_impl_code.reset(
+ exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_item_info_function_code, eLanguageTypeObjC,
+ g_get_item_info_function_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Failed to get utility function: %s.",
+ error.AsCString());
+ return args_addr;
}
- }
-
- diagnostics.Clear();
-
- // Now write down the argument values for this particular call. This looks like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!get_item_info_caller->WriteFunctionArguments(exe_ctx, args_addr, get_item_info_arglist, diagnostics))
- {
- if (log)
- {
- log->Printf("Error writing get-item-info function arguments.");
+ if (!m_get_item_info_impl_code->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf("Failed to install get-item-info introspection.");
diagnostics.Dump(log);
+ }
+ m_get_item_info_impl_code.reset();
+ return args_addr;
}
-
+ } else {
+ if (log)
+ log->Printf("No get-item-info introspection code found.");
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // Next make the runner function for our implementation utility function.
+ Error error;
+
+ TypeSystem *type_system =
+ thread.GetProcess()->GetTarget().GetScratchTypeSystemForLanguage(
+ nullptr, eLanguageTypeC);
+ CompilerType get_item_info_return_type =
+ type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
+
+ get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(
+ get_item_info_return_type, get_item_info_arglist,
+ thread.shared_from_this(), error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Error Inserting get-item-info function: \"%s\".",
+ error.AsCString());
return args_addr;
- }
-
- return args_addr;
-}
-
-AppleGetItemInfoHandler::GetItemInfoReturnInfo
-AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
-{
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp (thread.CalculateProcess());
- TargetSP target_sp (thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetItemInfoReturnInfo return_value;
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.item_buffer_size = 0;
-
- error.Clear();
-
- if (thread.SafeToCallFunctions() == false)
- {
+ }
+ } else {
+ // If it's already made, then we can just retrieve the caller:
+ get_item_info_caller = m_get_item_info_impl_code->GetFunctionCaller();
+ if (!get_item_info_caller) {
if (log)
- log->Printf ("Not safe to call functions on thread 0x%" PRIx64, thread.GetID());
- error.SetErrorString ("Not safe to call functions on this thread.");
- return return_value;
+ log->Printf("Failed to get get-item-info introspection caller.");
+ m_get_item_info_impl_code.reset();
+ return args_addr;
+ }
}
+ }
- // Set up the arguments for a call to
+ diagnostics.Clear();
- // struct get_item_info_return_values
- // {
- // uint64_t item_info_buffer_ptr; /* the address of the items buffer from libBacktraceRecording */
- // uint64_t item_info_buffer_size; /* the size of the items buffer from libBacktraceRecording */
- // };
- //
- // void __lldb_backtrace_recording_get_item_info
- // (struct get_item_info_return_values *return_buffer,
- // int debug,
- // uint64_t item,
- // void *page_to_free,
- // uint64_t page_to_free_size)
-
- // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
- // the inferior process.
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType (Value::eValueTypeScalar);
- debug_value.SetCompilerType (clang_int_type);
-
- CompilerType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value item_value;
- item_value.SetValueType (Value::eValueTypeScalar);
- item_value.SetCompilerType (clang_uint64_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType (clang_void_ptr_type);
-
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_item_info_retbuffer_mutex);
- if (m_get_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS)
- {
- addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
- return return_value;
- }
- m_get_item_info_return_buffer_addr = bufaddr;
+ // Now write down the argument values for this particular call. This looks
+ // like it might be a race condition
+ // if other threads were calling into here, but actually it isn't because we
+ // allocate a new args structure for
+ // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+ if (!get_item_info_caller->WriteFunctionArguments(
+ exe_ctx, args_addr, get_item_info_arglist, diagnostics)) {
+ if (log) {
+ log->Printf("Error writing get-item-info function arguments.");
+ diagnostics.Dump(log);
}
- ValueList argument_values;
+ return args_addr;
+ }
- return_buffer_ptr_value.GetScalar() = m_get_item_info_return_buffer_addr;
- argument_values.PushValue (return_buffer_ptr_value);
+ return args_addr;
+}
- debug_value.GetScalar() = 0;
- argument_values.PushValue (debug_value);
+AppleGetItemInfoHandler::GetItemInfoReturnInfo
+AppleGetItemInfoHandler::GetItemInfo(Thread &thread, uint64_t item,
+ addr_t page_to_free,
+ uint64_t page_to_free_size, Error &error) {
+ lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+ ProcessSP process_sp(thread.CalculateProcess());
+ TargetSP target_sp(thread.CalculateTarget());
+ ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ GetItemInfoReturnInfo return_value;
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return_value.item_buffer_size = 0;
- item_value.GetScalar() = item;
- argument_values.PushValue (item_value);
-
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue (page_to_free_value);
-
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue (page_to_free_size_value);
-
- addr_t args_addr = SetupGetItemInfoFunction(thread, argument_values);
-
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints (true);
- options.SetStopOthers (true);
- options.SetTimeoutUsec(500000);
- options.SetTryAllThreads (false);
- thread.CalculateExecutionContext (exe_ctx);
-
- if (!m_get_item_info_impl_code)
- {
- error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_item_get_info");
- return return_value;
- }
+ error.Clear();
+ if (thread.SafeToCallFunctions() == false) {
+ if (log)
+ log->Printf("Not safe to call functions on thread 0x%" PRIx64,
+ thread.GetID());
+ error.SetErrorString("Not safe to call functions on this thread.");
+ return return_value;
+ }
- ExpressionResults func_call_ret;
- Value results;
- FunctionCaller *func_caller = m_get_item_info_impl_code->GetFunctionCaller();
- if (!func_caller)
- {
- if (log)
- log->Printf ("Could not retrieve function caller for __introspection_dispatch_queue_item_get_info.");
- error.SetErrorString("Could not retrieve function caller for __introspection_dispatch_queue_item_get_info.");
- return return_value;
- }
+ // Set up the arguments for a call to
- func_call_ret = func_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success())
- {
- if (log)
- log->Printf ("Unable to call __introspection_dispatch_queue_item_get_info(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
- error.SetErrorString ("Unable to call __introspection_dispatch_queue_get_item_info() for list of queues");
- return return_value;
+ // struct get_item_info_return_values
+ // {
+ // uint64_t item_info_buffer_ptr; /* the address of the items buffer
+ // from libBacktraceRecording */
+ // uint64_t item_info_buffer_size; /* the size of the items buffer from
+ // libBacktraceRecording */
+ // };
+ //
+ // void __lldb_backtrace_recording_get_item_info
+ // (struct
+ // get_item_info_return_values
+ // *return_buffer,
+ // int debug,
+ // uint64_t item,
+ // void *page_to_free,
+ // uint64_t page_to_free_size)
+
+ // Where the return_buffer argument points to a 24 byte region of memory
+ // already allocated by lldb in
+ // the inferior process.
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Value return_buffer_ptr_value;
+ return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+ return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+ Value debug_value;
+ debug_value.SetValueType(Value::eValueTypeScalar);
+ debug_value.SetCompilerType(clang_int_type);
+
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+ Value item_value;
+ item_value.SetValueType(Value::eValueTypeScalar);
+ item_value.SetCompilerType(clang_uint64_type);
+
+ Value page_to_free_value;
+ page_to_free_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_value.SetCompilerType(clang_void_ptr_type);
+
+ Value page_to_free_size_value;
+ page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_size_value.SetCompilerType(clang_uint64_type);
+
+ std::lock_guard<std::mutex> guard(m_get_item_info_retbuffer_mutex);
+ if (m_get_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS) {
+ addr_t bufaddr = process_sp->AllocateMemory(
+ 32, ePermissionsReadable | ePermissionsWritable, error);
+ if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Failed to allocate memory for return buffer for get "
+ "current queues func call");
+ return return_value;
}
+ m_get_item_info_return_buffer_addr = bufaddr;
+ }
- return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() || return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS)
- {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ ValueList argument_values;
- return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_item_info_return_buffer_addr + 8, 8, 0, error);
+ return_buffer_ptr_value.GetScalar() = m_get_item_info_return_buffer_addr;
+ argument_values.PushValue(return_buffer_ptr_value);
- if (!error.Success())
- {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ debug_value.GetScalar() = 0;
+ argument_values.PushValue(debug_value);
+
+ item_value.GetScalar() = item;
+ argument_values.PushValue(item_value);
+
+ if (page_to_free != LLDB_INVALID_ADDRESS)
+ page_to_free_value.GetScalar() = page_to_free;
+ else
+ page_to_free_value.GetScalar() = 0;
+ argument_values.PushValue(page_to_free_value);
+
+ page_to_free_size_value.GetScalar() = page_to_free_size;
+ argument_values.PushValue(page_to_free_size_value);
+
+ addr_t args_addr = SetupGetItemInfoFunction(thread, argument_values);
+
+ DiagnosticManager diagnostics;
+ ExecutionContext exe_ctx;
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetStopOthers(true);
+ options.SetTimeoutUsec(500000);
+ options.SetTryAllThreads(false);
+ thread.CalculateExecutionContext(exe_ctx);
+
+ if (!m_get_item_info_impl_code) {
+ error.SetErrorString("Unable to compile function to call "
+ "__introspection_dispatch_queue_item_get_info");
+ return return_value;
+ }
+
+ ExpressionResults func_call_ret;
+ Value results;
+ FunctionCaller *func_caller = m_get_item_info_impl_code->GetFunctionCaller();
+ if (!func_caller) {
if (log)
- log->Printf ("AppleGetItemInfoHandler called __introspection_dispatch_queue_item_get_info (page_to_free == 0x%" PRIx64 ", size = %" PRId64 "), returned page is at 0x%" PRIx64 ", size %" PRId64, page_to_free, page_to_free_size, return_value.item_buffer_ptr, return_value.item_buffer_size);
+ log->Printf("Could not retrieve function caller for "
+ "__introspection_dispatch_queue_item_get_info.");
+ error.SetErrorString("Could not retrieve function caller for "
+ "__introspection_dispatch_queue_item_get_info.");
+ return return_value;
+ }
+ func_call_ret = func_caller->ExecuteFunction(exe_ctx, &args_addr, options,
+ diagnostics, results);
+ if (func_call_ret != eExpressionCompleted || !error.Success()) {
+ if (log)
+ log->Printf("Unable to call "
+ "__introspection_dispatch_queue_item_get_info(), got "
+ "ExpressionResults %d, error contains %s",
+ func_call_ret, error.AsCString(""));
+ error.SetErrorString("Unable to call "
+ "__introspection_dispatch_queue_get_item_info() for "
+ "list of queues");
+ return return_value;
+ }
+ return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+ if (!error.Success() ||
+ return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS) {
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
return return_value;
+ }
+
+ return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_item_info_return_buffer_addr + 8, 8, 0, error);
+
+ if (!error.Success()) {
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
+ if (log)
+ log->Printf("AppleGetItemInfoHandler called "
+ "__introspection_dispatch_queue_item_get_info (page_to_free == "
+ "0x%" PRIx64 ", size = %" PRId64
+ "), returned page is at 0x%" PRIx64 ", size %" PRId64,
+ page_to_free, page_to_free_size, return_value.item_buffer_ptr,
+ return_value.item_buffer_size);
+
+ return return_value;
}
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h Tue Sep 6 15:57:50 2016
@@ -18,13 +18,14 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-public.h"
// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's __introspection_dispatch_queue_item_get_info()
+// calling libBacktraceRecording's
+// __introspection_dispatch_queue_item_get_info()
// function. The function in the inferior will return a struct by value
// with these members:
//
@@ -36,82 +37,83 @@
//
// The item_buffer pointer is an address in the inferior program's address
// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
-// lldb.
+// lldb.
//
// The AppleGetItemInfoHandler object should persist so that the UtilityFunction
// can be reused multiple times.
-namespace lldb_private
-{
+namespace lldb_private {
class AppleGetItemInfoHandler {
public:
+ AppleGetItemInfoHandler(lldb_private::Process *process);
- AppleGetItemInfoHandler (lldb_private::Process *process);
-
- ~AppleGetItemInfoHandler();
+ ~AppleGetItemInfoHandler();
- struct GetItemInfoReturnInfo
- {
- lldb::addr_t item_buffer_ptr; /* the address of the item buffer from libBacktraceRecording */
- lldb::addr_t item_buffer_size; /* the size of the item buffer from libBacktraceRecording */
-
- GetItemInfoReturnInfo() :
- item_buffer_ptr(LLDB_INVALID_ADDRESS),
- item_buffer_size(0)
- {}
- };
-
- //----------------------------------------------------------
- /// Get the information about a work item by calling
- /// __introspection_dispatch_queue_item_get_info. If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread
- /// The thread to run this plan on.
- ///
- /// @param [in] item
- /// The introspection_dispatch_item_info_ref value for the item of interest.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a failure of any kind while getting
- /// the information, the item_buffer_ptr value will be LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetItemInfoReturnInfo
- GetItemInfo (Thread &thread, lldb::addr_t item, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
+ struct GetItemInfoReturnInfo {
+ lldb::addr_t item_buffer_ptr; /* the address of the item buffer from
+ libBacktraceRecording */
+ lldb::addr_t item_buffer_size; /* the size of the item buffer from
+ libBacktraceRecording */
+
+ GetItemInfoReturnInfo()
+ : item_buffer_ptr(LLDB_INVALID_ADDRESS), item_buffer_size(0) {}
+ };
+
+ //----------------------------------------------------------
+ /// Get the information about a work item by calling
+ /// __introspection_dispatch_queue_item_get_info. If there's a page of
+ /// memory that needs to be freed, pass in the address and size and it will
+ /// be freed before getting the list of queues.
+ ///
+ /// @param [in] thread
+ /// The thread to run this plan on.
+ ///
+ /// @param [in] item
+ /// The introspection_dispatch_item_info_ref value for the item of
+ /// interest.
+ ///
+ /// @param [in] page_to_free
+ /// An address of an inferior process vm page that needs to be
+ /// deallocated,
+ /// LLDB_INVALID_ADDRESS if this is not needed.
+ ///
+ /// @param [in] page_to_free_size
+ /// The size of the vm page that needs to be deallocated if an address was
+ /// passed in to page_to_free.
+ ///
+ /// @param [out] error
+ /// This object will be updated with the error status / error string from
+ /// any failures encountered.
+ ///
+ /// @returns
+ /// The result of the inferior function call execution. If there was a
+ /// failure of any kind while getting
+ /// the information, the item_buffer_ptr value will be
+ /// LLDB_INVALID_ADDRESS.
+ //----------------------------------------------------------
+ GetItemInfoReturnInfo GetItemInfo(Thread &thread, lldb::addr_t item,
+ lldb::addr_t page_to_free,
+ uint64_t page_to_free_size,
+ lldb_private::Error &error);
-
- void
- Detach ();
+ void Detach();
private:
+ lldb::addr_t SetupGetItemInfoFunction(Thread &thread,
+ ValueList &get_item_info_arglist);
- lldb::addr_t
- SetupGetItemInfoFunction (Thread &thread, ValueList &get_item_info_arglist);
-
- static const char *g_get_item_info_function_name;
- static const char *g_get_item_info_function_code;
+ static const char *g_get_item_info_function_name;
+ static const char *g_get_item_info_function_code;
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_item_info_impl_code;
- std::mutex m_get_item_info_function_mutex;
+ lldb_private::Process *m_process;
+ std::unique_ptr<UtilityFunction> m_get_item_info_impl_code;
+ std::mutex m_get_item_info_function_mutex;
- lldb::addr_t m_get_item_info_return_buffer_addr;
- std::mutex m_get_item_info_retbuffer_mutex;
+ lldb::addr_t m_get_item_info_return_buffer_addr;
+ std::mutex m_get_item_info_retbuffer_mutex;
};
-} // using namespace lldb_private
+} // using namespace lldb_private
-#endif // lldb_AppleGetItemInfoHandler_h_
+#endif // lldb_AppleGetItemInfoHandler_h_
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp Tue Sep 6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- AppleGetPendingItemsHandler.cpp -------------------------------*- C++ -*-===//
+//===-- AppleGetPendingItemsHandler.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,8 +33,10 @@
using namespace lldb;
using namespace lldb_private;
-const char *AppleGetPendingItemsHandler::g_get_pending_items_function_name = "__lldb_backtrace_recording_get_pending_items";
-const char *AppleGetPendingItemsHandler::g_get_pending_items_function_code = " \n\
+const char *AppleGetPendingItemsHandler::g_get_pending_items_function_name =
+ "__lldb_backtrace_recording_get_pending_items";
+const char *AppleGetPendingItemsHandler::g_get_pending_items_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
/* \n\
@@ -101,290 +104,310 @@ extern \"C\"
";
AppleGetPendingItemsHandler::AppleGetPendingItemsHandler(Process *process)
- : m_process(process),
- m_get_pending_items_impl_code(),
+ : m_process(process), m_get_pending_items_impl_code(),
m_get_pending_items_function_mutex(),
m_get_pending_items_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_pending_items_retbuffer_mutex()
-{
-}
+ m_get_pending_items_retbuffer_mutex() {}
-AppleGetPendingItemsHandler::~AppleGetPendingItemsHandler ()
-{
-}
+AppleGetPendingItemsHandler::~AppleGetPendingItemsHandler() {}
-void
-AppleGetPendingItemsHandler::Detach()
-{
- if (m_process && m_process->IsAlive() && m_get_pending_items_return_buffer_addr != LLDB_INVALID_ADDRESS)
- {
- std::unique_lock<std::mutex> lock(m_get_pending_items_retbuffer_mutex, std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_pending_items_return_buffer_addr);
- }
+void AppleGetPendingItemsHandler::Detach() {
+ if (m_process && m_process->IsAlive() &&
+ m_get_pending_items_return_buffer_addr != LLDB_INVALID_ADDRESS) {
+ std::unique_lock<std::mutex> lock(m_get_pending_items_retbuffer_mutex,
+ std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_pending_items_return_buffer_addr);
+ }
}
// Compile our __lldb_backtrace_recording_get_pending_items() function (from the
-// source above in g_get_pending_items_function_code) if we don't find that function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for testing.)
+// source above in g_get_pending_items_function_code) if we don't find that
+// function in the inferior
+// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
+// testing.)
//
-// Insert the __lldb_backtrace_recording_get_pending_items into the inferior process if needed.
+// Insert the __lldb_backtrace_recording_get_pending_items into the inferior
+// process if needed.
//
-// Write the get_pending_items_arglist into the inferior's memory space to prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process, which can be used to
+// Write the get_pending_items_arglist into the inferior's memory space to
+// prepare for the call.
+//
+// Returns the address of the arguments written down in the inferior process,
+// which can be used to
// make the function call.
-lldb::addr_t
-AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(Thread &thread, ValueList &get_pending_items_arglist)
-{
- ThreadSP thread_sp (thread.shared_from_this());
- ExecutionContext exe_ctx (thread_sp);
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *get_pending_items_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_pending_items_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_get_pending_items_impl_code.get())
- {
- if (g_get_pending_items_function_code != NULL)
- {
- Error error;
- m_get_pending_items_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_get_pending_items_function_code,
- eLanguageTypeObjC,
- g_get_pending_items_function_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get UtilityFunction for pending-items introspection: %s.", error.AsCString());
- return args_addr;
- }
-
- if (!m_get_pending_items_impl_code->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install pending-items introspection.");
- diagnostics.Dump(log);
- }
- m_get_pending_items_impl_code.reset();
- return args_addr;
- }
- }
- else
- {
- if (log)
- log->Printf("No pending-items introspection code found.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Next make the runner function for our implementation utility function.
- Error error;
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_pending_items_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- get_pending_items_caller = m_get_pending_items_impl_code->MakeFunctionCaller (get_pending_items_return_type,
- get_pending_items_arglist,
- thread_sp,
- error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to install pending-items introspection function caller: %s.", error.AsCString());
- m_get_pending_items_impl_code.reset();
- return args_addr;
- }
+lldb::addr_t AppleGetPendingItemsHandler::SetupGetPendingItemsFunction(
+ Thread &thread, ValueList &get_pending_items_arglist) {
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx(thread_sp);
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *get_pending_items_caller = nullptr;
+
+ // Scope for mutex locker:
+ {
+ std::lock_guard<std::mutex> guard(m_get_pending_items_function_mutex);
+
+ // First stage is to make the ClangUtility to hold our injected function:
+
+ if (!m_get_pending_items_impl_code.get()) {
+ if (g_get_pending_items_function_code != NULL) {
+ Error error;
+ m_get_pending_items_impl_code.reset(
+ exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_pending_items_function_code, eLanguageTypeObjC,
+ g_get_pending_items_function_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Failed to get UtilityFunction for pending-items "
+ "introspection: %s.",
+ error.AsCString());
+ return args_addr;
}
- }
-
- diagnostics.Clear();
- if (get_pending_items_caller == nullptr)
- {
+ if (!m_get_pending_items_impl_code->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf("Failed to install pending-items introspection.");
+ diagnostics.Dump(log);
+ }
+ m_get_pending_items_impl_code.reset();
+ return args_addr;
+ }
+ } else {
if (log)
- log->Printf ("Failed to get get_pending_items_caller.");
+ log->Printf("No pending-items introspection code found.");
return LLDB_INVALID_ADDRESS;
- }
-
- // Now write down the argument values for this particular call. This looks like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+ }
- if (!get_pending_items_caller->WriteFunctionArguments(exe_ctx, args_addr, get_pending_items_arglist, diagnostics))
- {
+ // Next make the runner function for our implementation utility function.
+ Error error;
+ ClangASTContext *clang_ast_context =
+ thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+ CompilerType get_pending_items_return_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ get_pending_items_caller =
+ m_get_pending_items_impl_code->MakeFunctionCaller(
+ get_pending_items_return_type, get_pending_items_arglist,
+ thread_sp, error);
+ if (error.Fail()) {
if (log)
- {
- log->Printf("Error writing pending-items function arguments.");
- diagnostics.Dump(log);
- }
-
+ log->Printf("Failed to install pending-items introspection function "
+ "caller: %s.",
+ error.AsCString());
+ m_get_pending_items_impl_code.reset();
return args_addr;
+ }
}
+ }
- return args_addr;
-}
-
-AppleGetPendingItemsHandler::GetPendingItemsReturnInfo
-AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
-{
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp (thread.CalculateProcess());
- TargetSP target_sp (thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetPendingItemsReturnInfo return_value;
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.items_buffer_size = 0;
- return_value.count = 0;
+ diagnostics.Clear();
- error.Clear();
-
- if (thread.SafeToCallFunctions() == false)
- {
- if (log)
- log->Printf ("Not safe to call functions on thread 0x%" PRIx64, thread.GetID());
- error.SetErrorString ("Not safe to call functions on this thread.");
- return return_value;
+ if (get_pending_items_caller == nullptr) {
+ if (log)
+ log->Printf("Failed to get get_pending_items_caller.");
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // Now write down the argument values for this particular call. This looks
+ // like it might be a race condition
+ // if other threads were calling into here, but actually it isn't because we
+ // allocate a new args structure for
+ // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+ if (!get_pending_items_caller->WriteFunctionArguments(
+ exe_ctx, args_addr, get_pending_items_arglist, diagnostics)) {
+ if (log) {
+ log->Printf("Error writing pending-items function arguments.");
+ diagnostics.Dump(log);
}
- // Set up the arguments for a call to
-
- // struct get_pending_items_return_values
- // {
- // uint64_t pending_items_buffer_ptr; /* the address of the items buffer from libBacktraceRecording */
- // uint64_t pending_items_buffer_size; /* the size of the items buffer from libBacktraceRecording */
- // uint64_t count; /* the number of items included in the queues buffer */
- // };
- //
- // void __lldb_backtrace_recording_get_pending_items
- // (struct get_pending_items_return_values *return_buffer,
- // int debug,
- // uint64_t /* dispatch_queue_t */ queue
- // void *page_to_free,
- // uint64_t page_to_free_size)
-
- // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
- // the inferior process.
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType (Value::eValueTypeScalar);
- debug_value.SetCompilerType (clang_int_type);
-
- CompilerType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value queue_value;
- queue_value.SetValueType (Value::eValueTypeScalar);
- queue_value.SetCompilerType (clang_uint64_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType (clang_void_ptr_type);
-
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_pending_items_retbuffer_mutex);
- if (m_get_pending_items_return_buffer_addr == LLDB_INVALID_ADDRESS)
- {
- addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
- return return_value;
- }
- m_get_pending_items_return_buffer_addr = bufaddr;
- }
+ return args_addr;
+ }
- ValueList argument_values;
+ return args_addr;
+}
- return_buffer_ptr_value.GetScalar() = m_get_pending_items_return_buffer_addr;
- argument_values.PushValue (return_buffer_ptr_value);
+AppleGetPendingItemsHandler::GetPendingItemsReturnInfo
+AppleGetPendingItemsHandler::GetPendingItems(Thread &thread, addr_t queue,
+ addr_t page_to_free,
+ uint64_t page_to_free_size,
+ Error &error) {
+ lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+ ProcessSP process_sp(thread.CalculateProcess());
+ TargetSP target_sp(thread.CalculateTarget());
+ ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ GetPendingItemsReturnInfo return_value;
+ return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return_value.items_buffer_size = 0;
+ return_value.count = 0;
- debug_value.GetScalar() = 0;
- argument_values.PushValue (debug_value);
+ error.Clear();
- queue_value.GetScalar() = queue;
- argument_values.PushValue (queue_value);
-
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue (page_to_free_value);
-
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue (page_to_free_size_value);
-
- addr_t args_addr = SetupGetPendingItemsFunction(thread, argument_values);
-
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- FunctionCaller *get_pending_items_caller = m_get_pending_items_impl_code->GetFunctionCaller();
-
- EvaluateExpressionOptions options;
- options.SetUnwindOnError (true);
- options.SetIgnoreBreakpoints (true);
- options.SetStopOthers (true);
- options.SetTimeoutUsec(500000);
- options.SetTryAllThreads (false);
- thread.CalculateExecutionContext (exe_ctx);
-
- if (get_pending_items_caller == NULL)
- {
- error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_get_pending_items");
- return return_value;
- }
+ if (thread.SafeToCallFunctions() == false) {
+ if (log)
+ log->Printf("Not safe to call functions on thread 0x%" PRIx64,
+ thread.GetID());
+ error.SetErrorString("Not safe to call functions on this thread.");
+ return return_value;
+ }
- ExpressionResults func_call_ret;
- Value results;
- func_call_ret = get_pending_items_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success())
- {
- if (log)
- log->Printf ("Unable to call __introspection_dispatch_queue_get_pending_items(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
- error.SetErrorString ("Unable to call __introspection_dispatch_queue_get_pending_items() for list of queues");
- return return_value;
- }
+ // Set up the arguments for a call to
- return_value.items_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_pending_items_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() || return_value.items_buffer_ptr == LLDB_INVALID_ADDRESS)
- {
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ // struct get_pending_items_return_values
+ // {
+ // uint64_t pending_items_buffer_ptr; /* the address of the items
+ // buffer from libBacktraceRecording */
+ // uint64_t pending_items_buffer_size; /* the size of the items buffer
+ // from libBacktraceRecording */
+ // uint64_t count; /* the number of items included in the
+ // queues buffer */
+ // };
+ //
+ // void __lldb_backtrace_recording_get_pending_items
+ // (struct
+ // get_pending_items_return_values
+ // *return_buffer,
+ // int debug,
+ // uint64_t /* dispatch_queue_t */
+ // queue
+ // void *page_to_free,
+ // uint64_t page_to_free_size)
+
+ // Where the return_buffer argument points to a 24 byte region of memory
+ // already allocated by lldb in
+ // the inferior process.
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Value return_buffer_ptr_value;
+ return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+ return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+ Value debug_value;
+ debug_value.SetValueType(Value::eValueTypeScalar);
+ debug_value.SetCompilerType(clang_int_type);
+
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+ Value queue_value;
+ queue_value.SetValueType(Value::eValueTypeScalar);
+ queue_value.SetCompilerType(clang_uint64_type);
+
+ Value page_to_free_value;
+ page_to_free_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_value.SetCompilerType(clang_void_ptr_type);
+
+ Value page_to_free_size_value;
+ page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_size_value.SetCompilerType(clang_uint64_type);
+
+ std::lock_guard<std::mutex> guard(m_get_pending_items_retbuffer_mutex);
+ if (m_get_pending_items_return_buffer_addr == LLDB_INVALID_ADDRESS) {
+ addr_t bufaddr = process_sp->AllocateMemory(
+ 32, ePermissionsReadable | ePermissionsWritable, error);
+ if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Failed to allocate memory for return buffer for get "
+ "current queues func call");
+ return return_value;
+ }
+ m_get_pending_items_return_buffer_addr = bufaddr;
+ }
+
+ ValueList argument_values;
+
+ return_buffer_ptr_value.GetScalar() = m_get_pending_items_return_buffer_addr;
+ argument_values.PushValue(return_buffer_ptr_value);
+
+ debug_value.GetScalar() = 0;
+ argument_values.PushValue(debug_value);
+
+ queue_value.GetScalar() = queue;
+ argument_values.PushValue(queue_value);
+
+ if (page_to_free != LLDB_INVALID_ADDRESS)
+ page_to_free_value.GetScalar() = page_to_free;
+ else
+ page_to_free_value.GetScalar() = 0;
+ argument_values.PushValue(page_to_free_value);
+
+ page_to_free_size_value.GetScalar() = page_to_free_size;
+ argument_values.PushValue(page_to_free_size_value);
+
+ addr_t args_addr = SetupGetPendingItemsFunction(thread, argument_values);
+
+ DiagnosticManager diagnostics;
+ ExecutionContext exe_ctx;
+ FunctionCaller *get_pending_items_caller =
+ m_get_pending_items_impl_code->GetFunctionCaller();
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetStopOthers(true);
+ options.SetTimeoutUsec(500000);
+ options.SetTryAllThreads(false);
+ thread.CalculateExecutionContext(exe_ctx);
+
+ if (get_pending_items_caller == NULL) {
+ error.SetErrorString("Unable to compile function to call "
+ "__introspection_dispatch_queue_get_pending_items");
+ return return_value;
+ }
- return_value.items_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_pending_items_return_buffer_addr + 8, 8, 0, error);
+ ExpressionResults func_call_ret;
+ Value results;
+ func_call_ret = get_pending_items_caller->ExecuteFunction(
+ exe_ctx, &args_addr, options, diagnostics, results);
+ if (func_call_ret != eExpressionCompleted || !error.Success()) {
+ if (log)
+ log->Printf("Unable to call "
+ "__introspection_dispatch_queue_get_pending_items(), got "
+ "ExpressionResults %d, error contains %s",
+ func_call_ret, error.AsCString(""));
+ error.SetErrorString("Unable to call "
+ "__introspection_dispatch_queue_get_pending_items() "
+ "for list of queues");
+ return return_value;
+ }
- if (!error.Success())
- {
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.items_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_pending_items_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+ if (!error.Success() ||
+ return_value.items_buffer_ptr == LLDB_INVALID_ADDRESS) {
+ return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- return_value.count = m_process->ReadUnsignedIntegerFromMemory (m_get_pending_items_return_buffer_addr + 16, 8, 0, error);
- if (!error.Success())
- {
- return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.items_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_pending_items_return_buffer_addr + 8, 8, 0, error);
- if (log)
- log->Printf ("AppleGetPendingItemsHandler called __introspection_dispatch_queue_get_pending_items (page_to_free == 0x%" PRIx64 ", size = %" PRId64 "), returned page is at 0x%" PRIx64 ", size %" PRId64 ", count = %" PRId64, page_to_free, page_to_free_size, return_value.items_buffer_ptr, return_value.items_buffer_size, return_value.count);
+ if (!error.Success()) {
+ return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
+ return_value.count = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_pending_items_return_buffer_addr + 16, 8, 0, error);
+ if (!error.Success()) {
+ return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
return return_value;
+ }
+
+ if (log)
+ log->Printf("AppleGetPendingItemsHandler called "
+ "__introspection_dispatch_queue_get_pending_items "
+ "(page_to_free == 0x%" PRIx64 ", size = %" PRId64
+ "), returned page is at 0x%" PRIx64 ", size %" PRId64
+ ", count = %" PRId64,
+ page_to_free, page_to_free_size, return_value.items_buffer_ptr,
+ return_value.items_buffer_size, return_value.count);
+
+ return return_value;
}
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h Tue Sep 6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- AppleGetPendingItemsHandler.h ----------------------------*- C++ -*-===//
+//===-- AppleGetPendingItemsHandler.h ----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,12 +19,13 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-public.h"
// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's __introspection_dispatch_queue_get_pending_items()
+// calling libBacktraceRecording's
+// __introspection_dispatch_queue_get_pending_items()
// function. The function in the inferior will return a struct by value
// with these members:
//
@@ -38,82 +40,85 @@
// space (items_buffer_size in size) which must be mach_vm_deallocate'd by
// lldb. count is the number of items that were stored in the buffer.
//
-// The AppleGetPendingItemsHandler object should persist so that the UtilityFunction
+// The AppleGetPendingItemsHandler object should persist so that the
+// UtilityFunction
// can be reused multiple times.
-namespace lldb_private
-{
+namespace lldb_private {
class AppleGetPendingItemsHandler {
public:
+ AppleGetPendingItemsHandler(lldb_private::Process *process);
- AppleGetPendingItemsHandler (lldb_private::Process *process);
-
- ~AppleGetPendingItemsHandler();
-
- struct GetPendingItemsReturnInfo
- {
- lldb::addr_t items_buffer_ptr; /* the address of the pending items buffer from libBacktraceRecording */
- lldb::addr_t items_buffer_size; /* the size of the pending items buffer from libBacktraceRecording */
- uint64_t count; /* the number of pending items included in the buffer */
-
- GetPendingItemsReturnInfo () :
- items_buffer_ptr(LLDB_INVALID_ADDRESS),
- items_buffer_size(0),
- count(0)
- {}
- };
-
- //----------------------------------------------------------
- /// Get the list of pending items for a given queue via a call to
- /// __introspection_dispatch_queue_get_pending_items. If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread
- /// The thread to run this plan on.
- ///
- /// @param [in] queue
- /// The dispatch_queue_t value for the queue of interest.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a failure of any kind while getting
- /// the information, the items_buffer_ptr value will be LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetPendingItemsReturnInfo
- GetPendingItems (Thread &thread, lldb::addr_t queue, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
-
-
- void
- Detach ();
-
-private:
+ ~AppleGetPendingItemsHandler();
+ struct GetPendingItemsReturnInfo {
+ lldb::addr_t items_buffer_ptr; /* the address of the pending items buffer
+ from libBacktraceRecording */
lldb::addr_t
- SetupGetPendingItemsFunction (Thread &thread, ValueList &get_pending_items_arglist);
+ items_buffer_size; /* the size of the pending items buffer from
+ libBacktraceRecording */
+ uint64_t count; /* the number of pending items included in the buffer */
+
+ GetPendingItemsReturnInfo()
+ : items_buffer_ptr(LLDB_INVALID_ADDRESS), items_buffer_size(0),
+ count(0) {}
+ };
+
+ //----------------------------------------------------------
+ /// Get the list of pending items for a given queue via a call to
+ /// __introspection_dispatch_queue_get_pending_items. If there's a page of
+ /// memory that needs to be freed, pass in the address and size and it will
+ /// be freed before getting the list of queues.
+ ///
+ /// @param [in] thread
+ /// The thread to run this plan on.
+ ///
+ /// @param [in] queue
+ /// The dispatch_queue_t value for the queue of interest.
+ ///
+ /// @param [in] page_to_free
+ /// An address of an inferior process vm page that needs to be
+ /// deallocated,
+ /// LLDB_INVALID_ADDRESS if this is not needed.
+ ///
+ /// @param [in] page_to_free_size
+ /// The size of the vm page that needs to be deallocated if an address was
+ /// passed in to page_to_free.
+ ///
+ /// @param [out] error
+ /// This object will be updated with the error status / error string from
+ /// any failures encountered.
+ ///
+ /// @returns
+ /// The result of the inferior function call execution. If there was a
+ /// failure of any kind while getting
+ /// the information, the items_buffer_ptr value will be
+ /// LLDB_INVALID_ADDRESS.
+ //----------------------------------------------------------
+ GetPendingItemsReturnInfo GetPendingItems(Thread &thread, lldb::addr_t queue,
+ lldb::addr_t page_to_free,
+ uint64_t page_to_free_size,
+ lldb_private::Error &error);
- static const char *g_get_pending_items_function_name;
- static const char *g_get_pending_items_function_code;
+ void Detach();
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_pending_items_impl_code;
- std::mutex m_get_pending_items_function_mutex;
+private:
+ lldb::addr_t
+ SetupGetPendingItemsFunction(Thread &thread,
+ ValueList &get_pending_items_arglist);
+
+ static const char *g_get_pending_items_function_name;
+ static const char *g_get_pending_items_function_code;
+
+ lldb_private::Process *m_process;
+ std::unique_ptr<UtilityFunction> m_get_pending_items_impl_code;
+ std::mutex m_get_pending_items_function_mutex;
- lldb::addr_t m_get_pending_items_return_buffer_addr;
- std::mutex m_get_pending_items_retbuffer_mutex;
+ lldb::addr_t m_get_pending_items_return_buffer_addr;
+ std::mutex m_get_pending_items_retbuffer_mutex;
};
-} // using namespace lldb_private
+} // using namespace lldb_private
-#endif // lldb_AppleGetPendingItemsHandler_h_
+#endif // lldb_AppleGetPendingItemsHandler_h_
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp Tue Sep 6 15:57:50 2016
@@ -31,8 +31,10 @@
using namespace lldb;
using namespace lldb_private;
-const char *AppleGetQueuesHandler::g_get_current_queues_function_name = "__lldb_backtrace_recording_get_current_queues";
-const char *AppleGetQueuesHandler::g_get_current_queues_function_code = " \n\
+const char *AppleGetQueuesHandler::g_get_current_queues_function_name =
+ "__lldb_backtrace_recording_get_current_queues";
+const char *AppleGetQueuesHandler::g_get_current_queues_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
/* \n\
@@ -97,31 +99,26 @@ extern \"C\"
";
AppleGetQueuesHandler::AppleGetQueuesHandler(Process *process)
- : m_process(process),
- m_get_queues_impl_code_up(),
+ : m_process(process), m_get_queues_impl_code_up(),
m_get_queues_function_mutex(),
m_get_queues_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_queues_retbuffer_mutex()
-{
-}
+ m_get_queues_retbuffer_mutex() {}
-AppleGetQueuesHandler::~AppleGetQueuesHandler ()
-{
-}
+AppleGetQueuesHandler::~AppleGetQueuesHandler() {}
-void
-AppleGetQueuesHandler::Detach()
-{
-
- if (m_process && m_process->IsAlive() && m_get_queues_return_buffer_addr != LLDB_INVALID_ADDRESS)
- {
- std::unique_lock<std::mutex> lock(m_get_queues_retbuffer_mutex, std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_queues_return_buffer_addr);
- }
+void AppleGetQueuesHandler::Detach() {
+
+ if (m_process && m_process->IsAlive() &&
+ m_get_queues_return_buffer_addr != LLDB_INVALID_ADDRESS) {
+ std::unique_lock<std::mutex> lock(m_get_queues_retbuffer_mutex,
+ std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_queues_return_buffer_addr);
+ }
}
-// Construct a CompilerType for the structure that g_get_current_queues_function_code will return by value
+// Construct a CompilerType for the structure that
+// g_get_current_queues_function_code will return by value
// so we can extract the fields after performing the function call.
// i.e. we are getting this struct returned to us:
//
@@ -132,262 +129,283 @@ AppleGetQueuesHandler::Detach()
// uint64_t count;
// };
-
-// Compile our __lldb_backtrace_recording_get_current_queues() function (from the
-// source above in g_get_current_queues_function_code) if we don't find that function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for testing.)
+// Compile our __lldb_backtrace_recording_get_current_queues() function (from
+// the
+// source above in g_get_current_queues_function_code) if we don't find that
+// function in the inferior
+// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
+// testing.)
+//
+// Insert the __lldb_backtrace_recording_get_current_queues into the inferior
+// process if needed.
//
-// Insert the __lldb_backtrace_recording_get_current_queues into the inferior process if needed.
+// Write the get_queues_arglist into the inferior's memory space to prepare for
+// the call.
//
-// Write the get_queues_arglist into the inferior's memory space to prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process, which can be used to
+// Returns the address of the arguments written down in the inferior process,
+// which can be used to
// make the function call.
lldb::addr_t
-AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_queues_arglist)
-{
- ThreadSP thread_sp(thread.shared_from_this());
- ExecutionContext exe_ctx (thread_sp);
-
- Address impl_code_address;
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
-
- FunctionCaller *get_queues_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_queues_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_get_queues_impl_code_up.get())
- {
- if (g_get_current_queues_function_code != NULL)
- {
- Error error;
- m_get_queues_impl_code_up.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_get_current_queues_function_code,
- eLanguageTypeC,
- g_get_current_queues_function_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get UtilityFunction for queues introspection: %s.", error.AsCString());
- return args_addr;
- }
-
- if (!m_get_queues_impl_code_up->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install queues introspection");
- diagnostics.Dump(log);
- }
- m_get_queues_impl_code_up.reset();
- return args_addr;
- }
- }
- else
- {
- if (log)
- {
- log->Printf("No queues introspection code found.");
- diagnostics.Dump(log);
- }
- return LLDB_INVALID_ADDRESS;
- }
- }
+AppleGetQueuesHandler::SetupGetQueuesFunction(Thread &thread,
+ ValueList &get_queues_arglist) {
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx(thread_sp);
+
+ Address impl_code_address;
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+ lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+
+ FunctionCaller *get_queues_caller = nullptr;
+
+ // Scope for mutex locker:
+ {
+ std::lock_guard<std::mutex> guard(m_get_queues_function_mutex);
+
+ // First stage is to make the ClangUtility to hold our injected function:
- // Next make the runner function for our implementation utility function.
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_queues_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ if (!m_get_queues_impl_code_up.get()) {
+ if (g_get_current_queues_function_code != NULL) {
Error error;
- get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller (get_queues_return_type,
- get_queues_arglist,
- thread_sp,
- error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("Could not get function caller for get-queues function: %s.", error.AsCString());
- return args_addr;
+ m_get_queues_impl_code_up.reset(
+ exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_current_queues_function_code, eLanguageTypeC,
+ g_get_current_queues_function_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "Failed to get UtilityFunction for queues introspection: %s.",
+ error.AsCString());
+ return args_addr;
}
- }
- diagnostics.Clear();
-
- // Now write down the argument values for this particular call. This looks like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
-
- if (!get_queues_caller->WriteFunctionArguments(exe_ctx, args_addr, get_queues_arglist, diagnostics))
- {
- if (log)
- {
- log->Printf("Error writing get-queues function arguments.");
+ if (!m_get_queues_impl_code_up->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf("Failed to install queues introspection");
diagnostics.Dump(log);
+ }
+ m_get_queues_impl_code_up.reset();
+ return args_addr;
+ }
+ } else {
+ if (log) {
+ log->Printf("No queues introspection code found.");
+ diagnostics.Dump(log);
}
- return args_addr;
+ return LLDB_INVALID_ADDRESS;
+ }
}
+ // Next make the runner function for our implementation utility function.
+ ClangASTContext *clang_ast_context =
+ thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+ CompilerType get_queues_return_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Error error;
+ get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller(
+ get_queues_return_type, get_queues_arglist, thread_sp, error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "Could not get function caller for get-queues function: %s.",
+ error.AsCString());
+ return args_addr;
+ }
+ }
+
+ diagnostics.Clear();
+
+ // Now write down the argument values for this particular call. This looks
+ // like it might be a race condition
+ // if other threads were calling into here, but actually it isn't because we
+ // allocate a new args structure for
+ // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+ if (!get_queues_caller->WriteFunctionArguments(
+ exe_ctx, args_addr, get_queues_arglist, diagnostics)) {
+ if (log) {
+ log->Printf("Error writing get-queues function arguments.");
+ diagnostics.Dump(log);
+ }
return args_addr;
+ }
+
+ return args_addr;
}
AppleGetQueuesHandler::GetQueuesReturnInfo
-AppleGetQueuesHandler::GetCurrentQueues (Thread &thread, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
-{
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp (thread.CalculateProcess());
- TargetSP target_sp (thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
-
- GetQueuesReturnInfo return_value;
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.queues_buffer_size = 0;
- return_value.count = 0;
-
- error.Clear();
-
- if (thread.SafeToCallFunctions() == false)
- {
- if (log)
- log->Printf ("Not safe to call functions on thread 0x%" PRIx64, thread.GetID());
- error.SetErrorString ("Not safe to call functions on this thread.");
- return return_value;
- }
-
- // Set up the arguments for a call to
-
- // struct get_current_queues_return_values
- // {
- // uint64_t queues_buffer_ptr; /* the address of the queues buffer from libBacktraceRecording */
- // uint64_t queues_buffer_size; /* the size of the queues buffer from libBacktraceRecording */
- // uint64_t count; /* the number of queues included in the queues buffer */
- // };
- //
- // void
- // __lldb_backtrace_recording_get_current_queues
- // (struct get_current_queues_return_values *return_buffer,
- // void *page_to_free,
- // uint64_t page_to_free_size);
-
- // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
- // the inferior process.
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType (Value::eValueTypeScalar);
- debug_value.SetCompilerType (clang_int_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_queues_retbuffer_mutex);
- if (m_get_queues_return_buffer_addr == LLDB_INVALID_ADDRESS)
- {
- addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
- return return_value;
- }
- m_get_queues_return_buffer_addr = bufaddr;
- }
+AppleGetQueuesHandler::GetCurrentQueues(Thread &thread, addr_t page_to_free,
+ uint64_t page_to_free_size,
+ Error &error) {
+ lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+ ProcessSP process_sp(thread.CalculateProcess());
+ TargetSP target_sp(thread.CalculateTarget());
+ ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ GetQueuesReturnInfo return_value;
+ return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return_value.queues_buffer_size = 0;
+ return_value.count = 0;
- ValueList argument_values;
+ error.Clear();
- return_buffer_ptr_value.GetScalar() = m_get_queues_return_buffer_addr;
- argument_values.PushValue (return_buffer_ptr_value);
-
- debug_value.GetScalar() = 0;
- argument_values.PushValue (debug_value);
+ if (thread.SafeToCallFunctions() == false) {
+ if (log)
+ log->Printf("Not safe to call functions on thread 0x%" PRIx64,
+ thread.GetID());
+ error.SetErrorString("Not safe to call functions on this thread.");
+ return return_value;
+ }
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue (page_to_free_value);
+ // Set up the arguments for a call to
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue (page_to_free_size_value);
+ // struct get_current_queues_return_values
+ // {
+ // uint64_t queues_buffer_ptr; /* the address of the queues buffer from
+ // libBacktraceRecording */
+ // uint64_t queues_buffer_size; /* the size of the queues buffer from
+ // libBacktraceRecording */
+ // uint64_t count; /* the number of queues included in the
+ // queues buffer */
+ // };
+ //
+ // void
+ // __lldb_backtrace_recording_get_current_queues
+ // (struct
+ // get_current_queues_return_values
+ // *return_buffer,
+ // void *page_to_free,
+ // uint64_t page_to_free_size);
+
+ // Where the return_buffer argument points to a 24 byte region of memory
+ // already allocated by lldb in
+ // the inferior process.
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Value return_buffer_ptr_value;
+ return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+ return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+ Value debug_value;
+ debug_value.SetValueType(Value::eValueTypeScalar);
+ debug_value.SetCompilerType(clang_int_type);
+
+ Value page_to_free_value;
+ page_to_free_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+ Value page_to_free_size_value;
+ page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_size_value.SetCompilerType(clang_uint64_type);
+
+ std::lock_guard<std::mutex> guard(m_get_queues_retbuffer_mutex);
+ if (m_get_queues_return_buffer_addr == LLDB_INVALID_ADDRESS) {
+ addr_t bufaddr = process_sp->AllocateMemory(
+ 32, ePermissionsReadable | ePermissionsWritable, error);
+ if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Failed to allocate memory for return buffer for get "
+ "current queues func call");
+ return return_value;
+ }
+ m_get_queues_return_buffer_addr = bufaddr;
+ }
+
+ ValueList argument_values;
+
+ return_buffer_ptr_value.GetScalar() = m_get_queues_return_buffer_addr;
+ argument_values.PushValue(return_buffer_ptr_value);
+
+ debug_value.GetScalar() = 0;
+ argument_values.PushValue(debug_value);
+
+ if (page_to_free != LLDB_INVALID_ADDRESS)
+ page_to_free_value.GetScalar() = page_to_free;
+ else
+ page_to_free_value.GetScalar() = 0;
+ argument_values.PushValue(page_to_free_value);
+
+ page_to_free_size_value.GetScalar() = page_to_free_size;
+ argument_values.PushValue(page_to_free_size_value);
+
+ addr_t args_addr = SetupGetQueuesFunction(thread, argument_values);
+
+ if (!m_get_queues_impl_code_up) {
+ error.SetErrorString(
+ "Unable to compile __introspection_dispatch_get_queues.");
+ return return_value;
+ }
- addr_t args_addr = SetupGetQueuesFunction (thread, argument_values);
+ FunctionCaller *get_queues_caller =
+ m_get_queues_impl_code_up->GetFunctionCaller();
- if (!m_get_queues_impl_code_up)
- {
- error.SetErrorString ("Unable to compile __introspection_dispatch_get_queues.");
- return return_value;
- }
-
- FunctionCaller *get_queues_caller = m_get_queues_impl_code_up->GetFunctionCaller();
-
- if (get_queues_caller == NULL)
- {
- error.SetErrorString ("Unable to get caller for call __introspection_dispatch_get_queues");
- return return_value;
- }
+ if (get_queues_caller == NULL) {
+ error.SetErrorString(
+ "Unable to get caller for call __introspection_dispatch_get_queues");
+ return return_value;
+ }
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints (true);
- options.SetStopOthers (true);
- options.SetTimeoutUsec(500000);
- options.SetTryAllThreads (false);
- thread.CalculateExecutionContext (exe_ctx);
-
- ExpressionResults func_call_ret;
- Value results;
- func_call_ret = get_queues_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success())
- {
- if (log)
- log->Printf ("Unable to call introspection_get_dispatch_queues(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
- error.SetErrorString ("Unable to call introspection_get_dispatch_queues() for list of queues");
- return return_value;
- }
+ DiagnosticManager diagnostics;
+ ExecutionContext exe_ctx;
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetStopOthers(true);
+ options.SetTimeoutUsec(500000);
+ options.SetTryAllThreads(false);
+ thread.CalculateExecutionContext(exe_ctx);
+
+ ExpressionResults func_call_ret;
+ Value results;
+ func_call_ret = get_queues_caller->ExecuteFunction(
+ exe_ctx, &args_addr, options, diagnostics, results);
+ if (func_call_ret != eExpressionCompleted || !error.Success()) {
+ if (log)
+ log->Printf("Unable to call introspection_get_dispatch_queues(), got "
+ "ExpressionResults %d, error contains %s",
+ func_call_ret, error.AsCString(""));
+ error.SetErrorString("Unable to call introspection_get_dispatch_queues() "
+ "for list of queues");
+ return return_value;
+ }
- return_value.queues_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_queues_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() || return_value.queues_buffer_ptr == LLDB_INVALID_ADDRESS)
- {
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.queues_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_queues_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+ if (!error.Success() ||
+ return_value.queues_buffer_ptr == LLDB_INVALID_ADDRESS) {
+ return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- return_value.queues_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_queues_return_buffer_addr + 8, 8, 0, error);
+ return_value.queues_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_queues_return_buffer_addr + 8, 8, 0, error);
- if (!error.Success())
- {
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ if (!error.Success()) {
+ return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- return_value.count = m_process->ReadUnsignedIntegerFromMemory (m_get_queues_return_buffer_addr + 16, 8, 0, error);
- if (!error.Success())
- {
- return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.count = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_queues_return_buffer_addr + 16, 8, 0, error);
+ if (!error.Success()) {
+ return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- if (log)
- log->Printf ("AppleGetQueuesHandler called __introspection_dispatch_get_queues (page_to_free == 0x%" PRIx64 ", size = %" PRId64 "), returned page is at 0x%" PRIx64 ", size %" PRId64 ", count = %" PRId64, page_to_free, page_to_free_size, return_value.queues_buffer_ptr, return_value.queues_buffer_size, return_value.count);
+ if (log)
+ log->Printf("AppleGetQueuesHandler called "
+ "__introspection_dispatch_get_queues (page_to_free == "
+ "0x%" PRIx64 ", size = %" PRId64
+ "), returned page is at 0x%" PRIx64 ", size %" PRId64
+ ", count = %" PRId64,
+ page_to_free, page_to_free_size, return_value.queues_buffer_ptr,
+ return_value.queues_buffer_size, return_value.count);
- return return_value;
+ return return_value;
}
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h Tue Sep 6 15:57:50 2016
@@ -18,9 +18,9 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-public.h"
// This class will insert a UtilityFunction into the inferior process for
// calling libBacktraceRecording's introspection_get_dispatch_queues()
@@ -41,76 +41,76 @@
// The AppleGetQueuesHandler object should persist so that the UtilityFunction
// can be reused multiple times.
-namespace lldb_private
-{
+namespace lldb_private {
class AppleGetQueuesHandler {
public:
+ AppleGetQueuesHandler(lldb_private::Process *process);
- AppleGetQueuesHandler (lldb_private::Process *process);
-
- ~AppleGetQueuesHandler();
+ ~AppleGetQueuesHandler();
- struct GetQueuesReturnInfo
- {
- lldb::addr_t queues_buffer_ptr; /* the address of the queues buffer from libBacktraceRecording */
- lldb::addr_t queues_buffer_size; /* the size of the queues buffer from libBacktraceRecording */
- uint64_t count; /* the number of queues included in the queues buffer */
-
- GetQueuesReturnInfo() :
- queues_buffer_ptr(LLDB_INVALID_ADDRESS),
- queues_buffer_size(0),
- count(0)
- {}
- };
-
- //----------------------------------------------------------
- /// Get the list of queues that exist (with any active or pending items) via
- /// a call to introspection_get_dispatch_queues(). If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread
- /// The thread to run this plan on.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a failure of any kind while getting
- /// the information, the queues_buffer_ptr value will be LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetQueuesReturnInfo
- GetCurrentQueues (Thread &thread, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
+ struct GetQueuesReturnInfo {
+ lldb::addr_t queues_buffer_ptr; /* the address of the queues buffer from
+ libBacktraceRecording */
+ lldb::addr_t queues_buffer_size; /* the size of the queues buffer from
+ libBacktraceRecording */
+ uint64_t count; /* the number of queues included in the queues buffer */
+
+ GetQueuesReturnInfo()
+ : queues_buffer_ptr(LLDB_INVALID_ADDRESS), queues_buffer_size(0),
+ count(0) {}
+ };
+
+ //----------------------------------------------------------
+ /// Get the list of queues that exist (with any active or pending items) via
+ /// a call to introspection_get_dispatch_queues(). If there's a page of
+ /// memory that needs to be freed, pass in the address and size and it will
+ /// be freed before getting the list of queues.
+ ///
+ /// @param [in] thread
+ /// The thread to run this plan on.
+ ///
+ /// @param [in] page_to_free
+ /// An address of an inferior process vm page that needs to be
+ /// deallocated,
+ /// LLDB_INVALID_ADDRESS if this is not needed.
+ ///
+ /// @param [in] page_to_free_size
+ /// The size of the vm page that needs to be deallocated if an address was
+ /// passed in to page_to_free.
+ ///
+ /// @param [out] error
+ /// This object will be updated with the error status / error string from
+ /// any failures encountered.
+ ///
+ /// @returns
+ /// The result of the inferior function call execution. If there was a
+ /// failure of any kind while getting
+ /// the information, the queues_buffer_ptr value will be
+ /// LLDB_INVALID_ADDRESS.
+ //----------------------------------------------------------
+ GetQueuesReturnInfo GetCurrentQueues(Thread &thread,
+ lldb::addr_t page_to_free,
+ uint64_t page_to_free_size,
+ lldb_private::Error &error);
-
- void
- Detach ();
+ void Detach();
private:
+ lldb::addr_t SetupGetQueuesFunction(Thread &thread,
+ ValueList &get_queues_arglist);
- lldb::addr_t
- SetupGetQueuesFunction (Thread &thread, ValueList &get_queues_arglist);
-
- static const char *g_get_current_queues_function_name;
- static const char *g_get_current_queues_function_code;
+ static const char *g_get_current_queues_function_name;
+ static const char *g_get_current_queues_function_code;
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_queues_impl_code_up;
- std::mutex m_get_queues_function_mutex;
+ lldb_private::Process *m_process;
+ std::unique_ptr<UtilityFunction> m_get_queues_impl_code_up;
+ std::mutex m_get_queues_function_mutex;
- lldb::addr_t m_get_queues_return_buffer_addr;
- std::mutex m_get_queues_retbuffer_mutex;
+ lldb::addr_t m_get_queues_return_buffer_addr;
+ std::mutex m_get_queues_retbuffer_mutex;
};
-} // using namespace lldb_private
+} // using namespace lldb_private
-#endif // lldb_AppleGetQueuesHandler_h_
+#endif // lldb_AppleGetQueuesHandler_h_
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp Tue Sep 6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- AppleGetThreadItemInfoHandler.cpp -------------------------------*- C++ -*-===//
+//===-- AppleGetThreadItemInfoHandler.cpp -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -35,8 +36,12 @@
using namespace lldb;
using namespace lldb_private;
-const char *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_name = "__lldb_backtrace_recording_get_thread_item_info";
-const char *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_code = " \n\
+const char
+ *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_name =
+ "__lldb_backtrace_recording_get_thread_item_info";
+const char
+ *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_code =
+ " \n\
extern \"C\" \n\
{ \n\
/* \n\
@@ -104,291 +109,311 @@ extern \"C\"
";
AppleGetThreadItemInfoHandler::AppleGetThreadItemInfoHandler(Process *process)
- : m_process(process),
- m_get_thread_item_info_impl_code(),
+ : m_process(process), m_get_thread_item_info_impl_code(),
m_get_thread_item_info_function_mutex(),
m_get_thread_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
- m_get_thread_item_info_retbuffer_mutex()
-{
-}
+ m_get_thread_item_info_retbuffer_mutex() {}
-AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler ()
-{
-}
+AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler() {}
-void
-AppleGetThreadItemInfoHandler::Detach()
-{
-
- if (m_process && m_process->IsAlive() && m_get_thread_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS)
- {
- std::unique_lock<std::mutex> lock(m_get_thread_item_info_retbuffer_mutex, std::defer_lock);
- lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
- m_process->DeallocateMemory(m_get_thread_item_info_return_buffer_addr);
- }
+void AppleGetThreadItemInfoHandler::Detach() {
+
+ if (m_process && m_process->IsAlive() &&
+ m_get_thread_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS) {
+ std::unique_lock<std::mutex> lock(m_get_thread_item_info_retbuffer_mutex,
+ std::defer_lock);
+ lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
+ m_process->DeallocateMemory(m_get_thread_item_info_return_buffer_addr);
+ }
}
-// Compile our __lldb_backtrace_recording_get_thread_item_info() function (from the
-// source above in g_get_thread_item_info_function_code) if we don't find that function in the inferior
-// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for testing.)
+// Compile our __lldb_backtrace_recording_get_thread_item_info() function (from
+// the
+// source above in g_get_thread_item_info_function_code) if we don't find that
+// function in the inferior
+// already with USE_BUILTIN_FUNCTION defined. (e.g. this would be the case for
+// testing.)
+//
+// Insert the __lldb_backtrace_recording_get_thread_item_info into the inferior
+// process if needed.
//
-// Insert the __lldb_backtrace_recording_get_thread_item_info into the inferior process if needed.
+// Write the get_thread_item_info_arglist into the inferior's memory space to
+// prepare for the call.
//
-// Write the get_thread_item_info_arglist into the inferior's memory space to prepare for the call.
-//
-// Returns the address of the arguments written down in the inferior process, which can be used to
+// Returns the address of the arguments written down in the inferior process,
+// which can be used to
// make the function call.
-lldb::addr_t
-AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, ValueList &get_thread_item_info_arglist)
-{
- ThreadSP thread_sp(thread.shared_from_this());
- ExecutionContext exe_ctx (thread_sp);
- Address impl_code_address;
- DiagnosticManager diagnostics;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
- lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
- FunctionCaller *get_thread_item_info_caller = nullptr;
-
- // Scope for mutex locker:
- {
- std::lock_guard<std::mutex> guard(m_get_thread_item_info_function_mutex);
-
- // First stage is to make the ClangUtility to hold our injected function:
-
- if (!m_get_thread_item_info_impl_code.get())
- {
- Error error;
- if (g_get_thread_item_info_function_code != NULL)
- {
- m_get_thread_item_info_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_get_thread_item_info_function_code,
- eLanguageTypeC,
- g_get_thread_item_info_function_name,
- error));
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to get UtilityFunction for get-thread-item-info introspection: %s.",
- error.AsCString());
- m_get_thread_item_info_impl_code.reset();
- return args_addr;
- }
-
- if (!m_get_thread_item_info_impl_code->Install(diagnostics, exe_ctx))
- {
- if (log)
- {
- log->Printf("Failed to install get-thread-item-info introspection.");
- diagnostics.Dump(log);
- }
-
- m_get_thread_item_info_impl_code.reset();
- return args_addr;
- }
- }
- else
- {
- if (log)
- log->Printf("No get-thread-item-info introspection code found.");
- return LLDB_INVALID_ADDRESS;
- }
-
- // Also make the FunctionCaller for this UtilityFunction:
-
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_thread_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-
- get_thread_item_info_caller = m_get_thread_item_info_impl_code->MakeFunctionCaller (get_thread_item_info_return_type,
- get_thread_item_info_arglist,
- thread_sp,
- error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("Failed to install get-thread-item-info introspection caller: %s.", error.AsCString());
- m_get_thread_item_info_impl_code.reset();
- return args_addr;
- }
-
- }
- else
- {
- get_thread_item_info_caller = m_get_thread_item_info_impl_code->GetFunctionCaller();
+lldb::addr_t AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction(
+ Thread &thread, ValueList &get_thread_item_info_arglist) {
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx(thread_sp);
+ Address impl_code_address;
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+ lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *get_thread_item_info_caller = nullptr;
+
+ // Scope for mutex locker:
+ {
+ std::lock_guard<std::mutex> guard(m_get_thread_item_info_function_mutex);
+
+ // First stage is to make the ClangUtility to hold our injected function:
+
+ if (!m_get_thread_item_info_impl_code.get()) {
+ Error error;
+ if (g_get_thread_item_info_function_code != NULL) {
+ m_get_thread_item_info_impl_code.reset(
+ exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
+ g_get_thread_item_info_function_code, eLanguageTypeC,
+ g_get_thread_item_info_function_name, error));
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Failed to get UtilityFunction for "
+ "get-thread-item-info introspection: %s.",
+ error.AsCString());
+ m_get_thread_item_info_impl_code.reset();
+ return args_addr;
}
- }
-
- diagnostics.Clear();
- // Now write down the argument values for this particular call. This looks like it might be a race condition
- // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
- // this call by passing args_addr = LLDB_INVALID_ADDRESS...
-
- if (!get_thread_item_info_caller->WriteFunctionArguments(exe_ctx, args_addr, get_thread_item_info_arglist,
- diagnostics))
- {
- if (log)
- {
- log->Printf("Error writing get-thread-item-info function arguments");
+ if (!m_get_thread_item_info_impl_code->Install(diagnostics, exe_ctx)) {
+ if (log) {
+ log->Printf(
+ "Failed to install get-thread-item-info introspection.");
diagnostics.Dump(log);
+ }
+
+ m_get_thread_item_info_impl_code.reset();
+ return args_addr;
}
+ } else {
+ if (log)
+ log->Printf("No get-thread-item-info introspection code found.");
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // Also make the FunctionCaller for this UtilityFunction:
+
+ ClangASTContext *clang_ast_context =
+ thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+ CompilerType get_thread_item_info_return_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ get_thread_item_info_caller =
+ m_get_thread_item_info_impl_code->MakeFunctionCaller(
+ get_thread_item_info_return_type, get_thread_item_info_arglist,
+ thread_sp, error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("Failed to install get-thread-item-info introspection "
+ "caller: %s.",
+ error.AsCString());
+ m_get_thread_item_info_impl_code.reset();
return args_addr;
+ }
+
+ } else {
+ get_thread_item_info_caller =
+ m_get_thread_item_info_impl_code->GetFunctionCaller();
}
+ }
+
+ diagnostics.Clear();
+ // Now write down the argument values for this particular call. This looks
+ // like it might be a race condition
+ // if other threads were calling into here, but actually it isn't because we
+ // allocate a new args structure for
+ // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+ if (!get_thread_item_info_caller->WriteFunctionArguments(
+ exe_ctx, args_addr, get_thread_item_info_arglist, diagnostics)) {
+ if (log) {
+ log->Printf("Error writing get-thread-item-info function arguments");
+ diagnostics.Dump(log);
+ }
return args_addr;
+ }
+
+ return args_addr;
}
AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo
-AppleGetThreadItemInfoHandler::GetThreadItemInfo (Thread &thread, tid_t thread_id, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
-{
- lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
- ProcessSP process_sp (thread.CalculateProcess());
- TargetSP target_sp (thread.CalculateTarget());
- ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+AppleGetThreadItemInfoHandler::GetThreadItemInfo(Thread &thread,
+ tid_t thread_id,
+ addr_t page_to_free,
+ uint64_t page_to_free_size,
+ Error &error) {
+ lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+ ProcessSP process_sp(thread.CalculateProcess());
+ TargetSP target_sp(thread.CalculateTarget());
+ ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+ GetThreadItemInfoReturnInfo return_value;
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return_value.item_buffer_size = 0;
- GetThreadItemInfoReturnInfo return_value;
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return_value.item_buffer_size = 0;
-
- error.Clear();
+ error.Clear();
- if (thread.SafeToCallFunctions() == false)
- {
- if (log)
- log->Printf ("Not safe to call functions on thread 0x%" PRIx64, thread.GetID());
- error.SetErrorString ("Not safe to call functions on this thread.");
- return return_value;
- }
+ if (thread.SafeToCallFunctions() == false) {
+ if (log)
+ log->Printf("Not safe to call functions on thread 0x%" PRIx64,
+ thread.GetID());
+ error.SetErrorString("Not safe to call functions on this thread.");
+ return return_value;
+ }
- // Set up the arguments for a call to
+ // Set up the arguments for a call to
- // struct get_thread_item_info_return_values
- // {
- // uint64_t item_info_buffer_ptr; /* the address of the items buffer from libBacktraceRecording */
- // uint64_t item_info_buffer_size; /* the size of the items buffer from libBacktraceRecording */
- // };
- //
- // void __lldb_backtrace_recording_get_thread_item_info
- // (struct get_thread_item_info_return_values *return_buffer,
- // int debug,
- // void *page_to_free,
- // uint64_t page_to_free_size)
-
- // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
- // the inferior process.
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Value return_buffer_ptr_value;
- return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
- return_buffer_ptr_value.SetCompilerType (clang_void_ptr_type);
-
- CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
- Value debug_value;
- debug_value.SetValueType (Value::eValueTypeScalar);
- debug_value.SetCompilerType (clang_int_type);
-
- CompilerType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
- Value thread_id_value;
- thread_id_value.SetValueType (Value::eValueTypeScalar);
- thread_id_value.SetCompilerType (clang_uint64_type);
-
- Value page_to_free_value;
- page_to_free_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_value.SetCompilerType (clang_void_ptr_type);
-
- Value page_to_free_size_value;
- page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
- page_to_free_size_value.SetCompilerType (clang_uint64_type);
-
- std::lock_guard<std::mutex> guard(m_get_thread_item_info_retbuffer_mutex);
- if (m_get_thread_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS)
- {
- addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
- if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
- return return_value;
- }
- m_get_thread_item_info_return_buffer_addr = bufaddr;
+ // struct get_thread_item_info_return_values
+ // {
+ // uint64_t item_info_buffer_ptr; /* the address of the items buffer
+ // from libBacktraceRecording */
+ // uint64_t item_info_buffer_size; /* the size of the items buffer from
+ // libBacktraceRecording */
+ // };
+ //
+ // void __lldb_backtrace_recording_get_thread_item_info
+ // (struct
+ // get_thread_item_info_return_values
+ // *return_buffer,
+ // int debug,
+ // void *page_to_free,
+ // uint64_t page_to_free_size)
+
+ // Where the return_buffer argument points to a 24 byte region of memory
+ // already allocated by lldb in
+ // the inferior process.
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Value return_buffer_ptr_value;
+ return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+ return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
+
+ CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+ Value debug_value;
+ debug_value.SetValueType(Value::eValueTypeScalar);
+ debug_value.SetCompilerType(clang_int_type);
+
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+ Value thread_id_value;
+ thread_id_value.SetValueType(Value::eValueTypeScalar);
+ thread_id_value.SetCompilerType(clang_uint64_type);
+
+ Value page_to_free_value;
+ page_to_free_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_value.SetCompilerType(clang_void_ptr_type);
+
+ Value page_to_free_size_value;
+ page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+ page_to_free_size_value.SetCompilerType(clang_uint64_type);
+
+ std::lock_guard<std::mutex> guard(m_get_thread_item_info_retbuffer_mutex);
+ if (m_get_thread_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS) {
+ addr_t bufaddr = process_sp->AllocateMemory(
+ 32, ePermissionsReadable | ePermissionsWritable, error);
+ if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Failed to allocate memory for return buffer for get "
+ "current queues func call");
+ return return_value;
}
+ m_get_thread_item_info_return_buffer_addr = bufaddr;
+ }
- ValueList argument_values;
-
- return_buffer_ptr_value.GetScalar() = m_get_thread_item_info_return_buffer_addr;
- argument_values.PushValue (return_buffer_ptr_value);
+ ValueList argument_values;
- debug_value.GetScalar() = 0;
- argument_values.PushValue (debug_value);
-
- thread_id_value.GetScalar() = thread_id;
- argument_values.PushValue (thread_id_value);
-
- if (page_to_free != LLDB_INVALID_ADDRESS)
- page_to_free_value.GetScalar() = page_to_free;
- else
- page_to_free_value.GetScalar() = 0;
- argument_values.PushValue (page_to_free_value);
-
- page_to_free_size_value.GetScalar() = page_to_free_size;
- argument_values.PushValue (page_to_free_size_value);
-
- addr_t args_addr = SetupGetThreadItemInfoFunction(thread, argument_values);
-
- DiagnosticManager diagnostics;
- ExecutionContext exe_ctx;
- EvaluateExpressionOptions options;
- FunctionCaller *get_thread_item_info_caller = nullptr;
-
- options.SetUnwindOnError (true);
- options.SetIgnoreBreakpoints (true);
- options.SetStopOthers (true);
- options.SetTimeoutUsec(500000);
- options.SetTryAllThreads (false);
- thread.CalculateExecutionContext (exe_ctx);
-
- if (!m_get_thread_item_info_impl_code)
- {
- error.SetErrorString ("Unable to compile function to call __introspection_dispatch_thread_get_item_info");
- return return_value;
- }
+ return_buffer_ptr_value.GetScalar() =
+ m_get_thread_item_info_return_buffer_addr;
+ argument_values.PushValue(return_buffer_ptr_value);
+
+ debug_value.GetScalar() = 0;
+ argument_values.PushValue(debug_value);
+
+ thread_id_value.GetScalar() = thread_id;
+ argument_values.PushValue(thread_id_value);
+
+ if (page_to_free != LLDB_INVALID_ADDRESS)
+ page_to_free_value.GetScalar() = page_to_free;
+ else
+ page_to_free_value.GetScalar() = 0;
+ argument_values.PushValue(page_to_free_value);
+
+ page_to_free_size_value.GetScalar() = page_to_free_size;
+ argument_values.PushValue(page_to_free_size_value);
+
+ addr_t args_addr = SetupGetThreadItemInfoFunction(thread, argument_values);
+
+ DiagnosticManager diagnostics;
+ ExecutionContext exe_ctx;
+ EvaluateExpressionOptions options;
+ FunctionCaller *get_thread_item_info_caller = nullptr;
+
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetStopOthers(true);
+ options.SetTimeoutUsec(500000);
+ options.SetTryAllThreads(false);
+ thread.CalculateExecutionContext(exe_ctx);
+
+ if (!m_get_thread_item_info_impl_code) {
+ error.SetErrorString("Unable to compile function to call "
+ "__introspection_dispatch_thread_get_item_info");
+ return return_value;
+ }
- get_thread_item_info_caller = m_get_thread_item_info_impl_code->GetFunctionCaller();
+ get_thread_item_info_caller =
+ m_get_thread_item_info_impl_code->GetFunctionCaller();
- if (!get_thread_item_info_caller)
- {
- error.SetErrorString ("Unable to compile function caller for __introspection_dispatch_thread_get_item_info");
- return return_value;
- }
+ if (!get_thread_item_info_caller) {
+ error.SetErrorString("Unable to compile function caller for "
+ "__introspection_dispatch_thread_get_item_info");
+ return return_value;
+ }
- ExpressionResults func_call_ret;
- Value results;
- func_call_ret = get_thread_item_info_caller->ExecuteFunction(exe_ctx, &args_addr, options, diagnostics, results);
- if (func_call_ret != eExpressionCompleted || !error.Success())
- {
- if (log)
- log->Printf ("Unable to call __introspection_dispatch_thread_get_item_info(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
- error.SetErrorString ("Unable to call __introspection_dispatch_thread_get_item_info() for list of queues");
- return return_value;
- }
+ ExpressionResults func_call_ret;
+ Value results;
+ func_call_ret = get_thread_item_info_caller->ExecuteFunction(
+ exe_ctx, &args_addr, options, diagnostics, results);
+ if (func_call_ret != eExpressionCompleted || !error.Success()) {
+ if (log)
+ log->Printf("Unable to call "
+ "__introspection_dispatch_thread_get_item_info(), got "
+ "ExpressionResults %d, error contains %s",
+ func_call_ret, error.AsCString(""));
+ error.SetErrorString("Unable to call "
+ "__introspection_dispatch_thread_get_item_info() for "
+ "list of queues");
+ return return_value;
+ }
- return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_thread_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
- if (!error.Success() || return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS)
- {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_thread_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS,
+ error);
+ if (!error.Success() ||
+ return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS) {
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_thread_item_info_return_buffer_addr + 8, 8, 0, error);
+ return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
+ m_get_thread_item_info_return_buffer_addr + 8, 8, 0, error);
- if (!error.Success())
- {
- return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
- return return_value;
- }
+ if (!error.Success()) {
+ return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+ return return_value;
+ }
- if (log)
- log->Printf ("AppleGetThreadItemInfoHandler called __introspection_dispatch_thread_get_item_info (page_to_free == 0x%" PRIx64 ", size = %" PRId64 "), returned page is at 0x%" PRIx64 ", size %" PRId64, page_to_free, page_to_free_size, return_value.item_buffer_ptr, return_value.item_buffer_size);
+ if (log)
+ log->Printf("AppleGetThreadItemInfoHandler called "
+ "__introspection_dispatch_thread_get_item_info (page_to_free "
+ "== 0x%" PRIx64 ", size = %" PRId64
+ "), returned page is at 0x%" PRIx64 ", size %" PRId64,
+ page_to_free, page_to_free_size, return_value.item_buffer_ptr,
+ return_value.item_buffer_size);
- return return_value;
+ return return_value;
}
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h Tue Sep 6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- AppleGetThreadItemInfoHandler.h ----------------------------*- C++ -*-===//
+//===-- AppleGetThreadItemInfoHandler.h ----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,12 +19,13 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-public.h"
// This class will insert a UtilityFunction into the inferior process for
-// calling libBacktraceRecording's __introspection_dispatch_thread_get_item_info()
+// calling libBacktraceRecording's
+// __introspection_dispatch_thread_get_item_info()
// function. The function in the inferior will return a struct by value
// with these members:
//
@@ -35,79 +37,82 @@
//
// The item_buffer pointer is an address in the inferior program's address
// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
-// lldb.
+// lldb.
//
-// The AppleGetThreadItemInfoHandler object should persist so that the UtilityFunction
+// The AppleGetThreadItemInfoHandler object should persist so that the
+// UtilityFunction
// can be reused multiple times.
-namespace lldb_private
-{
+namespace lldb_private {
class AppleGetThreadItemInfoHandler {
public:
+ AppleGetThreadItemInfoHandler(lldb_private::Process *process);
- AppleGetThreadItemInfoHandler (lldb_private::Process *process);
-
- ~AppleGetThreadItemInfoHandler();
-
- struct GetThreadItemInfoReturnInfo
- {
- lldb::addr_t item_buffer_ptr; /* the address of the item buffer from libBacktraceRecording */
- lldb::addr_t item_buffer_size; /* the size of the item buffer from libBacktraceRecording */
-
- GetThreadItemInfoReturnInfo() :
- item_buffer_ptr(LLDB_INVALID_ADDRESS),
- item_buffer_size(0)
- {}
- };
-
- //----------------------------------------------------------
- /// Get the information about a work item by calling
- /// __introspection_dispatch_thread_get_item_info. If there's a page of
- /// memory that needs to be freed, pass in the address and size and it will
- /// be freed before getting the list of queues.
- ///
- /// @param [in] thread_id
- /// The thread to get the extended backtrace for.
- ///
- /// @param [in] page_to_free
- /// An address of an inferior process vm page that needs to be deallocated,
- /// LLDB_INVALID_ADDRESS if this is not needed.
- ///
- /// @param [in] page_to_free_size
- /// The size of the vm page that needs to be deallocated if an address was
- /// passed in to page_to_free.
- ///
- /// @param [out] error
- /// This object will be updated with the error status / error string from any failures encountered.
- ///
- /// @returns
- /// The result of the inferior function call execution. If there was a failure of any kind while getting
- /// the information, the item_buffer_ptr value will be LLDB_INVALID_ADDRESS.
- //----------------------------------------------------------
- GetThreadItemInfoReturnInfo
- GetThreadItemInfo (Thread &thread, lldb::tid_t thread_id, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
+ ~AppleGetThreadItemInfoHandler();
+ struct GetThreadItemInfoReturnInfo {
+ lldb::addr_t item_buffer_ptr; /* the address of the item buffer from
+ libBacktraceRecording */
+ lldb::addr_t item_buffer_size; /* the size of the item buffer from
+ libBacktraceRecording */
+
+ GetThreadItemInfoReturnInfo()
+ : item_buffer_ptr(LLDB_INVALID_ADDRESS), item_buffer_size(0) {}
+ };
+
+ //----------------------------------------------------------
+ /// Get the information about a work item by calling
+ /// __introspection_dispatch_thread_get_item_info. If there's a page of
+ /// memory that needs to be freed, pass in the address and size and it will
+ /// be freed before getting the list of queues.
+ ///
+ /// @param [in] thread_id
+ /// The thread to get the extended backtrace for.
+ ///
+ /// @param [in] page_to_free
+ /// An address of an inferior process vm page that needs to be
+ /// deallocated,
+ /// LLDB_INVALID_ADDRESS if this is not needed.
+ ///
+ /// @param [in] page_to_free_size
+ /// The size of the vm page that needs to be deallocated if an address was
+ /// passed in to page_to_free.
+ ///
+ /// @param [out] error
+ /// This object will be updated with the error status / error string from
+ /// any failures encountered.
+ ///
+ /// @returns
+ /// The result of the inferior function call execution. If there was a
+ /// failure of any kind while getting
+ /// the information, the item_buffer_ptr value will be
+ /// LLDB_INVALID_ADDRESS.
+ //----------------------------------------------------------
+ GetThreadItemInfoReturnInfo GetThreadItemInfo(Thread &thread,
+ lldb::tid_t thread_id,
+ lldb::addr_t page_to_free,
+ uint64_t page_to_free_size,
+ lldb_private::Error &error);
- void
- Detach ();
+ void Detach();
private:
+ lldb::addr_t
+ SetupGetThreadItemInfoFunction(Thread &thread,
+ ValueList &get_thread_item_info_arglist);
+
+ static const char *g_get_thread_item_info_function_name;
+ static const char *g_get_thread_item_info_function_code;
+
+ lldb_private::Process *m_process;
+ std::unique_ptr<UtilityFunction> m_get_thread_item_info_impl_code;
+ std::mutex m_get_thread_item_info_function_mutex;
- lldb::addr_t
- SetupGetThreadItemInfoFunction (Thread &thread, ValueList &get_thread_item_info_arglist);
-
- static const char *g_get_thread_item_info_function_name;
- static const char *g_get_thread_item_info_function_code;
-
- lldb_private::Process *m_process;
- std::unique_ptr<UtilityFunction> m_get_thread_item_info_impl_code;
- std::mutex m_get_thread_item_info_function_mutex;
-
- lldb::addr_t m_get_thread_item_info_return_buffer_addr;
- std::mutex m_get_thread_item_info_retbuffer_mutex;
+ lldb::addr_t m_get_thread_item_info_return_buffer_addr;
+ std::mutex m_get_thread_item_info_retbuffer_mutex;
};
-} // using namespace lldb_private
+} // using namespace lldb_private
-#endif // lldb_AppleGetThreadItemInfoHandler_h_
+#endif // lldb_AppleGetThreadItemInfoHandler_h_
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp Tue Sep 6 15:57:50 2016
@@ -7,26 +7,25 @@
//
//===----------------------------------------------------------------------===//
-
+#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
-#include "Plugins/Process/Utility/HistoryThread.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/Queue.h"
#include "lldb/Target/QueueList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/Process.h"
#include "lldb/Utility/ProcessStructReader.h"
#include "SystemRuntimeMacOSX.h"
@@ -39,397 +38,380 @@ using namespace lldb_private;
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
-SystemRuntime *
-SystemRuntimeMacOSX::CreateInstance (Process* process)
-{
- bool create = false;
- if (!create)
- {
- create = true;
- Module* exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- create = (object_file->GetStrata() == ObjectFile::eStrataUser);
- }
- }
-
- if (create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
- }
- }
-
- if (create)
- return new SystemRuntimeMacOSX (process);
- return NULL;
+SystemRuntime *SystemRuntimeMacOSX::CreateInstance(Process *process) {
+ bool create = false;
+ if (!create) {
+ create = true;
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ create = (object_file->GetStrata() == ObjectFile::eStrataUser);
+ }
+ }
+
+ if (create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ create = triple_ref.getVendor() == llvm::Triple::Apple;
+ break;
+ default:
+ create = false;
+ break;
+ }
+ }
+ }
+
+ if (create)
+ return new SystemRuntimeMacOSX(process);
+ return NULL;
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
SystemRuntimeMacOSX::SystemRuntimeMacOSX(Process *process)
- : SystemRuntime(process),
- m_break_id(LLDB_INVALID_BREAK_ID),
- m_mutex(),
- m_get_queues_handler(process),
- m_get_pending_items_handler(process),
- m_get_item_info_handler(process),
- m_get_thread_item_info_handler(process),
- m_page_to_free(LLDB_INVALID_ADDRESS),
- m_page_to_free_size(0),
+ : SystemRuntime(process), m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
+ m_get_queues_handler(process), m_get_pending_items_handler(process),
+ m_get_item_info_handler(process), m_get_thread_item_info_handler(process),
+ m_page_to_free(LLDB_INVALID_ADDRESS), m_page_to_free_size(0),
m_lib_backtrace_recording_info(),
m_dispatch_queue_offsets_addr(LLDB_INVALID_ADDRESS),
m_libdispatch_offsets(),
m_libpthread_layout_offsets_addr(LLDB_INVALID_ADDRESS),
- m_libpthread_offsets(),
- m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
+ m_libpthread_offsets(), m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
m_libdispatch_tsd_indexes(),
m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
- m_libdispatch_voucher_offsets()
-{
-}
+ m_libdispatch_voucher_offsets() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-SystemRuntimeMacOSX::~SystemRuntimeMacOSX()
-{
- Clear (true);
-}
+SystemRuntimeMacOSX::~SystemRuntimeMacOSX() { Clear(true); }
-void
-SystemRuntimeMacOSX::Detach ()
-{
- m_get_queues_handler.Detach();
- m_get_pending_items_handler.Detach();
- m_get_item_info_handler.Detach();
- m_get_thread_item_info_handler.Detach();
+void SystemRuntimeMacOSX::Detach() {
+ m_get_queues_handler.Detach();
+ m_get_pending_items_handler.Detach();
+ m_get_item_info_handler.Detach();
+ m_get_thread_item_info_handler.Detach();
}
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
-void
-SystemRuntimeMacOSX::Clear (bool clear_process)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->ClearBreakpointSiteByID(m_break_id);
-
- if (clear_process)
- m_process = NULL;
- m_break_id = LLDB_INVALID_BREAK_ID;
-}
+void SystemRuntimeMacOSX::Clear(bool clear_process) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->ClearBreakpointSiteByID(m_break_id);
-std::string
-SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress (addr_t dispatch_qaddr)
-{
- std::string dispatch_queue_name;
- if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
- return "";
-
- ReadLibdispatchOffsets ();
- if (m_libdispatch_offsets.IsValid ())
- {
- // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a thread -
- // deref it to get the address of the dispatch_queue_t structure for this thread's
- // queue.
- Error error;
- addr_t dispatch_queue_addr = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
- if (error.Success())
- {
- if (m_libdispatch_offsets.dqo_version >= 4)
- {
- // libdispatch versions 4+, pointer to dispatch name is in the
- // queue structure.
- addr_t pointer_to_label_address = dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
- addr_t label_addr = m_process->ReadPointerFromMemory (pointer_to_label_address, error);
- if (error.Success())
- {
- m_process->ReadCStringFromMemory (label_addr, dispatch_queue_name, error);
- }
- }
- else
- {
- // libdispatch versions 1-3, dispatch name is a fixed width char array
- // in the queue structure.
- addr_t label_addr = dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
- dispatch_queue_name.resize (m_libdispatch_offsets.dqo_label_size, '\0');
- size_t bytes_read = m_process->ReadMemory (label_addr, &dispatch_queue_name[0], m_libdispatch_offsets.dqo_label_size, error);
- if (bytes_read < m_libdispatch_offsets.dqo_label_size)
- dispatch_queue_name.erase (bytes_read);
- }
- }
- }
- return dispatch_queue_name;
+ if (clear_process)
+ m_process = NULL;
+ m_break_id = LLDB_INVALID_BREAK_ID;
}
-lldb::addr_t
-SystemRuntimeMacOSX::GetLibdispatchQueueAddressFromThreadQAddress (addr_t dispatch_qaddr)
-{
- addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
+std::string
+SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress(addr_t dispatch_qaddr) {
+ std::string dispatch_queue_name;
+ if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
+ return "";
+
+ ReadLibdispatchOffsets();
+ if (m_libdispatch_offsets.IsValid()) {
+ // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
+ // thread -
+ // deref it to get the address of the dispatch_queue_t structure for this
+ // thread's
+ // queue.
Error error;
- libdispatch_queue_t_address = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
- if (!error.Success())
- {
- libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
- }
- return libdispatch_queue_t_address;
-}
-
-lldb::QueueKind
-SystemRuntimeMacOSX::GetQueueKind (addr_t dispatch_queue_addr)
-{
- if (dispatch_queue_addr == LLDB_INVALID_ADDRESS || dispatch_queue_addr == 0)
- return eQueueKindUnknown;
-
- QueueKind kind = eQueueKindUnknown;
- ReadLibdispatchOffsets ();
- if (m_libdispatch_offsets.IsValid () && m_libdispatch_offsets.dqo_version >= 4)
- {
- Error error;
- uint64_t width = m_process->ReadUnsignedIntegerFromMemory (dispatch_queue_addr + m_libdispatch_offsets.dqo_width, m_libdispatch_offsets.dqo_width_size, 0, error);
- if (error.Success())
- {
- if (width == 1)
- {
- kind = eQueueKindSerial;
- }
- if (width > 1)
- {
- kind = eQueueKindConcurrent;
- }
- }
- }
- return kind;
-}
-
-void
-SystemRuntimeMacOSX::AddThreadExtendedInfoPacketHints (lldb_private::StructuredData::ObjectSP dict_sp)
-{
- StructuredData::Dictionary *dict = dict_sp->GetAsDictionary();
- if (dict)
- {
- ReadLibpthreadOffsets();
- if (m_libpthread_offsets.IsValid())
- {
- dict->AddIntegerItem ("plo_pthread_tsd_base_offset", m_libpthread_offsets.plo_pthread_tsd_base_offset);
- dict->AddIntegerItem ("plo_pthread_tsd_base_address_offset", m_libpthread_offsets.plo_pthread_tsd_base_address_offset);
- dict->AddIntegerItem ("plo_pthread_tsd_entry_size", m_libpthread_offsets.plo_pthread_tsd_entry_size);
- }
-
- ReadLibdispatchTSDIndexes ();
- if (m_libdispatch_tsd_indexes.IsValid())
- {
- dict->AddIntegerItem ("dti_queue_index", m_libdispatch_tsd_indexes.dti_queue_index);
- dict->AddIntegerItem ("dti_voucher_index", m_libdispatch_tsd_indexes.dti_voucher_index);
- dict->AddIntegerItem ("dti_qos_class_index", m_libdispatch_tsd_indexes.dti_qos_class_index);
- }
- }
-}
-
-bool
-SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread (ThreadSP thread_sp)
-{
- if (thread_sp && thread_sp->GetStackFrameCount() > 0 && thread_sp->GetFrameWithConcreteFrameIndex(0))
- {
- const SymbolContext sym_ctx (thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext (eSymbolContextSymbol));
- static ConstString g_select_symbol ("__select");
- if (sym_ctx.GetFunctionName() == g_select_symbol)
- {
- return false;
- }
+ addr_t dispatch_queue_addr =
+ m_process->ReadPointerFromMemory(dispatch_qaddr, error);
+ if (error.Success()) {
+ if (m_libdispatch_offsets.dqo_version >= 4) {
+ // libdispatch versions 4+, pointer to dispatch name is in the
+ // queue structure.
+ addr_t pointer_to_label_address =
+ dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
+ addr_t label_addr =
+ m_process->ReadPointerFromMemory(pointer_to_label_address, error);
+ if (error.Success()) {
+ m_process->ReadCStringFromMemory(label_addr, dispatch_queue_name,
+ error);
+ }
+ } else {
+ // libdispatch versions 1-3, dispatch name is a fixed width char array
+ // in the queue structure.
+ addr_t label_addr =
+ dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
+ dispatch_queue_name.resize(m_libdispatch_offsets.dqo_label_size, '\0');
+ size_t bytes_read =
+ m_process->ReadMemory(label_addr, &dispatch_queue_name[0],
+ m_libdispatch_offsets.dqo_label_size, error);
+ if (bytes_read < m_libdispatch_offsets.dqo_label_size)
+ dispatch_queue_name.erase(bytes_read);
+ }
+ }
+ }
+ return dispatch_queue_name;
+}
+
+lldb::addr_t SystemRuntimeMacOSX::GetLibdispatchQueueAddressFromThreadQAddress(
+ addr_t dispatch_qaddr) {
+ addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
+ Error error;
+ libdispatch_queue_t_address =
+ m_process->ReadPointerFromMemory(dispatch_qaddr, error);
+ if (!error.Success()) {
+ libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
+ }
+ return libdispatch_queue_t_address;
+}
+
+lldb::QueueKind SystemRuntimeMacOSX::GetQueueKind(addr_t dispatch_queue_addr) {
+ if (dispatch_queue_addr == LLDB_INVALID_ADDRESS || dispatch_queue_addr == 0)
+ return eQueueKindUnknown;
+
+ QueueKind kind = eQueueKindUnknown;
+ ReadLibdispatchOffsets();
+ if (m_libdispatch_offsets.IsValid() &&
+ m_libdispatch_offsets.dqo_version >= 4) {
+ Error error;
+ uint64_t width = m_process->ReadUnsignedIntegerFromMemory(
+ dispatch_queue_addr + m_libdispatch_offsets.dqo_width,
+ m_libdispatch_offsets.dqo_width_size, 0, error);
+ if (error.Success()) {
+ if (width == 1) {
+ kind = eQueueKindSerial;
+ }
+ if (width > 1) {
+ kind = eQueueKindConcurrent;
+ }
+ }
+ }
+ return kind;
+}
+
+void SystemRuntimeMacOSX::AddThreadExtendedInfoPacketHints(
+ lldb_private::StructuredData::ObjectSP dict_sp) {
+ StructuredData::Dictionary *dict = dict_sp->GetAsDictionary();
+ if (dict) {
+ ReadLibpthreadOffsets();
+ if (m_libpthread_offsets.IsValid()) {
+ dict->AddIntegerItem("plo_pthread_tsd_base_offset",
+ m_libpthread_offsets.plo_pthread_tsd_base_offset);
+ dict->AddIntegerItem(
+ "plo_pthread_tsd_base_address_offset",
+ m_libpthread_offsets.plo_pthread_tsd_base_address_offset);
+ dict->AddIntegerItem("plo_pthread_tsd_entry_size",
+ m_libpthread_offsets.plo_pthread_tsd_entry_size);
+ }
+
+ ReadLibdispatchTSDIndexes();
+ if (m_libdispatch_tsd_indexes.IsValid()) {
+ dict->AddIntegerItem("dti_queue_index",
+ m_libdispatch_tsd_indexes.dti_queue_index);
+ dict->AddIntegerItem("dti_voucher_index",
+ m_libdispatch_tsd_indexes.dti_voucher_index);
+ dict->AddIntegerItem("dti_qos_class_index",
+ m_libdispatch_tsd_indexes.dti_qos_class_index);
+ }
+ }
+}
+
+bool SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread(ThreadSP thread_sp) {
+ if (thread_sp && thread_sp->GetStackFrameCount() > 0 &&
+ thread_sp->GetFrameWithConcreteFrameIndex(0)) {
+ const SymbolContext sym_ctx(
+ thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext(
+ eSymbolContextSymbol));
+ static ConstString g_select_symbol("__select");
+ if (sym_ctx.GetFunctionName() == g_select_symbol) {
+ return false;
}
- return true;
+ }
+ return true;
}
lldb::queue_id_t
-SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress (lldb::addr_t dispatch_qaddr)
-{
- queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;
-
- if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
- return queue_id;
-
- ReadLibdispatchOffsets ();
- if (m_libdispatch_offsets.IsValid ())
- {
- // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a thread -
- // deref it to get the address of the dispatch_queue_t structure for this thread's
- // queue.
- Error error;
- uint64_t dispatch_queue_addr = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
- if (error.Success())
- {
- addr_t serialnum_address = dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
- queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory (serialnum_address, m_libdispatch_offsets.dqo_serialnum_size, LLDB_INVALID_QUEUE_ID, error);
- if (error.Success())
- {
- queue_id = serialnum;
- }
- }
- }
+SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
+ queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;
+ if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
return queue_id;
-}
-
-
-void
-SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress ()
-{
- if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
- return;
-
- static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
- const Symbol *dispatch_queue_offsets_symbol = NULL;
-
- // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6 ("Snow Leopard")
- ModuleSpec libSystem_module_spec (FileSpec("libSystem.B.dylib", false));
- ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule (libSystem_module_spec));
- if (module_sp)
- dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
-
- // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion") and later
- if (dispatch_queue_offsets_symbol == NULL)
- {
- ModuleSpec libdispatch_module_spec (FileSpec("libdispatch.dylib", false));
- module_sp = m_process->GetTarget().GetImages().FindFirstModule (libdispatch_module_spec);
- if (module_sp)
- dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
- }
- if (dispatch_queue_offsets_symbol)
- m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
-}
-
-void
-SystemRuntimeMacOSX::ReadLibdispatchOffsets ()
-{
- if (m_libdispatch_offsets.IsValid())
- return;
-
- ReadLibdispatchOffsetsAddress ();
-
- uint8_t memory_buffer[sizeof (struct LibdispatchOffsets)];
- DataExtractor data (memory_buffer,
- sizeof(memory_buffer),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
+ ReadLibdispatchOffsets();
+ if (m_libdispatch_offsets.IsValid()) {
+ // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
+ // thread -
+ // deref it to get the address of the dispatch_queue_t structure for this
+ // thread's
+ // queue.
Error error;
- if (m_process->ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer))
- {
- lldb::offset_t data_offset = 0;
-
- // The struct LibdispatchOffsets is a series of uint16_t's - extract them all
- // in one big go.
- data.GetU16 (&data_offset, &m_libdispatch_offsets.dqo_version, sizeof (struct LibdispatchOffsets) / sizeof (uint16_t));
- }
-}
-
-void
-SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress ()
-{
- if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
- return;
-
- static ConstString g_libpthread_layout_offsets_symbol_name ("pthread_layout_offsets");
- const Symbol *libpthread_layout_offsets_symbol = NULL;
-
- ModuleSpec libpthread_module_spec (FileSpec("libsystem_pthread.dylib", false));
- ModuleSP module_sp (m_process->GetTarget().GetImages().FindFirstModule (libpthread_module_spec));
+ uint64_t dispatch_queue_addr =
+ m_process->ReadPointerFromMemory(dispatch_qaddr, error);
+ if (error.Success()) {
+ addr_t serialnum_address =
+ dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
+ queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory(
+ serialnum_address, m_libdispatch_offsets.dqo_serialnum_size,
+ LLDB_INVALID_QUEUE_ID, error);
+ if (error.Success()) {
+ queue_id = serialnum;
+ }
+ }
+ }
+
+ return queue_id;
+}
+
+void SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress() {
+ if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
+ return;
+
+ static ConstString g_dispatch_queue_offsets_symbol_name(
+ "dispatch_queue_offsets");
+ const Symbol *dispatch_queue_offsets_symbol = NULL;
+
+ // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6
+ // ("Snow Leopard")
+ ModuleSpec libSystem_module_spec(FileSpec("libSystem.B.dylib", false));
+ ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
+ libSystem_module_spec));
+ if (module_sp)
+ dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
+ g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
+
+ // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion") and
+ // later
+ if (dispatch_queue_offsets_symbol == NULL) {
+ ModuleSpec libdispatch_module_spec(FileSpec("libdispatch.dylib", false));
+ module_sp = m_process->GetTarget().GetImages().FindFirstModule(
+ libdispatch_module_spec);
if (module_sp)
- {
- libpthread_layout_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType
- (g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
- if (libpthread_layout_offsets_symbol)
- {
- m_libpthread_layout_offsets_addr = libpthread_layout_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
- }
- }
-}
-
-void
-SystemRuntimeMacOSX::ReadLibpthreadOffsets ()
-{
- if (m_libpthread_offsets.IsValid())
- return;
-
- ReadLibpthreadOffsetsAddress ();
-
- if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
- {
- uint8_t memory_buffer[sizeof (struct LibpthreadOffsets)];
- DataExtractor data (memory_buffer,
- sizeof(memory_buffer),
- m_process->GetByteOrder(),
- m_process->GetAddressByteSize());
- Error error;
- if (m_process->ReadMemory (m_libpthread_layout_offsets_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer))
- {
- lldb::offset_t data_offset = 0;
-
- // The struct LibpthreadOffsets is a series of uint16_t's - extract them all
- // in one big go.
- data.GetU16 (&data_offset, &m_libpthread_offsets.plo_version, sizeof (struct LibpthreadOffsets) / sizeof (uint16_t));
- }
- }
-}
-
-void
-SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress ()
-{
- if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
- return;
-
- static ConstString g_libdispatch_tsd_indexes_symbol_name ("dispatch_tsd_indexes");
- const Symbol *libdispatch_tsd_indexes_symbol = NULL;
-
- ModuleSpec libpthread_module_spec (FileSpec("libdispatch.dylib", false));
- ModuleSP module_sp (m_process->GetTarget().GetImages().FindFirstModule (libpthread_module_spec));
- if (module_sp)
- {
- libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType
- (g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
- if (libdispatch_tsd_indexes_symbol)
- {
- m_dispatch_tsd_indexes_addr = libdispatch_tsd_indexes_symbol->GetLoadAddress(&m_process->GetTarget());
- }
- }
-}
-
-void
-SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes ()
-{
- if (m_libdispatch_tsd_indexes.IsValid())
- return;
-
- ReadLibdispatchTSDIndexesAddress ();
-
- if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
- {
-
- // We don't need to check the version number right now, it will be at least 2, but
- // keep this code around to fetch just the version # for the future where we need
- // to fetch alternate versions of the struct.
-# if 0
+ dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
+ g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
+ }
+ if (dispatch_queue_offsets_symbol)
+ m_dispatch_queue_offsets_addr =
+ dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
+}
+
+void SystemRuntimeMacOSX::ReadLibdispatchOffsets() {
+ if (m_libdispatch_offsets.IsValid())
+ return;
+
+ ReadLibdispatchOffsetsAddress();
+
+ uint8_t memory_buffer[sizeof(struct LibdispatchOffsets)];
+ DataExtractor data(memory_buffer, sizeof(memory_buffer),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+
+ Error error;
+ if (m_process->ReadMemory(m_dispatch_queue_offsets_addr, memory_buffer,
+ sizeof(memory_buffer),
+ error) == sizeof(memory_buffer)) {
+ lldb::offset_t data_offset = 0;
+
+ // The struct LibdispatchOffsets is a series of uint16_t's - extract them
+ // all
+ // in one big go.
+ data.GetU16(&data_offset, &m_libdispatch_offsets.dqo_version,
+ sizeof(struct LibdispatchOffsets) / sizeof(uint16_t));
+ }
+}
+
+void SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress() {
+ if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
+ return;
+
+ static ConstString g_libpthread_layout_offsets_symbol_name(
+ "pthread_layout_offsets");
+ const Symbol *libpthread_layout_offsets_symbol = NULL;
+
+ ModuleSpec libpthread_module_spec(FileSpec("libsystem_pthread.dylib", false));
+ ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
+ libpthread_module_spec));
+ if (module_sp) {
+ libpthread_layout_offsets_symbol =
+ module_sp->FindFirstSymbolWithNameAndType(
+ g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
+ if (libpthread_layout_offsets_symbol) {
+ m_libpthread_layout_offsets_addr =
+ libpthread_layout_offsets_symbol->GetLoadAddress(
+ &m_process->GetTarget());
+ }
+ }
+}
+
+void SystemRuntimeMacOSX::ReadLibpthreadOffsets() {
+ if (m_libpthread_offsets.IsValid())
+ return;
+
+ ReadLibpthreadOffsetsAddress();
+
+ if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS) {
+ uint8_t memory_buffer[sizeof(struct LibpthreadOffsets)];
+ DataExtractor data(memory_buffer, sizeof(memory_buffer),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+ Error error;
+ if (m_process->ReadMemory(m_libpthread_layout_offsets_addr, memory_buffer,
+ sizeof(memory_buffer),
+ error) == sizeof(memory_buffer)) {
+ lldb::offset_t data_offset = 0;
+
+ // The struct LibpthreadOffsets is a series of uint16_t's - extract them
+ // all
+ // in one big go.
+ data.GetU16(&data_offset, &m_libpthread_offsets.plo_version,
+ sizeof(struct LibpthreadOffsets) / sizeof(uint16_t));
+ }
+ }
+}
+
+void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress() {
+ if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
+ return;
+
+ static ConstString g_libdispatch_tsd_indexes_symbol_name(
+ "dispatch_tsd_indexes");
+ const Symbol *libdispatch_tsd_indexes_symbol = NULL;
+
+ ModuleSpec libpthread_module_spec(FileSpec("libdispatch.dylib", false));
+ ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
+ libpthread_module_spec));
+ if (module_sp) {
+ libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType(
+ g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
+ if (libdispatch_tsd_indexes_symbol) {
+ m_dispatch_tsd_indexes_addr =
+ libdispatch_tsd_indexes_symbol->GetLoadAddress(
+ &m_process->GetTarget());
+ }
+ }
+}
+
+void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
+ if (m_libdispatch_tsd_indexes.IsValid())
+ return;
+
+ ReadLibdispatchTSDIndexesAddress();
+
+ if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
+
+// We don't need to check the version number right now, it will be at least 2,
+// but
+// keep this code around to fetch just the version # for the future where we
+// need
+// to fetch alternate versions of the struct.
+#if 0
uint16_t dti_version = 2;
Address dti_struct_addr;
if (m_process->GetTarget().ResolveLoadAddress (m_dispatch_tsd_indexes_addr, dti_struct_addr))
@@ -443,141 +425,171 @@ SystemRuntimeMacOSX::ReadLibdispatchTSDI
}
#endif
- ClangASTContext *ast_ctx = m_process->GetTarget().GetScratchClangASTContext();
- if (ast_ctx->getASTContext() && m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
- {
- CompilerType uint16 = ast_ctx->GetBuiltinTypeForEncodingAndBitSize (eEncodingUint, 16);
- CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct, lldb::eLanguageTypeC);
-
- ClangASTContext::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
- ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_version", uint16, lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_queue_index", uint16, lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_voucher_index", uint16, lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_qos_class_index", uint16, lldb::eAccessPublic, 0);
- ClangASTContext::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);
-
- ProcessStructReader struct_reader (m_process, m_dispatch_tsd_indexes_addr, dispatch_tsd_indexes_s);
-
- m_libdispatch_tsd_indexes.dti_version = struct_reader.GetField<uint16_t>(ConstString("dti_version"));
- m_libdispatch_tsd_indexes.dti_queue_index = struct_reader.GetField<uint16_t>(ConstString("dti_queue_index"));
- m_libdispatch_tsd_indexes.dti_voucher_index = struct_reader.GetField<uint16_t>(ConstString("dti_voucher_index"));
- m_libdispatch_tsd_indexes.dti_qos_class_index = struct_reader.GetField<uint16_t>(ConstString("dti_qos_class_index"));
- }
- }
-}
-
-
-ThreadSP
-SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP real_thread, ConstString type)
-{
- ThreadSP originating_thread_sp;
- if (BacktraceRecordingHeadersInitialized() && type == ConstString ("libdispatch"))
- {
- Error error;
-
- // real_thread is either an actual, live thread (in which case we need to call into
- // libBacktraceRecording to find its originator) or it is an extended backtrace itself,
- // in which case we get the token from it and call into libBacktraceRecording to find
- // the originator of that token.
+ ClangASTContext *ast_ctx =
+ m_process->GetTarget().GetScratchClangASTContext();
+ if (ast_ctx->getASTContext() &&
+ m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
+ CompilerType uint16 =
+ ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
+ CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(
+ nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s",
+ clang::TTK_Struct, lldb::eLanguageTypeC);
+
+ ClangASTContext::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
+ ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
+ "dti_version", uint16,
+ lldb::eAccessPublic, 0);
+ ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
+ "dti_queue_index", uint16,
+ lldb::eAccessPublic, 0);
+ ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
+ "dti_voucher_index", uint16,
+ lldb::eAccessPublic, 0);
+ ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
+ "dti_qos_class_index", uint16,
+ lldb::eAccessPublic, 0);
+ ClangASTContext::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);
+
+ ProcessStructReader struct_reader(m_process, m_dispatch_tsd_indexes_addr,
+ dispatch_tsd_indexes_s);
+
+ m_libdispatch_tsd_indexes.dti_version =
+ struct_reader.GetField<uint16_t>(ConstString("dti_version"));
+ m_libdispatch_tsd_indexes.dti_queue_index =
+ struct_reader.GetField<uint16_t>(ConstString("dti_queue_index"));
+ m_libdispatch_tsd_indexes.dti_voucher_index =
+ struct_reader.GetField<uint16_t>(ConstString("dti_voucher_index"));
+ m_libdispatch_tsd_indexes.dti_qos_class_index =
+ struct_reader.GetField<uint16_t>(ConstString("dti_qos_class_index"));
+ }
+ }
+}
+
+ThreadSP SystemRuntimeMacOSX::GetExtendedBacktraceThread(ThreadSP real_thread,
+ ConstString type) {
+ ThreadSP originating_thread_sp;
+ if (BacktraceRecordingHeadersInitialized() &&
+ type == ConstString("libdispatch")) {
+ Error error;
- if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS)
- {
- originating_thread_sp = GetExtendedBacktraceFromItemRef (real_thread->GetExtendedBacktraceToken());
- }
- else
- {
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
- AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret = m_get_thread_item_info_handler.GetThreadItemInfo (*cur_thread_sp.get(), real_thread->GetID(), m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
- {
- DataBufferHeap data (ret.item_buffer_size, 0);
- if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
- {
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
- ItemInfo item = ExtractItemInfoFromBuffer (extractor);
- bool stop_id_is_valid = true;
- if (item.stop_id == 0)
- stop_id_is_valid = false;
- originating_thread_sp.reset (new HistoryThread (*m_process,
- item.enqueuing_thread_id,
- item.enqueuing_callstack,
- item.stop_id,
- stop_id_is_valid));
- originating_thread_sp->SetExtendedBacktraceToken (item.item_that_enqueued_this);
- originating_thread_sp->SetQueueName (item.enqueuing_queue_label.c_str());
- originating_thread_sp->SetQueueID (item.enqueuing_queue_serialnum);
-// originating_thread_sp->SetThreadName (item.enqueuing_thread_label.c_str());
- }
- m_page_to_free = ret.item_buffer_ptr;
- m_page_to_free_size = ret.item_buffer_size;
- }
+ // real_thread is either an actual, live thread (in which case we need to
+ // call into
+ // libBacktraceRecording to find its originator) or it is an extended
+ // backtrace itself,
+ // in which case we get the token from it and call into
+ // libBacktraceRecording to find
+ // the originator of that token.
+
+ if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS) {
+ originating_thread_sp = GetExtendedBacktraceFromItemRef(
+ real_thread->GetExtendedBacktraceToken());
+ } else {
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret =
+ m_get_thread_item_info_handler.GetThreadItemInfo(
+ *cur_thread_sp.get(), real_thread->GetID(), m_page_to_free,
+ m_page_to_free_size, error);
+ m_page_to_free = LLDB_INVALID_ADDRESS;
+ m_page_to_free_size = 0;
+ if (ret.item_buffer_ptr != 0 &&
+ ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
+ ret.item_buffer_size > 0) {
+ DataBufferHeap data(ret.item_buffer_size, 0);
+ if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
+ ret.item_buffer_size, error) &&
+ error.Success()) {
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+ ItemInfo item = ExtractItemInfoFromBuffer(extractor);
+ bool stop_id_is_valid = true;
+ if (item.stop_id == 0)
+ stop_id_is_valid = false;
+ originating_thread_sp.reset(new HistoryThread(
+ *m_process, item.enqueuing_thread_id, item.enqueuing_callstack,
+ item.stop_id, stop_id_is_valid));
+ originating_thread_sp->SetExtendedBacktraceToken(
+ item.item_that_enqueued_this);
+ originating_thread_sp->SetQueueName(
+ item.enqueuing_queue_label.c_str());
+ originating_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
+ // originating_thread_sp->SetThreadName
+ // (item.enqueuing_thread_label.c_str());
}
+ m_page_to_free = ret.item_buffer_ptr;
+ m_page_to_free_size = ret.item_buffer_size;
+ }
}
- return originating_thread_sp;
+ }
+ return originating_thread_sp;
}
ThreadSP
-SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef (lldb::addr_t item_ref)
-{
- ThreadSP return_thread_sp;
+SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref) {
+ ThreadSP return_thread_sp;
- AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
- Error error;
- ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), item_ref, m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
- {
- DataBufferHeap data (ret.item_buffer_size, 0);
- if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
- {
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
- ItemInfo item = ExtractItemInfoFromBuffer (extractor);
- bool stop_id_is_valid = true;
- if (item.stop_id == 0)
- stop_id_is_valid = false;
- return_thread_sp.reset (new HistoryThread (*m_process,
- item.enqueuing_thread_id,
- item.enqueuing_callstack,
- item.stop_id,
- stop_id_is_valid));
- return_thread_sp->SetExtendedBacktraceToken (item.item_that_enqueued_this);
- return_thread_sp->SetQueueName (item.enqueuing_queue_label.c_str());
- return_thread_sp->SetQueueID (item.enqueuing_queue_serialnum);
-// return_thread_sp->SetThreadName (item.enqueuing_thread_label.c_str());
+ AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ Error error;
+ ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
+ m_page_to_free, m_page_to_free_size,
+ error);
+ m_page_to_free = LLDB_INVALID_ADDRESS;
+ m_page_to_free_size = 0;
+ if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
+ ret.item_buffer_size > 0) {
+ DataBufferHeap data(ret.item_buffer_size, 0);
+ if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
+ ret.item_buffer_size, error) &&
+ error.Success()) {
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+ ItemInfo item = ExtractItemInfoFromBuffer(extractor);
+ bool stop_id_is_valid = true;
+ if (item.stop_id == 0)
+ stop_id_is_valid = false;
+ return_thread_sp.reset(new HistoryThread(
+ *m_process, item.enqueuing_thread_id, item.enqueuing_callstack,
+ item.stop_id, stop_id_is_valid));
+ return_thread_sp->SetExtendedBacktraceToken(item.item_that_enqueued_this);
+ return_thread_sp->SetQueueName(item.enqueuing_queue_label.c_str());
+ return_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
+ // return_thread_sp->SetThreadName
+ // (item.enqueuing_thread_label.c_str());
- m_page_to_free = ret.item_buffer_ptr;
- m_page_to_free_size = ret.item_buffer_size;
- }
+ m_page_to_free = ret.item_buffer_ptr;
+ m_page_to_free_size = ret.item_buffer_size;
}
- return return_thread_sp;
+ }
+ return return_thread_sp;
}
ThreadSP
-SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem (QueueItemSP queue_item_sp, ConstString type)
-{
- ThreadSP extended_thread_sp;
- if (type != ConstString("libdispatch"))
- return extended_thread_sp;
-
- bool stop_id_is_valid = true;
- if (queue_item_sp->GetStopID() == 0)
- stop_id_is_valid = false;
+SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem(QueueItemSP queue_item_sp,
+ ConstString type) {
+ ThreadSP extended_thread_sp;
+ if (type != ConstString("libdispatch"))
+ return extended_thread_sp;
- extended_thread_sp.reset (new HistoryThread (*m_process,
- queue_item_sp->GetEnqueueingThreadID(),
- queue_item_sp->GetEnqueueingBacktrace(),
- queue_item_sp->GetStopID(),
- stop_id_is_valid));
- extended_thread_sp->SetExtendedBacktraceToken (queue_item_sp->GetItemThatEnqueuedThis());
- extended_thread_sp->SetQueueName (queue_item_sp->GetQueueLabel().c_str());
- extended_thread_sp->SetQueueID (queue_item_sp->GetEnqueueingQueueID());
-// extended_thread_sp->SetThreadName (queue_item_sp->GetThreadLabel().c_str());
+ bool stop_id_is_valid = true;
+ if (queue_item_sp->GetStopID() == 0)
+ stop_id_is_valid = false;
+
+ extended_thread_sp.reset(
+ new HistoryThread(*m_process, queue_item_sp->GetEnqueueingThreadID(),
+ queue_item_sp->GetEnqueueingBacktrace(),
+ queue_item_sp->GetStopID(), stop_id_is_valid));
+ extended_thread_sp->SetExtendedBacktraceToken(
+ queue_item_sp->GetItemThatEnqueuedThis());
+ extended_thread_sp->SetQueueName(queue_item_sp->GetQueueLabel().c_str());
+ extended_thread_sp->SetQueueID(queue_item_sp->GetEnqueueingQueueID());
+ // extended_thread_sp->SetThreadName
+ // (queue_item_sp->GetThreadLabel().c_str());
- return extended_thread_sp;
+ return extended_thread_sp;
}
/* Returns true if we were able to get the version / offset information
@@ -585,438 +597,439 @@ SystemRuntimeMacOSX::GetExtendedBacktrac
* this; the queue_info_version field will be 0.
*/
-bool
-SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized ()
-{
- if (m_lib_backtrace_recording_info.queue_info_version != 0)
- return true;
-
- addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
- addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
- addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
- addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
- Target &target = m_process->GetTarget();
-
-
- static ConstString introspection_dispatch_queue_info_version ("__introspection_dispatch_queue_info_version");
- SymbolContextList sc_list;
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list) > 0)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- AddressRange addr_range;
- sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
- queue_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
- sc_list.Clear();
-
- static ConstString introspection_dispatch_queue_info_data_offset ("__introspection_dispatch_queue_info_data_offset");
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_data_offset, eSymbolTypeData, sc_list) > 0)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- AddressRange addr_range;
- sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
- queue_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
- sc_list.Clear();
-
- static ConstString introspection_dispatch_item_info_version ("__introspection_dispatch_item_info_version");
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_version, eSymbolTypeData, sc_list) > 0)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- AddressRange addr_range;
- sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
- item_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
- sc_list.Clear();
-
- static ConstString introspection_dispatch_item_info_data_offset ("__introspection_dispatch_item_info_data_offset");
- if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_data_offset, eSymbolTypeData, sc_list) > 0)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- AddressRange addr_range;
- sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
- item_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
- }
-
- if (queue_info_version_address != LLDB_INVALID_ADDRESS
- && queue_info_data_offset_address != LLDB_INVALID_ADDRESS
- && item_info_version_address != LLDB_INVALID_ADDRESS
- && item_info_data_offset_address != LLDB_INVALID_ADDRESS)
- {
- Error error;
- m_lib_backtrace_recording_info.queue_info_version = m_process->ReadUnsignedIntegerFromMemory (queue_info_version_address, 2, 0, error);
- if (error.Success())
- {
- m_lib_backtrace_recording_info.queue_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (queue_info_data_offset_address, 2, 0, error);
- if (error.Success())
- {
- m_lib_backtrace_recording_info.item_info_version = m_process->ReadUnsignedIntegerFromMemory (item_info_version_address, 2, 0, error);
- if (error.Success())
- {
- m_lib_backtrace_recording_info.item_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (item_info_data_offset_address, 2, 0, error);
- if (!error.Success())
- {
- m_lib_backtrace_recording_info.queue_info_version = 0;
- }
- }
- else
- {
- m_lib_backtrace_recording_info.queue_info_version = 0;
- }
- }
- else
- {
- m_lib_backtrace_recording_info.queue_info_version = 0;
- }
- }
- }
-
- return m_lib_backtrace_recording_info.queue_info_version != 0;
-}
-
-const std::vector<ConstString> &
-SystemRuntimeMacOSX::GetExtendedBacktraceTypes ()
-{
- if (m_types.size () == 0)
- {
- m_types.push_back(ConstString("libdispatch"));
- // We could have pthread as another type in the future if we have a way of
- // gathering that information & it's useful to distinguish between them.
- }
- return m_types;
-}
-
-void
-SystemRuntimeMacOSX::PopulateQueueList (lldb_private::QueueList &queue_list)
-{
- if (BacktraceRecordingHeadersInitialized())
- {
- AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
- if (cur_thread_sp)
- {
- Error error;
- queue_info_pointer = m_get_queues_handler.GetCurrentQueues (*cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (error.Success())
- {
+bool SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized() {
+ if (m_lib_backtrace_recording_info.queue_info_version != 0)
+ return true;
- if (queue_info_pointer.count > 0
- && queue_info_pointer.queues_buffer_size > 0
- && queue_info_pointer.queues_buffer_ptr != 0
- && queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS)
- {
- PopulateQueuesUsingLibBTR (queue_info_pointer.queues_buffer_ptr, queue_info_pointer.queues_buffer_size, queue_info_pointer.count, queue_list);
- }
- }
- }
+ addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
+ addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
+ addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
+ addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
+ Target &target = m_process->GetTarget();
+
+ static ConstString introspection_dispatch_queue_info_version(
+ "__introspection_dispatch_queue_info_version");
+ SymbolContextList sc_list;
+ if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list) >
+ 0) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ AddressRange addr_range;
+ sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
+ queue_info_version_address =
+ addr_range.GetBaseAddress().GetLoadAddress(&target);
+ }
+ sc_list.Clear();
+
+ static ConstString introspection_dispatch_queue_info_data_offset(
+ "__introspection_dispatch_queue_info_data_offset");
+ if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ introspection_dispatch_queue_info_data_offset, eSymbolTypeData,
+ sc_list) > 0) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ AddressRange addr_range;
+ sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
+ queue_info_data_offset_address =
+ addr_range.GetBaseAddress().GetLoadAddress(&target);
+ }
+ sc_list.Clear();
+
+ static ConstString introspection_dispatch_item_info_version(
+ "__introspection_dispatch_item_info_version");
+ if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ introspection_dispatch_item_info_version, eSymbolTypeData, sc_list) >
+ 0) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ AddressRange addr_range;
+ sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
+ item_info_version_address =
+ addr_range.GetBaseAddress().GetLoadAddress(&target);
+ }
+ sc_list.Clear();
+
+ static ConstString introspection_dispatch_item_info_data_offset(
+ "__introspection_dispatch_item_info_data_offset");
+ if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ introspection_dispatch_item_info_data_offset, eSymbolTypeData,
+ sc_list) > 0) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ AddressRange addr_range;
+ sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
+ item_info_data_offset_address =
+ addr_range.GetBaseAddress().GetLoadAddress(&target);
+ }
+
+ if (queue_info_version_address != LLDB_INVALID_ADDRESS &&
+ queue_info_data_offset_address != LLDB_INVALID_ADDRESS &&
+ item_info_version_address != LLDB_INVALID_ADDRESS &&
+ item_info_data_offset_address != LLDB_INVALID_ADDRESS) {
+ Error error;
+ m_lib_backtrace_recording_info.queue_info_version =
+ m_process->ReadUnsignedIntegerFromMemory(queue_info_version_address, 2,
+ 0, error);
+ if (error.Success()) {
+ m_lib_backtrace_recording_info.queue_info_data_offset =
+ m_process->ReadUnsignedIntegerFromMemory(
+ queue_info_data_offset_address, 2, 0, error);
+ if (error.Success()) {
+ m_lib_backtrace_recording_info.item_info_version =
+ m_process->ReadUnsignedIntegerFromMemory(item_info_version_address,
+ 2, 0, error);
+ if (error.Success()) {
+ m_lib_backtrace_recording_info.item_info_data_offset =
+ m_process->ReadUnsignedIntegerFromMemory(
+ item_info_data_offset_address, 2, 0, error);
+ if (!error.Success()) {
+ m_lib_backtrace_recording_info.queue_info_version = 0;
+ }
+ } else {
+ m_lib_backtrace_recording_info.queue_info_version = 0;
+ }
+ } else {
+ m_lib_backtrace_recording_info.queue_info_version = 0;
+ }
}
+ }
- // We either didn't have libBacktraceRecording (and need to create the queues list based on threads)
- // or we did get the queues list from libBacktraceRecording but some special queues may not be
- // included in its information. This is needed because libBacktraceRecording
- // will only list queues with pending or running items by default - but the magic com.apple.main-thread
- // queue on thread 1 is always around.
-
- for (ThreadSP thread_sp : m_process->Threads())
- {
- if (thread_sp->GetAssociatedWithLibdispatchQueue () != eLazyBoolNo)
- {
- if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID)
- {
- if (queue_list.FindQueueByID (thread_sp->GetQueueID()).get() == NULL)
- {
- QueueSP queue_sp (new Queue(m_process->shared_from_this(), thread_sp->GetQueueID(), thread_sp->GetQueueName()));
- if (thread_sp->ThreadHasQueueInformation ())
- {
- queue_sp->SetKind (thread_sp->GetQueueKind ());
- queue_sp->SetLibdispatchQueueAddress (thread_sp->GetQueueLibdispatchQueueAddress());
- queue_list.AddQueue (queue_sp);
- }
- else
- {
- queue_sp->SetKind (GetQueueKind (thread_sp->GetQueueLibdispatchQueueAddress()));
- queue_sp->SetLibdispatchQueueAddress (thread_sp->GetQueueLibdispatchQueueAddress());
- queue_list.AddQueue (queue_sp);
- }
- }
- }
- }
- }
+ return m_lib_backtrace_recording_info.queue_info_version != 0;
}
-// Returns either an array of introspection_dispatch_item_info_ref's for the pending items on
-// a queue or an array introspection_dispatch_item_info_ref's and code addresses for the
-// pending items on a queue. The information about each of these pending items then needs to
+const std::vector<ConstString> &
+SystemRuntimeMacOSX::GetExtendedBacktraceTypes() {
+ if (m_types.size() == 0) {
+ m_types.push_back(ConstString("libdispatch"));
+ // We could have pthread as another type in the future if we have a way of
+ // gathering that information & it's useful to distinguish between them.
+ }
+ return m_types;
+}
+
+void SystemRuntimeMacOSX::PopulateQueueList(
+ lldb_private::QueueList &queue_list) {
+ if (BacktraceRecordingHeadersInitialized()) {
+ AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ if (cur_thread_sp) {
+ Error error;
+ queue_info_pointer = m_get_queues_handler.GetCurrentQueues(
+ *cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
+ m_page_to_free = LLDB_INVALID_ADDRESS;
+ m_page_to_free_size = 0;
+ if (error.Success()) {
+
+ if (queue_info_pointer.count > 0 &&
+ queue_info_pointer.queues_buffer_size > 0 &&
+ queue_info_pointer.queues_buffer_ptr != 0 &&
+ queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS) {
+ PopulateQueuesUsingLibBTR(queue_info_pointer.queues_buffer_ptr,
+ queue_info_pointer.queues_buffer_size,
+ queue_info_pointer.count, queue_list);
+ }
+ }
+ }
+ }
+
+ // We either didn't have libBacktraceRecording (and need to create the queues
+ // list based on threads)
+ // or we did get the queues list from libBacktraceRecording but some special
+ // queues may not be
+ // included in its information. This is needed because libBacktraceRecording
+ // will only list queues with pending or running items by default - but the
+ // magic com.apple.main-thread
+ // queue on thread 1 is always around.
+
+ for (ThreadSP thread_sp : m_process->Threads()) {
+ if (thread_sp->GetAssociatedWithLibdispatchQueue() != eLazyBoolNo) {
+ if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID) {
+ if (queue_list.FindQueueByID(thread_sp->GetQueueID()).get() == NULL) {
+ QueueSP queue_sp(new Queue(m_process->shared_from_this(),
+ thread_sp->GetQueueID(),
+ thread_sp->GetQueueName()));
+ if (thread_sp->ThreadHasQueueInformation()) {
+ queue_sp->SetKind(thread_sp->GetQueueKind());
+ queue_sp->SetLibdispatchQueueAddress(
+ thread_sp->GetQueueLibdispatchQueueAddress());
+ queue_list.AddQueue(queue_sp);
+ } else {
+ queue_sp->SetKind(
+ GetQueueKind(thread_sp->GetQueueLibdispatchQueueAddress()));
+ queue_sp->SetLibdispatchQueueAddress(
+ thread_sp->GetQueueLibdispatchQueueAddress());
+ queue_list.AddQueue(queue_sp);
+ }
+ }
+ }
+ }
+ }
+}
+
+// Returns either an array of introspection_dispatch_item_info_ref's for the
+// pending items on
+// a queue or an array introspection_dispatch_item_info_ref's and code addresses
+// for the
+// pending items on a queue. The information about each of these pending items
+// then needs to
// be fetched individually by passing the ref to libBacktraceRecording.
SystemRuntimeMacOSX::PendingItemsForQueue
-SystemRuntimeMacOSX::GetPendingItemRefsForQueue (lldb::addr_t queue)
-{
- PendingItemsForQueue pending_item_refs;
- AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
- if (cur_thread_sp)
- {
- Error error;
- pending_items_pointer = m_get_pending_items_handler.GetPendingItems (*cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size, error);
- m_page_to_free = LLDB_INVALID_ADDRESS;
- m_page_to_free_size = 0;
- if (error.Success())
- {
- if (pending_items_pointer.count > 0
- && pending_items_pointer.items_buffer_size > 0
- && pending_items_pointer.items_buffer_ptr != 0
- && pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS)
- {
- DataBufferHeap data (pending_items_pointer.items_buffer_size, 0);
- if (m_process->ReadMemory (pending_items_pointer.items_buffer_ptr, data.GetBytes(), pending_items_pointer.items_buffer_size, error))
- {
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
-
- // We either have an array of
- // void* item_ref
- // (old style) or we have a structure returned which looks like
- //
- // struct introspection_dispatch_pending_item_info_s {
- // void *item_ref;
- // void *function_or_block;
- // };
- //
- // struct introspection_dispatch_pending_items_array_s {
- // uint32_t version;
- // uint32_t size_of_item_info;
- // introspection_dispatch_pending_item_info_s items[];
- // }
-
- offset_t offset = 0;
- int i = 0;
- uint32_t version = extractor.GetU32(&offset);
- if (version == 1)
- {
- pending_item_refs.new_style = true;
- uint32_t item_size = extractor.GetU32(&offset);
- uint32_t start_of_array_offset = offset;
- while (offset < pending_items_pointer.items_buffer_size &&
- static_cast<size_t>(i) < pending_items_pointer.count)
- {
- offset = start_of_array_offset + (i * item_size);
- ItemRefAndCodeAddress item;
- item.item_ref = extractor.GetPointer (&offset);
- item.code_address = extractor.GetPointer (&offset);
- pending_item_refs.item_refs_and_code_addresses.push_back (item);
- i++;
- }
- }
- else
- {
- offset = 0;
- pending_item_refs.new_style = false;
- while (offset < pending_items_pointer.items_buffer_size &&
- static_cast<size_t>(i) < pending_items_pointer.count)
- {
- ItemRefAndCodeAddress item;
- item.item_ref = extractor.GetPointer (&offset);
- item.code_address = LLDB_INVALID_ADDRESS;
- pending_item_refs.item_refs_and_code_addresses.push_back (item);
- i++;
- }
- }
- }
- m_page_to_free = pending_items_pointer.items_buffer_ptr;
- m_page_to_free_size = pending_items_pointer.items_buffer_size;
- }
- }
- }
- return pending_item_refs;
-}
-
-
-
-void
-SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue)
-{
- if (BacktraceRecordingHeadersInitialized())
- {
- PendingItemsForQueue pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress());
- for (ItemRefAndCodeAddress pending_item : pending_item_refs.item_refs_and_code_addresses)
- {
- Address addr;
- m_process->GetTarget().ResolveLoadAddress (pending_item.code_address, addr);
- QueueItemSP queue_item_sp (new QueueItem (queue->shared_from_this(), m_process->shared_from_this(), pending_item.item_ref, addr));
- queue->PushPendingQueueItem (queue_item_sp);
- }
- }
-}
-
-void
-SystemRuntimeMacOSX::CompleteQueueItem (QueueItem *queue_item, addr_t item_ref)
-{
- AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
-
- ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
+SystemRuntimeMacOSX::GetPendingItemRefsForQueue(lldb::addr_t queue) {
+ PendingItemsForQueue pending_item_refs;
+ AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ if (cur_thread_sp) {
Error error;
- ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), item_ref, m_page_to_free, m_page_to_free_size, error);
+ pending_items_pointer = m_get_pending_items_handler.GetPendingItems(
+ *cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size,
+ error);
m_page_to_free = LLDB_INVALID_ADDRESS;
m_page_to_free_size = 0;
- if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
- {
- DataBufferHeap data (ret.item_buffer_size, 0);
- if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
- {
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
- ItemInfo item = ExtractItemInfoFromBuffer (extractor);
- queue_item->SetItemThatEnqueuedThis (item.item_that_enqueued_this);
- queue_item->SetEnqueueingThreadID (item.enqueuing_thread_id);
- queue_item->SetEnqueueingQueueID (item.enqueuing_queue_serialnum);
- queue_item->SetStopID (item.stop_id);
- queue_item->SetEnqueueingBacktrace (item.enqueuing_callstack);
- queue_item->SetThreadLabel (item.enqueuing_thread_label);
- queue_item->SetQueueLabel (item.enqueuing_queue_label);
- queue_item->SetTargetQueueLabel (item.target_queue_label);
- }
- m_page_to_free = ret.item_buffer_ptr;
- m_page_to_free_size = ret.item_buffer_size;
- }
-}
-
-void
-SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size,
- uint64_t count, lldb_private::QueueList &queue_list)
-{
- Error error;
- DataBufferHeap data (queues_buffer_size, 0);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
- if (m_process->ReadMemory (queues_buffer, data.GetBytes(), queues_buffer_size, error) == queues_buffer_size && error.Success())
- {
- // We've read the information out of inferior memory; free it on the next call we make
- m_page_to_free = queues_buffer;
- m_page_to_free_size = queues_buffer_size;
-
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
- offset_t offset = 0;
- uint64_t queues_read = 0;
-
- // The information about the queues is stored in this format (v1):
- // typedef struct introspection_dispatch_queue_info_s {
- // uint32_t offset_to_next;
- // dispatch_queue_t queue;
- // uint64_t serialnum; // queue's serialnum in the process, as provided by libdispatch
- // uint32_t running_work_items_count;
- // uint32_t pending_work_items_count;
- //
- // char data[]; // Starting here, we have variable-length data:
- // // char queue_label[];
- // } introspection_dispatch_queue_info_s;
-
- while (queues_read < count && offset < queues_buffer_size)
- {
- offset_t start_of_this_item = offset;
-
- uint32_t offset_to_next = extractor.GetU32 (&offset);
-
- offset += 4; // Skip over the 4 bytes of reserved space
- addr_t queue = extractor.GetPointer (&offset);
- uint64_t serialnum = extractor.GetU64 (&offset);
- uint32_t running_work_items_count = extractor.GetU32 (&offset);
- uint32_t pending_work_items_count = extractor.GetU32 (&offset);
-
- // Read the first field of the variable length data
- offset = start_of_this_item + m_lib_backtrace_recording_info.queue_info_data_offset;
- const char *queue_label = extractor.GetCStr (&offset);
- if (queue_label == NULL)
- queue_label = "";
-
- offset_t start_of_next_item = start_of_this_item + offset_to_next;
- offset = start_of_next_item;
-
- if (log)
- log->Printf ("SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added queue with dispatch_queue_t 0x%" PRIx64 ", serial number 0x%" PRIx64 ", running items %d, pending items %d, name '%s'", queue, serialnum, running_work_items_count, pending_work_items_count, queue_label);
-
- QueueSP queue_sp (new Queue (m_process->shared_from_this(), serialnum, queue_label));
- queue_sp->SetNumRunningWorkItems (running_work_items_count);
- queue_sp->SetNumPendingWorkItems (pending_work_items_count);
- queue_sp->SetLibdispatchQueueAddress (queue);
- queue_sp->SetKind (GetQueueKind (queue));
- queue_list.AddQueue (queue_sp);
- queues_read++;
+ if (error.Success()) {
+ if (pending_items_pointer.count > 0 &&
+ pending_items_pointer.items_buffer_size > 0 &&
+ pending_items_pointer.items_buffer_ptr != 0 &&
+ pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS) {
+ DataBufferHeap data(pending_items_pointer.items_buffer_size, 0);
+ if (m_process->ReadMemory(
+ pending_items_pointer.items_buffer_ptr, data.GetBytes(),
+ pending_items_pointer.items_buffer_size, error)) {
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+
+ // We either have an array of
+ // void* item_ref
+ // (old style) or we have a structure returned which looks like
+ //
+ // struct introspection_dispatch_pending_item_info_s {
+ // void *item_ref;
+ // void *function_or_block;
+ // };
+ //
+ // struct introspection_dispatch_pending_items_array_s {
+ // uint32_t version;
+ // uint32_t size_of_item_info;
+ // introspection_dispatch_pending_item_info_s items[];
+ // }
+
+ offset_t offset = 0;
+ int i = 0;
+ uint32_t version = extractor.GetU32(&offset);
+ if (version == 1) {
+ pending_item_refs.new_style = true;
+ uint32_t item_size = extractor.GetU32(&offset);
+ uint32_t start_of_array_offset = offset;
+ while (offset < pending_items_pointer.items_buffer_size &&
+ static_cast<size_t>(i) < pending_items_pointer.count) {
+ offset = start_of_array_offset + (i * item_size);
+ ItemRefAndCodeAddress item;
+ item.item_ref = extractor.GetPointer(&offset);
+ item.code_address = extractor.GetPointer(&offset);
+ pending_item_refs.item_refs_and_code_addresses.push_back(item);
+ i++;
+ }
+ } else {
+ offset = 0;
+ pending_item_refs.new_style = false;
+ while (offset < pending_items_pointer.items_buffer_size &&
+ static_cast<size_t>(i) < pending_items_pointer.count) {
+ ItemRefAndCodeAddress item;
+ item.item_ref = extractor.GetPointer(&offset);
+ item.code_address = LLDB_INVALID_ADDRESS;
+ pending_item_refs.item_refs_and_code_addresses.push_back(item);
+ i++;
+ }
+ }
}
- }
-}
-
-SystemRuntimeMacOSX::ItemInfo
-SystemRuntimeMacOSX::ExtractItemInfoFromBuffer (lldb_private::DataExtractor &extractor)
-{
- ItemInfo item;
+ m_page_to_free = pending_items_pointer.items_buffer_ptr;
+ m_page_to_free_size = pending_items_pointer.items_buffer_size;
+ }
+ }
+ }
+ return pending_item_refs;
+}
+
+void SystemRuntimeMacOSX::PopulatePendingItemsForQueue(Queue *queue) {
+ if (BacktraceRecordingHeadersInitialized()) {
+ PendingItemsForQueue pending_item_refs =
+ GetPendingItemRefsForQueue(queue->GetLibdispatchQueueAddress());
+ for (ItemRefAndCodeAddress pending_item :
+ pending_item_refs.item_refs_and_code_addresses) {
+ Address addr;
+ m_process->GetTarget().ResolveLoadAddress(pending_item.code_address,
+ addr);
+ QueueItemSP queue_item_sp(new QueueItem(queue->shared_from_this(),
+ m_process->shared_from_this(),
+ pending_item.item_ref, addr));
+ queue->PushPendingQueueItem(queue_item_sp);
+ }
+ }
+}
+
+void SystemRuntimeMacOSX::CompleteQueueItem(QueueItem *queue_item,
+ addr_t item_ref) {
+ AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
+
+ ThreadSP cur_thread_sp(
+ m_process->GetThreadList().GetExpressionExecutionThread());
+ Error error;
+ ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
+ m_page_to_free, m_page_to_free_size,
+ error);
+ m_page_to_free = LLDB_INVALID_ADDRESS;
+ m_page_to_free_size = 0;
+ if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
+ ret.item_buffer_size > 0) {
+ DataBufferHeap data(ret.item_buffer_size, 0);
+ if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
+ ret.item_buffer_size, error) &&
+ error.Success()) {
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
+ ItemInfo item = ExtractItemInfoFromBuffer(extractor);
+ queue_item->SetItemThatEnqueuedThis(item.item_that_enqueued_this);
+ queue_item->SetEnqueueingThreadID(item.enqueuing_thread_id);
+ queue_item->SetEnqueueingQueueID(item.enqueuing_queue_serialnum);
+ queue_item->SetStopID(item.stop_id);
+ queue_item->SetEnqueueingBacktrace(item.enqueuing_callstack);
+ queue_item->SetThreadLabel(item.enqueuing_thread_label);
+ queue_item->SetQueueLabel(item.enqueuing_queue_label);
+ queue_item->SetTargetQueueLabel(item.target_queue_label);
+ }
+ m_page_to_free = ret.item_buffer_ptr;
+ m_page_to_free_size = ret.item_buffer_size;
+ }
+}
+
+void SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR(
+ lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count,
+ lldb_private::QueueList &queue_list) {
+ Error error;
+ DataBufferHeap data(queues_buffer_size, 0);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
+ if (m_process->ReadMemory(queues_buffer, data.GetBytes(), queues_buffer_size,
+ error) == queues_buffer_size &&
+ error.Success()) {
+ // We've read the information out of inferior memory; free it on the next
+ // call we make
+ m_page_to_free = queues_buffer;
+ m_page_to_free_size = queues_buffer_size;
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
+ m_process->GetByteOrder(),
+ m_process->GetAddressByteSize());
offset_t offset = 0;
-
- item.item_that_enqueued_this = extractor.GetPointer (&offset);
- item.function_or_block = extractor.GetPointer (&offset);
- item.enqueuing_thread_id = extractor.GetU64 (&offset);
- item.enqueuing_queue_serialnum = extractor.GetU64 (&offset);
- item.target_queue_serialnum = extractor.GetU64 (&offset);
- item.enqueuing_callstack_frame_count = extractor.GetU32 (&offset);
- item.stop_id = extractor.GetU32 (&offset);
-
- offset = m_lib_backtrace_recording_info.item_info_data_offset;
+ uint64_t queues_read = 0;
- for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++)
- {
- item.enqueuing_callstack.push_back (extractor.GetPointer (&offset));
- }
- item.enqueuing_thread_label = extractor.GetCStr (&offset);
- item.enqueuing_queue_label = extractor.GetCStr (&offset);
- item.target_queue_label = extractor.GetCStr (&offset);
-
- return item;
-}
-
-void
-SystemRuntimeMacOSX::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+ // The information about the queues is stored in this format (v1):
+ // typedef struct introspection_dispatch_queue_info_s {
+ // uint32_t offset_to_next;
+ // dispatch_queue_t queue;
+ // uint64_t serialnum; // queue's serialnum in the process, as
+ // provided by libdispatch
+ // uint32_t running_work_items_count;
+ // uint32_t pending_work_items_count;
+ //
+ // char data[]; // Starting here, we have variable-length data:
+ // // char queue_label[];
+ // } introspection_dispatch_queue_info_s;
+
+ while (queues_read < count && offset < queues_buffer_size) {
+ offset_t start_of_this_item = offset;
+
+ uint32_t offset_to_next = extractor.GetU32(&offset);
+
+ offset += 4; // Skip over the 4 bytes of reserved space
+ addr_t queue = extractor.GetPointer(&offset);
+ uint64_t serialnum = extractor.GetU64(&offset);
+ uint32_t running_work_items_count = extractor.GetU32(&offset);
+ uint32_t pending_work_items_count = extractor.GetU32(&offset);
+
+ // Read the first field of the variable length data
+ offset = start_of_this_item +
+ m_lib_backtrace_recording_info.queue_info_data_offset;
+ const char *queue_label = extractor.GetCStr(&offset);
+ if (queue_label == NULL)
+ queue_label = "";
+
+ offset_t start_of_next_item = start_of_this_item + offset_to_next;
+ offset = start_of_next_item;
+
+ if (log)
+ log->Printf("SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added "
+ "queue with dispatch_queue_t 0x%" PRIx64
+ ", serial number 0x%" PRIx64
+ ", running items %d, pending items %d, name '%s'",
+ queue, serialnum, running_work_items_count,
+ pending_work_items_count, queue_label);
+
+ QueueSP queue_sp(
+ new Queue(m_process->shared_from_this(), serialnum, queue_label));
+ queue_sp->SetNumRunningWorkItems(running_work_items_count);
+ queue_sp->SetNumPendingWorkItems(pending_work_items_count);
+ queue_sp->SetLibdispatchQueueAddress(queue);
+ queue_sp->SetKind(GetQueueKind(queue));
+ queue_list.AddQueue(queue_sp);
+ queues_read++;
+ }
+ }
+}
+
+SystemRuntimeMacOSX::ItemInfo SystemRuntimeMacOSX::ExtractItemInfoFromBuffer(
+ lldb_private::DataExtractor &extractor) {
+ ItemInfo item;
+
+ offset_t offset = 0;
+
+ item.item_that_enqueued_this = extractor.GetPointer(&offset);
+ item.function_or_block = extractor.GetPointer(&offset);
+ item.enqueuing_thread_id = extractor.GetU64(&offset);
+ item.enqueuing_queue_serialnum = extractor.GetU64(&offset);
+ item.target_queue_serialnum = extractor.GetU64(&offset);
+ item.enqueuing_callstack_frame_count = extractor.GetU32(&offset);
+ item.stop_id = extractor.GetU32(&offset);
+
+ offset = m_lib_backtrace_recording_info.item_info_data_offset;
+
+ for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++) {
+ item.enqueuing_callstack.push_back(extractor.GetPointer(&offset));
+ }
+ item.enqueuing_thread_label = extractor.GetCStr(&offset);
+ item.enqueuing_queue_label = extractor.GetCStr(&offset);
+ item.target_queue_label = extractor.GetCStr(&offset);
+
+ return item;
+}
+
+void SystemRuntimeMacOSX::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void SystemRuntimeMacOSX::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString SystemRuntimeMacOSX::GetPluginNameStatic() {
+ static ConstString g_name("systemruntime-macosx");
+ return g_name;
}
-void
-SystemRuntimeMacOSX::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+const char *SystemRuntimeMacOSX::GetPluginDescriptionStatic() {
+ return "System runtime plugin for Mac OS X native libraries.";
}
-
-lldb_private::ConstString
-SystemRuntimeMacOSX::GetPluginNameStatic()
-{
- static ConstString g_name("systemruntime-macosx");
- return g_name;
-}
-
-const char *
-SystemRuntimeMacOSX::GetPluginDescriptionStatic()
-{
- return "System runtime plugin for Mac OS X native libraries.";
-}
-
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-SystemRuntimeMacOSX::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString SystemRuntimeMacOSX::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-SystemRuntimeMacOSX::GetPluginVersion()
-{
- return 1;
-}
+uint32_t SystemRuntimeMacOSX::GetPluginVersion() { return 1; }
Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h Tue Sep 6 15:57:50 2016
@@ -18,7 +18,6 @@
// Other libraries and framework include
// Project includes
-#include "lldb/Target/SystemRuntime.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/StructuredData.h"
@@ -26,311 +25,278 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/QueueItem.h"
+#include "lldb/Target/SystemRuntime.h"
#include "AppleGetItemInfoHandler.h"
-#include "AppleGetQueuesHandler.h"
#include "AppleGetPendingItemsHandler.h"
+#include "AppleGetQueuesHandler.h"
#include "AppleGetThreadItemInfoHandler.h"
-class SystemRuntimeMacOSX : public lldb_private::SystemRuntime
-{
+class SystemRuntimeMacOSX : public lldb_private::SystemRuntime {
public:
- SystemRuntimeMacOSX(lldb_private::Process *process);
+ SystemRuntimeMacOSX(lldb_private::Process *process);
- ~SystemRuntimeMacOSX() override;
+ ~SystemRuntimeMacOSX() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::SystemRuntime *
- CreateInstance (lldb_private::Process *process);
+ static lldb_private::SystemRuntime *
+ CreateInstance(lldb_private::Process *process);
- //------------------------------------------------------------------
- // instance methods
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // instance methods
+ //------------------------------------------------------------------
- void
- Clear(bool clear_process);
+ void Clear(bool clear_process);
- void
- Detach() override;
+ void Detach() override;
- const std::vector<lldb_private::ConstString> &
- GetExtendedBacktraceTypes() override;
+ const std::vector<lldb_private::ConstString> &
+ GetExtendedBacktraceTypes() override;
- lldb::ThreadSP
- GetExtendedBacktraceThread(lldb::ThreadSP thread, lldb_private::ConstString type) override;
+ lldb::ThreadSP
+ GetExtendedBacktraceThread(lldb::ThreadSP thread,
+ lldb_private::ConstString type) override;
- lldb::ThreadSP
- GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp,
- lldb_private::ConstString type) override;
+ lldb::ThreadSP
+ GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp,
+ lldb_private::ConstString type) override;
- lldb::ThreadSP
- GetExtendedBacktraceFromItemRef (lldb::addr_t item_ref);
+ lldb::ThreadSP GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref);
- void
- PopulateQueueList(lldb_private::QueueList &queue_list) override;
+ void PopulateQueueList(lldb_private::QueueList &queue_list) override;
- void
- PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count, lldb_private::QueueList &queue_list);
+ void PopulateQueuesUsingLibBTR(lldb::addr_t queues_buffer,
+ uint64_t queues_buffer_size, uint64_t count,
+ lldb_private::QueueList &queue_list);
- void
- PopulatePendingQueuesUsingLibBTR (lldb::addr_t items_buffer, uint64_t items_buffer_size, uint64_t count, lldb_private::Queue *queue);
+ void PopulatePendingQueuesUsingLibBTR(lldb::addr_t items_buffer,
+ uint64_t items_buffer_size,
+ uint64_t count,
+ lldb_private::Queue *queue);
- std::string
- GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
+ std::string
+ GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
- lldb::queue_id_t
- GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
+ lldb::queue_id_t
+ GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
- lldb::addr_t
- GetLibdispatchQueueAddressFromThreadQAddress(lldb::addr_t dispatch_qaddr) override;
+ lldb::addr_t GetLibdispatchQueueAddressFromThreadQAddress(
+ lldb::addr_t dispatch_qaddr) override;
- void
- PopulatePendingItemsForQueue(lldb_private::Queue *queue) override;
+ void PopulatePendingItemsForQueue(lldb_private::Queue *queue) override;
- void
- CompleteQueueItem(lldb_private::QueueItem *queue_item, lldb::addr_t item_ref) override;
+ void CompleteQueueItem(lldb_private::QueueItem *queue_item,
+ lldb::addr_t item_ref) override;
- lldb::QueueKind
- GetQueueKind (lldb::addr_t dispatch_queue_addr) override;
+ lldb::QueueKind GetQueueKind(lldb::addr_t dispatch_queue_addr) override;
- void
- AddThreadExtendedInfoPacketHints(lldb_private::StructuredData::ObjectSP dict) override;
+ void AddThreadExtendedInfoPacketHints(
+ lldb_private::StructuredData::ObjectSP dict) override;
- bool
- SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) override;
+ bool SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- lldb::user_id_t m_break_id;
- mutable std::recursive_mutex m_mutex;
+ lldb::user_id_t m_break_id;
+ mutable std::recursive_mutex m_mutex;
private:
- struct libBacktraceRecording_info {
- uint16_t queue_info_version;
- uint16_t queue_info_data_offset;
- uint16_t item_info_version;
- uint16_t item_info_data_offset;
-
- libBacktraceRecording_info () :
- queue_info_version(0),
- queue_info_data_offset(0),
- item_info_version(0),
- item_info_data_offset(0) {}
- };
-
- // A structure which reflects the data recorded in the
- // libBacktraceRecording introspection_dispatch_item_info_s.
- struct ItemInfo {
- lldb::addr_t item_that_enqueued_this;
- lldb::addr_t function_or_block;
- uint64_t enqueuing_thread_id;
- uint64_t enqueuing_queue_serialnum;
- uint64_t target_queue_serialnum;
- uint32_t enqueuing_callstack_frame_count;
- uint32_t stop_id;
- std::vector<lldb::addr_t> enqueuing_callstack;
- std::string enqueuing_thread_label;
- std::string enqueuing_queue_label;
- std::string target_queue_label;
- };
-
- // The offsets of different fields of the dispatch_queue_t structure in
- // a thread/queue process.
- // Based on libdispatch src/queue_private.h, struct dispatch_queue_offsets_s
- // With dqo_version 1-3, the dqo_label field is a per-queue value and cannot be cached.
- // With dqo_version 4 (Mac OS X 10.9 / iOS 7), dqo_label is a constant value that can be cached.
- struct LibdispatchOffsets
- {
- uint16_t dqo_version;
- uint16_t dqo_label;
- uint16_t dqo_label_size;
- uint16_t dqo_flags;
- uint16_t dqo_flags_size;
- uint16_t dqo_serialnum;
- uint16_t dqo_serialnum_size;
- uint16_t dqo_width;
- uint16_t dqo_width_size;
- uint16_t dqo_running;
- uint16_t dqo_running_size;
-
- uint16_t dqo_suspend_cnt; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_suspend_cnt_size; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_target_queue; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_target_queue_size; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_priority; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_priority_size; // version 5 and later, starting with Mac OS X 10.10/iOS 8
-
- LibdispatchOffsets ()
- {
- dqo_version = UINT16_MAX;
- dqo_flags = UINT16_MAX;
- dqo_serialnum = UINT16_MAX;
- dqo_label = UINT16_MAX;
- dqo_width = UINT16_MAX;
- dqo_running = UINT16_MAX;
- dqo_suspend_cnt = UINT16_MAX;
- dqo_target_queue = UINT16_MAX;
- dqo_target_queue = UINT16_MAX;
- dqo_priority = UINT16_MAX;
- }
-
- bool
- IsValid ()
- {
- return dqo_version != UINT16_MAX;
- }
-
- bool
- LabelIsValid ()
- {
- return dqo_label != UINT16_MAX;
- }
- };
-
- struct LibdispatchVoucherOffsets
- {
- uint16_t vo_version;
- uint16_t vo_activity_ids_count;
- uint16_t vo_activity_ids_count_size;
- uint16_t vo_activity_ids_array;
- uint16_t vo_activity_ids_array_entry_size;
-
- LibdispatchVoucherOffsets () :
- vo_version (UINT16_MAX),
- vo_activity_ids_count (UINT16_MAX),
- vo_activity_ids_count_size (UINT16_MAX),
- vo_activity_ids_array (UINT16_MAX),
- vo_activity_ids_array_entry_size (UINT16_MAX)
- { }
-
- bool IsValid () { return vo_version != UINT16_MAX; }
- };
-
- struct LibdispatchTSDIndexes
- {
- uint16_t dti_version;
- uint64_t dti_queue_index;
- uint64_t dti_voucher_index;
- uint64_t dti_qos_class_index;
-
- LibdispatchTSDIndexes () :
- dti_version (UINT16_MAX),
- dti_queue_index (UINT64_MAX),
- dti_voucher_index (UINT64_MAX),
- dti_qos_class_index (UINT64_MAX)
- { }
-
- bool IsValid () { return dti_version != UINT16_MAX; }
- };
-
- struct LibpthreadOffsets
- {
- uint16_t plo_version;
- uint16_t plo_pthread_tsd_base_offset;
- uint16_t plo_pthread_tsd_base_address_offset;
- uint16_t plo_pthread_tsd_entry_size;
-
- LibpthreadOffsets () :
- plo_version (UINT16_MAX),
- plo_pthread_tsd_base_offset (UINT16_MAX),
- plo_pthread_tsd_base_address_offset (UINT16_MAX),
- plo_pthread_tsd_entry_size (UINT16_MAX)
- {
- }
-
- bool IsValid ()
- {
- return plo_version != UINT16_MAX;
- }
- };
-
- // The libBacktraceRecording function __introspection_dispatch_queue_get_pending_items has
- // two forms. It can either return a simple array of item_refs (void *) size or it can return
- // a header with uint32_t version, a uint32_t size of item, and then an array of item_refs (void*)
- // and code addresses (void*) for all the pending blocks.
-
- struct ItemRefAndCodeAddress {
- lldb::addr_t item_ref;
- lldb::addr_t code_address;
- };
-
- struct PendingItemsForQueue {
- bool new_style; // new-style means both item_refs and code_addresses avail
- // old-style means only item_refs is filled in
- std::vector<ItemRefAndCodeAddress> item_refs_and_code_addresses;
- };
-
- bool
- BacktraceRecordingHeadersInitialized ();
-
- void
- ReadLibdispatchOffsetsAddress();
-
- void
- ReadLibdispatchOffsets ();
-
- void
- ReadLibpthreadOffsetsAddress();
-
- void
- ReadLibpthreadOffsets ();
-
- void
- ReadLibdispatchTSDIndexesAddress ();
-
- void
- ReadLibdispatchTSDIndexes ();
-
- PendingItemsForQueue
- GetPendingItemRefsForQueue (lldb::addr_t queue);
-
- ItemInfo
- ExtractItemInfoFromBuffer (lldb_private::DataExtractor &extractor);
-
- lldb_private::AppleGetQueuesHandler m_get_queues_handler;
- lldb_private::AppleGetPendingItemsHandler m_get_pending_items_handler;
- lldb_private::AppleGetItemInfoHandler m_get_item_info_handler;
- lldb_private::AppleGetThreadItemInfoHandler m_get_thread_item_info_handler;
-
- lldb::addr_t m_page_to_free;
- uint64_t m_page_to_free_size;
- libBacktraceRecording_info m_lib_backtrace_recording_info;
-
- lldb::addr_t m_dispatch_queue_offsets_addr;
- struct LibdispatchOffsets m_libdispatch_offsets;
-
- lldb::addr_t m_libpthread_layout_offsets_addr;
- struct LibpthreadOffsets m_libpthread_offsets;
+ struct libBacktraceRecording_info {
+ uint16_t queue_info_version;
+ uint16_t queue_info_data_offset;
+ uint16_t item_info_version;
+ uint16_t item_info_data_offset;
+
+ libBacktraceRecording_info()
+ : queue_info_version(0), queue_info_data_offset(0),
+ item_info_version(0), item_info_data_offset(0) {}
+ };
+
+ // A structure which reflects the data recorded in the
+ // libBacktraceRecording introspection_dispatch_item_info_s.
+ struct ItemInfo {
+ lldb::addr_t item_that_enqueued_this;
+ lldb::addr_t function_or_block;
+ uint64_t enqueuing_thread_id;
+ uint64_t enqueuing_queue_serialnum;
+ uint64_t target_queue_serialnum;
+ uint32_t enqueuing_callstack_frame_count;
+ uint32_t stop_id;
+ std::vector<lldb::addr_t> enqueuing_callstack;
+ std::string enqueuing_thread_label;
+ std::string enqueuing_queue_label;
+ std::string target_queue_label;
+ };
+
+ // The offsets of different fields of the dispatch_queue_t structure in
+ // a thread/queue process.
+ // Based on libdispatch src/queue_private.h, struct dispatch_queue_offsets_s
+ // With dqo_version 1-3, the dqo_label field is a per-queue value and cannot
+ // be cached.
+ // With dqo_version 4 (Mac OS X 10.9 / iOS 7), dqo_label is a constant value
+ // that can be cached.
+ struct LibdispatchOffsets {
+ uint16_t dqo_version;
+ uint16_t dqo_label;
+ uint16_t dqo_label_size;
+ uint16_t dqo_flags;
+ uint16_t dqo_flags_size;
+ uint16_t dqo_serialnum;
+ uint16_t dqo_serialnum_size;
+ uint16_t dqo_width;
+ uint16_t dqo_width_size;
+ uint16_t dqo_running;
+ uint16_t dqo_running_size;
+
+ uint16_t dqo_suspend_cnt; // version 5 and later, starting with Mac OS X
+ // 10.10/iOS 8
+ uint16_t dqo_suspend_cnt_size; // version 5 and later, starting with Mac OS
+ // X 10.10/iOS 8
+ uint16_t dqo_target_queue; // version 5 and later, starting with Mac OS X
+ // 10.10/iOS 8
+ uint16_t dqo_target_queue_size; // version 5 and later, starting with Mac OS
+ // X 10.10/iOS 8
+ uint16_t
+ dqo_priority; // version 5 and later, starting with Mac OS X 10.10/iOS 8
+ uint16_t dqo_priority_size; // version 5 and later, starting with Mac OS X
+ // 10.10/iOS 8
+
+ LibdispatchOffsets() {
+ dqo_version = UINT16_MAX;
+ dqo_flags = UINT16_MAX;
+ dqo_serialnum = UINT16_MAX;
+ dqo_label = UINT16_MAX;
+ dqo_width = UINT16_MAX;
+ dqo_running = UINT16_MAX;
+ dqo_suspend_cnt = UINT16_MAX;
+ dqo_target_queue = UINT16_MAX;
+ dqo_target_queue = UINT16_MAX;
+ dqo_priority = UINT16_MAX;
+ }
+
+ bool IsValid() { return dqo_version != UINT16_MAX; }
+
+ bool LabelIsValid() { return dqo_label != UINT16_MAX; }
+ };
+
+ struct LibdispatchVoucherOffsets {
+ uint16_t vo_version;
+ uint16_t vo_activity_ids_count;
+ uint16_t vo_activity_ids_count_size;
+ uint16_t vo_activity_ids_array;
+ uint16_t vo_activity_ids_array_entry_size;
+
+ LibdispatchVoucherOffsets()
+ : vo_version(UINT16_MAX), vo_activity_ids_count(UINT16_MAX),
+ vo_activity_ids_count_size(UINT16_MAX),
+ vo_activity_ids_array(UINT16_MAX),
+ vo_activity_ids_array_entry_size(UINT16_MAX) {}
+
+ bool IsValid() { return vo_version != UINT16_MAX; }
+ };
+
+ struct LibdispatchTSDIndexes {
+ uint16_t dti_version;
+ uint64_t dti_queue_index;
+ uint64_t dti_voucher_index;
+ uint64_t dti_qos_class_index;
+
+ LibdispatchTSDIndexes()
+ : dti_version(UINT16_MAX), dti_queue_index(UINT64_MAX),
+ dti_voucher_index(UINT64_MAX), dti_qos_class_index(UINT64_MAX) {}
+
+ bool IsValid() { return dti_version != UINT16_MAX; }
+ };
+
+ struct LibpthreadOffsets {
+ uint16_t plo_version;
+ uint16_t plo_pthread_tsd_base_offset;
+ uint16_t plo_pthread_tsd_base_address_offset;
+ uint16_t plo_pthread_tsd_entry_size;
+
+ LibpthreadOffsets()
+ : plo_version(UINT16_MAX), plo_pthread_tsd_base_offset(UINT16_MAX),
+ plo_pthread_tsd_base_address_offset(UINT16_MAX),
+ plo_pthread_tsd_entry_size(UINT16_MAX) {}
+
+ bool IsValid() { return plo_version != UINT16_MAX; }
+ };
+
+ // The libBacktraceRecording function
+ // __introspection_dispatch_queue_get_pending_items has
+ // two forms. It can either return a simple array of item_refs (void *) size
+ // or it can return
+ // a header with uint32_t version, a uint32_t size of item, and then an array
+ // of item_refs (void*)
+ // and code addresses (void*) for all the pending blocks.
+
+ struct ItemRefAndCodeAddress {
+ lldb::addr_t item_ref;
+ lldb::addr_t code_address;
+ };
+
+ struct PendingItemsForQueue {
+ bool new_style; // new-style means both item_refs and code_addresses avail
+ // old-style means only item_refs is filled in
+ std::vector<ItemRefAndCodeAddress> item_refs_and_code_addresses;
+ };
+
+ bool BacktraceRecordingHeadersInitialized();
+
+ void ReadLibdispatchOffsetsAddress();
+
+ void ReadLibdispatchOffsets();
+
+ void ReadLibpthreadOffsetsAddress();
+
+ void ReadLibpthreadOffsets();
+
+ void ReadLibdispatchTSDIndexesAddress();
+
+ void ReadLibdispatchTSDIndexes();
+
+ PendingItemsForQueue GetPendingItemRefsForQueue(lldb::addr_t queue);
+
+ ItemInfo ExtractItemInfoFromBuffer(lldb_private::DataExtractor &extractor);
+
+ lldb_private::AppleGetQueuesHandler m_get_queues_handler;
+ lldb_private::AppleGetPendingItemsHandler m_get_pending_items_handler;
+ lldb_private::AppleGetItemInfoHandler m_get_item_info_handler;
+ lldb_private::AppleGetThreadItemInfoHandler m_get_thread_item_info_handler;
+
+ lldb::addr_t m_page_to_free;
+ uint64_t m_page_to_free_size;
+ libBacktraceRecording_info m_lib_backtrace_recording_info;
+
+ lldb::addr_t m_dispatch_queue_offsets_addr;
+ struct LibdispatchOffsets m_libdispatch_offsets;
+
+ lldb::addr_t m_libpthread_layout_offsets_addr;
+ struct LibpthreadOffsets m_libpthread_offsets;
- lldb::addr_t m_dispatch_tsd_indexes_addr;
- struct LibdispatchTSDIndexes m_libdispatch_tsd_indexes;
+ lldb::addr_t m_dispatch_tsd_indexes_addr;
+ struct LibdispatchTSDIndexes m_libdispatch_tsd_indexes;
- lldb::addr_t m_dispatch_voucher_offsets_addr;
- struct LibdispatchVoucherOffsets m_libdispatch_voucher_offsets;
+ lldb::addr_t m_dispatch_voucher_offsets_addr;
+ struct LibdispatchVoucherOffsets m_libdispatch_voucher_offsets;
- DISALLOW_COPY_AND_ASSIGN (SystemRuntimeMacOSX);
+ DISALLOW_COPY_AND_ASSIGN(SystemRuntimeMacOSX);
};
#endif // liblldb_SystemRuntimeMacOSX_h_
Modified: lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp Tue Sep 6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- UnwindAssemblyInstEmulation.cpp --------------------------*- C++ -*-===//
+//===-- UnwindAssemblyInstEmulation.cpp --------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,658 +22,614 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-
-
//-----------------------------------------------------------------------------------------------
-// UnwindAssemblyInstEmulation method definitions
+// UnwindAssemblyInstEmulation method definitions
//-----------------------------------------------------------------------------------------------
-bool
-UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& range,
- Thread& thread,
- UnwindPlan& unwind_plan)
-{
- if (range.GetByteSize() > 0 &&
- range.GetBaseAddress().IsValid() &&
- m_inst_emulator_ap.get())
- {
-
- // The instruction emulation subclass setup the unwind plan for the
- // first instruction.
- m_inst_emulator_ap->CreateFunctionEntryUnwind (unwind_plan);
-
- // CreateFunctionEntryUnwind should have created the first row. If it
- // doesn't, then we are done.
- if (unwind_plan.GetRowCount() == 0)
- return false;
-
- ExecutionContext exe_ctx;
- thread.CalculateExecutionContext(exe_ctx);
- const bool prefer_file_cache = true;
- DisassemblerSP disasm_sp (Disassembler::DisassembleRange (m_arch,
- NULL,
- NULL,
- exe_ctx,
- range,
- prefer_file_cache));
-
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (disasm_sp)
- {
-
- m_range_ptr = ⦥
- m_thread_ptr = &thread;
- m_unwind_plan_ptr = &unwind_plan;
-
- const uint32_t addr_byte_size = m_arch.GetAddressByteSize();
- const bool show_address = true;
- const bool show_bytes = true;
- m_inst_emulator_ap->GetRegisterInfo (unwind_plan.GetRegisterKind(),
- unwind_plan.GetInitialCFARegister(),
- m_cfa_reg_info);
-
- m_fp_is_cfa = false;
- m_register_values.clear();
- m_pushed_regs.clear();
-
- // Initialize the CFA with a known value. In the 32 bit case
- // it will be 0x80000000, and in the 64 bit case 0x8000000000000000.
- // We use the address byte size to be safe for any future address sizes
- m_initial_sp = (1ull << ((addr_byte_size * 8) - 1));
- RegisterValue cfa_reg_value;
- cfa_reg_value.SetUInt (m_initial_sp, m_cfa_reg_info.byte_size);
- SetRegisterValue (m_cfa_reg_info, cfa_reg_value);
-
- const InstructionList &inst_list = disasm_sp->GetInstructionList ();
- const size_t num_instructions = inst_list.GetSize();
-
- if (num_instructions > 0)
- {
- Instruction *inst = inst_list.GetInstructionAtIndex (0).get();
- const lldb::addr_t base_addr = inst->GetAddress().GetFileAddress();
-
- // Map for storing the unwind plan row and the value of the registers at a given offset.
- // When we see a forward branch we add a new entry to this map with the actual unwind plan
- // row and register context for the target address of the branch as the current data have
- // to be valid for the target address of the branch too if we are in the same function.
- std::map<lldb::addr_t, std::pair<UnwindPlan::RowSP, RegisterValueMap>> saved_unwind_states;
-
- // Make a copy of the current instruction Row and save it in m_curr_row
- // so we can add updates as we process the instructions.
- UnwindPlan::RowSP last_row = unwind_plan.GetLastRow();
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- if (last_row.get())
- *newrow = *last_row.get();
- m_curr_row.reset(newrow);
+bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
+ AddressRange &range, Thread &thread, UnwindPlan &unwind_plan) {
+ if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid() &&
+ m_inst_emulator_ap.get()) {
+
+ // The instruction emulation subclass setup the unwind plan for the
+ // first instruction.
+ m_inst_emulator_ap->CreateFunctionEntryUnwind(unwind_plan);
+
+ // CreateFunctionEntryUnwind should have created the first row. If it
+ // doesn't, then we are done.
+ if (unwind_plan.GetRowCount() == 0)
+ return false;
+
+ ExecutionContext exe_ctx;
+ thread.CalculateExecutionContext(exe_ctx);
+ const bool prefer_file_cache = true;
+ DisassemblerSP disasm_sp(Disassembler::DisassembleRange(
+ m_arch, NULL, NULL, exe_ctx, range, prefer_file_cache));
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (disasm_sp) {
+
+ m_range_ptr = ⦥
+ m_thread_ptr = &thread;
+ m_unwind_plan_ptr = &unwind_plan;
+
+ const uint32_t addr_byte_size = m_arch.GetAddressByteSize();
+ const bool show_address = true;
+ const bool show_bytes = true;
+ m_inst_emulator_ap->GetRegisterInfo(unwind_plan.GetRegisterKind(),
+ unwind_plan.GetInitialCFARegister(),
+ m_cfa_reg_info);
+
+ m_fp_is_cfa = false;
+ m_register_values.clear();
+ m_pushed_regs.clear();
+
+ // Initialize the CFA with a known value. In the 32 bit case
+ // it will be 0x80000000, and in the 64 bit case 0x8000000000000000.
+ // We use the address byte size to be safe for any future address sizes
+ m_initial_sp = (1ull << ((addr_byte_size * 8) - 1));
+ RegisterValue cfa_reg_value;
+ cfa_reg_value.SetUInt(m_initial_sp, m_cfa_reg_info.byte_size);
+ SetRegisterValue(m_cfa_reg_info, cfa_reg_value);
+
+ const InstructionList &inst_list = disasm_sp->GetInstructionList();
+ const size_t num_instructions = inst_list.GetSize();
+
+ if (num_instructions > 0) {
+ Instruction *inst = inst_list.GetInstructionAtIndex(0).get();
+ const lldb::addr_t base_addr = inst->GetAddress().GetFileAddress();
+
+ // Map for storing the unwind plan row and the value of the registers at
+ // a given offset.
+ // When we see a forward branch we add a new entry to this map with the
+ // actual unwind plan
+ // row and register context for the target address of the branch as the
+ // current data have
+ // to be valid for the target address of the branch too if we are in the
+ // same function.
+ std::map<lldb::addr_t, std::pair<UnwindPlan::RowSP, RegisterValueMap>>
+ saved_unwind_states;
+
+ // Make a copy of the current instruction Row and save it in m_curr_row
+ // so we can add updates as we process the instructions.
+ UnwindPlan::RowSP last_row = unwind_plan.GetLastRow();
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ if (last_row.get())
+ *newrow = *last_row.get();
+ m_curr_row.reset(newrow);
+
+ // Add the initial state to the save list with offset 0.
+ saved_unwind_states.insert({0, {last_row, m_register_values}});
+
+ // cache the pc register number (in whatever register numbering this
+ // UnwindPlan uses) for
+ // quick reference during instruction parsing.
+ RegisterInfo pc_reg_info;
+ m_inst_emulator_ap->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info);
+
+ // cache the return address register number (in whatever register
+ // numbering this UnwindPlan uses) for
+ // quick reference during instruction parsing.
+ RegisterInfo ra_reg_info;
+ m_inst_emulator_ap->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info);
+
+ // The architecture dependent condition code of the last processed
+ // instruction.
+ EmulateInstruction::InstructionCondition last_condition =
+ EmulateInstruction::UnconditionalCondition;
+ lldb::addr_t condition_block_start_offset = 0;
+
+ for (size_t idx = 0; idx < num_instructions; ++idx) {
+ m_curr_row_modified = false;
+ m_forward_branch_offset = 0;
+
+ inst = inst_list.GetInstructionAtIndex(idx).get();
+ if (inst) {
+ lldb::addr_t current_offset =
+ inst->GetAddress().GetFileAddress() - base_addr;
+ auto it = saved_unwind_states.upper_bound(current_offset);
+ assert(it != saved_unwind_states.begin() &&
+ "Unwind row for the function entry missing");
+ --it; // Move it to the row corresponding to the current offset
+
+ // If the offset of m_curr_row don't match with the offset we see in
+ // saved_unwind_states
+ // then we have to update m_curr_row and m_register_values based on
+ // the saved values. It
+ // is happenning after we processed an epilogue and a return to
+ // caller instruction.
+ if (it->second.first->GetOffset() != m_curr_row->GetOffset()) {
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *it->second.first;
+ m_curr_row.reset(newrow);
+ m_register_values = it->second.second;
+ }
+
+ m_inst_emulator_ap->SetInstruction(
+ inst->GetOpcode(), inst->GetAddress(), exe_ctx.GetTargetPtr());
- // Add the initial state to the save list with offset 0.
- saved_unwind_states.insert({0, {last_row, m_register_values}});
+ if (last_condition !=
+ m_inst_emulator_ap->GetInstructionCondition()) {
+ if (m_inst_emulator_ap->GetInstructionCondition() !=
+ EmulateInstruction::UnconditionalCondition &&
+ saved_unwind_states.count(current_offset) == 0) {
+ // If we don't have a saved row for the current offset then save
+ // our
+ // current state because we will have to restore it after the
+ // conditional block.
+ auto new_row =
+ std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
+ saved_unwind_states.insert(
+ {current_offset, {new_row, m_register_values}});
+ }
+
+ // If the last instruction was conditional with a different
+ // condition
+ // then the then current condition then restore the condition.
+ if (last_condition !=
+ EmulateInstruction::UnconditionalCondition) {
+ const auto &saved_state =
+ saved_unwind_states.at(condition_block_start_offset);
+ m_curr_row =
+ std::make_shared<UnwindPlan::Row>(*saved_state.first);
+ m_curr_row->SetOffset(current_offset);
+ m_register_values = saved_state.second;
+ bool replace_existing =
+ true; // The last instruction might already
+ // created a row for this offset and
+ // we want to overwrite it.
+ unwind_plan.InsertRow(
+ std::make_shared<UnwindPlan::Row>(*m_curr_row),
+ replace_existing);
+ }
- // cache the pc register number (in whatever register numbering this UnwindPlan uses) for
- // quick reference during instruction parsing.
- RegisterInfo pc_reg_info;
- m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info);
-
- // cache the return address register number (in whatever register numbering this UnwindPlan uses) for
- // quick reference during instruction parsing.
- RegisterInfo ra_reg_info;
- m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info);
-
- // The architecture dependent condition code of the last processed instruction.
- EmulateInstruction::InstructionCondition last_condition = EmulateInstruction::UnconditionalCondition;
- lldb::addr_t condition_block_start_offset = 0;
-
- for (size_t idx=0; idx<num_instructions; ++idx)
- {
- m_curr_row_modified = false;
- m_forward_branch_offset = 0;
-
- inst = inst_list.GetInstructionAtIndex (idx).get();
- if (inst)
- {
- lldb::addr_t current_offset = inst->GetAddress().GetFileAddress() - base_addr;
- auto it = saved_unwind_states.upper_bound(current_offset);
- assert(it != saved_unwind_states.begin() && "Unwind row for the function entry missing");
- --it; // Move it to the row corresponding to the current offset
-
- // If the offset of m_curr_row don't match with the offset we see in saved_unwind_states
- // then we have to update m_curr_row and m_register_values based on the saved values. It
- // is happenning after we processed an epilogue and a return to caller instruction.
- if (it->second.first->GetOffset() != m_curr_row->GetOffset())
- {
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *it->second.first;
- m_curr_row.reset(newrow);
- m_register_values = it->second.second;
- }
-
- m_inst_emulator_ap->SetInstruction (inst->GetOpcode(),
- inst->GetAddress(),
- exe_ctx.GetTargetPtr());
-
- if (last_condition != m_inst_emulator_ap->GetInstructionCondition())
- {
- if (m_inst_emulator_ap->GetInstructionCondition() != EmulateInstruction::UnconditionalCondition &&
- saved_unwind_states.count(current_offset) == 0)
- {
- // If we don't have a saved row for the current offset then save our
- // current state because we will have to restore it after the
- // conditional block.
- auto new_row = std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
- saved_unwind_states.insert({current_offset, {new_row, m_register_values}});
- }
-
- // If the last instruction was conditional with a different condition
- // then the then current condition then restore the condition.
- if (last_condition != EmulateInstruction::UnconditionalCondition)
- {
- const auto& saved_state = saved_unwind_states.at(condition_block_start_offset);
- m_curr_row = std::make_shared<UnwindPlan::Row>(*saved_state.first);
- m_curr_row->SetOffset(current_offset);
- m_register_values = saved_state.second;
- bool replace_existing = true; // The last instruction might already
- // created a row for this offset and
- // we want to overwrite it.
- unwind_plan.InsertRow(std::make_shared<UnwindPlan::Row>(*m_curr_row), replace_existing);
- }
-
- // We are starting a new conditional block at the catual offset
- condition_block_start_offset = current_offset;
- }
-
- if (log && log->GetVerbose ())
- {
- StreamString strm;
- lldb_private::FormatEntity::Entry format;
- FormatEntity::Parse("${frame.pc}: ", format);
- inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, &format, 0);
- log->PutCString (strm.GetData());
- }
-
- last_condition = m_inst_emulator_ap->GetInstructionCondition();
-
- m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);
-
- // If the current instruction is a branch forward then save the current CFI information
- // for the offset where we are branching.
- if (m_forward_branch_offset != 0 && range.ContainsFileAddress(inst->GetAddress().GetFileAddress() + m_forward_branch_offset))
- {
- auto newrow = std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
- newrow->SetOffset(current_offset + m_forward_branch_offset);
- saved_unwind_states.insert({current_offset + m_forward_branch_offset, {newrow, m_register_values}});
- unwind_plan.InsertRow(newrow);
- }
-
- // Were there any changes to the CFI while evaluating this instruction?
- if (m_curr_row_modified)
- {
- // Save the modified row if we don't already have a CFI row in the currennt address
- if (saved_unwind_states.count(current_offset + inst->GetOpcode().GetByteSize()) == 0)
- {
- m_curr_row->SetOffset (current_offset + inst->GetOpcode().GetByteSize());
- unwind_plan.InsertRow (m_curr_row);
- saved_unwind_states.insert({current_offset + inst->GetOpcode().GetByteSize(), {m_curr_row, m_register_values}});
-
- // Allocate a new Row for m_curr_row, copy the current state into it
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *m_curr_row.get();
- m_curr_row.reset(newrow);
- }
- }
- }
- }
+ // We are starting a new conditional block at the catual offset
+ condition_block_start_offset = current_offset;
}
- }
-
- if (log && log->GetVerbose ())
- {
- StreamString strm;
- lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(thread.CalculateTarget().get());
- strm.Printf ("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):", base_addr, base_addr + range.GetByteSize());
- unwind_plan.Dump(strm, &thread, base_addr);
- log->PutCString (strm.GetData());
- }
- return unwind_plan.GetRowCount() > 0;
- }
- return false;
-}
-bool
-UnwindAssemblyInstEmulation::AugmentUnwindPlanFromCallSite (AddressRange& func,
- Thread& thread,
- UnwindPlan& unwind_plan)
-{
- return false;
-}
-
-bool
-UnwindAssemblyInstEmulation::GetFastUnwindPlan (AddressRange& func,
- Thread& thread,
- UnwindPlan &unwind_plan)
-{
- return false;
-}
-
-bool
-UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func,
- const ExecutionContext &exe_ctx,
- Address& first_non_prologue_insn)
-{
- return false;
-}
+ if (log && log->GetVerbose()) {
+ StreamString strm;
+ lldb_private::FormatEntity::Entry format;
+ FormatEntity::Parse("${frame.pc}: ", format);
+ inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize(), show_address,
+ show_bytes, NULL, NULL, NULL, &format, 0);
+ log->PutCString(strm.GetData());
+ }
-UnwindAssembly *
-UnwindAssemblyInstEmulation::CreateInstance (const ArchSpec &arch)
-{
- std::unique_ptr<EmulateInstruction> inst_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypePrologueEpilogue, NULL));
- // Make sure that all prologue instructions are handled
- if (inst_emulator_ap.get())
- return new UnwindAssemblyInstEmulation (arch, inst_emulator_ap.release());
- return NULL;
-}
+ last_condition = m_inst_emulator_ap->GetInstructionCondition();
+ m_inst_emulator_ap->EvaluateInstruction(
+ eEmulateInstructionOptionIgnoreConditions);
-//------------------------------------------------------------------
-// PluginInterface protocol in UnwindAssemblyParser_x86
-//------------------------------------------------------------------
-ConstString
-UnwindAssemblyInstEmulation::GetPluginName()
-{
- return GetPluginNameStatic();
-}
+ // If the current instruction is a branch forward then save the
+ // current CFI information
+ // for the offset where we are branching.
+ if (m_forward_branch_offset != 0 &&
+ range.ContainsFileAddress(inst->GetAddress().GetFileAddress() +
+ m_forward_branch_offset)) {
+ auto newrow =
+ std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
+ newrow->SetOffset(current_offset + m_forward_branch_offset);
+ saved_unwind_states.insert(
+ {current_offset + m_forward_branch_offset,
+ {newrow, m_register_values}});
+ unwind_plan.InsertRow(newrow);
+ }
-uint32_t
-UnwindAssemblyInstEmulation::GetPluginVersion()
-{
- return 1;
-}
+ // Were there any changes to the CFI while evaluating this
+ // instruction?
+ if (m_curr_row_modified) {
+ // Save the modified row if we don't already have a CFI row in the
+ // currennt address
+ if (saved_unwind_states.count(
+ current_offset + inst->GetOpcode().GetByteSize()) == 0) {
+ m_curr_row->SetOffset(current_offset +
+ inst->GetOpcode().GetByteSize());
+ unwind_plan.InsertRow(m_curr_row);
+ saved_unwind_states.insert(
+ {current_offset + inst->GetOpcode().GetByteSize(),
+ {m_curr_row, m_register_values}});
-void
-UnwindAssemblyInstEmulation::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
+ // Allocate a new Row for m_curr_row, copy the current state
+ // into it
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *m_curr_row.get();
+ m_curr_row.reset(newrow);
+ }
+ }
+ }
+ }
+ }
+ }
-void
-UnwindAssemblyInstEmulation::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+ if (log && log->GetVerbose()) {
+ StreamString strm;
+ lldb::addr_t base_addr =
+ range.GetBaseAddress().GetLoadAddress(thread.CalculateTarget().get());
+ strm.Printf("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):",
+ base_addr, base_addr + range.GetByteSize());
+ unwind_plan.Dump(strm, &thread, base_addr);
+ log->PutCString(strm.GetData());
+ }
+ return unwind_plan.GetRowCount() > 0;
+ }
+ return false;
}
-
-ConstString
-UnwindAssemblyInstEmulation::GetPluginNameStatic()
-{
- static ConstString g_name("inst-emulation");
- return g_name;
+bool UnwindAssemblyInstEmulation::AugmentUnwindPlanFromCallSite(
+ AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
+ return false;
}
-const char *
-UnwindAssemblyInstEmulation::GetPluginDescriptionStatic()
-{
- return "Instruction emulation based unwind information.";
+bool UnwindAssemblyInstEmulation::GetFastUnwindPlan(AddressRange &func,
+ Thread &thread,
+ UnwindPlan &unwind_plan) {
+ return false;
}
-
-uint64_t
-UnwindAssemblyInstEmulation::MakeRegisterKindValuePair (const RegisterInfo ®_info)
-{
- lldb::RegisterKind reg_kind;
- uint32_t reg_num;
- if (EmulateInstruction::GetBestRegisterKindAndNumber (®_info, reg_kind, reg_num))
- return (uint64_t)reg_kind << 24 | reg_num;
- return 0ull;
+bool UnwindAssemblyInstEmulation::FirstNonPrologueInsn(
+ AddressRange &func, const ExecutionContext &exe_ctx,
+ Address &first_non_prologue_insn) {
+ return false;
}
-void
-UnwindAssemblyInstEmulation::SetRegisterValue (const RegisterInfo ®_info, const RegisterValue ®_value)
-{
- m_register_values[MakeRegisterKindValuePair (reg_info)] = reg_value;
+UnwindAssembly *
+UnwindAssemblyInstEmulation::CreateInstance(const ArchSpec &arch) {
+ std::unique_ptr<EmulateInstruction> inst_emulator_ap(
+ EmulateInstruction::FindPlugin(arch, eInstructionTypePrologueEpilogue,
+ NULL));
+ // Make sure that all prologue instructions are handled
+ if (inst_emulator_ap.get())
+ return new UnwindAssemblyInstEmulation(arch, inst_emulator_ap.release());
+ return NULL;
}
-bool
-UnwindAssemblyInstEmulation::GetRegisterValue (const RegisterInfo ®_info, RegisterValue ®_value)
-{
- const uint64_t reg_id = MakeRegisterKindValuePair (reg_info);
- RegisterValueMap::const_iterator pos = m_register_values.find(reg_id);
- if (pos != m_register_values.end())
- {
- reg_value = pos->second;
- return true; // We had a real value that comes from an opcode that wrote
- // to it...
- }
- // We are making up a value that is recognizable...
- reg_value.SetUInt(reg_id, reg_info.byte_size);
- return false;
+//------------------------------------------------------------------
+// PluginInterface protocol in UnwindAssemblyParser_x86
+//------------------------------------------------------------------
+ConstString UnwindAssemblyInstEmulation::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t UnwindAssemblyInstEmulation::GetPluginVersion() { return 1; }
-size_t
-UnwindAssemblyInstEmulation::ReadMemory (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t dst_len)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (log && log->GetVerbose ())
- {
- StreamString strm;
- strm.Printf ("UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16" PRIx64 ", dst = %p, dst_len = %" PRIu64 ", context = ",
- addr,
- dst,
- (uint64_t)dst_len);
- context.Dump(strm, instruction);
- log->PutCString (strm.GetData ());
+void UnwindAssemblyInstEmulation::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void UnwindAssemblyInstEmulation::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString UnwindAssemblyInstEmulation::GetPluginNameStatic() {
+ static ConstString g_name("inst-emulation");
+ return g_name;
+}
+
+const char *UnwindAssemblyInstEmulation::GetPluginDescriptionStatic() {
+ return "Instruction emulation based unwind information.";
+}
+
+uint64_t UnwindAssemblyInstEmulation::MakeRegisterKindValuePair(
+ const RegisterInfo ®_info) {
+ lldb::RegisterKind reg_kind;
+ uint32_t reg_num;
+ if (EmulateInstruction::GetBestRegisterKindAndNumber(®_info, reg_kind,
+ reg_num))
+ return (uint64_t)reg_kind << 24 | reg_num;
+ return 0ull;
+}
+
+void UnwindAssemblyInstEmulation::SetRegisterValue(
+ const RegisterInfo ®_info, const RegisterValue ®_value) {
+ m_register_values[MakeRegisterKindValuePair(reg_info)] = reg_value;
+}
+
+bool UnwindAssemblyInstEmulation::GetRegisterValue(const RegisterInfo ®_info,
+ RegisterValue ®_value) {
+ const uint64_t reg_id = MakeRegisterKindValuePair(reg_info);
+ RegisterValueMap::const_iterator pos = m_register_values.find(reg_id);
+ if (pos != m_register_values.end()) {
+ reg_value = pos->second;
+ return true; // We had a real value that comes from an opcode that wrote
+ // to it...
+ }
+ // We are making up a value that is recognizable...
+ reg_value.SetUInt(reg_id, reg_info.byte_size);
+ return false;
+}
+
+size_t UnwindAssemblyInstEmulation::ReadMemory(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
+ size_t dst_len) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (log && log->GetVerbose()) {
+ StreamString strm;
+ strm.Printf(
+ "UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16" PRIx64
+ ", dst = %p, dst_len = %" PRIu64 ", context = ",
+ addr, dst, (uint64_t)dst_len);
+ context.Dump(strm, instruction);
+ log->PutCString(strm.GetData());
+ }
+ memset(dst, 0, dst_len);
+ return dst_len;
+}
+
+size_t UnwindAssemblyInstEmulation::WriteMemory(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, lldb::addr_t addr,
+ const void *dst, size_t dst_len) {
+ if (baton && dst && dst_len)
+ return ((UnwindAssemblyInstEmulation *)baton)
+ ->WriteMemory(instruction, context, addr, dst, dst_len);
+ return 0;
+}
+
+size_t UnwindAssemblyInstEmulation::WriteMemory(
+ EmulateInstruction *instruction, const EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst, size_t dst_len) {
+ DataExtractor data(dst, dst_len,
+ instruction->GetArchitecture().GetByteOrder(),
+ instruction->GetArchitecture().GetAddressByteSize());
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (log && log->GetVerbose()) {
+ StreamString strm;
+
+ strm.PutCString("UnwindAssemblyInstEmulation::WriteMemory (");
+ data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
+ strm.PutCString(", context = ");
+ context.Dump(strm, instruction);
+ log->PutCString(strm.GetData());
+ }
+
+ const bool cant_replace = false;
+
+ switch (context.type) {
+ default:
+ case EmulateInstruction::eContextInvalid:
+ case EmulateInstruction::eContextReadOpcode:
+ case EmulateInstruction::eContextImmediate:
+ case EmulateInstruction::eContextAdjustBaseRegister:
+ case EmulateInstruction::eContextRegisterPlusOffset:
+ case EmulateInstruction::eContextAdjustPC:
+ case EmulateInstruction::eContextRegisterStore:
+ case EmulateInstruction::eContextRegisterLoad:
+ case EmulateInstruction::eContextRelativeBranchImmediate:
+ case EmulateInstruction::eContextAbsoluteBranchRegister:
+ case EmulateInstruction::eContextSupervisorCall:
+ case EmulateInstruction::eContextTableBranchReadMemory:
+ case EmulateInstruction::eContextWriteRegisterRandomBits:
+ case EmulateInstruction::eContextWriteMemoryRandomBits:
+ case EmulateInstruction::eContextArithmetic:
+ case EmulateInstruction::eContextAdvancePC:
+ case EmulateInstruction::eContextReturnFromException:
+ case EmulateInstruction::eContextPopRegisterOffStack:
+ case EmulateInstruction::eContextAdjustStackPointer:
+ break;
+
+ case EmulateInstruction::eContextPushRegisterOnStack: {
+ uint32_t reg_num = LLDB_INVALID_REGNUM;
+ uint32_t generic_regnum = LLDB_INVALID_REGNUM;
+ if (context.info_type ==
+ EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset) {
+ const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
+ reg_num = context.info.RegisterToRegisterPlusOffset.data_reg
+ .kinds[unwind_reg_kind];
+ generic_regnum = context.info.RegisterToRegisterPlusOffset.data_reg
+ .kinds[eRegisterKindGeneric];
+ } else
+ assert(!"unhandled case, add code to handle this!");
+
+ if (reg_num != LLDB_INVALID_REGNUM &&
+ generic_regnum != LLDB_REGNUM_GENERIC_SP) {
+ if (m_pushed_regs.find(reg_num) == m_pushed_regs.end()) {
+ m_pushed_regs[reg_num] = addr;
+ const int32_t offset = addr - m_initial_sp;
+ m_curr_row->SetRegisterLocationToAtCFAPlusOffset(reg_num, offset,
+ cant_replace);
+ m_curr_row_modified = true;
+ }
}
- memset (dst, 0, dst_len);
- return dst_len;
+ } break;
+ }
+
+ return dst_len;
}
-size_t
-UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t dst_len)
-{
- if (baton && dst && dst_len)
- return ((UnwindAssemblyInstEmulation *)baton)->WriteMemory (instruction, context, addr, dst, dst_len);
- return 0;
-}
-
-size_t
-UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t dst_len)
-{
- DataExtractor data (dst,
- dst_len,
- instruction->GetArchitecture ().GetByteOrder(),
- instruction->GetArchitecture ().GetAddressByteSize());
-
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (log && log->GetVerbose ())
- {
- StreamString strm;
-
- strm.PutCString ("UnwindAssemblyInstEmulation::WriteMemory (");
- data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
- strm.PutCString (", context = ");
- context.Dump(strm, instruction);
- log->PutCString (strm.GetData());
+bool UnwindAssemblyInstEmulation::ReadRegister(EmulateInstruction *instruction,
+ void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue ®_value) {
+
+ if (baton && reg_info)
+ return ((UnwindAssemblyInstEmulation *)baton)
+ ->ReadRegister(instruction, reg_info, reg_value);
+ return false;
+}
+bool UnwindAssemblyInstEmulation::ReadRegister(EmulateInstruction *instruction,
+ const RegisterInfo *reg_info,
+ RegisterValue ®_value) {
+ bool synthetic = GetRegisterValue(*reg_info, reg_value);
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (log && log->GetVerbose()) {
+
+ StreamString strm;
+ strm.Printf("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => "
+ "synthetic_value = %i, value = ",
+ reg_info->name, synthetic);
+ reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
+ log->PutCString(strm.GetData());
+ }
+ return true;
+}
+
+bool UnwindAssemblyInstEmulation::WriteRegister(
+ EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context, const RegisterInfo *reg_info,
+ const RegisterValue ®_value) {
+ if (baton && reg_info)
+ return ((UnwindAssemblyInstEmulation *)baton)
+ ->WriteRegister(instruction, context, reg_info, reg_value);
+ return false;
+}
+bool UnwindAssemblyInstEmulation::WriteRegister(
+ EmulateInstruction *instruction, const EmulateInstruction::Context &context,
+ const RegisterInfo *reg_info, const RegisterValue ®_value) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ if (log && log->GetVerbose()) {
+
+ StreamString strm;
+ strm.Printf(
+ "UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ",
+ reg_info->name);
+ reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
+ strm.PutCString(", context = ");
+ context.Dump(strm, instruction);
+ log->PutCString(strm.GetData());
+ }
+
+ SetRegisterValue(*reg_info, reg_value);
+
+ switch (context.type) {
+ case EmulateInstruction::eContextInvalid:
+ case EmulateInstruction::eContextReadOpcode:
+ case EmulateInstruction::eContextImmediate:
+ case EmulateInstruction::eContextAdjustBaseRegister:
+ case EmulateInstruction::eContextRegisterPlusOffset:
+ case EmulateInstruction::eContextAdjustPC:
+ case EmulateInstruction::eContextRegisterStore:
+ case EmulateInstruction::eContextSupervisorCall:
+ case EmulateInstruction::eContextTableBranchReadMemory:
+ case EmulateInstruction::eContextWriteRegisterRandomBits:
+ case EmulateInstruction::eContextWriteMemoryRandomBits:
+ case EmulateInstruction::eContextAdvancePC:
+ case EmulateInstruction::eContextReturnFromException:
+ case EmulateInstruction::eContextPushRegisterOnStack:
+ case EmulateInstruction::eContextRegisterLoad:
+ // {
+ // const uint32_t reg_num =
+ // reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ // if (reg_num != LLDB_INVALID_REGNUM)
+ // {
+ // const bool can_replace_only_if_unspecified = true;
+ //
+ // m_curr_row.SetRegisterLocationToUndefined (reg_num,
+ // can_replace_only_if_unspecified,
+ // can_replace_only_if_unspecified);
+ // m_curr_row_modified = true;
+ // }
+ // }
+ break;
+
+ case EmulateInstruction::eContextArithmetic: {
+ // If we adjusted the current frame pointer by a constant then adjust the
+ // CFA offset
+ // with the same amount.
+ lldb::RegisterKind kind = m_unwind_plan_ptr->GetRegisterKind();
+ if (m_fp_is_cfa && reg_info->kinds[kind] == m_cfa_reg_info.kinds[kind] &&
+ context.info_type == EmulateInstruction::eInfoTypeRegisterPlusOffset &&
+ context.info.RegisterPlusOffset.reg.kinds[kind] ==
+ m_cfa_reg_info.kinds[kind]) {
+ const int64_t offset = context.info.RegisterPlusOffset.signed_offset;
+ m_curr_row->GetCFAValue().IncOffset(-1 * offset);
+ m_curr_row_modified = true;
}
+ } break;
- const bool cant_replace = false;
-
- switch (context.type)
- {
- default:
- case EmulateInstruction::eContextInvalid:
- case EmulateInstruction::eContextReadOpcode:
- case EmulateInstruction::eContextImmediate:
- case EmulateInstruction::eContextAdjustBaseRegister:
- case EmulateInstruction::eContextRegisterPlusOffset:
- case EmulateInstruction::eContextAdjustPC:
- case EmulateInstruction::eContextRegisterStore:
- case EmulateInstruction::eContextRegisterLoad:
- case EmulateInstruction::eContextRelativeBranchImmediate:
- case EmulateInstruction::eContextAbsoluteBranchRegister:
- case EmulateInstruction::eContextSupervisorCall:
- case EmulateInstruction::eContextTableBranchReadMemory:
- case EmulateInstruction::eContextWriteRegisterRandomBits:
- case EmulateInstruction::eContextWriteMemoryRandomBits:
- case EmulateInstruction::eContextArithmetic:
- case EmulateInstruction::eContextAdvancePC:
- case EmulateInstruction::eContextReturnFromException:
- case EmulateInstruction::eContextPopRegisterOffStack:
- case EmulateInstruction::eContextAdjustStackPointer:
- break;
-
- case EmulateInstruction::eContextPushRegisterOnStack:
- {
- uint32_t reg_num = LLDB_INVALID_REGNUM;
- uint32_t generic_regnum = LLDB_INVALID_REGNUM;
- if (context.info_type == EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset)
- {
- const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
- reg_num = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[unwind_reg_kind];
- generic_regnum = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[eRegisterKindGeneric];
- }
- else
- assert (!"unhandled case, add code to handle this!");
-
- if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP)
- {
- if (m_pushed_regs.find (reg_num) == m_pushed_regs.end())
- {
- m_pushed_regs[reg_num] = addr;
- const int32_t offset = addr - m_initial_sp;
- m_curr_row->SetRegisterLocationToAtCFAPlusOffset (reg_num, offset, cant_replace);
- m_curr_row_modified = true;
- }
- }
- }
- break;
-
+ case EmulateInstruction::eContextAbsoluteBranchRegister:
+ case EmulateInstruction::eContextRelativeBranchImmediate: {
+ if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediate &&
+ context.info.ISAAndImmediate.unsigned_data32 > 0) {
+ m_forward_branch_offset =
+ context.info.ISAAndImmediateSigned.signed_data32;
+ } else if (context.info_type ==
+ EmulateInstruction::eInfoTypeISAAndImmediateSigned &&
+ context.info.ISAAndImmediateSigned.signed_data32 > 0) {
+ m_forward_branch_offset = context.info.ISAAndImmediate.unsigned_data32;
+ } else if (context.info_type == EmulateInstruction::eInfoTypeImmediate &&
+ context.info.unsigned_immediate > 0) {
+ m_forward_branch_offset = context.info.unsigned_immediate;
+ } else if (context.info_type ==
+ EmulateInstruction::eInfoTypeImmediateSigned &&
+ context.info.signed_immediate > 0) {
+ m_forward_branch_offset = context.info.signed_immediate;
}
+ } break;
- return dst_len;
-}
-
-bool
-UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction,
- void *baton,
- const RegisterInfo *reg_info,
- RegisterValue ®_value)
-{
-
- if (baton && reg_info)
- return ((UnwindAssemblyInstEmulation *)baton)->ReadRegister (instruction, reg_info, reg_value);
- return false;
-}
-bool
-UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction,
- const RegisterInfo *reg_info,
- RegisterValue ®_value)
-{
- bool synthetic = GetRegisterValue (*reg_info, reg_value);
-
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (log && log->GetVerbose ())
- {
-
- StreamString strm;
- strm.Printf ("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => synthetic_value = %i, value = ", reg_info->name, synthetic);
- reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
- log->PutCString(strm.GetData());
+ case EmulateInstruction::eContextPopRegisterOffStack: {
+ const uint32_t reg_num =
+ reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric];
+ if (reg_num != LLDB_INVALID_REGNUM &&
+ generic_regnum != LLDB_REGNUM_GENERIC_SP) {
+ switch (context.info_type) {
+ case EmulateInstruction::eInfoTypeAddress:
+ if (m_pushed_regs.find(reg_num) != m_pushed_regs.end() &&
+ context.info.address == m_pushed_regs[reg_num]) {
+ m_curr_row->SetRegisterLocationToSame(reg_num,
+ false /*must_replace*/);
+ m_curr_row_modified = true;
+ }
+ break;
+ case EmulateInstruction::eInfoTypeISA:
+ assert(
+ (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
+ generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) &&
+ "eInfoTypeISA used for poping a register other the the PC/FLAGS");
+ if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS) {
+ m_curr_row->SetRegisterLocationToSame(reg_num,
+ false /*must_replace*/);
+ m_curr_row_modified = true;
+ }
+ break;
+ default:
+ assert(false && "unhandled case, add code to handle this!");
+ break;
+ }
}
- return true;
-}
+ } break;
-bool
-UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue ®_value)
-{
- if (baton && reg_info)
- return ((UnwindAssemblyInstEmulation *)baton)->WriteRegister (instruction, context, reg_info, reg_value);
- return false;
-}
-bool
-UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue ®_value)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- if (log && log->GetVerbose ())
- {
-
- StreamString strm;
- strm.Printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ", reg_info->name);
- reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
- strm.PutCString (", context = ");
- context.Dump(strm, instruction);
- log->PutCString(strm.GetData());
+ case EmulateInstruction::eContextSetFramePointer:
+ if (!m_fp_is_cfa) {
+ m_fp_is_cfa = true;
+ m_cfa_reg_info = *reg_info;
+ const uint32_t cfa_reg_num =
+ reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ assert(cfa_reg_num != LLDB_INVALID_REGNUM);
+ m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
+ cfa_reg_num, m_initial_sp - reg_value.GetAsUInt64());
+ m_curr_row_modified = true;
}
+ break;
- SetRegisterValue (*reg_info, reg_value);
-
- switch (context.type)
- {
- case EmulateInstruction::eContextInvalid:
- case EmulateInstruction::eContextReadOpcode:
- case EmulateInstruction::eContextImmediate:
- case EmulateInstruction::eContextAdjustBaseRegister:
- case EmulateInstruction::eContextRegisterPlusOffset:
- case EmulateInstruction::eContextAdjustPC:
- case EmulateInstruction::eContextRegisterStore:
- case EmulateInstruction::eContextSupervisorCall:
- case EmulateInstruction::eContextTableBranchReadMemory:
- case EmulateInstruction::eContextWriteRegisterRandomBits:
- case EmulateInstruction::eContextWriteMemoryRandomBits:
- case EmulateInstruction::eContextAdvancePC:
- case EmulateInstruction::eContextReturnFromException:
- case EmulateInstruction::eContextPushRegisterOnStack:
- case EmulateInstruction::eContextRegisterLoad:
-// {
-// const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
-// if (reg_num != LLDB_INVALID_REGNUM)
-// {
-// const bool can_replace_only_if_unspecified = true;
-//
-// m_curr_row.SetRegisterLocationToUndefined (reg_num,
-// can_replace_only_if_unspecified,
-// can_replace_only_if_unspecified);
-// m_curr_row_modified = true;
-// }
-// }
- break;
-
- case EmulateInstruction::eContextArithmetic:
- {
- // If we adjusted the current frame pointer by a constant then adjust the CFA offset
- // with the same amount.
- lldb::RegisterKind kind = m_unwind_plan_ptr->GetRegisterKind();
- if (m_fp_is_cfa && reg_info->kinds[kind] == m_cfa_reg_info.kinds[kind] &&
- context.info_type == EmulateInstruction::eInfoTypeRegisterPlusOffset &&
- context.info.RegisterPlusOffset.reg.kinds[kind] == m_cfa_reg_info.kinds[kind])
- {
- const int64_t offset = context.info.RegisterPlusOffset.signed_offset;
- m_curr_row->GetCFAValue().IncOffset(-1 * offset);
- m_curr_row_modified = true;
- }
- }
- break;
-
- case EmulateInstruction::eContextAbsoluteBranchRegister:
- case EmulateInstruction::eContextRelativeBranchImmediate:
- {
- if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediate &&
- context.info.ISAAndImmediate.unsigned_data32 > 0)
- {
- m_forward_branch_offset = context.info.ISAAndImmediateSigned.signed_data32;
- }
- else if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediateSigned &&
- context.info.ISAAndImmediateSigned.signed_data32 > 0)
- {
- m_forward_branch_offset = context.info.ISAAndImmediate.unsigned_data32;
- }
- else if (context.info_type == EmulateInstruction::eInfoTypeImmediate &&
- context.info.unsigned_immediate > 0)
- {
- m_forward_branch_offset = context.info.unsigned_immediate;
- }
- else if (context.info_type == EmulateInstruction::eInfoTypeImmediateSigned &&
- context.info.signed_immediate > 0)
- {
- m_forward_branch_offset = context.info.signed_immediate;
- }
- }
- break;
-
- case EmulateInstruction::eContextPopRegisterOffStack:
- {
- const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
- const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric];
- if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP)
- {
- switch (context.info_type)
- {
- case EmulateInstruction::eInfoTypeAddress:
- if (m_pushed_regs.find(reg_num) != m_pushed_regs.end() &&
- context.info.address == m_pushed_regs[reg_num])
- {
- m_curr_row->SetRegisterLocationToSame(reg_num,
- false /*must_replace*/);
- m_curr_row_modified = true;
- }
- break;
- case EmulateInstruction::eInfoTypeISA:
- assert((generic_regnum == LLDB_REGNUM_GENERIC_PC ||
- generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) &&
- "eInfoTypeISA used for poping a register other the the PC/FLAGS");
- if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS)
- {
- m_curr_row->SetRegisterLocationToSame(reg_num,
- false /*must_replace*/);
- m_curr_row_modified = true;
- }
- break;
- default:
- assert(false && "unhandled case, add code to handle this!");
- break;
- }
- }
- }
- break;
-
- case EmulateInstruction::eContextSetFramePointer:
- if (!m_fp_is_cfa)
- {
- m_fp_is_cfa = true;
- m_cfa_reg_info = *reg_info;
- const uint32_t cfa_reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
- assert (cfa_reg_num != LLDB_INVALID_REGNUM);
- m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(cfa_reg_num, m_initial_sp -
- reg_value.GetAsUInt64());
- m_curr_row_modified = true;
- }
- break;
-
- case EmulateInstruction::eContextAdjustStackPointer:
- // If we have created a frame using the frame pointer, don't follow
- // subsequent adjustments to the stack pointer.
- if (!m_fp_is_cfa)
- {
- m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
- m_curr_row->GetCFAValue().GetRegisterNumber(),
- m_initial_sp - reg_value.GetAsUInt64());
- m_curr_row_modified = true;
- }
- break;
+ case EmulateInstruction::eContextAdjustStackPointer:
+ // If we have created a frame using the frame pointer, don't follow
+ // subsequent adjustments to the stack pointer.
+ if (!m_fp_is_cfa) {
+ m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_curr_row->GetCFAValue().GetRegisterNumber(),
+ m_initial_sp - reg_value.GetAsUInt64());
+ m_curr_row_modified = true;
}
- return true;
+ break;
+ }
+ return true;
}
-
-
Modified: lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h Tue Sep 6 15:57:50 2016
@@ -14,172 +14,144 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/UnwindAssembly.h"
+#include "lldb/lldb-private.h"
-class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly
-{
+class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly {
public:
- ~UnwindAssemblyInstEmulation() override = default;
+ ~UnwindAssemblyInstEmulation() override = default;
+
+ bool GetNonCallSiteUnwindPlanFromAssembly(
+ lldb_private::AddressRange &func, lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool
+ AugmentUnwindPlanFromCallSite(lldb_private::AddressRange &func,
+ lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool GetFastUnwindPlan(lldb_private::AddressRange &func,
+ lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ // thread may be NULL in which case we only use the Target (e.g. if this is
+ // called pre-process-launch).
+ bool
+ FirstNonPrologueInsn(lldb_private::AddressRange &func,
+ const lldb_private::ExecutionContext &exe_ctx,
+ lldb_private::Address &first_non_prologue_insn) override;
+
+ static lldb_private::UnwindAssembly *
+ CreateInstance(const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
- bool
- GetNonCallSiteUnwindPlanFromAssembly(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan& unwind_plan) override;
-
- bool
- AugmentUnwindPlanFromCallSite(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan& unwind_plan) override;
-
- bool
- GetFastUnwindPlan(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan &unwind_plan) override;
-
- // thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
- bool
- FirstNonPrologueInsn(lldb_private::AddressRange& func,
- const lldb_private::ExecutionContext &exe_ctx,
- lldb_private::Address& first_non_prologue_insn) override;
-
- static lldb_private::UnwindAssembly *
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
private:
- // Call CreateInstance to get an instance of this class
- UnwindAssemblyInstEmulation(const lldb_private::ArchSpec &arch,
- lldb_private::EmulateInstruction *inst_emulator) :
- UnwindAssembly (arch),
- m_inst_emulator_ap (inst_emulator),
- m_range_ptr (NULL),
- m_thread_ptr (NULL),
- m_unwind_plan_ptr (NULL),
- m_curr_row (),
- m_cfa_reg_info (),
- m_fp_is_cfa (false),
- m_register_values (),
- m_pushed_regs(),
- m_curr_row_modified (false),
- m_forward_branch_offset (0)
- {
- if (m_inst_emulator_ap.get())
- {
- m_inst_emulator_ap->SetBaton (this);
- m_inst_emulator_ap->SetCallbacks (ReadMemory, WriteMemory, ReadRegister, WriteRegister);
- }
+ // Call CreateInstance to get an instance of this class
+ UnwindAssemblyInstEmulation(const lldb_private::ArchSpec &arch,
+ lldb_private::EmulateInstruction *inst_emulator)
+ : UnwindAssembly(arch), m_inst_emulator_ap(inst_emulator),
+ m_range_ptr(NULL), m_thread_ptr(NULL), m_unwind_plan_ptr(NULL),
+ m_curr_row(), m_cfa_reg_info(), m_fp_is_cfa(false), m_register_values(),
+ m_pushed_regs(), m_curr_row_modified(false),
+ m_forward_branch_offset(0) {
+ if (m_inst_emulator_ap.get()) {
+ m_inst_emulator_ap->SetBaton(this);
+ m_inst_emulator_ap->SetCallbacks(ReadMemory, WriteMemory, ReadRegister,
+ WriteRegister);
}
+ }
- static size_t
- ReadMemory (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length);
-
- static size_t
- WriteMemory (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length);
-
- static bool
- ReadRegister (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue ®_value);
-
- static bool
- WriteRegister (lldb_private::EmulateInstruction *instruction,
- void *baton,
- const lldb_private::EmulateInstruction::Context &context,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue ®_value);
-
-// size_t
-// ReadMemory (lldb_private::EmulateInstruction *instruction,
-// const lldb_private::EmulateInstruction::Context &context,
-// lldb::addr_t addr,
-// void *dst,
-// size_t length);
-
- size_t
- WriteMemory (lldb_private::EmulateInstruction *instruction,
- const lldb_private::EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length);
-
- bool
- ReadRegister (lldb_private::EmulateInstruction *instruction,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue ®_value);
-
- bool
- WriteRegister (lldb_private::EmulateInstruction *instruction,
- const lldb_private::EmulateInstruction::Context &context,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue ®_value);
-
- static uint64_t
- MakeRegisterKindValuePair (const lldb_private::RegisterInfo ®_info);
-
- void
- SetRegisterValue (const lldb_private::RegisterInfo ®_info,
- const lldb_private::RegisterValue ®_value);
-
- bool
- GetRegisterValue (const lldb_private::RegisterInfo ®_info,
- lldb_private::RegisterValue ®_value);
-
- std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
- lldb_private::AddressRange* m_range_ptr;
- lldb_private::Thread* m_thread_ptr;
- lldb_private::UnwindPlan* m_unwind_plan_ptr;
- lldb_private::UnwindPlan::RowSP m_curr_row;
- typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
- uint64_t m_initial_sp;
- lldb_private::RegisterInfo m_cfa_reg_info;
- bool m_fp_is_cfa;
- typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
- RegisterValueMap m_register_values;
- PushedRegisterToAddrMap m_pushed_regs;
-
- // While processing the instruction stream, we need to communicate some state change
- // information up to the higher level loop that makes decisions about how to push
- // the unwind instructions for the UnwindPlan we're constructing.
-
- // The instruction we're processing updated the UnwindPlan::Row contents
- bool m_curr_row_modified;
- // The instruction is branching forward with the given offset. 0 value means no branching.
- uint32_t m_forward_branch_offset;
+ static size_t
+ ReadMemory(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length);
+
+ static size_t
+ WriteMemory(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst, size_t length);
+
+ static bool ReadRegister(lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue ®_value);
+
+ static bool
+ WriteRegister(lldb_private::EmulateInstruction *instruction, void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue ®_value);
+
+ // size_t
+ // ReadMemory (lldb_private::EmulateInstruction *instruction,
+ // const lldb_private::EmulateInstruction::Context &context,
+ // lldb::addr_t addr,
+ // void *dst,
+ // size_t length);
+
+ size_t WriteMemory(lldb_private::EmulateInstruction *instruction,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst, size_t length);
+
+ bool ReadRegister(lldb_private::EmulateInstruction *instruction,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue ®_value);
+
+ bool WriteRegister(lldb_private::EmulateInstruction *instruction,
+ const lldb_private::EmulateInstruction::Context &context,
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue ®_value);
+
+ static uint64_t
+ MakeRegisterKindValuePair(const lldb_private::RegisterInfo ®_info);
+
+ void SetRegisterValue(const lldb_private::RegisterInfo ®_info,
+ const lldb_private::RegisterValue ®_value);
+
+ bool GetRegisterValue(const lldb_private::RegisterInfo ®_info,
+ lldb_private::RegisterValue ®_value);
+
+ std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
+ lldb_private::AddressRange *m_range_ptr;
+ lldb_private::Thread *m_thread_ptr;
+ lldb_private::UnwindPlan *m_unwind_plan_ptr;
+ lldb_private::UnwindPlan::RowSP m_curr_row;
+ typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
+ uint64_t m_initial_sp;
+ lldb_private::RegisterInfo m_cfa_reg_info;
+ bool m_fp_is_cfa;
+ typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
+ RegisterValueMap m_register_values;
+ PushedRegisterToAddrMap m_pushed_regs;
+
+ // While processing the instruction stream, we need to communicate some state
+ // change
+ // information up to the higher level loop that makes decisions about how to
+ // push
+ // the unwind instructions for the UnwindPlan we're constructing.
+
+ // The instruction we're processing updated the UnwindPlan::Row contents
+ bool m_curr_row_modified;
+ // The instruction is branching forward with the given offset. 0 value means
+ // no branching.
+ uint32_t m_forward_branch_offset;
};
#endif // liblldb_UnwindAssemblyInstEmulation_h_
Modified: lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp Tue Sep 6 15:57:50 2016
@@ -14,108 +14,86 @@
#include "llvm/Support/TargetSelect.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
#include "lldb/Target/UnwindAssembly.h"
#include "lldb/Utility/RegisterNumber.h"
using namespace lldb;
using namespace lldb_private;
-enum CPU
-{
- k_i386,
- k_x86_64
-};
+enum CPU { k_i386, k_x86_64 };
-enum i386_register_numbers
-{
- k_machine_eax = 0,
- k_machine_ecx = 1,
- k_machine_edx = 2,
- k_machine_ebx = 3,
- k_machine_esp = 4,
- k_machine_ebp = 5,
- k_machine_esi = 6,
- k_machine_edi = 7,
- k_machine_eip = 8
+enum i386_register_numbers {
+ k_machine_eax = 0,
+ k_machine_ecx = 1,
+ k_machine_edx = 2,
+ k_machine_ebx = 3,
+ k_machine_esp = 4,
+ k_machine_ebp = 5,
+ k_machine_esi = 6,
+ k_machine_edi = 7,
+ k_machine_eip = 8
};
-enum x86_64_register_numbers
-{
- k_machine_rax = 0,
- k_machine_rcx = 1,
- k_machine_rdx = 2,
- k_machine_rbx = 3,
- k_machine_rsp = 4,
- k_machine_rbp = 5,
- k_machine_rsi = 6,
- k_machine_rdi = 7,
- k_machine_r8 = 8,
- k_machine_r9 = 9,
- k_machine_r10 = 10,
- k_machine_r11 = 11,
- k_machine_r12 = 12,
- k_machine_r13 = 13,
- k_machine_r14 = 14,
- k_machine_r15 = 15,
- k_machine_rip = 16
+enum x86_64_register_numbers {
+ k_machine_rax = 0,
+ k_machine_rcx = 1,
+ k_machine_rdx = 2,
+ k_machine_rbx = 3,
+ k_machine_rsp = 4,
+ k_machine_rbp = 5,
+ k_machine_rsi = 6,
+ k_machine_rdi = 7,
+ k_machine_r8 = 8,
+ k_machine_r9 = 9,
+ k_machine_r10 = 10,
+ k_machine_r11 = 11,
+ k_machine_r12 = 12,
+ k_machine_r13 = 13,
+ k_machine_r14 = 14,
+ k_machine_r15 = 15,
+ k_machine_rip = 16
};
-struct regmap_ent
-{
- const char *name;
- int machine_regno;
- int lldb_regno;
+struct regmap_ent {
+ const char *name;
+ int machine_regno;
+ int lldb_regno;
};
-static struct regmap_ent i386_register_map[] =
-{
- {"eax", k_machine_eax, -1},
- {"ecx", k_machine_ecx, -1},
- {"edx", k_machine_edx, -1},
- {"ebx", k_machine_ebx, -1},
- {"esp", k_machine_esp, -1},
- {"ebp", k_machine_ebp, -1},
- {"esi", k_machine_esi, -1},
- {"edi", k_machine_edi, -1},
- {"eip", k_machine_eip, -1}
-};
+static struct regmap_ent i386_register_map[] = {
+ {"eax", k_machine_eax, -1}, {"ecx", k_machine_ecx, -1},
+ {"edx", k_machine_edx, -1}, {"ebx", k_machine_ebx, -1},
+ {"esp", k_machine_esp, -1}, {"ebp", k_machine_ebp, -1},
+ {"esi", k_machine_esi, -1}, {"edi", k_machine_edi, -1},
+ {"eip", k_machine_eip, -1}};
-const int size_of_i386_register_map = llvm::array_lengthof (i386_register_map);
+const int size_of_i386_register_map = llvm::array_lengthof(i386_register_map);
static int i386_register_map_initialized = 0;
-static struct regmap_ent x86_64_register_map[] =
-{
- {"rax", k_machine_rax, -1},
- {"rcx", k_machine_rcx, -1},
- {"rdx", k_machine_rdx, -1},
- {"rbx", k_machine_rbx, -1},
- {"rsp", k_machine_rsp, -1},
- {"rbp", k_machine_rbp, -1},
- {"rsi", k_machine_rsi, -1},
- {"rdi", k_machine_rdi, -1},
- {"r8", k_machine_r8, -1},
- {"r9", k_machine_r9, -1},
- {"r10", k_machine_r10, -1},
- {"r11", k_machine_r11, -1},
- {"r12", k_machine_r12, -1},
- {"r13", k_machine_r13, -1},
- {"r14", k_machine_r14, -1},
- {"r15", k_machine_r15, -1},
- {"rip", k_machine_rip, -1}
-};
+static struct regmap_ent x86_64_register_map[] = {
+ {"rax", k_machine_rax, -1}, {"rcx", k_machine_rcx, -1},
+ {"rdx", k_machine_rdx, -1}, {"rbx", k_machine_rbx, -1},
+ {"rsp", k_machine_rsp, -1}, {"rbp", k_machine_rbp, -1},
+ {"rsi", k_machine_rsi, -1}, {"rdi", k_machine_rdi, -1},
+ {"r8", k_machine_r8, -1}, {"r9", k_machine_r9, -1},
+ {"r10", k_machine_r10, -1}, {"r11", k_machine_r11, -1},
+ {"r12", k_machine_r12, -1}, {"r13", k_machine_r13, -1},
+ {"r14", k_machine_r14, -1}, {"r15", k_machine_r15, -1},
+ {"rip", k_machine_rip, -1}};
-const int size_of_x86_64_register_map = llvm::array_lengthof (x86_64_register_map);
+const int size_of_x86_64_register_map =
+ llvm::array_lengthof(x86_64_register_map);
static int x86_64_register_map_initialized = 0;
@@ -123,391 +101,340 @@ static int x86_64_register_map_initializ
// AssemblyParse_x86 local-file class definition & implementation functions
//-----------------------------------------------------------------------------------------------
-class AssemblyParse_x86
-{
+class AssemblyParse_x86 {
public:
+ AssemblyParse_x86(const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch,
+ AddressRange func);
- AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func);
+ ~AssemblyParse_x86();
- ~AssemblyParse_x86 ();
+ bool get_non_call_site_unwind_plan(UnwindPlan &unwind_plan);
- bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan);
+ bool augment_unwind_plan_from_call_site(AddressRange &func,
+ UnwindPlan &unwind_plan);
- bool augment_unwind_plan_from_call_site (AddressRange& func, UnwindPlan &unwind_plan);
+ bool get_fast_unwind_plan(AddressRange &func, UnwindPlan &unwind_plan);
- bool get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan);
-
- bool find_first_non_prologue_insn (Address &address);
+ bool find_first_non_prologue_insn(Address &address);
private:
- enum { kMaxInstructionByteSize = 32 };
+ enum { kMaxInstructionByteSize = 32 };
- bool nonvolatile_reg_p (int machine_regno);
- bool push_rbp_pattern_p ();
- bool push_0_pattern_p ();
- bool mov_rsp_rbp_pattern_p ();
- bool sub_rsp_pattern_p (int& amount);
- bool add_rsp_pattern_p (int& amount);
- bool lea_rsp_pattern_p (int& amount);
- bool push_reg_p (int& regno);
- bool pop_reg_p (int& regno);
- bool push_imm_pattern_p ();
- bool mov_reg_to_local_stack_frame_p (int& regno, int& fp_offset);
- bool ret_pattern_p ();
- bool pop_rbp_pattern_p ();
- bool leave_pattern_p ();
- bool call_next_insn_pattern_p();
- uint32_t extract_4 (uint8_t *b);
- bool machine_regno_to_lldb_regno (int machine_regno, uint32_t& lldb_regno);
- bool instruction_length (Address addr, int &length);
-
- const ExecutionContext m_exe_ctx;
-
- AddressRange m_func_bounds;
-
- Address m_cur_insn;
- uint8_t m_cur_insn_bytes[kMaxInstructionByteSize];
-
- uint32_t m_machine_ip_regnum;
- uint32_t m_machine_sp_regnum;
- uint32_t m_machine_fp_regnum;
-
- uint32_t m_lldb_ip_regnum;
- uint32_t m_lldb_sp_regnum;
- uint32_t m_lldb_fp_regnum;
-
- int m_wordsize;
- int m_cpu;
- ArchSpec m_arch;
- ::LLVMDisasmContextRef m_disasm_context;
+ bool nonvolatile_reg_p(int machine_regno);
+ bool push_rbp_pattern_p();
+ bool push_0_pattern_p();
+ bool mov_rsp_rbp_pattern_p();
+ bool sub_rsp_pattern_p(int &amount);
+ bool add_rsp_pattern_p(int &amount);
+ bool lea_rsp_pattern_p(int &amount);
+ bool push_reg_p(int ®no);
+ bool pop_reg_p(int ®no);
+ bool push_imm_pattern_p();
+ bool mov_reg_to_local_stack_frame_p(int ®no, int &fp_offset);
+ bool ret_pattern_p();
+ bool pop_rbp_pattern_p();
+ bool leave_pattern_p();
+ bool call_next_insn_pattern_p();
+ uint32_t extract_4(uint8_t *b);
+ bool machine_regno_to_lldb_regno(int machine_regno, uint32_t &lldb_regno);
+ bool instruction_length(Address addr, int &length);
+
+ const ExecutionContext m_exe_ctx;
+
+ AddressRange m_func_bounds;
+
+ Address m_cur_insn;
+ uint8_t m_cur_insn_bytes[kMaxInstructionByteSize];
+
+ uint32_t m_machine_ip_regnum;
+ uint32_t m_machine_sp_regnum;
+ uint32_t m_machine_fp_regnum;
+
+ uint32_t m_lldb_ip_regnum;
+ uint32_t m_lldb_sp_regnum;
+ uint32_t m_lldb_fp_regnum;
+
+ int m_wordsize;
+ int m_cpu;
+ ArchSpec m_arch;
+ ::LLVMDisasmContextRef m_disasm_context;
- DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86);
+ DISALLOW_COPY_AND_ASSIGN(AssemblyParse_x86);
};
-AssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func) :
- m_exe_ctx (exe_ctx),
- m_func_bounds(func),
- m_cur_insn (),
- m_machine_ip_regnum (LLDB_INVALID_REGNUM),
- m_machine_sp_regnum (LLDB_INVALID_REGNUM),
- m_machine_fp_regnum (LLDB_INVALID_REGNUM),
- m_lldb_ip_regnum (LLDB_INVALID_REGNUM),
- m_lldb_sp_regnum (LLDB_INVALID_REGNUM),
- m_lldb_fp_regnum (LLDB_INVALID_REGNUM),
- m_wordsize (-1),
- m_cpu(cpu),
- m_arch(arch)
-{
- int *initialized_flag = NULL;
- if (cpu == k_i386)
- {
- m_machine_ip_regnum = k_machine_eip;
- m_machine_sp_regnum = k_machine_esp;
- m_machine_fp_regnum = k_machine_ebp;
- m_wordsize = 4;
- initialized_flag = &i386_register_map_initialized;
- }
- else
- {
- m_machine_ip_regnum = k_machine_rip;
- m_machine_sp_regnum = k_machine_rsp;
- m_machine_fp_regnum = k_machine_rbp;
- m_wordsize = 8;
- initialized_flag = &x86_64_register_map_initialized;
- }
-
- // we only look at prologue - it will be complete earlier than 512 bytes into func
- if (m_func_bounds.GetByteSize() == 0)
- m_func_bounds.SetByteSize(512);
-
- Thread *thread = m_exe_ctx.GetThreadPtr();
- if (thread && *initialized_flag == 0)
- {
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
- if (reg_ctx)
- {
- struct regmap_ent *ent;
- int count, i;
- if (cpu == k_i386)
- {
- ent = i386_register_map;
- count = size_of_i386_register_map;
- }
- else
- {
- ent = x86_64_register_map;
- count = size_of_x86_64_register_map;
- }
- for (i = 0; i < count; i++, ent++)
- {
- const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName (ent->name);
- if (ri)
- ent->lldb_regno = ri->kinds[eRegisterKindLLDB];
- }
- *initialized_flag = 1;
- }
- }
+AssemblyParse_x86::AssemblyParse_x86(const ExecutionContext &exe_ctx, int cpu,
+ ArchSpec &arch, AddressRange func)
+ : m_exe_ctx(exe_ctx), m_func_bounds(func), m_cur_insn(),
+ m_machine_ip_regnum(LLDB_INVALID_REGNUM),
+ m_machine_sp_regnum(LLDB_INVALID_REGNUM),
+ m_machine_fp_regnum(LLDB_INVALID_REGNUM),
+ m_lldb_ip_regnum(LLDB_INVALID_REGNUM),
+ m_lldb_sp_regnum(LLDB_INVALID_REGNUM),
+ m_lldb_fp_regnum(LLDB_INVALID_REGNUM), m_wordsize(-1), m_cpu(cpu),
+ m_arch(arch) {
+ int *initialized_flag = NULL;
+ if (cpu == k_i386) {
+ m_machine_ip_regnum = k_machine_eip;
+ m_machine_sp_regnum = k_machine_esp;
+ m_machine_fp_regnum = k_machine_ebp;
+ m_wordsize = 4;
+ initialized_flag = &i386_register_map_initialized;
+ } else {
+ m_machine_ip_regnum = k_machine_rip;
+ m_machine_sp_regnum = k_machine_rsp;
+ m_machine_fp_regnum = k_machine_rbp;
+ m_wordsize = 8;
+ initialized_flag = &x86_64_register_map_initialized;
+ }
+
+ // we only look at prologue - it will be complete earlier than 512 bytes into
+ // func
+ if (m_func_bounds.GetByteSize() == 0)
+ m_func_bounds.SetByteSize(512);
+
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ if (thread && *initialized_flag == 0) {
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+ if (reg_ctx) {
+ struct regmap_ent *ent;
+ int count, i;
+ if (cpu == k_i386) {
+ ent = i386_register_map;
+ count = size_of_i386_register_map;
+ } else {
+ ent = x86_64_register_map;
+ count = size_of_x86_64_register_map;
+ }
+ for (i = 0; i < count; i++, ent++) {
+ const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName(ent->name);
+ if (ri)
+ ent->lldb_regno = ri->kinds[eRegisterKindLLDB];
+ }
+ *initialized_flag = 1;
+ }
+ }
+
+ // on initial construction we may not have a Thread so these have to remain
+ // uninitialized until we can get a RegisterContext to set up the register map
+ // table
+ if (*initialized_flag == 1) {
+ uint32_t lldb_regno;
+ if (machine_regno_to_lldb_regno(m_machine_sp_regnum, lldb_regno))
+ m_lldb_sp_regnum = lldb_regno;
+ if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno))
+ m_lldb_fp_regnum = lldb_regno;
+ if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno))
+ m_lldb_ip_regnum = lldb_regno;
+ }
+
+ m_disasm_context =
+ ::LLVMCreateDisasm(m_arch.GetTriple().getTriple().c_str(), (void *)this,
+ /*TagType=*/1, NULL, NULL);
+}
- // on initial construction we may not have a Thread so these have to remain
- // uninitialized until we can get a RegisterContext to set up the register map table
- if (*initialized_flag == 1)
- {
- uint32_t lldb_regno;
- if (machine_regno_to_lldb_regno (m_machine_sp_regnum, lldb_regno))
- m_lldb_sp_regnum = lldb_regno;
- if (machine_regno_to_lldb_regno (m_machine_fp_regnum, lldb_regno))
- m_lldb_fp_regnum = lldb_regno;
- if (machine_regno_to_lldb_regno (m_machine_ip_regnum, lldb_regno))
- m_lldb_ip_regnum = lldb_regno;
- }
-
- m_disasm_context = ::LLVMCreateDisasm(m_arch.GetTriple().getTriple().c_str(),
- (void*)this,
- /*TagType=*/1,
- NULL,
- NULL);
-}
-
-AssemblyParse_x86::~AssemblyParse_x86 ()
-{
- ::LLVMDisasmDispose(m_disasm_context);
+AssemblyParse_x86::~AssemblyParse_x86() {
+ ::LLVMDisasmDispose(m_disasm_context);
}
-// This function expects an x86 native register number (i.e. the bits stripped out of the
+// This function expects an x86 native register number (i.e. the bits stripped
+// out of the
// actual instruction), not an lldb register number.
-bool
-AssemblyParse_x86::nonvolatile_reg_p (int machine_regno)
-{
- if (m_cpu == k_i386)
- {
- switch (machine_regno)
- {
- case k_machine_ebx:
- case k_machine_ebp: // not actually a nonvolatile but often treated as such by convention
- case k_machine_esi:
- case k_machine_edi:
- case k_machine_esp:
- return true;
- default:
- return false;
- }
+bool AssemblyParse_x86::nonvolatile_reg_p(int machine_regno) {
+ if (m_cpu == k_i386) {
+ switch (machine_regno) {
+ case k_machine_ebx:
+ case k_machine_ebp: // not actually a nonvolatile but often treated as such
+ // by convention
+ case k_machine_esi:
+ case k_machine_edi:
+ case k_machine_esp:
+ return true;
+ default:
+ return false;
}
- if (m_cpu == k_x86_64)
- {
- switch (machine_regno)
- {
- case k_machine_rbx:
- case k_machine_rsp:
- case k_machine_rbp: // not actually a nonvolatile but often treated as such by convention
- case k_machine_r12:
- case k_machine_r13:
- case k_machine_r14:
- case k_machine_r15:
- return true;
- default:
- return false;
- }
+ }
+ if (m_cpu == k_x86_64) {
+ switch (machine_regno) {
+ case k_machine_rbx:
+ case k_machine_rsp:
+ case k_machine_rbp: // not actually a nonvolatile but often treated as such
+ // by convention
+ case k_machine_r12:
+ case k_machine_r13:
+ case k_machine_r14:
+ case k_machine_r15:
+ return true;
+ default:
+ return false;
}
- return false;
+ }
+ return false;
}
-
// Macro to detect if this is a REX mode prefix byte.
#define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
-// The high bit which should be added to the source register number (the "R" bit)
-#define REX_W_SRCREG(opcode) (((opcode) & 0x4) >> 2)
-
-// The high bit which should be added to the destination register number (the "B" bit)
-#define REX_W_DSTREG(opcode) ((opcode) & 0x1)
+// The high bit which should be added to the source register number (the "R"
+// bit)
+#define REX_W_SRCREG(opcode) (((opcode)&0x4) >> 2)
+
+// The high bit which should be added to the destination register number (the
+// "B" bit)
+#define REX_W_DSTREG(opcode) ((opcode)&0x1)
// pushq %rbp [0x55]
-bool
-AssemblyParse_x86::push_rbp_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (*p == 0x55)
- return true;
- return false;
+bool AssemblyParse_x86::push_rbp_pattern_p() {
+ uint8_t *p = m_cur_insn_bytes;
+ if (*p == 0x55)
+ return true;
+ return false;
}
// pushq $0 ; the first instruction in start() [0x6a 0x00]
-bool
-AssemblyParse_x86::push_0_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (*p == 0x6a && *(p + 1) == 0x0)
- return true;
- return false;
+bool AssemblyParse_x86::push_0_pattern_p() {
+ uint8_t *p = m_cur_insn_bytes;
+ if (*p == 0x6a && *(p + 1) == 0x0)
+ return true;
+ return false;
}
// pushq $0
// pushl $0
-bool
-AssemblyParse_x86::push_imm_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (*p == 0x68 || *p == 0x6a)
- return true;
- return false;
+bool AssemblyParse_x86::push_imm_pattern_p() {
+ uint8_t *p = m_cur_insn_bytes;
+ if (*p == 0x68 || *p == 0x6a)
+ return true;
+ return false;
}
// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
-bool
-AssemblyParse_x86::mov_rsp_rbp_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (m_wordsize == 8 && *p == 0x48)
- p++;
- if (*(p) == 0x8b && *(p + 1) == 0xec)
- return true;
- if (*(p) == 0x89 && *(p + 1) == 0xe5)
- return true;
- return false;
+bool AssemblyParse_x86::mov_rsp_rbp_pattern_p() {
+ uint8_t *p = m_cur_insn_bytes;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ if (*(p) == 0x8b && *(p + 1) == 0xec)
+ return true;
+ if (*(p) == 0x89 && *(p + 1) == 0xe5)
+ return true;
+ return false;
}
// subq $0x20, %rsp
-bool
-AssemblyParse_x86::sub_rsp_pattern_p (int& amount)
-{
- uint8_t *p = m_cur_insn_bytes;
- if (m_wordsize == 8 && *p == 0x48)
- p++;
- // 8-bit immediate operand
- if (*p == 0x83 && *(p + 1) == 0xec)
- {
- amount = (int8_t) *(p + 2);
- return true;
- }
- // 32-bit immediate operand
- if (*p == 0x81 && *(p + 1) == 0xec)
- {
- amount = (int32_t) extract_4 (p + 2);
- return true;
- }
- return false;
+bool AssemblyParse_x86::sub_rsp_pattern_p(int &amount) {
+ uint8_t *p = m_cur_insn_bytes;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ // 8-bit immediate operand
+ if (*p == 0x83 && *(p + 1) == 0xec) {
+ amount = (int8_t) * (p + 2);
+ return true;
+ }
+ // 32-bit immediate operand
+ if (*p == 0x81 && *(p + 1) == 0xec) {
+ amount = (int32_t)extract_4(p + 2);
+ return true;
+ }
+ return false;
}
// addq $0x20, %rsp
-bool
-AssemblyParse_x86::add_rsp_pattern_p (int& amount)
-{
- uint8_t *p = m_cur_insn_bytes;
- if (m_wordsize == 8 && *p == 0x48)
- p++;
- // 8-bit immediate operand
- if (*p == 0x83 && *(p + 1) == 0xc4)
- {
- amount = (int8_t) *(p + 2);
- return true;
- }
- // 32-bit immediate operand
- if (*p == 0x81 && *(p + 1) == 0xc4)
- {
- amount = (int32_t) extract_4 (p + 2);
- return true;
- }
- return false;
+bool AssemblyParse_x86::add_rsp_pattern_p(int &amount) {
+ uint8_t *p = m_cur_insn_bytes;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ // 8-bit immediate operand
+ if (*p == 0x83 && *(p + 1) == 0xc4) {
+ amount = (int8_t) * (p + 2);
+ return true;
+ }
+ // 32-bit immediate operand
+ if (*p == 0x81 && *(p + 1) == 0xc4) {
+ amount = (int32_t)extract_4(p + 2);
+ return true;
+ }
+ return false;
}
// lea esp, [esp - 0x28]
// lea esp, [esp + 0x28]
-bool
-AssemblyParse_x86::lea_rsp_pattern_p (int& amount)
-{
- uint8_t *p = m_cur_insn_bytes;
- if (m_wordsize == 8 && *p == 0x48)
- p++;
-
- // Check opcode
- if (*p != 0x8d)
- return false;
-
- // 8 bit displacement
- if (*(p + 1) == 0x64 && (*(p + 2) & 0x3f) == 0x24)
- {
- amount = (int8_t) *(p + 3);
- return true;
- }
-
- // 32 bit displacement
- if (*(p + 1) == 0xa4 && (*(p + 2) & 0x3f) == 0x24)
- {
- amount = (int32_t) extract_4 (p + 3);
- return true;
- }
+bool AssemblyParse_x86::lea_rsp_pattern_p(int &amount) {
+ uint8_t *p = m_cur_insn_bytes;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ // Check opcode
+ if (*p != 0x8d)
return false;
+
+ // 8 bit displacement
+ if (*(p + 1) == 0x64 && (*(p + 2) & 0x3f) == 0x24) {
+ amount = (int8_t) * (p + 3);
+ return true;
+ }
+
+ // 32 bit displacement
+ if (*(p + 1) == 0xa4 && (*(p + 2) & 0x3f) == 0x24) {
+ amount = (int32_t)extract_4(p + 3);
+ return true;
+ }
+
+ return false;
}
// pushq %rbx
// pushl %ebx
-bool
-AssemblyParse_x86::push_reg_p (int& regno)
-{
- uint8_t *p = m_cur_insn_bytes;
- int regno_prefix_bit = 0;
- // If we have a rex prefix byte, check to see if a B bit is set
- if (m_wordsize == 8 && *p == 0x41)
- {
- regno_prefix_bit = 1 << 3;
- p++;
- }
- if (*p >= 0x50 && *p <= 0x57)
- {
- regno = (*p - 0x50) | regno_prefix_bit;
- return true;
- }
- return false;
+bool AssemblyParse_x86::push_reg_p(int ®no) {
+ uint8_t *p = m_cur_insn_bytes;
+ int regno_prefix_bit = 0;
+ // If we have a rex prefix byte, check to see if a B bit is set
+ if (m_wordsize == 8 && *p == 0x41) {
+ regno_prefix_bit = 1 << 3;
+ p++;
+ }
+ if (*p >= 0x50 && *p <= 0x57) {
+ regno = (*p - 0x50) | regno_prefix_bit;
+ return true;
+ }
+ return false;
}
// popq %rbx
// popl %ebx
-bool
-AssemblyParse_x86::pop_reg_p (int& regno)
-{
- uint8_t *p = m_cur_insn_bytes;
- int regno_prefix_bit = 0;
- // If we have a rex prefix byte, check to see if a B bit is set
- if (m_wordsize == 8 && *p == 0x41)
- {
- regno_prefix_bit = 1 << 3;
- p++;
- }
- if (*p >= 0x58 && *p <= 0x5f)
- {
- regno = (*p - 0x58) | regno_prefix_bit;
- return true;
- }
- return false;
+bool AssemblyParse_x86::pop_reg_p(int ®no) {
+ uint8_t *p = m_cur_insn_bytes;
+ int regno_prefix_bit = 0;
+ // If we have a rex prefix byte, check to see if a B bit is set
+ if (m_wordsize == 8 && *p == 0x41) {
+ regno_prefix_bit = 1 << 3;
+ p++;
+ }
+ if (*p >= 0x58 && *p <= 0x5f) {
+ regno = (*p - 0x58) | regno_prefix_bit;
+ return true;
+ }
+ return false;
}
// popq %rbp [0x5d]
// popl %ebp [0x5d]
-bool
-AssemblyParse_x86::pop_rbp_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- return (*p == 0x5d);
+bool AssemblyParse_x86::pop_rbp_pattern_p() {
+ uint8_t *p = m_cur_insn_bytes;
+ return (*p == 0x5d);
}
// leave [0xc9]
-bool
-AssemblyParse_x86::leave_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- return (*p == 0xc9);
+bool AssemblyParse_x86::leave_pattern_p() {
+ uint8_t *p = m_cur_insn_bytes;
+ return (*p == 0xc9);
}
// call $0 [0xe8 0x0 0x0 0x0 0x0]
-bool
-AssemblyParse_x86::call_next_insn_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- return (*p == 0xe8) && (*(p+1) == 0x0) && (*(p+2) == 0x0)
- && (*(p+3) == 0x0) && (*(p+4) == 0x0);
+bool AssemblyParse_x86::call_next_insn_pattern_p() {
+ uint8_t *p = m_cur_insn_bytes;
+ return (*p == 0xe8) && (*(p + 1) == 0x0) && (*(p + 2) == 0x0) &&
+ (*(p + 3) == 0x0) && (*(p + 4) == 0x0);
}
// Look for an instruction sequence storing a nonvolatile register
@@ -521,1040 +448,957 @@ AssemblyParse_x86::call_next_insn_patter
// the actual location. The positive value returned for the offset
// is a convention used elsewhere for CFA offsets et al.
-bool
-AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset)
-{
- uint8_t *p = m_cur_insn_bytes;
- int src_reg_prefix_bit = 0;
- int target_reg_prefix_bit = 0;
-
- if (m_wordsize == 8 && REX_W_PREFIX_P (*p))
- {
- src_reg_prefix_bit = REX_W_SRCREG (*p) << 3;
- target_reg_prefix_bit = REX_W_DSTREG (*p) << 3;
- if (target_reg_prefix_bit == 1)
- {
- // rbp/ebp don't need a prefix bit - we know this isn't the
- // reg we care about.
- return false;
- }
- p++;
- }
+bool AssemblyParse_x86::mov_reg_to_local_stack_frame_p(int ®no,
+ int &rbp_offset) {
+ uint8_t *p = m_cur_insn_bytes;
+ int src_reg_prefix_bit = 0;
+ int target_reg_prefix_bit = 0;
+
+ if (m_wordsize == 8 && REX_W_PREFIX_P(*p)) {
+ src_reg_prefix_bit = REX_W_SRCREG(*p) << 3;
+ target_reg_prefix_bit = REX_W_DSTREG(*p) << 3;
+ if (target_reg_prefix_bit == 1) {
+ // rbp/ebp don't need a prefix bit - we know this isn't the
+ // reg we care about.
+ return false;
+ }
+ p++;
+ }
+
+ if (*p == 0x89) {
+ /* Mask off the 3-5 bits which indicate the destination register
+ if this is a ModR/M byte. */
+ int opcode_destreg_masked_out = *(p + 1) & (~0x38);
+
+ /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
+ and three bits between them, e.g. 01nnn101
+ We're looking for a destination of ebp-disp8 or ebp-disp32. */
+ int immsize;
+ if (opcode_destreg_masked_out == 0x45)
+ immsize = 2;
+ else if (opcode_destreg_masked_out == 0x85)
+ immsize = 4;
+ else
+ return false;
- if (*p == 0x89)
- {
- /* Mask off the 3-5 bits which indicate the destination register
- if this is a ModR/M byte. */
- int opcode_destreg_masked_out = *(p + 1) & (~0x38);
-
- /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
- and three bits between them, e.g. 01nnn101
- We're looking for a destination of ebp-disp8 or ebp-disp32. */
- int immsize;
- if (opcode_destreg_masked_out == 0x45)
- immsize = 2;
- else if (opcode_destreg_masked_out == 0x85)
- immsize = 4;
- else
- return false;
-
- int offset = 0;
- if (immsize == 2)
- offset = (int8_t) *(p + 2);
- if (immsize == 4)
- offset = (uint32_t) extract_4 (p + 2);
- if (offset > 0)
- return false;
+ int offset = 0;
+ if (immsize == 2)
+ offset = (int8_t) * (p + 2);
+ if (immsize == 4)
+ offset = (uint32_t)extract_4(p + 2);
+ if (offset > 0)
+ return false;
- regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
- rbp_offset = offset > 0 ? offset : -offset;
- return true;
- }
- return false;
+ regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
+ rbp_offset = offset > 0 ? offset : -offset;
+ return true;
+ }
+ return false;
}
// ret [0xc9] or [0xc2 imm8] or [0xca imm8]
-bool
-AssemblyParse_x86::ret_pattern_p ()
-{
- uint8_t *p = m_cur_insn_bytes;
- if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
- return true;
- return false;
-}
-
-uint32_t
-AssemblyParse_x86::extract_4 (uint8_t *b)
-{
- uint32_t v = 0;
- for (int i = 3; i >= 0; i--)
- v = (v << 8) | b[i];
- return v;
-}
-
-bool
-AssemblyParse_x86::machine_regno_to_lldb_regno (int machine_regno, uint32_t &lldb_regno)
-{
- struct regmap_ent *ent;
- int count, i;
- if (m_cpu == k_i386)
- {
- ent = i386_register_map;
- count = size_of_i386_register_map;
- }
- else
- {
- ent = x86_64_register_map;
- count = size_of_x86_64_register_map;
- }
- for (i = 0; i < count; i++, ent++)
- {
- if (ent->machine_regno == machine_regno)
- if (ent->lldb_regno != -1)
- {
- lldb_regno = ent->lldb_regno;
- return true;
- }
- }
- return false;
-}
-
-bool
-AssemblyParse_x86::instruction_length (Address addr, int &length)
-{
- const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
- llvm::SmallVector <uint8_t, 32> opcode_data;
- opcode_data.resize (max_op_byte_size);
-
- if (!addr.IsValid())
- return false;
-
- const bool prefer_file_cache = true;
- Error error;
- Target *target = m_exe_ctx.GetTargetPtr();
- if (target->ReadMemory (addr, prefer_file_cache, opcode_data.data(),
- max_op_byte_size, error) == static_cast<size_t>(-1))
- {
- return false;
- }
-
- char out_string[512];
- const addr_t pc = addr.GetFileAddress();
- const size_t inst_size = ::LLVMDisasmInstruction (m_disasm_context,
- opcode_data.data(),
- max_op_byte_size,
- pc, // PC value
- out_string,
- sizeof(out_string));
-
- length = inst_size;
+bool AssemblyParse_x86::ret_pattern_p() {
+ uint8_t *p = m_cur_insn_bytes;
+ if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
return true;
+ return false;
}
+uint32_t AssemblyParse_x86::extract_4(uint8_t *b) {
+ uint32_t v = 0;
+ for (int i = 3; i >= 0; i--)
+ v = (v << 8) | b[i];
+ return v;
+}
+
+bool AssemblyParse_x86::machine_regno_to_lldb_regno(int machine_regno,
+ uint32_t &lldb_regno) {
+ struct regmap_ent *ent;
+ int count, i;
+ if (m_cpu == k_i386) {
+ ent = i386_register_map;
+ count = size_of_i386_register_map;
+ } else {
+ ent = x86_64_register_map;
+ count = size_of_x86_64_register_map;
+ }
+ for (i = 0; i < count; i++, ent++) {
+ if (ent->machine_regno == machine_regno)
+ if (ent->lldb_regno != -1) {
+ lldb_regno = ent->lldb_regno;
+ return true;
+ }
+ }
+ return false;
+}
-bool
-AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
-{
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- m_cur_insn = m_func_bounds.GetBaseAddress ();
- addr_t current_func_text_offset = 0;
- int current_sp_bytes_offset_from_cfa = 0;
- UnwindPlan::Row::RegisterLocation initial_regloc;
- Error error;
-
- if (!m_cur_insn.IsValid())
- {
- return false;
- }
-
- unwind_plan.SetPlanValidAddressRange (m_func_bounds);
- unwind_plan.SetRegisterKind (eRegisterKindLLDB);
-
- // At the start of the function, find the CFA by adding wordsize to the SP register
- row->SetOffset (current_func_text_offset);
- row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum, m_wordsize);
-
- // caller's stack pointer value before the call insn is the CFA address
- initial_regloc.SetIsCFAPlusOffset (0);
- row->SetRegisterInfo (m_lldb_sp_regnum, initial_regloc);
-
- // saved instruction pointer can be found at CFA - wordsize.
- current_sp_bytes_offset_from_cfa = m_wordsize;
- initial_regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
- row->SetRegisterInfo (m_lldb_ip_regnum, initial_regloc);
-
- unwind_plan.AppendRow (row);
-
- // Allocate a new Row, populate it with the existing Row contents.
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
-
- // Track which registers have been saved so far in the prologue.
- // If we see another push of that register, it's not part of the prologue.
- // The register numbers used here are the machine register #'s
- // (i386_register_numbers, x86_64_register_numbers).
- std::vector<bool> saved_registers(32, false);
-
- const bool prefer_file_cache = true;
-
- // Once the prologue has completed we'll save a copy of the unwind instructions
- // If there is an epilogue in the middle of the function, after that epilogue we'll reinstate
- // the unwind setup -- we assume that some code path jumps over the mid-function epilogue
-
- UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI
- int prologue_completed_sp_bytes_offset_from_cfa; // The sp value before the epilogue started executed
- std::vector<bool> prologue_completed_saved_registers;
-
- Target *target = m_exe_ctx.GetTargetPtr();
- while (m_func_bounds.ContainsFileAddress (m_cur_insn))
- {
- int stack_offset, insn_len;
- int machine_regno; // register numbers masked directly out of instructions
- uint32_t lldb_regno; // register numbers in lldb's eRegisterKindLLDB numbering scheme
-
- bool in_epilogue = false; // we're in the middle of an epilogue sequence
- bool row_updated = false; // The UnwindPlan::Row 'row' has been updated
-
- if (!instruction_length (m_cur_insn, insn_len) || insn_len == 0 || insn_len > kMaxInstructionByteSize)
- {
- // An unrecognized/junk instruction
- break;
- }
-
- if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
- insn_len, error) == static_cast<size_t>(-1))
- {
- // Error reading the instruction out of the file, stop scanning
- break;
- }
-
- if (push_rbp_pattern_p ())
- {
- current_sp_bytes_offset_from_cfa += m_wordsize;
- row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
- UnwindPlan::Row::RegisterLocation regloc;
- regloc.SetAtCFAPlusOffset (-row->GetCFAValue().GetOffset());
- row->SetRegisterInfo (m_lldb_fp_regnum, regloc);
- saved_registers[m_machine_fp_regnum] = true;
- row_updated = true;
- }
-
- else if (mov_rsp_rbp_pattern_p ())
- {
- row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_fp_regnum, row->GetCFAValue().GetOffset());
- row_updated = true;
- }
-
- // This is the start() function (or a pthread equivalent), it starts with a pushl $0x0 which puts the
- // saved pc value of 0 on the stack. In this case we want to pretend we didn't see a stack movement at all --
- // normally the saved pc value is already on the stack by the time the function starts executing.
- else if (push_0_pattern_p ())
- {
- }
-
- else if (push_reg_p (machine_regno))
- {
- current_sp_bytes_offset_from_cfa += m_wordsize;
- // the PUSH instruction has moved the stack pointer - if the CFA is set in terms of the stack pointer,
- // we need to add a new row of instructions.
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
- {
- row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
- row_updated = true;
- }
- // record where non-volatile (callee-saved, spilled) registers are saved on the stack
- if (nonvolatile_reg_p (machine_regno)
- && machine_regno_to_lldb_regno (machine_regno, lldb_regno)
- && saved_registers[machine_regno] == false)
- {
- UnwindPlan::Row::RegisterLocation regloc;
- regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
- row->SetRegisterInfo (lldb_regno, regloc);
- saved_registers[machine_regno] = true;
- row_updated = true;
- }
- }
-
- else if (pop_reg_p (machine_regno))
- {
- current_sp_bytes_offset_from_cfa -= m_wordsize;
-
- if (nonvolatile_reg_p (machine_regno)
- && machine_regno_to_lldb_regno (machine_regno, lldb_regno)
- && saved_registers[machine_regno] == true)
- {
- saved_registers[machine_regno] = false;
- row->RemoveRegisterInfo (lldb_regno);
-
- if (machine_regno == (int)m_machine_fp_regnum)
- {
- row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
- }
-
- in_epilogue = true;
- row_updated = true;
- }
-
- // the POP instruction has moved the stack pointer - if the CFA is set in terms of the stack pointer,
- // we need to add a new row of instructions.
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
- {
- row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
- row_updated = true;
- }
- }
-
- // The LEAVE instruction moves the value from rbp into rsp and pops
- // a value off the stack into rbp (restoring the caller's rbp value).
- // It is the opposite of ENTER, or 'push rbp, mov rsp rbp'.
- else if (leave_pattern_p ())
- {
- // We're going to copy the value in rbp into rsp, so re-set the sp offset
- // based on the CFAValue. Also, adjust it to recognize that we're popping
- // the saved rbp value off the stack.
- current_sp_bytes_offset_from_cfa = row->GetCFAValue().GetOffset();
- current_sp_bytes_offset_from_cfa -= m_wordsize;
- row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
-
- // rbp is restored to the caller's value
- saved_registers[m_machine_fp_regnum] = false;
- row->RemoveRegisterInfo (m_lldb_fp_regnum);
-
- // cfa is now in terms of rsp again.
- row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
- row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
-
- in_epilogue = true;
- row_updated = true;
- }
-
- else if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset)
- && nonvolatile_reg_p (machine_regno)
- && machine_regno_to_lldb_regno (machine_regno, lldb_regno)
- && saved_registers[machine_regno] == false)
- {
- saved_registers[machine_regno] = true;
-
- UnwindPlan::Row::RegisterLocation regloc;
-
- // stack_offset for 'movq %r15, -80(%rbp)' will be 80.
- // In the Row, we want to express this as the offset from the CFA. If the frame base
- // is rbp (like the above instruction), the CFA offset for rbp is probably 16. So we
- // want to say that the value is stored at the CFA address - 96.
- regloc.SetAtCFAPlusOffset (-(stack_offset + row->GetCFAValue().GetOffset()));
-
- row->SetRegisterInfo (lldb_regno, regloc);
-
- row_updated = true;
- }
-
- else if (sub_rsp_pattern_p (stack_offset))
- {
- current_sp_bytes_offset_from_cfa += stack_offset;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
- {
- row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
- row_updated = true;
- }
- }
-
- else if (add_rsp_pattern_p (stack_offset))
- {
- current_sp_bytes_offset_from_cfa -= stack_offset;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
- {
- row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
- row_updated = true;
- }
- in_epilogue = true;
- }
-
- else if (lea_rsp_pattern_p (stack_offset))
- {
- current_sp_bytes_offset_from_cfa -= stack_offset;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
- {
- row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
- row_updated = true;
- }
- if (stack_offset > 0)
- in_epilogue = true;
- }
-
- else if (ret_pattern_p () && prologue_completed_row.get())
- {
- // Reinstate the saved prologue setup for any instructions
- // that come after the ret instruction
-
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *prologue_completed_row.get();
- row.reset (newrow);
- current_sp_bytes_offset_from_cfa = prologue_completed_sp_bytes_offset_from_cfa;
-
- saved_registers.clear();
- saved_registers.resize(prologue_completed_saved_registers.size(), false);
- for (size_t i = 0; i < prologue_completed_saved_registers.size(); ++i)
- {
- saved_registers[i] = prologue_completed_saved_registers[i];
- }
-
- in_epilogue = true;
- row_updated = true;
- }
-
- // call next instruction
- // call 0
- // => pop %ebx
- // This is used in i386 programs to get the PIC base address for finding global data
- else if (call_next_insn_pattern_p ())
- {
- current_sp_bytes_offset_from_cfa += m_wordsize;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
- {
- row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
- row_updated = true;
- }
- }
-
- if (row_updated)
- {
- if (current_func_text_offset + insn_len < m_func_bounds.GetByteSize())
- {
- row->SetOffset (current_func_text_offset + insn_len);
- unwind_plan.AppendRow (row);
- // Allocate a new Row, populate it with the existing Row contents.
- newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
- }
- }
-
- if (in_epilogue == false && row_updated)
- {
- // If we're not in an epilogue sequence, save the updated Row
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- prologue_completed_row.reset (newrow);
-
- prologue_completed_saved_registers.clear();
- prologue_completed_saved_registers.resize(saved_registers.size(), false);
- for (size_t i = 0; i < saved_registers.size(); ++i)
- {
- prologue_completed_saved_registers[i] = saved_registers[i];
- }
- }
+bool AssemblyParse_x86::instruction_length(Address addr, int &length) {
+ const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
+ llvm::SmallVector<uint8_t, 32> opcode_data;
+ opcode_data.resize(max_op_byte_size);
- // We may change the sp value without adding a new Row necessarily -- keep
- // track of it either way.
- if (in_epilogue == false)
- {
- prologue_completed_sp_bytes_offset_from_cfa = current_sp_bytes_offset_from_cfa;
- }
+ if (!addr.IsValid())
+ return false;
- m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
- current_func_text_offset += insn_len;
- }
+ const bool prefer_file_cache = true;
+ Error error;
+ Target *target = m_exe_ctx.GetTargetPtr();
+ if (target->ReadMemory(addr, prefer_file_cache, opcode_data.data(),
+ max_op_byte_size, error) == static_cast<size_t>(-1)) {
+ return false;
+ }
- unwind_plan.SetSourceName ("assembly insn profiling");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
+ char out_string[512];
+ const addr_t pc = addr.GetFileAddress();
+ const size_t inst_size = ::LLVMDisasmInstruction(
+ m_disasm_context, opcode_data.data(), max_op_byte_size,
+ pc, // PC value
+ out_string, sizeof(out_string));
+
+ length = inst_size;
+ return true;
+}
+
+bool AssemblyParse_x86::get_non_call_site_unwind_plan(UnwindPlan &unwind_plan) {
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ m_cur_insn = m_func_bounds.GetBaseAddress();
+ addr_t current_func_text_offset = 0;
+ int current_sp_bytes_offset_from_cfa = 0;
+ UnwindPlan::Row::RegisterLocation initial_regloc;
+ Error error;
- return true;
-}
+ if (!m_cur_insn.IsValid()) {
+ return false;
+ }
-bool
-AssemblyParse_x86::augment_unwind_plan_from_call_site (AddressRange& func, UnwindPlan &unwind_plan)
-{
- // Is func address valid?
- Address addr_start = func.GetBaseAddress();
- if (!addr_start.IsValid())
- return false;
-
- // Is original unwind_plan valid?
- // unwind_plan should have at least one row which is ABI-default (CFA register is sp),
- // and another row in mid-function.
- if (unwind_plan.GetRowCount() < 2)
- return false;
- UnwindPlan::RowSP first_row = unwind_plan.GetRowAtIndex (0);
- if (first_row->GetOffset() != 0)
- return false;
- uint32_t cfa_reg = m_exe_ctx.GetThreadPtr()->GetRegisterContext()
- ->ConvertRegisterKindToRegisterNumber (unwind_plan.GetRegisterKind(),
- first_row->GetCFAValue().GetRegisterNumber());
- if (cfa_reg != m_lldb_sp_regnum || first_row->GetCFAValue().GetOffset() != m_wordsize)
- return false;
-
- UnwindPlan::RowSP original_last_row = unwind_plan.GetRowForFunctionOffset (-1);
-
- Target *target = m_exe_ctx.GetTargetPtr();
- m_cur_insn = func.GetBaseAddress();
- uint64_t offset = 0;
- int row_id = 1;
- bool unwind_plan_updated = false;
- UnwindPlan::RowSP row(new UnwindPlan::Row(*first_row));
-
- // After a mid-function epilogue we will need to re-insert the original unwind rules
- // so unwinds work for the remainder of the function. These aren't common with clang/gcc
- // on x86 but it is possible.
- bool reinstate_unwind_state = false;
-
- while (func.ContainsFileAddress (m_cur_insn))
- {
- int insn_len;
- if (!instruction_length (m_cur_insn, insn_len)
- || insn_len == 0 || insn_len > kMaxInstructionByteSize)
- {
- // An unrecognized/junk instruction.
- break;
- }
- const bool prefer_file_cache = true;
- Error error;
- if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
- insn_len, error) == static_cast<size_t>(-1))
- {
- // Error reading the instruction out of the file, stop scanning.
- break;
- }
+ unwind_plan.SetPlanValidAddressRange(m_func_bounds);
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
- // Advance offsets.
- offset += insn_len;
- m_cur_insn.SetOffset(m_cur_insn.GetOffset() + insn_len);
-
- if (reinstate_unwind_state)
- {
- // that was the last instruction of this function
- if (func.ContainsFileAddress (m_cur_insn) == false)
- continue;
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row());
- *new_row = *original_last_row;
- new_row->SetOffset (offset);
- unwind_plan.AppendRow (new_row);
- row.reset (new UnwindPlan::Row());
- *row = *new_row;
- reinstate_unwind_state = false;
- unwind_plan_updated = true;
- continue;
- }
-
- // If we already have one row for this instruction, we can continue.
- while (row_id < unwind_plan.GetRowCount()
- && unwind_plan.GetRowAtIndex (row_id)->GetOffset() <= offset)
- {
- row_id++;
- }
- UnwindPlan::RowSP original_row = unwind_plan.GetRowAtIndex (row_id - 1);
- if (original_row->GetOffset() == offset)
- {
- *row = *original_row;
- continue;
- }
+ // At the start of the function, find the CFA by adding wordsize to the SP
+ // register
+ row->SetOffset(current_func_text_offset);
+ row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum, m_wordsize);
+
+ // caller's stack pointer value before the call insn is the CFA address
+ initial_regloc.SetIsCFAPlusOffset(0);
+ row->SetRegisterInfo(m_lldb_sp_regnum, initial_regloc);
+
+ // saved instruction pointer can be found at CFA - wordsize.
+ current_sp_bytes_offset_from_cfa = m_wordsize;
+ initial_regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa);
+ row->SetRegisterInfo(m_lldb_ip_regnum, initial_regloc);
+
+ unwind_plan.AppendRow(row);
+
+ // Allocate a new Row, populate it with the existing Row contents.
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *row.get();
+ row.reset(newrow);
+
+ // Track which registers have been saved so far in the prologue.
+ // If we see another push of that register, it's not part of the prologue.
+ // The register numbers used here are the machine register #'s
+ // (i386_register_numbers, x86_64_register_numbers).
+ std::vector<bool> saved_registers(32, false);
+
+ const bool prefer_file_cache = true;
+
+ // Once the prologue has completed we'll save a copy of the unwind
+ // instructions
+ // If there is an epilogue in the middle of the function, after that epilogue
+ // we'll reinstate
+ // the unwind setup -- we assume that some code path jumps over the
+ // mid-function epilogue
+
+ UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI
+ int prologue_completed_sp_bytes_offset_from_cfa; // The sp value before the
+ // epilogue started executed
+ std::vector<bool> prologue_completed_saved_registers;
+
+ Target *target = m_exe_ctx.GetTargetPtr();
+ while (m_func_bounds.ContainsFileAddress(m_cur_insn)) {
+ int stack_offset, insn_len;
+ int machine_regno; // register numbers masked directly out of instructions
+ uint32_t lldb_regno; // register numbers in lldb's eRegisterKindLLDB
+ // numbering scheme
+
+ bool in_epilogue = false; // we're in the middle of an epilogue sequence
+ bool row_updated = false; // The UnwindPlan::Row 'row' has been updated
+
+ if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
+ insn_len > kMaxInstructionByteSize) {
+ // An unrecognized/junk instruction
+ break;
+ }
+
+ if (target->ReadMemory(m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
+ insn_len, error) == static_cast<size_t>(-1)) {
+ // Error reading the instruction out of the file, stop scanning
+ break;
+ }
+
+ if (push_rbp_pattern_p()) {
+ current_sp_bytes_offset_from_cfa += m_wordsize;
+ row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ UnwindPlan::Row::RegisterLocation regloc;
+ regloc.SetAtCFAPlusOffset(-row->GetCFAValue().GetOffset());
+ row->SetRegisterInfo(m_lldb_fp_regnum, regloc);
+ saved_registers[m_machine_fp_regnum] = true;
+ row_updated = true;
+ }
+
+ else if (mov_rsp_rbp_pattern_p()) {
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_lldb_fp_regnum, row->GetCFAValue().GetOffset());
+ row_updated = true;
+ }
+
+ // This is the start() function (or a pthread equivalent), it starts with a
+ // pushl $0x0 which puts the
+ // saved pc value of 0 on the stack. In this case we want to pretend we
+ // didn't see a stack movement at all --
+ // normally the saved pc value is already on the stack by the time the
+ // function starts executing.
+ else if (push_0_pattern_p()) {
+ }
+
+ else if (push_reg_p(machine_regno)) {
+ current_sp_bytes_offset_from_cfa += m_wordsize;
+ // the PUSH instruction has moved the stack pointer - if the CFA is set in
+ // terms of the stack pointer,
+ // we need to add a new row of instructions.
+ if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+ row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ row_updated = true;
+ }
+ // record where non-volatile (callee-saved, spilled) registers are saved
+ // on the stack
+ if (nonvolatile_reg_p(machine_regno) &&
+ machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
+ saved_registers[machine_regno] == false) {
+ UnwindPlan::Row::RegisterLocation regloc;
+ regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa);
+ row->SetRegisterInfo(lldb_regno, regloc);
+ saved_registers[machine_regno] = true;
+ row_updated = true;
+ }
+ }
+
+ else if (pop_reg_p(machine_regno)) {
+ current_sp_bytes_offset_from_cfa -= m_wordsize;
+
+ if (nonvolatile_reg_p(machine_regno) &&
+ machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
+ saved_registers[machine_regno] == true) {
+ saved_registers[machine_regno] = false;
+ row->RemoveRegisterInfo(lldb_regno);
+
+ if (machine_regno == (int)m_machine_fp_regnum) {
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
+ }
+
+ in_epilogue = true;
+ row_updated = true;
+ }
+
+ // the POP instruction has moved the stack pointer - if the CFA is set in
+ // terms of the stack pointer,
+ // we need to add a new row of instructions.
+ if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
+ row_updated = true;
+ }
+ }
+
+ // The LEAVE instruction moves the value from rbp into rsp and pops
+ // a value off the stack into rbp (restoring the caller's rbp value).
+ // It is the opposite of ENTER, or 'push rbp, mov rsp rbp'.
+ else if (leave_pattern_p()) {
+ // We're going to copy the value in rbp into rsp, so re-set the sp offset
+ // based on the CFAValue. Also, adjust it to recognize that we're popping
+ // the saved rbp value off the stack.
+ current_sp_bytes_offset_from_cfa = row->GetCFAValue().GetOffset();
+ current_sp_bytes_offset_from_cfa -= m_wordsize;
+ row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+
+ // rbp is restored to the caller's value
+ saved_registers[m_machine_fp_regnum] = false;
+ row->RemoveRegisterInfo(m_lldb_fp_regnum);
+
+ // cfa is now in terms of rsp again.
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
+ row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+
+ in_epilogue = true;
+ row_updated = true;
+ }
+
+ else if (mov_reg_to_local_stack_frame_p(machine_regno, stack_offset) &&
+ nonvolatile_reg_p(machine_regno) &&
+ machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
+ saved_registers[machine_regno] == false) {
+ saved_registers[machine_regno] = true;
+
+ UnwindPlan::Row::RegisterLocation regloc;
+
+ // stack_offset for 'movq %r15, -80(%rbp)' will be 80.
+ // In the Row, we want to express this as the offset from the CFA. If the
+ // frame base
+ // is rbp (like the above instruction), the CFA offset for rbp is probably
+ // 16. So we
+ // want to say that the value is stored at the CFA address - 96.
+ regloc.SetAtCFAPlusOffset(
+ -(stack_offset + row->GetCFAValue().GetOffset()));
+
+ row->SetRegisterInfo(lldb_regno, regloc);
+
+ row_updated = true;
+ }
+
+ else if (sub_rsp_pattern_p(stack_offset)) {
+ current_sp_bytes_offset_from_cfa += stack_offset;
+ if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+ row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ row_updated = true;
+ }
+ }
+
+ else if (add_rsp_pattern_p(stack_offset)) {
+ current_sp_bytes_offset_from_cfa -= stack_offset;
+ if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+ row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ row_updated = true;
+ }
+ in_epilogue = true;
+ }
+
+ else if (lea_rsp_pattern_p(stack_offset)) {
+ current_sp_bytes_offset_from_cfa -= stack_offset;
+ if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+ row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ row_updated = true;
+ }
+ if (stack_offset > 0)
+ in_epilogue = true;
+ }
+
+ else if (ret_pattern_p() && prologue_completed_row.get()) {
+ // Reinstate the saved prologue setup for any instructions
+ // that come after the ret instruction
+
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *prologue_completed_row.get();
+ row.reset(newrow);
+ current_sp_bytes_offset_from_cfa =
+ prologue_completed_sp_bytes_offset_from_cfa;
+
+ saved_registers.clear();
+ saved_registers.resize(prologue_completed_saved_registers.size(), false);
+ for (size_t i = 0; i < prologue_completed_saved_registers.size(); ++i) {
+ saved_registers[i] = prologue_completed_saved_registers[i];
+ }
+
+ in_epilogue = true;
+ row_updated = true;
+ }
+
+ // call next instruction
+ // call 0
+ // => pop %ebx
+ // This is used in i386 programs to get the PIC base address for finding
+ // global data
+ else if (call_next_insn_pattern_p()) {
+ current_sp_bytes_offset_from_cfa += m_wordsize;
+ if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+ row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ row_updated = true;
+ }
+ }
+
+ if (row_updated) {
+ if (current_func_text_offset + insn_len < m_func_bounds.GetByteSize()) {
+ row->SetOffset(current_func_text_offset + insn_len);
+ unwind_plan.AppendRow(row);
+ // Allocate a new Row, populate it with the existing Row contents.
+ newrow = new UnwindPlan::Row;
+ *newrow = *row.get();
+ row.reset(newrow);
+ }
+ }
+
+ if (in_epilogue == false && row_updated) {
+ // If we're not in an epilogue sequence, save the updated Row
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *row.get();
+ prologue_completed_row.reset(newrow);
+
+ prologue_completed_saved_registers.clear();
+ prologue_completed_saved_registers.resize(saved_registers.size(), false);
+ for (size_t i = 0; i < saved_registers.size(); ++i) {
+ prologue_completed_saved_registers[i] = saved_registers[i];
+ }
+ }
+
+ // We may change the sp value without adding a new Row necessarily -- keep
+ // track of it either way.
+ if (in_epilogue == false) {
+ prologue_completed_sp_bytes_offset_from_cfa =
+ current_sp_bytes_offset_from_cfa;
+ }
+
+ m_cur_insn.SetOffset(m_cur_insn.GetOffset() + insn_len);
+ current_func_text_offset += insn_len;
+ }
+
+ unwind_plan.SetSourceName("assembly insn profiling");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+
+ return true;
+}
+
+bool AssemblyParse_x86::augment_unwind_plan_from_call_site(
+ AddressRange &func, UnwindPlan &unwind_plan) {
+ // Is func address valid?
+ Address addr_start = func.GetBaseAddress();
+ if (!addr_start.IsValid())
+ return false;
- if (row_id == 0)
- {
- // If we are here, compiler didn't generate CFI for prologue.
- // This won't happen to GCC or clang.
- // In this case, bail out directly.
- return false;
- }
+ // Is original unwind_plan valid?
+ // unwind_plan should have at least one row which is ABI-default (CFA register
+ // is sp),
+ // and another row in mid-function.
+ if (unwind_plan.GetRowCount() < 2)
+ return false;
+ UnwindPlan::RowSP first_row = unwind_plan.GetRowAtIndex(0);
+ if (first_row->GetOffset() != 0)
+ return false;
+ uint32_t cfa_reg = m_exe_ctx.GetThreadPtr()
+ ->GetRegisterContext()
+ ->ConvertRegisterKindToRegisterNumber(
+ unwind_plan.GetRegisterKind(),
+ first_row->GetCFAValue().GetRegisterNumber());
+ if (cfa_reg != m_lldb_sp_regnum ||
+ first_row->GetCFAValue().GetOffset() != m_wordsize)
+ return false;
- // Inspect the instruction to check if we need a new row for it.
- cfa_reg = m_exe_ctx.GetThreadPtr()->GetRegisterContext()
- ->ConvertRegisterKindToRegisterNumber (unwind_plan.GetRegisterKind(),
- row->GetCFAValue().GetRegisterNumber());
- if (cfa_reg == m_lldb_sp_regnum)
- {
- // CFA register is sp.
-
- // call next instruction
- // call 0
- // => pop %ebx
- if (call_next_insn_pattern_p ())
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- // push/pop register
- int regno;
- if (push_reg_p (regno))
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
- if (pop_reg_p (regno))
- {
- // Technically, this might be a nonvolatile register recover in epilogue.
- // We should reset RegisterInfo for the register.
- // But in practice, previous rule for the register is still valid...
- // So we ignore this case.
-
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (-m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- // push imm
- if (push_imm_pattern_p ())
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (m_wordsize);
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- // add/sub %rsp/%esp
- int amount;
- if (add_rsp_pattern_p (amount))
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (-amount);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
- if (sub_rsp_pattern_p (amount))
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (amount);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- // lea %rsp, [%rsp + $offset]
- if (lea_rsp_pattern_p (amount))
- {
- row->SetOffset (offset);
- row->GetCFAValue().IncOffset (-amount);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- continue;
- }
-
- if (ret_pattern_p ())
- {
- reinstate_unwind_state = true;
- continue;
- }
- }
- else if (cfa_reg == m_lldb_fp_regnum)
- {
- // CFA register is fp.
-
- // The only case we care about is epilogue:
- // [0x5d] pop %rbp/%ebp
- // => [0xc3] ret
- if (pop_rbp_pattern_p () || leave_pattern_p ())
- {
- if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
- 1, error) != static_cast<size_t>(-1)
- && ret_pattern_p ())
- {
- row->SetOffset (offset);
- row->GetCFAValue().SetIsRegisterPlusOffset (first_row->GetCFAValue().GetRegisterNumber(),
- m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow (new_row);
- unwind_plan_updated = true;
- reinstate_unwind_state = true;
- continue;
- }
- }
- }
- else
- {
- // CFA register is not sp or fp.
-
- // This must be hand-written assembly.
- // Just trust eh_frame and assume we have finished.
- break;
- }
- }
+ UnwindPlan::RowSP original_last_row = unwind_plan.GetRowForFunctionOffset(-1);
- unwind_plan.SetPlanValidAddressRange (func);
- if (unwind_plan_updated)
- {
- std::string unwind_plan_source (unwind_plan.GetSourceName().AsCString());
- unwind_plan_source += " plus augmentation from assembly parsing";
- unwind_plan.SetSourceName (unwind_plan_source.c_str());
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
+ Target *target = m_exe_ctx.GetTargetPtr();
+ m_cur_insn = func.GetBaseAddress();
+ uint64_t offset = 0;
+ int row_id = 1;
+ bool unwind_plan_updated = false;
+ UnwindPlan::RowSP row(new UnwindPlan::Row(*first_row));
+
+ // After a mid-function epilogue we will need to re-insert the original unwind
+ // rules
+ // so unwinds work for the remainder of the function. These aren't common
+ // with clang/gcc
+ // on x86 but it is possible.
+ bool reinstate_unwind_state = false;
+
+ while (func.ContainsFileAddress(m_cur_insn)) {
+ int insn_len;
+ if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
+ insn_len > kMaxInstructionByteSize) {
+ // An unrecognized/junk instruction.
+ break;
}
- return true;
-}
-
-/* The "fast unwind plan" is valid for functions that follow the usual convention of
- using the frame pointer register (ebp, rbp), i.e. the function prologue looks like
+ const bool prefer_file_cache = true;
+ Error error;
+ if (target->ReadMemory(m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
+ insn_len, error) == static_cast<size_t>(-1)) {
+ // Error reading the instruction out of the file, stop scanning.
+ break;
+ }
+
+ // Advance offsets.
+ offset += insn_len;
+ m_cur_insn.SetOffset(m_cur_insn.GetOffset() + insn_len);
+
+ if (reinstate_unwind_state) {
+ // that was the last instruction of this function
+ if (func.ContainsFileAddress(m_cur_insn) == false)
+ continue;
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row());
+ *new_row = *original_last_row;
+ new_row->SetOffset(offset);
+ unwind_plan.AppendRow(new_row);
+ row.reset(new UnwindPlan::Row());
+ *row = *new_row;
+ reinstate_unwind_state = false;
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // If we already have one row for this instruction, we can continue.
+ while (row_id < unwind_plan.GetRowCount() &&
+ unwind_plan.GetRowAtIndex(row_id)->GetOffset() <= offset) {
+ row_id++;
+ }
+ UnwindPlan::RowSP original_row = unwind_plan.GetRowAtIndex(row_id - 1);
+ if (original_row->GetOffset() == offset) {
+ *row = *original_row;
+ continue;
+ }
+
+ if (row_id == 0) {
+ // If we are here, compiler didn't generate CFI for prologue.
+ // This won't happen to GCC or clang.
+ // In this case, bail out directly.
+ return false;
+ }
+
+ // Inspect the instruction to check if we need a new row for it.
+ cfa_reg = m_exe_ctx.GetThreadPtr()
+ ->GetRegisterContext()
+ ->ConvertRegisterKindToRegisterNumber(
+ unwind_plan.GetRegisterKind(),
+ row->GetCFAValue().GetRegisterNumber());
+ if (cfa_reg == m_lldb_sp_regnum) {
+ // CFA register is sp.
+
+ // call next instruction
+ // call 0
+ // => pop %ebx
+ if (call_next_insn_pattern_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // push/pop register
+ int regno;
+ if (push_reg_p(regno)) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+ if (pop_reg_p(regno)) {
+ // Technically, this might be a nonvolatile register recover in
+ // epilogue.
+ // We should reset RegisterInfo for the register.
+ // But in practice, previous rule for the register is still valid...
+ // So we ignore this case.
+
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(-m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // push imm
+ if (push_imm_pattern_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(m_wordsize);
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // add/sub %rsp/%esp
+ int amount;
+ if (add_rsp_pattern_p(amount)) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(-amount);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+ if (sub_rsp_pattern_p(amount)) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(amount);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ // lea %rsp, [%rsp + $offset]
+ if (lea_rsp_pattern_p(amount)) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(-amount);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
+ if (ret_pattern_p()) {
+ reinstate_unwind_state = true;
+ continue;
+ }
+ } else if (cfa_reg == m_lldb_fp_regnum) {
+ // CFA register is fp.
+
+ // The only case we care about is epilogue:
+ // [0x5d] pop %rbp/%ebp
+ // => [0xc3] ret
+ if (pop_rbp_pattern_p() || leave_pattern_p()) {
+ if (target->ReadMemory(m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
+ 1, error) != static_cast<size_t>(-1) &&
+ ret_pattern_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ reinstate_unwind_state = true;
+ continue;
+ }
+ }
+ } else {
+ // CFA register is not sp or fp.
+
+ // This must be hand-written assembly.
+ // Just trust eh_frame and assume we have finished.
+ break;
+ }
+ }
+
+ unwind_plan.SetPlanValidAddressRange(func);
+ if (unwind_plan_updated) {
+ std::string unwind_plan_source(unwind_plan.GetSourceName().AsCString());
+ unwind_plan_source += " plus augmentation from assembly parsing";
+ unwind_plan.SetSourceName(unwind_plan_source.c_str());
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ }
+ return true;
+}
+
+/* The "fast unwind plan" is valid for functions that follow the usual
+ convention of
+ using the frame pointer register (ebp, rbp), i.e. the function prologue looks
+ like
push %rbp [0x55]
mov %rsp,%rbp [0x48 0x89 0xe5] (this is a 2-byte insn seq on i386)
*/
-bool
-AssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan)
-{
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- UnwindPlan::Row::RegisterLocation pc_reginfo;
- UnwindPlan::Row::RegisterLocation sp_reginfo;
- UnwindPlan::Row::RegisterLocation fp_reginfo;
- unwind_plan.SetRegisterKind (eRegisterKindLLDB);
+bool AssemblyParse_x86::get_fast_unwind_plan(AddressRange &func,
+ UnwindPlan &unwind_plan) {
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ UnwindPlan::Row::RegisterLocation pc_reginfo;
+ UnwindPlan::Row::RegisterLocation sp_reginfo;
+ UnwindPlan::Row::RegisterLocation fp_reginfo;
+ unwind_plan.SetRegisterKind(eRegisterKindLLDB);
- if (!func.GetBaseAddress().IsValid())
- return false;
-
- Target *target = m_exe_ctx.GetTargetPtr();
+ if (!func.GetBaseAddress().IsValid())
+ return false;
- uint8_t bytebuf[4];
- Error error;
- const bool prefer_file_cache = true;
- if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf,
- sizeof (bytebuf), error) == static_cast<size_t>(-1))
- return false;
-
- uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
- uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5};
- int prologue_size;
-
- if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0)
- {
- prologue_size = sizeof (i386_prologue);
- }
- else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0)
- {
- prologue_size = sizeof (x86_64_prologue);
- }
- else
- {
- return false;
- }
+ Target *target = m_exe_ctx.GetTargetPtr();
- pc_reginfo.SetAtCFAPlusOffset (-m_wordsize);
- row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo);
+ uint8_t bytebuf[4];
+ Error error;
+ const bool prefer_file_cache = true;
+ if (target->ReadMemory(func.GetBaseAddress(), prefer_file_cache, bytebuf,
+ sizeof(bytebuf), error) == static_cast<size_t>(-1))
+ return false;
- sp_reginfo.SetIsCFAPlusOffset (0);
- row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo);
-
- // Zero instructions into the function
- row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_sp_regnum, m_wordsize);
- row->SetOffset (0);
- unwind_plan.AppendRow (row);
- UnwindPlan::Row *newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
-
- // push %rbp has executed - stack moved, rbp now saved
- row->GetCFAValue().IncOffset (m_wordsize);
- fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize);
- row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo);
- row->SetOffset (1);
- unwind_plan.AppendRow (row);
-
- newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
-
- // mov %rsp, %rbp has executed
- row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_fp_regnum, 2 * m_wordsize);
- row->SetOffset (prologue_size); /// 3 or 4 bytes depending on arch
- unwind_plan.AppendRow (row);
-
- newrow = new UnwindPlan::Row;
- *newrow = *row.get();
- row.reset(newrow);
-
- unwind_plan.SetPlanValidAddressRange (func);
- unwind_plan.SetSourceName ("fast unwind assembly profiling");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- return true;
-}
+ uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
+ uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5};
+ int prologue_size;
+
+ if (memcmp(bytebuf, i386_prologue, sizeof(i386_prologue)) == 0) {
+ prologue_size = sizeof(i386_prologue);
+ } else if (memcmp(bytebuf, x86_64_prologue, sizeof(x86_64_prologue)) == 0) {
+ prologue_size = sizeof(x86_64_prologue);
+ } else {
+ return false;
+ }
-bool
-AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
-{
- m_cur_insn = m_func_bounds.GetBaseAddress ();
- if (!m_cur_insn.IsValid())
- {
- return false;
- }
+ pc_reginfo.SetAtCFAPlusOffset(-m_wordsize);
+ row->SetRegisterInfo(m_lldb_ip_regnum, pc_reginfo);
- const bool prefer_file_cache = true;
- Target *target = m_exe_ctx.GetTargetPtr();
- while (m_func_bounds.ContainsFileAddress (m_cur_insn))
- {
- Error error;
- int insn_len, offset, regno;
- if (!instruction_length (m_cur_insn, insn_len) || insn_len > kMaxInstructionByteSize || insn_len == 0)
- {
- // An error parsing the instruction, i.e. probably data/garbage - stop scanning
- break;
- }
- if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
- insn_len, error) == static_cast<size_t>(-1))
- {
- // Error reading the instruction out of the file, stop scanning
- break;
- }
+ sp_reginfo.SetIsCFAPlusOffset(0);
+ row->SetRegisterInfo(m_lldb_sp_regnum, sp_reginfo);
- if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset)
- || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset)
- || (lea_rsp_pattern_p (offset) && offset < 0))
- {
- m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
- continue;
- }
+ // Zero instructions into the function
+ row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum, m_wordsize);
+ row->SetOffset(0);
+ unwind_plan.AppendRow(row);
+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
+ *newrow = *row.get();
+ row.reset(newrow);
+
+ // push %rbp has executed - stack moved, rbp now saved
+ row->GetCFAValue().IncOffset(m_wordsize);
+ fp_reginfo.SetAtCFAPlusOffset(2 * -m_wordsize);
+ row->SetRegisterInfo(m_lldb_fp_regnum, fp_reginfo);
+ row->SetOffset(1);
+ unwind_plan.AppendRow(row);
+
+ newrow = new UnwindPlan::Row;
+ *newrow = *row.get();
+ row.reset(newrow);
+
+ // mov %rsp, %rbp has executed
+ row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_fp_regnum, 2 * m_wordsize);
+ row->SetOffset(prologue_size); /// 3 or 4 bytes depending on arch
+ unwind_plan.AppendRow(row);
+
+ newrow = new UnwindPlan::Row;
+ *newrow = *row.get();
+ row.reset(newrow);
+
+ unwind_plan.SetPlanValidAddressRange(func);
+ unwind_plan.SetSourceName("fast unwind assembly profiling");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
+}
+
+bool AssemblyParse_x86::find_first_non_prologue_insn(Address &address) {
+ m_cur_insn = m_func_bounds.GetBaseAddress();
+ if (!m_cur_insn.IsValid()) {
+ return false;
+ }
- // Unknown non-prologue instruction - stop scanning
- break;
- }
+ const bool prefer_file_cache = true;
+ Target *target = m_exe_ctx.GetTargetPtr();
+ while (m_func_bounds.ContainsFileAddress(m_cur_insn)) {
+ Error error;
+ int insn_len, offset, regno;
+ if (!instruction_length(m_cur_insn, insn_len) ||
+ insn_len > kMaxInstructionByteSize || insn_len == 0) {
+ // An error parsing the instruction, i.e. probably data/garbage - stop
+ // scanning
+ break;
+ }
+ if (target->ReadMemory(m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
+ insn_len, error) == static_cast<size_t>(-1)) {
+ // Error reading the instruction out of the file, stop scanning
+ break;
+ }
+
+ if (push_rbp_pattern_p() || mov_rsp_rbp_pattern_p() ||
+ sub_rsp_pattern_p(offset) || push_reg_p(regno) ||
+ mov_reg_to_local_stack_frame_p(regno, offset) ||
+ (lea_rsp_pattern_p(offset) && offset < 0)) {
+ m_cur_insn.SetOffset(m_cur_insn.GetOffset() + insn_len);
+ continue;
+ }
+
+ // Unknown non-prologue instruction - stop scanning
+ break;
+ }
- address = m_cur_insn;
- return true;
+ address = m_cur_insn;
+ return true;
}
-
-
-
-
-
//-----------------------------------------------------------------------------------------------
// UnwindAssemblyParser_x86 method definitions
//-----------------------------------------------------------------------------------------------
-UnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) :
- lldb_private::UnwindAssembly(arch),
- m_cpu(cpu),
- m_arch(arch)
-{
-}
+UnwindAssembly_x86::UnwindAssembly_x86(const ArchSpec &arch, int cpu)
+ : lldb_private::UnwindAssembly(arch), m_cpu(cpu), m_arch(arch) {}
+UnwindAssembly_x86::~UnwindAssembly_x86() {}
-UnwindAssembly_x86::~UnwindAssembly_x86 ()
-{
-}
-
-bool
-UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
-{
- ExecutionContext exe_ctx (thread.shared_from_this());
- AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
- return asm_parse.get_non_call_site_unwind_plan (unwind_plan);
-}
+bool UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly(
+ AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
+ return asm_parse.get_non_call_site_unwind_plan(unwind_plan);
+}
+
+bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
+ AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
+ bool do_augment_unwindplan = true;
+
+ UnwindPlan::RowSP first_row = unwind_plan.GetRowForFunctionOffset(0);
+ UnwindPlan::RowSP last_row = unwind_plan.GetRowForFunctionOffset(-1);
+
+ int wordsize = 8;
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ wordsize = process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
+ }
+
+ RegisterNumber sp_regnum(thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP);
+ RegisterNumber pc_regnum(thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC);
+
+ // Does this UnwindPlan describe the prologue? I want to see that the CFA is
+ // set
+ // in terms of the stack pointer plus an offset, and I want to see that rip is
+ // retrieved at the CFA-wordsize.
+ // If there is no description of the prologue, don't try to augment this
+ // eh_frame
+ // unwinder code, fall back to assembly parsing instead.
+
+ if (first_row->GetCFAValue().GetValueType() !=
+ UnwindPlan::Row::CFAValue::isRegisterPlusOffset ||
+ RegisterNumber(thread, unwind_plan.GetRegisterKind(),
+ first_row->GetCFAValue().GetRegisterNumber()) !=
+ sp_regnum ||
+ first_row->GetCFAValue().GetOffset() != wordsize) {
+ return false;
+ }
+ UnwindPlan::Row::RegisterLocation first_row_pc_loc;
+ if (first_row->GetRegisterInfo(
+ pc_regnum.GetAsKind(unwind_plan.GetRegisterKind()),
+ first_row_pc_loc) == false ||
+ first_row_pc_loc.IsAtCFAPlusOffset() == false ||
+ first_row_pc_loc.GetOffset() != -wordsize) {
+ return false;
+ }
-bool
-UnwindAssembly_x86::AugmentUnwindPlanFromCallSite (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
-{
- bool do_augment_unwindplan = true;
-
- UnwindPlan::RowSP first_row = unwind_plan.GetRowForFunctionOffset (0);
- UnwindPlan::RowSP last_row = unwind_plan.GetRowForFunctionOffset (-1);
-
- int wordsize = 8;
- ProcessSP process_sp (thread.GetProcess());
- if (process_sp)
- {
- wordsize = process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
- }
-
- RegisterNumber sp_regnum (thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- RegisterNumber pc_regnum (thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
-
- // Does this UnwindPlan describe the prologue? I want to see that the CFA is set
- // in terms of the stack pointer plus an offset, and I want to see that rip is
- // retrieved at the CFA-wordsize.
- // If there is no description of the prologue, don't try to augment this eh_frame
- // unwinder code, fall back to assembly parsing instead.
-
- if (first_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::isRegisterPlusOffset
- || RegisterNumber (thread, unwind_plan.GetRegisterKind(),
- first_row->GetCFAValue().GetRegisterNumber()) != sp_regnum
- || first_row->GetCFAValue().GetOffset() != wordsize)
- {
- return false;
- }
- UnwindPlan::Row::RegisterLocation first_row_pc_loc;
- if (first_row->GetRegisterInfo (pc_regnum.GetAsKind (unwind_plan.GetRegisterKind()), first_row_pc_loc) == false
- || first_row_pc_loc.IsAtCFAPlusOffset() == false
- || first_row_pc_loc.GetOffset() != -wordsize)
- {
- return false;
- }
-
-
- // It looks like the prologue is described.
- // Is the epilogue described? If it is, no need to do any augmentation.
-
- if (first_row != last_row && first_row->GetOffset() != last_row->GetOffset())
- {
- // The first & last row have the same CFA register
- // and the same CFA offset value
- // and the CFA register is esp/rsp (the stack pointer).
-
- // We're checking that both of them have an unwind rule like "CFA=esp+4" or CFA+rsp+8".
-
- if (first_row->GetCFAValue().GetValueType() == last_row->GetCFAValue().GetValueType()
- && first_row->GetCFAValue().GetRegisterNumber() == last_row->GetCFAValue().GetRegisterNumber()
- && first_row->GetCFAValue().GetOffset() == last_row->GetCFAValue().GetOffset())
- {
- // Get the register locations for eip/rip from the first & last rows.
- // Are they both CFA plus an offset? Is it the same offset?
-
- UnwindPlan::Row::RegisterLocation last_row_pc_loc;
- if (last_row->GetRegisterInfo (pc_regnum.GetAsKind (unwind_plan.GetRegisterKind()), last_row_pc_loc))
- {
- if (last_row_pc_loc.IsAtCFAPlusOffset()
- && first_row_pc_loc.GetOffset() == last_row_pc_loc.GetOffset())
- {
-
- // One last sanity check: Is the unwind rule for getting the caller pc value
- // "deref the CFA-4" or "deref the CFA-8"?
-
- // If so, we have an UnwindPlan that already describes the epilogue and we don't need
- // to modify it at all.
-
- if (first_row_pc_loc.GetOffset() == -wordsize)
- {
- do_augment_unwindplan = false;
- }
- }
- }
- }
- }
+ // It looks like the prologue is described.
+ // Is the epilogue described? If it is, no need to do any augmentation.
- if (do_augment_unwindplan)
- {
- ExecutionContext exe_ctx (thread.shared_from_this());
- AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
- return asm_parse.augment_unwind_plan_from_call_site (func, unwind_plan);
- }
-
- return false;
-}
+ if (first_row != last_row &&
+ first_row->GetOffset() != last_row->GetOffset()) {
+ // The first & last row have the same CFA register
+ // and the same CFA offset value
+ // and the CFA register is esp/rsp (the stack pointer).
+
+ // We're checking that both of them have an unwind rule like "CFA=esp+4" or
+ // CFA+rsp+8".
+
+ if (first_row->GetCFAValue().GetValueType() ==
+ last_row->GetCFAValue().GetValueType() &&
+ first_row->GetCFAValue().GetRegisterNumber() ==
+ last_row->GetCFAValue().GetRegisterNumber() &&
+ first_row->GetCFAValue().GetOffset() ==
+ last_row->GetCFAValue().GetOffset()) {
+ // Get the register locations for eip/rip from the first & last rows.
+ // Are they both CFA plus an offset? Is it the same offset?
+
+ UnwindPlan::Row::RegisterLocation last_row_pc_loc;
+ if (last_row->GetRegisterInfo(
+ pc_regnum.GetAsKind(unwind_plan.GetRegisterKind()),
+ last_row_pc_loc)) {
+ if (last_row_pc_loc.IsAtCFAPlusOffset() &&
+ first_row_pc_loc.GetOffset() == last_row_pc_loc.GetOffset()) {
+
+ // One last sanity check: Is the unwind rule for getting the caller
+ // pc value
+ // "deref the CFA-4" or "deref the CFA-8"?
+
+ // If so, we have an UnwindPlan that already describes the epilogue
+ // and we don't need
+ // to modify it at all.
-bool
-UnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan)
-{
- // if prologue is
- // 55 pushl %ebp
- // 89 e5 movl %esp, %ebp
- // or
- // 55 pushq %rbp
- // 48 89 e5 movq %rsp, %rbp
-
- // We should pull in the ABI architecture default unwind plan and return that
-
- llvm::SmallVector <uint8_t, 4> opcode_data;
-
- ProcessSP process_sp = thread.GetProcess();
- if (process_sp)
- {
- Target &target (process_sp->GetTarget());
- const bool prefer_file_cache = true;
- Error error;
- if (target.ReadMemory (func.GetBaseAddress (), prefer_file_cache, opcode_data.data(),
- 4, error) == 4)
- {
- uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5};
- uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5};
-
- if (memcmp (opcode_data.data(), i386_push_mov, sizeof (i386_push_mov)) == 0
- || memcmp (opcode_data.data(), x86_64_push_mov, sizeof (x86_64_push_mov)) == 0)
- {
- ABISP abi_sp = process_sp->GetABI();
- if (abi_sp)
- {
- return abi_sp->CreateDefaultUnwindPlan (unwind_plan);
- }
- }
+ if (first_row_pc_loc.GetOffset() == -wordsize) {
+ do_augment_unwindplan = false;
+ }
}
+ }
}
- return false;
-}
+ }
-bool
-UnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn)
-{
+ if (do_augment_unwindplan) {
+ ExecutionContext exe_ctx(thread.shared_from_this());
AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
- return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn);
-}
+ return asm_parse.augment_unwind_plan_from_call_site(func, unwind_plan);
+ }
-UnwindAssembly *
-UnwindAssembly_x86::CreateInstance (const ArchSpec &arch)
-{
- const llvm::Triple::ArchType cpu = arch.GetMachine ();
- if (cpu == llvm::Triple::x86)
- return new UnwindAssembly_x86 (arch, k_i386);
- else if (cpu == llvm::Triple::x86_64)
- return new UnwindAssembly_x86 (arch, k_x86_64);
- return NULL;
+ return false;
}
+bool UnwindAssembly_x86::GetFastUnwindPlan(AddressRange &func, Thread &thread,
+ UnwindPlan &unwind_plan) {
+ // if prologue is
+ // 55 pushl %ebp
+ // 89 e5 movl %esp, %ebp
+ // or
+ // 55 pushq %rbp
+ // 48 89 e5 movq %rsp, %rbp
+
+ // We should pull in the ABI architecture default unwind plan and return that
+
+ llvm::SmallVector<uint8_t, 4> opcode_data;
+
+ ProcessSP process_sp = thread.GetProcess();
+ if (process_sp) {
+ Target &target(process_sp->GetTarget());
+ const bool prefer_file_cache = true;
+ Error error;
+ if (target.ReadMemory(func.GetBaseAddress(), prefer_file_cache,
+ opcode_data.data(), 4, error) == 4) {
+ uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5};
+ uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5};
+
+ if (memcmp(opcode_data.data(), i386_push_mov, sizeof(i386_push_mov)) ==
+ 0 ||
+ memcmp(opcode_data.data(), x86_64_push_mov,
+ sizeof(x86_64_push_mov)) == 0) {
+ ABISP abi_sp = process_sp->GetABI();
+ if (abi_sp) {
+ return abi_sp->CreateDefaultUnwindPlan(unwind_plan);
+ }
+ }
+ }
+ }
+ return false;
+}
+
+bool UnwindAssembly_x86::FirstNonPrologueInsn(
+ AddressRange &func, const ExecutionContext &exe_ctx,
+ Address &first_non_prologue_insn) {
+ AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
+ return asm_parse.find_first_non_prologue_insn(first_non_prologue_insn);
+}
+
+UnwindAssembly *UnwindAssembly_x86::CreateInstance(const ArchSpec &arch) {
+ const llvm::Triple::ArchType cpu = arch.GetMachine();
+ if (cpu == llvm::Triple::x86)
+ return new UnwindAssembly_x86(arch, k_i386);
+ else if (cpu == llvm::Triple::x86_64)
+ return new UnwindAssembly_x86(arch, k_x86_64);
+ return NULL;
+}
//------------------------------------------------------------------
// PluginInterface protocol in UnwindAssemblyParser_x86
//------------------------------------------------------------------
-ConstString
-UnwindAssembly_x86::GetPluginName()
-{
- return GetPluginNameStatic();
+ConstString UnwindAssembly_x86::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t UnwindAssembly_x86::GetPluginVersion() { return 1; }
-uint32_t
-UnwindAssembly_x86::GetPluginVersion()
-{
- return 1;
+void UnwindAssembly_x86::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-UnwindAssembly_x86::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void UnwindAssembly_x86::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-void
-UnwindAssembly_x86::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-
-lldb_private::ConstString
-UnwindAssembly_x86::GetPluginNameStatic()
-{
- static ConstString g_name("x86");
- return g_name;
+lldb_private::ConstString UnwindAssembly_x86::GetPluginNameStatic() {
+ static ConstString g_name("x86");
+ return g_name;
}
-const char *
-UnwindAssembly_x86::GetPluginDescriptionStatic()
-{
- return "i386 and x86_64 assembly language profiler plugin.";
+const char *UnwindAssembly_x86::GetPluginDescriptionStatic() {
+ return "i386 and x86_64 assembly language profiler plugin.";
}
Modified: lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h Tue Sep 6 15:57:50 2016
@@ -16,64 +16,56 @@
#include "llvm-c/Disassembler.h"
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/UnwindAssembly.h"
+#include "lldb/lldb-private.h"
-class UnwindAssembly_x86 : public lldb_private::UnwindAssembly
-{
+class UnwindAssembly_x86 : public lldb_private::UnwindAssembly {
public:
- ~UnwindAssembly_x86() override;
+ ~UnwindAssembly_x86() override;
+
+ bool GetNonCallSiteUnwindPlanFromAssembly(
+ lldb_private::AddressRange &func, lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool
+ AugmentUnwindPlanFromCallSite(lldb_private::AddressRange &func,
+ lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool GetFastUnwindPlan(lldb_private::AddressRange &func,
+ lldb_private::Thread &thread,
+ lldb_private::UnwindPlan &unwind_plan) override;
+
+ // thread may be NULL in which case we only use the Target (e.g. if this is
+ // called pre-process-launch).
+ bool
+ FirstNonPrologueInsn(lldb_private::AddressRange &func,
+ const lldb_private::ExecutionContext &exe_ctx,
+ lldb_private::Address &first_non_prologue_insn) override;
+
+ static lldb_private::UnwindAssembly *
+ CreateInstance(const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
- bool
- GetNonCallSiteUnwindPlanFromAssembly(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan& unwind_plan) override;
-
- bool
- AugmentUnwindPlanFromCallSite(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan& unwind_plan) override;
-
- bool
- GetFastUnwindPlan(lldb_private::AddressRange& func,
- lldb_private::Thread& thread,
- lldb_private::UnwindPlan &unwind_plan) override;
-
- // thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
- bool
- FirstNonPrologueInsn(lldb_private::AddressRange& func,
- const lldb_private::ExecutionContext &exe_ctx,
- lldb_private::Address& first_non_prologue_insn) override;
-
- static lldb_private::UnwindAssembly *
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
private:
- UnwindAssembly_x86 (const lldb_private::ArchSpec &arch, int cpu);
+ UnwindAssembly_x86(const lldb_private::ArchSpec &arch, int cpu);
- int m_cpu;
- lldb_private::ArchSpec m_arch;
+ int m_cpu;
+ lldb_private::ArchSpec m_arch;
};
#endif // liblldb_UnwindAssembly_x86_h_
Modified: lldb/trunk/source/Symbol/ArmUnwindInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ArmUnwindInfo.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ArmUnwindInfo.cpp (original)
+++ lldb/trunk/source/Symbol/ArmUnwindInfo.cpp Tue Sep 6 15:57:50 2016
@@ -9,13 +9,13 @@
#include <vector>
+#include "Utility/ARM_DWARF_Registers.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "Utility/ARM_DWARF_Registers.h"
/*
* Unwind information reader and parser for the ARM exception handling ABI
@@ -31,415 +31,341 @@ using namespace lldb;
using namespace lldb_private;
// Converts a prel31 avlue to lldb::addr_t with sign extension
-static addr_t
-Prel31ToAddr(uint32_t prel31)
-{
- addr_t res = prel31;
- if (prel31 & (1<<30))
- res |= 0xffffffff80000000ULL;
- return res;
+static addr_t Prel31ToAddr(uint32_t prel31) {
+ addr_t res = prel31;
+ if (prel31 & (1 << 30))
+ res |= 0xffffffff80000000ULL;
+ return res;
}
-ArmUnwindInfo::ArmExidxEntry::ArmExidxEntry(uint32_t f, lldb::addr_t a, uint32_t d) :
- file_address(f), address(a), data(d)
-{
-}
+ArmUnwindInfo::ArmExidxEntry::ArmExidxEntry(uint32_t f, lldb::addr_t a,
+ uint32_t d)
+ : file_address(f), address(a), data(d) {}
-bool
-ArmUnwindInfo::ArmExidxEntry::operator<(const ArmExidxEntry& other) const
-{
- return address < other.address;
+bool ArmUnwindInfo::ArmExidxEntry::operator<(const ArmExidxEntry &other) const {
+ return address < other.address;
}
-ArmUnwindInfo::ArmUnwindInfo(const ObjectFile& objfile,
- SectionSP& arm_exidx,
- SectionSP& arm_extab) :
- m_byte_order(objfile.GetByteOrder()),
- m_arm_exidx_sp(arm_exidx),
- m_arm_extab_sp(arm_extab)
-{
- objfile.ReadSectionData(arm_exidx.get(), m_arm_exidx_data);
- objfile.ReadSectionData(arm_extab.get(), m_arm_extab_data);
-
- addr_t exidx_base_addr = m_arm_exidx_sp->GetFileAddress();
-
- offset_t offset = 0;
- while (m_arm_exidx_data.ValidOffset(offset))
- {
- lldb::addr_t file_addr = exidx_base_addr + offset;
- lldb::addr_t addr = exidx_base_addr +
- (addr_t)offset +
- Prel31ToAddr(m_arm_exidx_data.GetU32(&offset));
- uint32_t data = m_arm_exidx_data.GetU32(&offset);
- m_exidx_entries.emplace_back(file_addr, addr, data);
- }
-
- // Sort the entries in the exidx section. The entries should be sorted inside the section but
- // some old compiler isn't sorted them.
- std::sort(m_exidx_entries.begin(), m_exidx_entries.end());
+ArmUnwindInfo::ArmUnwindInfo(const ObjectFile &objfile, SectionSP &arm_exidx,
+ SectionSP &arm_extab)
+ : m_byte_order(objfile.GetByteOrder()), m_arm_exidx_sp(arm_exidx),
+ m_arm_extab_sp(arm_extab) {
+ objfile.ReadSectionData(arm_exidx.get(), m_arm_exidx_data);
+ objfile.ReadSectionData(arm_extab.get(), m_arm_extab_data);
+
+ addr_t exidx_base_addr = m_arm_exidx_sp->GetFileAddress();
+
+ offset_t offset = 0;
+ while (m_arm_exidx_data.ValidOffset(offset)) {
+ lldb::addr_t file_addr = exidx_base_addr + offset;
+ lldb::addr_t addr = exidx_base_addr + (addr_t)offset +
+ Prel31ToAddr(m_arm_exidx_data.GetU32(&offset));
+ uint32_t data = m_arm_exidx_data.GetU32(&offset);
+ m_exidx_entries.emplace_back(file_addr, addr, data);
+ }
+
+ // Sort the entries in the exidx section. The entries should be sorted inside
+ // the section but
+ // some old compiler isn't sorted them.
+ std::sort(m_exidx_entries.begin(), m_exidx_entries.end());
}
-ArmUnwindInfo::~ArmUnwindInfo()
-{
-}
+ArmUnwindInfo::~ArmUnwindInfo() {}
// Read a byte from the unwind instruction stream with the given offset.
-// Custom function is required because have to red in order of significance within their containing
+// Custom function is required because have to red in order of significance
+// within their containing
// word (most significant byte first) and in increasing word address order.
-uint8_t
-ArmUnwindInfo::GetByteAtOffset(const uint32_t* data, uint16_t offset) const
-{
- uint32_t value = data[offset / 4];
- if (m_byte_order != endian::InlHostByteOrder())
- value = llvm::ByteSwap_32(value);
- return (value >> ((3 - (offset % 4)) * 8)) & 0xff;
+uint8_t ArmUnwindInfo::GetByteAtOffset(const uint32_t *data,
+ uint16_t offset) const {
+ uint32_t value = data[offset / 4];
+ if (m_byte_order != endian::InlHostByteOrder())
+ value = llvm::ByteSwap_32(value);
+ return (value >> ((3 - (offset % 4)) * 8)) & 0xff;
}
-uint64_t
-ArmUnwindInfo::GetULEB128(const uint32_t* data, uint16_t& offset, uint16_t max_offset) const
-{
- uint64_t result = 0;
- uint8_t shift = 0;
- while (offset < max_offset)
- {
- uint8_t byte = GetByteAtOffset(data, offset++);
- result |= (uint64_t)(byte & 0x7f) << shift;
- if ((byte & 0x80) == 0)
- break;
- shift += 7;
- }
- return result;
+uint64_t ArmUnwindInfo::GetULEB128(const uint32_t *data, uint16_t &offset,
+ uint16_t max_offset) const {
+ uint64_t result = 0;
+ uint8_t shift = 0;
+ while (offset < max_offset) {
+ uint8_t byte = GetByteAtOffset(data, offset++);
+ result |= (uint64_t)(byte & 0x7f) << shift;
+ if ((byte & 0x80) == 0)
+ break;
+ shift += 7;
+ }
+ return result;
}
-bool
-ArmUnwindInfo::GetUnwindPlan(Target &target, const Address& addr, UnwindPlan& unwind_plan)
-{
- const uint32_t* data = (const uint32_t*)GetExceptionHandlingTableEntry(addr);
- if (data == nullptr)
- return false; // No unwind information for the function
-
- if (data[0] == 0x1)
- return false; // EXIDX_CANTUNWIND
-
- uint16_t byte_count = 0;
- uint16_t byte_offset = 0;
- if (data[0] & 0x80000000)
- {
- switch ((data[0] >> 24) & 0x0f)
- {
- case 0:
- byte_count = 4;
- byte_offset = 1;
- break;
- case 1:
- case 2:
- byte_count = 4 * ((data[0] >> 16) & 0xff) + 4;
- byte_offset = 2;
- break;
- default:
- // Unhandled personality routine index
- return false;
- }
+bool ArmUnwindInfo::GetUnwindPlan(Target &target, const Address &addr,
+ UnwindPlan &unwind_plan) {
+ const uint32_t *data = (const uint32_t *)GetExceptionHandlingTableEntry(addr);
+ if (data == nullptr)
+ return false; // No unwind information for the function
+
+ if (data[0] == 0x1)
+ return false; // EXIDX_CANTUNWIND
+
+ uint16_t byte_count = 0;
+ uint16_t byte_offset = 0;
+ if (data[0] & 0x80000000) {
+ switch ((data[0] >> 24) & 0x0f) {
+ case 0:
+ byte_count = 4;
+ byte_offset = 1;
+ break;
+ case 1:
+ case 2:
+ byte_count = 4 * ((data[0] >> 16) & 0xff) + 4;
+ byte_offset = 2;
+ break;
+ default:
+ // Unhandled personality routine index
+ return false;
}
- else
- {
- byte_count = 4 * ((data[1] >> 24) & 0xff) + 8;
- byte_offset = 5;
- }
-
- uint8_t vsp_reg = dwarf_sp;
- int32_t vsp = 0;
- std::vector<std::pair<uint32_t, int32_t>> register_offsets; // register -> (offset from vsp_reg)
-
- while (byte_offset < byte_count)
- {
- uint8_t byte1 = GetByteAtOffset(data, byte_offset++);
- if ((byte1&0xc0) == 0x00)
- {
- // 00xxxxxx
- // vsp = vsp + (xxxxxx << 2) + 4. Covers range 0x04-0x100 inclusive
- vsp += ((byte1 & 0x3f) << 2) + 4;
- }
- else if ((byte1&0xc0) == 0x40)
- {
- // 01xxxxxx
- // vsp = vsp â (xxxxxx << 2) - 4. Covers range 0x04-0x100 inclusive
- vsp -= ((byte1 & 0x3f) << 2) + 4;
- }
- else if ((byte1&0xf0) == 0x80)
- {
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- if (byte1 == 0x80 && byte2 == 0)
- {
- // 10000000 00000000
- // Refuse to unwind (for example, out of a cleanup) (see remark a)
- return false;
- }
- else
- {
- // 1000iiii iiiiiiii (i not all 0)
- // Pop up to 12 integer registers under masks {r15-r12}, {r11-r4} (see remark b)
- uint16_t regs = ((byte1&0x0f) << 8) | byte2;
- for (uint8_t i = 0; i < 12; ++i)
- {
- if (regs & (1<<i))
- {
- register_offsets.emplace_back(dwarf_r4 + i, vsp);
- vsp += 4;
- }
- }
- }
- }
- else if ((byte1&0xff) == 0x9d)
- {
- // 10011101
- // Reserved as prefix for ARM register to register moves
- return false;
- }
- else if ((byte1&0xff) == 0x9f)
- {
- // 10011111
- // Reserved as prefix for Intel Wireless MMX register to register moves
- return false;
- }
- else if ((byte1&0xf0) == 0x90)
- {
- // 1001nnnn (nnnn != 13,15)
- // Set vsp = r[nnnn]
- vsp_reg = dwarf_r0 + (byte1&0x0f);
- }
- else if ((byte1&0xf8) == 0xa0)
- {
- // 10100nnn
- // Pop r4-r[4+nnn]
- uint8_t n = byte1&0x7;
- for (uint8_t i = 0; i <= n; ++i)
- {
- register_offsets.emplace_back(dwarf_r4 + i, vsp);
- vsp += 4;
- }
- }
- else if ((byte1&0xf8) == 0xa8)
- {
- // 10101nnn
- // Pop r4-r[4+nnn], r14
- uint8_t n = byte1&0x7;
- for (uint8_t i = 0; i <= n; ++i)
- {
- register_offsets.emplace_back(dwarf_r4 + i, vsp);
- vsp += 4;
- }
-
- register_offsets.emplace_back(dwarf_lr, vsp);
+ } else {
+ byte_count = 4 * ((data[1] >> 24) & 0xff) + 8;
+ byte_offset = 5;
+ }
+
+ uint8_t vsp_reg = dwarf_sp;
+ int32_t vsp = 0;
+ std::vector<std::pair<uint32_t, int32_t>>
+ register_offsets; // register -> (offset from vsp_reg)
+
+ while (byte_offset < byte_count) {
+ uint8_t byte1 = GetByteAtOffset(data, byte_offset++);
+ if ((byte1 & 0xc0) == 0x00) {
+ // 00xxxxxx
+ // vsp = vsp + (xxxxxx << 2) + 4. Covers range 0x04-0x100 inclusive
+ vsp += ((byte1 & 0x3f) << 2) + 4;
+ } else if ((byte1 & 0xc0) == 0x40) {
+ // 01xxxxxx
+ // vsp = vsp â (xxxxxx << 2) - 4. Covers range 0x04-0x100 inclusive
+ vsp -= ((byte1 & 0x3f) << 2) + 4;
+ } else if ((byte1 & 0xf0) == 0x80) {
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ if (byte1 == 0x80 && byte2 == 0) {
+ // 10000000 00000000
+ // Refuse to unwind (for example, out of a cleanup) (see remark a)
+ return false;
+ } else {
+ // 1000iiii iiiiiiii (i not all 0)
+ // Pop up to 12 integer registers under masks {r15-r12}, {r11-r4} (see
+ // remark b)
+ uint16_t regs = ((byte1 & 0x0f) << 8) | byte2;
+ for (uint8_t i = 0; i < 12; ++i) {
+ if (regs & (1 << i)) {
+ register_offsets.emplace_back(dwarf_r4 + i, vsp);
vsp += 4;
+ }
}
- else if ((byte1&0xff) == 0xb0)
- {
- // 10110000
- // Finish (see remark c)
- break;
- }
- else if ((byte1&0xff) == 0xb1)
- {
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- if ((byte2&0xff) == 0x00)
- {
- // 10110001 00000000
- // Spare (see remark f)
- return false;
- }
- else if ((byte2&0xf0) == 0x00)
- {
- // 10110001 0000iiii (i not all 0)
- // Pop integer registers under mask {r3, r2, r1, r0}
- for (uint8_t i = 0; i < 4; ++i)
- {
- if (byte2 & (1<<i))
- {
- register_offsets.emplace_back(dwarf_r0 + i, vsp);
- vsp += 4;
- }
- }
- }
- else
- {
- // 10110001 xxxxyyyy
- // Spare (xxxx != 0000)
- return false;
- }
- }
- else if ((byte1&0xff) == 0xb2)
- {
- // 10110010 uleb128
- // vsp = vsp + 0x204+ (uleb128 << 2)
- uint64_t uleb128 = GetULEB128(data, byte_offset, byte_count);
- vsp += 0x204 + (uleb128 << 2);
- }
- else if ((byte1&0xff) == 0xb3)
- {
- // 10110011 sssscccc
- // Pop VFP double-precision registers D[ssss]-D[ssss+cccc] saved (as if) by FSTMFDX (see remark d)
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- uint8_t s = (byte2&0xf0) >> 4;
- uint8_t c = (byte2&0x0f) >> 0;
- for (uint8_t i = 0; i <= c; ++i)
- {
- register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
- vsp += 8;
- }
+ }
+ } else if ((byte1 & 0xff) == 0x9d) {
+ // 10011101
+ // Reserved as prefix for ARM register to register moves
+ return false;
+ } else if ((byte1 & 0xff) == 0x9f) {
+ // 10011111
+ // Reserved as prefix for Intel Wireless MMX register to register moves
+ return false;
+ } else if ((byte1 & 0xf0) == 0x90) {
+ // 1001nnnn (nnnn != 13,15)
+ // Set vsp = r[nnnn]
+ vsp_reg = dwarf_r0 + (byte1 & 0x0f);
+ } else if ((byte1 & 0xf8) == 0xa0) {
+ // 10100nnn
+ // Pop r4-r[4+nnn]
+ uint8_t n = byte1 & 0x7;
+ for (uint8_t i = 0; i <= n; ++i) {
+ register_offsets.emplace_back(dwarf_r4 + i, vsp);
+ vsp += 4;
+ }
+ } else if ((byte1 & 0xf8) == 0xa8) {
+ // 10101nnn
+ // Pop r4-r[4+nnn], r14
+ uint8_t n = byte1 & 0x7;
+ for (uint8_t i = 0; i <= n; ++i) {
+ register_offsets.emplace_back(dwarf_r4 + i, vsp);
+ vsp += 4;
+ }
+
+ register_offsets.emplace_back(dwarf_lr, vsp);
+ vsp += 4;
+ } else if ((byte1 & 0xff) == 0xb0) {
+ // 10110000
+ // Finish (see remark c)
+ break;
+ } else if ((byte1 & 0xff) == 0xb1) {
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ if ((byte2 & 0xff) == 0x00) {
+ // 10110001 00000000
+ // Spare (see remark f)
+ return false;
+ } else if ((byte2 & 0xf0) == 0x00) {
+ // 10110001 0000iiii (i not all 0)
+ // Pop integer registers under mask {r3, r2, r1, r0}
+ for (uint8_t i = 0; i < 4; ++i) {
+ if (byte2 & (1 << i)) {
+ register_offsets.emplace_back(dwarf_r0 + i, vsp);
vsp += 4;
+ }
}
- else if ((byte1&0xfc) == 0xb4)
- {
- // 101101nn
- // Spare (was Pop FPA)
- return false;
- }
- else if ((byte1&0xf8) == 0xb8)
- {
- // 10111nnn
- // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by FSTMFDX (see remark d)
- uint8_t n = byte1&0x07;
- for (uint8_t i = 0; i <= n; ++i)
- {
- register_offsets.emplace_back(dwarf_d8 + i, vsp);
- vsp += 8;
- }
- vsp += 4;
- }
- else if ((byte1&0xf8) == 0xc0)
- {
- // 11000nnn (nnn != 6,7)
- // Intel Wireless MMX pop wR[10]-wR[10+nnn]
-
- // 11000110 sssscccc
- // Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc] (see remark e)
-
- // 11000111 00000000
- // Spare
-
- // 11000111 0000iiii
- // Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0}
-
- // 11000111 xxxxyyyy
- // Spare (xxxx != 0000)
-
- return false;
- }
- else if ((byte1&0xff) == 0xc8)
- {
- // 11001000 sssscccc
- // Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc] saved (as if) by FSTMFDD (see remarks d,e)
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- uint8_t s = (byte2&0xf0) >> 4;
- uint8_t c = (byte2&0x0f) >> 0;
- for (uint8_t i = 0; i <= c; ++i)
- {
- register_offsets.emplace_back(dwarf_d16 + s + i, vsp);
- vsp += 8;
- }
- }
- else if ((byte1&0xff) == 0xc9)
- {
- // 11001001 sssscccc
- // Pop VFP double precision registers D[ssss]-D[ssss+cccc] saved (as if) by FSTMFDD (see remark d)
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- uint8_t s = (byte2&0xf0) >> 4;
- uint8_t c = (byte2&0x0f) >> 0;
- for (uint8_t i = 0; i <= c; ++i)
- {
- register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
- vsp += 8;
- }
- }
- else if ((byte1&0xf8) == 0xc8)
- {
- // 11001yyy
- // Spare (yyy != 000, 001)
- return false;
- }
- else if ((byte1&0xf8) == 0xc0)
- {
- // 11010nnn
- // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by FSTMFDD (see remark d)
- uint8_t n = byte1&0x07;
- for (uint8_t i = 0; i <= n; ++i)
- {
- register_offsets.emplace_back(dwarf_d8 + i, vsp);
- vsp += 8;
- }
- }
- else if ((byte1&0xc0) == 0xc0)
- {
- // 11xxxyyy Spare (xxx != 000, 001, 010)
- return false;
- }
- else
- {
- return false;
- }
+ } else {
+ // 10110001 xxxxyyyy
+ // Spare (xxxx != 0000)
+ return false;
+ }
+ } else if ((byte1 & 0xff) == 0xb2) {
+ // 10110010 uleb128
+ // vsp = vsp + 0x204+ (uleb128 << 2)
+ uint64_t uleb128 = GetULEB128(data, byte_offset, byte_count);
+ vsp += 0x204 + (uleb128 << 2);
+ } else if ((byte1 & 0xff) == 0xb3) {
+ // 10110011 sssscccc
+ // Pop VFP double-precision registers D[ssss]-D[ssss+cccc] saved (as if)
+ // by FSTMFDX (see remark d)
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ uint8_t s = (byte2 & 0xf0) >> 4;
+ uint8_t c = (byte2 & 0x0f) >> 0;
+ for (uint8_t i = 0; i <= c; ++i) {
+ register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
+ vsp += 8;
+ }
+ vsp += 4;
+ } else if ((byte1 & 0xfc) == 0xb4) {
+ // 101101nn
+ // Spare (was Pop FPA)
+ return false;
+ } else if ((byte1 & 0xf8) == 0xb8) {
+ // 10111nnn
+ // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by
+ // FSTMFDX (see remark d)
+ uint8_t n = byte1 & 0x07;
+ for (uint8_t i = 0; i <= n; ++i) {
+ register_offsets.emplace_back(dwarf_d8 + i, vsp);
+ vsp += 8;
+ }
+ vsp += 4;
+ } else if ((byte1 & 0xf8) == 0xc0) {
+ // 11000nnn (nnn != 6,7)
+ // Intel Wireless MMX pop wR[10]-wR[10+nnn]
+
+ // 11000110 sssscccc
+ // Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc] (see remark e)
+
+ // 11000111 00000000
+ // Spare
+
+ // 11000111 0000iiii
+ // Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0}
+
+ // 11000111 xxxxyyyy
+ // Spare (xxxx != 0000)
+
+ return false;
+ } else if ((byte1 & 0xff) == 0xc8) {
+ // 11001000 sssscccc
+ // Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc] saved (as
+ // if) by FSTMFDD (see remarks d,e)
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ uint8_t s = (byte2 & 0xf0) >> 4;
+ uint8_t c = (byte2 & 0x0f) >> 0;
+ for (uint8_t i = 0; i <= c; ++i) {
+ register_offsets.emplace_back(dwarf_d16 + s + i, vsp);
+ vsp += 8;
+ }
+ } else if ((byte1 & 0xff) == 0xc9) {
+ // 11001001 sssscccc
+ // Pop VFP double precision registers D[ssss]-D[ssss+cccc] saved (as if)
+ // by FSTMFDD (see remark d)
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ uint8_t s = (byte2 & 0xf0) >> 4;
+ uint8_t c = (byte2 & 0x0f) >> 0;
+ for (uint8_t i = 0; i <= c; ++i) {
+ register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
+ vsp += 8;
+ }
+ } else if ((byte1 & 0xf8) == 0xc8) {
+ // 11001yyy
+ // Spare (yyy != 000, 001)
+ return false;
+ } else if ((byte1 & 0xf8) == 0xc0) {
+ // 11010nnn
+ // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by
+ // FSTMFDD (see remark d)
+ uint8_t n = byte1 & 0x07;
+ for (uint8_t i = 0; i <= n; ++i) {
+ register_offsets.emplace_back(dwarf_d8 + i, vsp);
+ vsp += 8;
+ }
+ } else if ((byte1 & 0xc0) == 0xc0) {
+ // 11xxxyyy Spare (xxx != 000, 001, 010)
+ return false;
+ } else {
+ return false;
}
+ }
- UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>();
- row->SetOffset(0);
- row->GetCFAValue().SetIsRegisterPlusOffset(vsp_reg, vsp);
-
- bool have_location_for_pc = false;
- for (const auto& offset : register_offsets)
- {
- have_location_for_pc |= offset.first == dwarf_pc;
- row->SetRegisterLocationToAtCFAPlusOffset(offset.first, offset.second - vsp, true);
- }
-
- if (!have_location_for_pc)
- {
- UnwindPlan::Row::RegisterLocation lr_location;
- if (row->GetRegisterInfo(dwarf_lr, lr_location))
- row->SetRegisterInfo(dwarf_pc, lr_location);
- else
- row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, false);
- }
+ UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>();
+ row->SetOffset(0);
+ row->GetCFAValue().SetIsRegisterPlusOffset(vsp_reg, vsp);
+
+ bool have_location_for_pc = false;
+ for (const auto &offset : register_offsets) {
+ have_location_for_pc |= offset.first == dwarf_pc;
+ row->SetRegisterLocationToAtCFAPlusOffset(offset.first, offset.second - vsp,
+ true);
+ }
+
+ if (!have_location_for_pc) {
+ UnwindPlan::Row::RegisterLocation lr_location;
+ if (row->GetRegisterInfo(dwarf_lr, lr_location))
+ row->SetRegisterInfo(dwarf_pc, lr_location);
+ else
+ row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, false);
+ }
- unwind_plan.AppendRow(row);
- unwind_plan.SetSourceName ("ARM.exidx unwind info");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolYes);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("ARM.exidx unwind info");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- return true;
+ return true;
}
-const uint8_t*
-ArmUnwindInfo::GetExceptionHandlingTableEntry(const Address& addr)
-{
- auto it = std::upper_bound(m_exidx_entries.begin(),
- m_exidx_entries.end(),
- ArmExidxEntry{0, addr.GetFileAddress(), 0});
- if (it == m_exidx_entries.begin())
- return nullptr;
- --it;
-
- if (it->data == 0x1)
- return nullptr; // EXIDX_CANTUNWIND
-
- if (it->data & 0x80000000)
- return (const uint8_t*)&it->data;
-
- addr_t data_file_addr = it->file_address + 4 + Prel31ToAddr(it->data);
- return m_arm_extab_data.GetDataStart() + (data_file_addr - m_arm_extab_sp->GetFileAddress());
+const uint8_t *
+ArmUnwindInfo::GetExceptionHandlingTableEntry(const Address &addr) {
+ auto it = std::upper_bound(m_exidx_entries.begin(), m_exidx_entries.end(),
+ ArmExidxEntry{0, addr.GetFileAddress(), 0});
+ if (it == m_exidx_entries.begin())
+ return nullptr;
+ --it;
+
+ if (it->data == 0x1)
+ return nullptr; // EXIDX_CANTUNWIND
+
+ if (it->data & 0x80000000)
+ return (const uint8_t *)&it->data;
+
+ addr_t data_file_addr = it->file_address + 4 + Prel31ToAddr(it->data);
+ return m_arm_extab_data.GetDataStart() +
+ (data_file_addr - m_arm_extab_sp->GetFileAddress());
}
Modified: lldb/trunk/source/Symbol/Block.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Block.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Block.cpp (original)
+++ lldb/trunk/source/Symbol/Block.cpp Tue Sep 6 15:57:50 2016
@@ -20,628 +20,486 @@
using namespace lldb;
using namespace lldb_private;
-Block::Block(lldb::user_id_t uid) :
- UserID(uid),
- m_parent_scope (nullptr),
- m_children (),
- m_ranges (),
- m_inlineInfoSP (),
- m_variable_list_sp (),
- m_parsed_block_info (false),
- m_parsed_block_variables (false),
- m_parsed_child_blocks (false)
-{
-}
-
-Block::~Block ()
-{
-}
-
-void
-Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Target *target) const
-{
- *s << "id = " << ((const UserID&)*this);
+Block::Block(lldb::user_id_t uid)
+ : UserID(uid), m_parent_scope(nullptr), m_children(), m_ranges(),
+ m_inlineInfoSP(), m_variable_list_sp(), m_parsed_block_info(false),
+ m_parsed_block_variables(false), m_parsed_child_blocks(false) {}
+
+Block::~Block() {}
+
+void Block::GetDescription(Stream *s, Function *function,
+ lldb::DescriptionLevel level, Target *target) const {
+ *s << "id = " << ((const UserID &)*this);
+
+ size_t num_ranges = m_ranges.GetSize();
+ if (num_ranges > 0) {
+
+ addr_t base_addr = LLDB_INVALID_ADDRESS;
+ if (target)
+ base_addr =
+ function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
+ if (base_addr == LLDB_INVALID_ADDRESS)
+ base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
+
+ s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const Range &range = m_ranges.GetEntryRef(i);
+ s->AddressRange(base_addr + range.GetRangeBase(),
+ base_addr + range.GetRangeEnd(), 4);
+ }
+ }
+
+ if (m_inlineInfoSP.get() != nullptr) {
+ bool show_fullpaths = (level == eDescriptionLevelVerbose);
+ m_inlineInfoSP->Dump(s, show_fullpaths);
+ }
+}
+
+void Block::Dump(Stream *s, addr_t base_addr, int32_t depth,
+ bool show_context) const {
+ if (depth < 0) {
+ Block *parent = GetParent();
+ if (parent) {
+ // We have a depth that is less than zero, print our parent blocks
+ // first
+ parent->Dump(s, base_addr, depth + 1, show_context);
+ }
+ }
+
+ s->Printf("%p: ", static_cast<const void *>(this));
+ s->Indent();
+ *s << "Block" << static_cast<const UserID &>(*this);
+ const Block *parent_block = GetParent();
+ if (parent_block) {
+ s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
+ }
+ if (m_inlineInfoSP.get() != nullptr) {
+ bool show_fullpaths = false;
+ m_inlineInfoSP->Dump(s, show_fullpaths);
+ }
- size_t num_ranges = m_ranges.GetSize();
- if (num_ranges > 0)
- {
-
- addr_t base_addr = LLDB_INVALID_ADDRESS;
- if (target)
- base_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
- if (base_addr == LLDB_INVALID_ADDRESS)
- base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
-
- s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
- for (size_t i=0; i<num_ranges; ++i)
- {
- const Range &range = m_ranges.GetEntryRef(i);
- s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
- }
- }
-
- if (m_inlineInfoSP.get() != nullptr)
- {
- bool show_fullpaths = (level == eDescriptionLevelVerbose);
- m_inlineInfoSP->Dump(s, show_fullpaths);
- }
-}
+ if (!m_ranges.IsEmpty()) {
+ *s << ", ranges =";
-void
-Block::Dump(Stream *s, addr_t base_addr, int32_t depth, bool show_context) const
-{
- if (depth < 0)
- {
- Block *parent = GetParent();
- if (parent)
- {
- // We have a depth that is less than zero, print our parent blocks
- // first
- parent->Dump(s, base_addr, depth + 1, show_context);
- }
- }
-
- s->Printf("%p: ", static_cast<const void*>(this));
- s->Indent();
- *s << "Block" << static_cast<const UserID&>(*this);
- const Block* parent_block = GetParent();
- if (parent_block)
- {
- s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
- }
- if (m_inlineInfoSP.get() != nullptr)
- {
- bool show_fullpaths = false;
- m_inlineInfoSP->Dump(s, show_fullpaths);
- }
-
- if (!m_ranges.IsEmpty())
- {
- *s << ", ranges =";
-
- size_t num_ranges = m_ranges.GetSize();
- for (size_t i=0; i<num_ranges; ++i)
- {
- const Range &range = m_ranges.GetEntryRef(i);
- if (parent_block != nullptr && parent_block->Contains(range) == false)
- *s << '!';
- else
- *s << ' ';
- s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
- }
+ size_t num_ranges = m_ranges.GetSize();
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const Range &range = m_ranges.GetEntryRef(i);
+ if (parent_block != nullptr && parent_block->Contains(range) == false)
+ *s << '!';
+ else
+ *s << ' ';
+ s->AddressRange(base_addr + range.GetRangeBase(),
+ base_addr + range.GetRangeEnd(), 4);
}
- s->EOL();
-
- if (depth > 0)
- {
- s->IndentMore();
-
- if (m_variable_list_sp.get())
- {
- m_variable_list_sp->Dump(s, show_context);
- }
+ }
+ s->EOL();
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- (*pos)->Dump(s, base_addr, depth - 1, show_context);
+ if (depth > 0) {
+ s->IndentMore();
- s->IndentLess();
+ if (m_variable_list_sp.get()) {
+ m_variable_list_sp->Dump(s, show_context);
}
-}
-
-
-Block *
-Block::FindBlockByID (user_id_t block_id)
-{
- if (block_id == GetID())
- return this;
-
- Block *matching_block = nullptr;
collection::const_iterator pos, end = m_children.end();
for (pos = m_children.begin(); pos != end; ++pos)
- {
- matching_block = (*pos)->FindBlockByID (block_id);
- if (matching_block)
- break;
- }
- return matching_block;
-}
+ (*pos)->Dump(s, base_addr, depth - 1, show_context);
-void
-Block::CalculateSymbolContext (SymbolContext* sc)
-{
- if (m_parent_scope)
- m_parent_scope->CalculateSymbolContext(sc);
- sc->block = this;
+ s->IndentLess();
+ }
}
-lldb::ModuleSP
-Block::CalculateSymbolContextModule ()
-{
- if (m_parent_scope)
- return m_parent_scope->CalculateSymbolContextModule ();
- return lldb::ModuleSP();
+Block *Block::FindBlockByID(user_id_t block_id) {
+ if (block_id == GetID())
+ return this;
+
+ Block *matching_block = nullptr;
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos) {
+ matching_block = (*pos)->FindBlockByID(block_id);
+ if (matching_block)
+ break;
+ }
+ return matching_block;
}
-CompileUnit *
-Block::CalculateSymbolContextCompileUnit ()
-{
- if (m_parent_scope)
- return m_parent_scope->CalculateSymbolContextCompileUnit ();
- return nullptr;
+void Block::CalculateSymbolContext(SymbolContext *sc) {
+ if (m_parent_scope)
+ m_parent_scope->CalculateSymbolContext(sc);
+ sc->block = this;
}
-Function *
-Block::CalculateSymbolContextFunction ()
-{
- if (m_parent_scope)
- return m_parent_scope->CalculateSymbolContextFunction ();
- return nullptr;
+lldb::ModuleSP Block::CalculateSymbolContextModule() {
+ if (m_parent_scope)
+ return m_parent_scope->CalculateSymbolContextModule();
+ return lldb::ModuleSP();
}
-Block *
-Block::CalculateSymbolContextBlock ()
-{
- return this;
+CompileUnit *Block::CalculateSymbolContextCompileUnit() {
+ if (m_parent_scope)
+ return m_parent_scope->CalculateSymbolContextCompileUnit();
+ return nullptr;
}
-void
-Block::DumpSymbolContext(Stream *s)
-{
- Function *function = CalculateSymbolContextFunction();
- if (function)
- function->DumpSymbolContext(s);
- s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
+Function *Block::CalculateSymbolContextFunction() {
+ if (m_parent_scope)
+ return m_parent_scope->CalculateSymbolContextFunction();
+ return nullptr;
}
-void
-Block::DumpAddressRanges (Stream *s, lldb::addr_t base_addr)
-{
- if (!m_ranges.IsEmpty())
- {
- size_t num_ranges = m_ranges.GetSize();
- for (size_t i=0; i<num_ranges; ++i)
- {
- const Range &range = m_ranges.GetEntryRef(i);
- s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
- }
- }
+Block *Block::CalculateSymbolContextBlock() { return this; }
+
+void Block::DumpSymbolContext(Stream *s) {
+ Function *function = CalculateSymbolContextFunction();
+ if (function)
+ function->DumpSymbolContext(s);
+ s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
}
-bool
-Block::Contains (addr_t range_offset) const
-{
- return m_ranges.FindEntryThatContains(range_offset) != nullptr;
-}
-
-bool
-Block::Contains (const Block *block) const
-{
- if (this == block)
- return false; // This block doesn't contain itself...
-
- // Walk the parent chain for "block" and see if any if them match this block
- const Block *block_parent;
- for (block_parent = block->GetParent();
- block_parent != nullptr;
- block_parent = block_parent->GetParent())
- {
- if (this == block_parent)
- return true; // One of the parents of "block" is this object!
+void Block::DumpAddressRanges(Stream *s, lldb::addr_t base_addr) {
+ if (!m_ranges.IsEmpty()) {
+ size_t num_ranges = m_ranges.GetSize();
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const Range &range = m_ranges.GetEntryRef(i);
+ s->AddressRange(base_addr + range.GetRangeBase(),
+ base_addr + range.GetRangeEnd(), 4);
}
- return false;
+ }
}
-bool
-Block::Contains (const Range& range) const
-{
- return m_ranges.FindEntryThatContains (range) != nullptr;
-}
-
-Block *
-Block::GetParent () const
-{
- if (m_parent_scope)
- return m_parent_scope->CalculateSymbolContextBlock();
- return nullptr;
-}
-
-Block *
-Block::GetContainingInlinedBlock ()
-{
- if (GetInlinedFunctionInfo())
- return this;
- return GetInlinedParent ();
-}
-
-Block *
-Block::GetInlinedParent ()
-{
- Block *parent_block = GetParent ();
- if (parent_block)
- {
- if (parent_block->GetInlinedFunctionInfo())
- return parent_block;
- else
- return parent_block->GetInlinedParent();
- }
- return nullptr;
+bool Block::Contains(addr_t range_offset) const {
+ return m_ranges.FindEntryThatContains(range_offset) != nullptr;
}
+bool Block::Contains(const Block *block) const {
+ if (this == block)
+ return false; // This block doesn't contain itself...
-bool
-Block::GetRangeContainingOffset (const addr_t offset, Range &range)
-{
- const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
- if (range_ptr)
- {
- range = *range_ptr;
- return true;
- }
- range.Clear();
- return false;
+ // Walk the parent chain for "block" and see if any if them match this block
+ const Block *block_parent;
+ for (block_parent = block->GetParent(); block_parent != nullptr;
+ block_parent = block_parent->GetParent()) {
+ if (this == block_parent)
+ return true; // One of the parents of "block" is this object!
+ }
+ return false;
}
-
-bool
-Block::GetRangeContainingAddress (const Address& addr, AddressRange &range)
-{
- Function *function = CalculateSymbolContextFunction();
- if (function)
- {
- const AddressRange &func_range = function->GetAddressRange();
- if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
- {
- const addr_t addr_offset = addr.GetOffset();
- const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
- if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
- {
- addr_t offset = addr_offset - func_offset;
-
- const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
-
- if (range_ptr)
- {
- range.GetBaseAddress() = func_range.GetBaseAddress();
- range.GetBaseAddress().SetOffset(func_offset + range_ptr->GetRangeBase());
- range.SetByteSize(range_ptr->GetByteSize());
- return true;
- }
- }
- }
- }
- range.Clear();
- return false;
+bool Block::Contains(const Range &range) const {
+ return m_ranges.FindEntryThatContains(range) != nullptr;
}
-bool
-Block::GetRangeContainingLoadAddress (lldb::addr_t load_addr, Target &target, AddressRange &range)
-{
- Address load_address;
- load_address.SetLoadAddress(load_addr, &target);
- AddressRange containing_range;
- return GetRangeContainingAddress(load_address, containing_range);
+Block *Block::GetParent() const {
+ if (m_parent_scope)
+ return m_parent_scope->CalculateSymbolContextBlock();
+ return nullptr;
}
-
-uint32_t
-Block::GetRangeIndexContainingAddress (const Address& addr)
-{
- Function *function = CalculateSymbolContextFunction();
- if (function)
- {
- const AddressRange &func_range = function->GetAddressRange();
- if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
- {
- const addr_t addr_offset = addr.GetOffset();
- const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
- if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
- {
- addr_t offset = addr_offset - func_offset;
- return m_ranges.FindEntryIndexThatContains (offset);
- }
- }
- }
- return UINT32_MAX;
+Block *Block::GetContainingInlinedBlock() {
+ if (GetInlinedFunctionInfo())
+ return this;
+ return GetInlinedParent();
}
-bool
-Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
-{
- if (range_idx < m_ranges.GetSize())
- {
- Function *function = CalculateSymbolContextFunction();
- if (function)
- {
- const Range &vm_range = m_ranges.GetEntryRef(range_idx);
- range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
- range.GetBaseAddress().Slide(vm_range.GetRangeBase ());
- range.SetByteSize (vm_range.GetByteSize());
- return true;
- }
+Block *Block::GetInlinedParent() {
+ Block *parent_block = GetParent();
+ if (parent_block) {
+ if (parent_block->GetInlinedFunctionInfo())
+ return parent_block;
+ else
+ return parent_block->GetInlinedParent();
+ }
+ return nullptr;
+}
+
+bool Block::GetRangeContainingOffset(const addr_t offset, Range &range) {
+ const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
+ if (range_ptr) {
+ range = *range_ptr;
+ return true;
+ }
+ range.Clear();
+ return false;
+}
+
+bool Block::GetRangeContainingAddress(const Address &addr,
+ AddressRange &range) {
+ Function *function = CalculateSymbolContextFunction();
+ if (function) {
+ const AddressRange &func_range = function->GetAddressRange();
+ if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
+ const addr_t addr_offset = addr.GetOffset();
+ const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
+ if (addr_offset >= func_offset &&
+ addr_offset < func_offset + func_range.GetByteSize()) {
+ addr_t offset = addr_offset - func_offset;
+
+ const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
+
+ if (range_ptr) {
+ range.GetBaseAddress() = func_range.GetBaseAddress();
+ range.GetBaseAddress().SetOffset(func_offset +
+ range_ptr->GetRangeBase());
+ range.SetByteSize(range_ptr->GetByteSize());
+ return true;
+ }
+ }
+ }
+ }
+ range.Clear();
+ return false;
+}
+
+bool Block::GetRangeContainingLoadAddress(lldb::addr_t load_addr,
+ Target &target, AddressRange &range) {
+ Address load_address;
+ load_address.SetLoadAddress(load_addr, &target);
+ AddressRange containing_range;
+ return GetRangeContainingAddress(load_address, containing_range);
+}
+
+uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
+ Function *function = CalculateSymbolContextFunction();
+ if (function) {
+ const AddressRange &func_range = function->GetAddressRange();
+ if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
+ const addr_t addr_offset = addr.GetOffset();
+ const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
+ if (addr_offset >= func_offset &&
+ addr_offset < func_offset + func_range.GetByteSize()) {
+ addr_t offset = addr_offset - func_offset;
+ return m_ranges.FindEntryIndexThatContains(offset);
+ }
}
- return false;
+ }
+ return UINT32_MAX;
}
-bool
-Block::GetStartAddress (Address &addr)
-{
- if (m_ranges.IsEmpty())
- return false;
-
+bool Block::GetRangeAtIndex(uint32_t range_idx, AddressRange &range) {
+ if (range_idx < m_ranges.GetSize()) {
Function *function = CalculateSymbolContextFunction();
- if (function)
- {
- addr = function->GetAddressRange().GetBaseAddress();
- addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase ());
- return true;
+ if (function) {
+ const Range &vm_range = m_ranges.GetEntryRef(range_idx);
+ range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
+ range.GetBaseAddress().Slide(vm_range.GetRangeBase());
+ range.SetByteSize(vm_range.GetByteSize());
+ return true;
}
- return false;
+ }
+ return false;
}
-void
-Block::FinalizeRanges ()
-{
- m_ranges.Sort();
- m_ranges.CombineConsecutiveRanges ();
-}
-
-void
-Block::AddRange (const Range& range)
-{
- Block *parent_block = GetParent ();
- if (parent_block && !parent_block->Contains(range))
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
- if (log)
- {
- ModuleSP module_sp (m_parent_scope->CalculateSymbolContextModule());
- Function *function = m_parent_scope->CalculateSymbolContextFunction();
- const addr_t function_file_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
- const addr_t block_start_addr = function_file_addr + range.GetRangeBase ();
- const addr_t block_end_addr = function_file_addr + range.GetRangeEnd ();
- Type *func_type = function->GetType();
-
- const Declaration &func_decl = func_type->GetDeclaration();
- if (func_decl.GetLine())
- {
- log->Printf ("warning: %s:%u block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s",
- func_decl.GetFile().GetPath().c_str(),
- func_decl.GetLine(),
- GetID(),
- (uint32_t)m_ranges.GetSize(),
- block_start_addr,
- block_end_addr,
- parent_block->GetID(),
- function->GetID(),
- module_sp->GetFileSpec().GetPath().c_str());
- }
- else
- {
- log->Printf ("warning: block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s",
- GetID(),
- (uint32_t)m_ranges.GetSize(),
- block_start_addr,
- block_end_addr,
- parent_block->GetID(),
- function->GetID(),
- module_sp->GetFileSpec().GetPath().c_str());
- }
- }
- parent_block->AddRange (range);
- }
- m_ranges.Append(range);
-}
-
-// Return the current number of bytes that this object occupies in memory
-size_t
-Block::MemorySize() const
-{
- size_t mem_size = sizeof(Block) + m_ranges.GetSize() * sizeof(Range);
- if (m_inlineInfoSP.get())
- mem_size += m_inlineInfoSP->MemorySize();
- if (m_variable_list_sp.get())
- mem_size += m_variable_list_sp->MemorySize();
- return mem_size;
+bool Block::GetStartAddress(Address &addr) {
+ if (m_ranges.IsEmpty())
+ return false;
+ Function *function = CalculateSymbolContextFunction();
+ if (function) {
+ addr = function->GetAddressRange().GetBaseAddress();
+ addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase());
+ return true;
+ }
+ return false;
+}
+
+void Block::FinalizeRanges() {
+ m_ranges.Sort();
+ m_ranges.CombineConsecutiveRanges();
+}
+
+void Block::AddRange(const Range &range) {
+ Block *parent_block = GetParent();
+ if (parent_block && !parent_block->Contains(range)) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
+ if (log) {
+ ModuleSP module_sp(m_parent_scope->CalculateSymbolContextModule());
+ Function *function = m_parent_scope->CalculateSymbolContextFunction();
+ const addr_t function_file_addr =
+ function->GetAddressRange().GetBaseAddress().GetFileAddress();
+ const addr_t block_start_addr = function_file_addr + range.GetRangeBase();
+ const addr_t block_end_addr = function_file_addr + range.GetRangeEnd();
+ Type *func_type = function->GetType();
+
+ const Declaration &func_decl = func_type->GetDeclaration();
+ if (func_decl.GetLine()) {
+ log->Printf("warning: %s:%u block {0x%8.8" PRIx64
+ "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64
+ ") which is not contained in parent block {0x%8.8" PRIx64
+ "} in function {0x%8.8" PRIx64 "} from %s",
+ func_decl.GetFile().GetPath().c_str(), func_decl.GetLine(),
+ GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
+ block_end_addr, parent_block->GetID(), function->GetID(),
+ module_sp->GetFileSpec().GetPath().c_str());
+ } else {
+ log->Printf("warning: block {0x%8.8" PRIx64
+ "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64
+ ") which is not contained in parent block {0x%8.8" PRIx64
+ "} in function {0x%8.8" PRIx64 "} from %s",
+ GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
+ block_end_addr, parent_block->GetID(), function->GetID(),
+ module_sp->GetFileSpec().GetPath().c_str());
+ }
+ }
+ parent_block->AddRange(range);
+ }
+ m_ranges.Append(range);
}
-void
-Block::AddChild(const BlockSP &child_block_sp)
-{
- if (child_block_sp)
- {
- child_block_sp->SetParentScope (this);
- m_children.push_back (child_block_sp);
+// Return the current number of bytes that this object occupies in memory
+size_t Block::MemorySize() const {
+ size_t mem_size = sizeof(Block) + m_ranges.GetSize() * sizeof(Range);
+ if (m_inlineInfoSP.get())
+ mem_size += m_inlineInfoSP->MemorySize();
+ if (m_variable_list_sp.get())
+ mem_size += m_variable_list_sp->MemorySize();
+ return mem_size;
+}
+
+void Block::AddChild(const BlockSP &child_block_sp) {
+ if (child_block_sp) {
+ child_block_sp->SetParentScope(this);
+ m_children.push_back(child_block_sp);
+ }
+}
+
+void Block::SetInlinedFunctionInfo(const char *name, const char *mangled,
+ const Declaration *decl_ptr,
+ const Declaration *call_decl_ptr) {
+ m_inlineInfoSP.reset(
+ new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
+}
+
+VariableListSP Block::GetBlockVariableList(bool can_create) {
+ if (m_parsed_block_variables == false) {
+ if (m_variable_list_sp.get() == nullptr && can_create) {
+ m_parsed_block_variables = true;
+ SymbolContext sc;
+ CalculateSymbolContext(&sc);
+ assert(sc.module_sp);
+ sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
}
+ }
+ return m_variable_list_sp;
}
-void
-Block::SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
-{
- m_inlineInfoSP.reset(new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
-}
-
+uint32_t
+Block::AppendBlockVariables(bool can_create, bool get_child_block_variables,
+ bool stop_if_child_block_is_inlined_function,
+ const std::function<bool(Variable *)> &filter,
+ VariableList *variable_list) {
+ uint32_t num_variables_added = 0;
+ VariableList *block_var_list = GetBlockVariableList(can_create).get();
+ if (block_var_list) {
+ for (size_t i = 0; i < block_var_list->GetSize(); ++i) {
+ VariableSP variable = block_var_list->GetVariableAtIndex(i);
+ if (filter(variable.get())) {
+ num_variables_added++;
+ variable_list->AddVariable(variable);
+ }
+ }
+ }
+ if (get_child_block_variables) {
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos) {
+ Block *child_block = pos->get();
+ if (stop_if_child_block_is_inlined_function == false ||
+ child_block->GetInlinedFunctionInfo() == nullptr) {
+ num_variables_added += child_block->AppendBlockVariables(
+ can_create, get_child_block_variables,
+ stop_if_child_block_is_inlined_function, filter, variable_list);
+ }
+ }
+ }
+ return num_variables_added;
+}
+
+uint32_t Block::AppendVariables(bool can_create, bool get_parent_variables,
+ bool stop_if_block_is_inlined_function,
+ const std::function<bool(Variable *)> &filter,
+ VariableList *variable_list) {
+ uint32_t num_variables_added = 0;
+ VariableListSP variable_list_sp(GetBlockVariableList(can_create));
+
+ bool is_inlined_function = GetInlinedFunctionInfo() != nullptr;
+ if (variable_list_sp) {
+ for (size_t i = 0; i < variable_list_sp->GetSize(); ++i) {
+ VariableSP variable = variable_list_sp->GetVariableAtIndex(i);
+ if (filter(variable.get())) {
+ num_variables_added++;
+ variable_list->AddVariable(variable);
+ }
+ }
+ }
+
+ if (get_parent_variables) {
+ if (stop_if_block_is_inlined_function && is_inlined_function)
+ return num_variables_added;
-VariableListSP
-Block::GetBlockVariableList (bool can_create)
-{
- if (m_parsed_block_variables == false)
- {
- if (m_variable_list_sp.get() == nullptr && can_create)
- {
- m_parsed_block_variables = true;
- SymbolContext sc;
- CalculateSymbolContext(&sc);
- assert(sc.module_sp);
- sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
- }
- }
- return m_variable_list_sp;
+ Block *parent_block = GetParent();
+ if (parent_block)
+ num_variables_added += parent_block->AppendVariables(
+ can_create, get_parent_variables, stop_if_block_is_inlined_function,
+ filter, variable_list);
+ }
+ return num_variables_added;
}
-uint32_t
-Block::AppendBlockVariables (bool can_create,
- bool get_child_block_variables,
- bool stop_if_child_block_is_inlined_function,
- const std::function<bool(Variable*)>& filter,
- VariableList *variable_list)
-{
- uint32_t num_variables_added = 0;
- VariableList *block_var_list = GetBlockVariableList (can_create).get();
- if (block_var_list)
- {
- for (size_t i = 0; i < block_var_list->GetSize(); ++i)
- {
- VariableSP variable = block_var_list->GetVariableAtIndex(i);
- if (filter(variable.get()))
- {
- num_variables_added++;
- variable_list->AddVariable(variable);
- }
- }
- }
+CompilerDeclContext Block::GetDeclContext() {
+ ModuleSP module_sp = CalculateSymbolContextModule();
- if (get_child_block_variables)
- {
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- {
- Block *child_block = pos->get();
- if (stop_if_child_block_is_inlined_function == false ||
- child_block->GetInlinedFunctionInfo() == nullptr)
- {
- num_variables_added += child_block->AppendBlockVariables (can_create,
- get_child_block_variables,
- stop_if_child_block_is_inlined_function,
- filter,
- variable_list);
- }
- }
- }
- return num_variables_added;
-}
+ if (module_sp) {
+ SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
-uint32_t
-Block::AppendVariables
-(
- bool can_create,
- bool get_parent_variables,
- bool stop_if_block_is_inlined_function,
- const std::function<bool(Variable*)>& filter,
- VariableList *variable_list
-)
-{
- uint32_t num_variables_added = 0;
- VariableListSP variable_list_sp(GetBlockVariableList(can_create));
-
- bool is_inlined_function = GetInlinedFunctionInfo() != nullptr;
- if (variable_list_sp)
- {
- for (size_t i = 0; i < variable_list_sp->GetSize(); ++i)
- {
- VariableSP variable = variable_list_sp->GetVariableAtIndex(i);
- if (filter(variable.get()))
- {
- num_variables_added++;
- variable_list->AddVariable(variable);
- }
- }
- }
+ if (sym_vendor) {
+ SymbolFile *sym_file = sym_vendor->GetSymbolFile();
- if (get_parent_variables)
- {
- if (stop_if_block_is_inlined_function && is_inlined_function)
- return num_variables_added;
-
- Block* parent_block = GetParent();
- if (parent_block)
- num_variables_added += parent_block->AppendVariables(can_create,
- get_parent_variables,
- stop_if_block_is_inlined_function,
- filter,
- variable_list);
- }
- return num_variables_added;
-}
-
-CompilerDeclContext
-Block::GetDeclContext()
-{
- ModuleSP module_sp = CalculateSymbolContextModule ();
-
- if (module_sp)
- {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
-
- if (sym_vendor)
- {
- SymbolFile *sym_file = sym_vendor->GetSymbolFile();
-
- if (sym_file)
- return sym_file->GetDeclContextForUID (GetID());
- }
+ if (sym_file)
+ return sym_file->GetDeclContextForUID(GetID());
}
- return CompilerDeclContext();
+ }
+ return CompilerDeclContext();
}
-void
-Block::SetBlockInfoHasBeenParsed (bool b, bool set_children)
-{
- m_parsed_block_info = b;
- if (set_children)
- {
- m_parsed_child_blocks = true;
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- (*pos)->SetBlockInfoHasBeenParsed (b, true);
- }
+void Block::SetBlockInfoHasBeenParsed(bool b, bool set_children) {
+ m_parsed_block_info = b;
+ if (set_children) {
+ m_parsed_child_blocks = true;
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos)
+ (*pos)->SetBlockInfoHasBeenParsed(b, true);
+ }
}
-void
-Block::SetDidParseVariables (bool b, bool set_children)
-{
- m_parsed_block_variables = b;
- if (set_children)
- {
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- (*pos)->SetDidParseVariables (b, true);
- }
+void Block::SetDidParseVariables(bool b, bool set_children) {
+ m_parsed_block_variables = b;
+ if (set_children) {
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos)
+ (*pos)->SetDidParseVariables(b, true);
+ }
}
-
-Block *
-Block::GetSibling() const
-{
- if (m_parent_scope)
- {
- Block *parent_block = GetParent();
- if (parent_block)
- return parent_block->GetSiblingForChild (this);
- }
- return nullptr;
+Block *Block::GetSibling() const {
+ if (m_parent_scope) {
+ Block *parent_block = GetParent();
+ if (parent_block)
+ return parent_block->GetSiblingForChild(this);
+ }
+ return nullptr;
}
// A parent of child blocks can be asked to find a sibling block given
// one of its child blocks
-Block *
-Block::GetSiblingForChild (const Block *child_block) const
-{
- if (!m_children.empty())
- {
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- {
- if (pos->get() == child_block)
- {
- if (++pos != end)
- return pos->get();
- break;
- }
- }
+Block *Block::GetSiblingForChild(const Block *child_block) const {
+ if (!m_children.empty()) {
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos) {
+ if (pos->get() == child_block) {
+ if (++pos != end)
+ return pos->get();
+ break;
+ }
}
- return nullptr;
+ }
+ return nullptr;
}
-
More information about the lldb-commits
mailing list