diff options
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/include/lldb/API/SBModule.h | 45 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/ObjectFile.h | 51 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBModule.i | 4 | ||||
-rw-r--r-- | lldb/source/API/SBModule.cpp | 178 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 51 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h | 3 |
6 files changed, 263 insertions, 69 deletions
diff --git a/lldb/include/lldb/API/SBModule.h b/lldb/include/lldb/API/SBModule.h index 23e1ed4d94b..aa2074bfac7 100644 --- a/lldb/include/lldb/API/SBModule.h +++ b/lldb/include/lldb/API/SBModule.h @@ -167,6 +167,51 @@ public: lldb::SBTypeList FindTypes (const char* type); + + //------------------------------------------------------------------ + /// Get the module version numbers. + /// + /// Many object files have a set of version numbers that describe + /// the version of the executable or shared library. Typically there + /// are major, minor and build, but there may be more. This function + /// will extract the versions from object files if they are available. + /// + /// If \a versions is NULL, or if \a num_versions is 0, the return + /// value will indicate how many version numbers are available in + /// this object file. Then a subsequent call can be made to this + /// function with a value of \a versions and \a num_versions that + /// has enough storage to store some or all version numbers. + /// + /// @param[out] versions + /// A pointer to an array of uint32_t types that is \a num_versions + /// long. If this value is NULL, the return value will indicate + /// how many version numbers are required for a subsequent call + /// to this function so that all versions can be retrieved. If + /// the value is non-NULL, then at most \a num_versions of the + /// existing versions numbers will be filled into \a versions. + /// If there is no version information available, \a versions + /// will be filled with \a num_versions UINT32_MAX values + /// and zero will be returned. + /// + /// @param[in] num_versions + /// The maximum number of entries to fill into \a versions. If + /// this value is zero, then the return value will indicate + /// how many version numbers there are in total so another call + /// to this function can be make with adequate storage in + /// \a versions to get all of the version numbers. If \a + /// num_versions is less than the actual number of version + /// numbers in this object file, only \a num_versions will be + /// filled into \a versions (if \a versions is non-NULL). + /// + /// @return + /// This function always returns the number of version numbers + /// that this object file has regardless of the number of + /// version numbers that were copied into \a versions. + //------------------------------------------------------------------ + uint32_t + GetVersion (uint32_t *versions, + uint32_t num_versions); + private: friend class SBAddress; friend class SBFrame; diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h index bb65be70efb..b19c1ee7f33 100644 --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -460,6 +460,57 @@ public: CalculateStrata() = 0; //------------------------------------------------------------------ + /// Get the object file version numbers. + /// + /// Many object files have a set of version numbers that describe + /// the version of the executable or shared library. Typically there + /// are major, minor and build, but there may be more. This function + /// will extract the versions from object files if they are available. + /// + /// If \a versions is NULL, or if \a num_versions is 0, the return + /// value will indicate how many version numbers are available in + /// this object file. Then a subsequent call can be made to this + /// function with a value of \a versions and \a num_versions that + /// has enough storage to store some or all version numbers. + /// + /// @param[out] versions + /// A pointer to an array of uint32_t types that is \a num_versions + /// long. If this value is NULL, the return value will indicate + /// how many version numbers are required for a subsequent call + /// to this function so that all versions can be retrieved. If + /// the value is non-NULL, then at most \a num_versions of the + /// existing versions numbers will be filled into \a versions. + /// If there is no version information available, \a versions + /// will be filled with \a num_versions UINT32_MAX values + /// and zero will be returned. + /// + /// @param[in] num_versions + /// The maximum number of entries to fill into \a versions. If + /// this value is zero, then the return value will indicate + /// how many version numbers there are in total so another call + /// to this function can be make with adequate storage in + /// \a versions to get all of the version numbers. If \a + /// num_versions is less than the actual number of version + /// numbers in this object file, only \a num_versions will be + /// filled into \a versions (if \a versions is non-NULL). + /// + /// @return + /// This function always returns the number of version numbers + /// that this object file has regardless of the number of + /// version numbers that were copied into \a versions. + //------------------------------------------------------------------ + virtual uint32_t + GetVersion (uint32_t *versions, uint32_t num_versions) + { + if (versions && num_versions) + { + for (uint32_t i=0; i<num_versions; ++i) + versions[i] = UINT32_MAX; + } + return 0; + } + + //------------------------------------------------------------------ // Member Functions //------------------------------------------------------------------ Type diff --git a/lldb/scripts/Python/interface/SBModule.i b/lldb/scripts/Python/interface/SBModule.i index 44d3a86d667..c826134ff42 100644 --- a/lldb/scripts/Python/interface/SBModule.i +++ b/lldb/scripts/Python/interface/SBModule.i @@ -239,6 +239,10 @@ public: const char * GetTriple (); + + uint32_t + GetVersion (uint32_t *versions, + uint32_t num_versions); %pythoncode %{ class symbols_access(object): diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp index 09f354e2710..77a7af2c62e 100644 --- a/lldb/source/API/SBModule.cpp +++ b/lldb/source/API/SBModule.cpp @@ -86,13 +86,14 @@ SBModule::GetFileSpec () const LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBFileSpec file_spec; - if (m_opaque_sp) - file_spec.SetFileSpec(m_opaque_sp->GetFileSpec()); + ModuleSP module_sp (GetSP ()); + if (module_sp) + file_spec.SetFileSpec(module_sp->GetFileSpec()); if (log) { log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)", - m_opaque_sp.get(), file_spec.get()); + module_sp.get(), file_spec.get()); } return file_spec; @@ -104,13 +105,14 @@ SBModule::GetPlatformFileSpec () const LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBFileSpec file_spec; - if (m_opaque_sp) - file_spec.SetFileSpec(m_opaque_sp->GetPlatformFileSpec()); + ModuleSP module_sp (GetSP ()); + if (module_sp) + file_spec.SetFileSpec(module_sp->GetPlatformFileSpec()); if (log) { log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)", - m_opaque_sp.get(), file_spec.get()); + module_sp.get(), file_spec.get()); } return file_spec; @@ -123,16 +125,17 @@ SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file) bool result = false; LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - if (m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (module_sp) { - m_opaque_sp->SetPlatformFileSpec(*platform_file); + module_sp->SetPlatformFileSpec(*platform_file); result = true; } if (log) { log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s%s%s)) => %i", - m_opaque_sp.get(), + module_sp.get(), platform_file.get(), platform_file->GetDirectory().GetCString(), platform_file->GetDirectory() ? "/" : "", @@ -150,19 +153,20 @@ SBModule::GetUUIDBytes () const LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); const uint8_t *uuid_bytes = NULL; - if (m_opaque_sp) - uuid_bytes = (const uint8_t *)m_opaque_sp->GetUUID().GetBytes(); + ModuleSP module_sp (GetSP ()); + if (module_sp) + uuid_bytes = (const uint8_t *)module_sp->GetUUID().GetBytes(); if (log) { if (uuid_bytes) { StreamString s; - m_opaque_sp->GetUUID().Dump (&s); - log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", m_opaque_sp.get(), s.GetData()); + module_sp->GetUUID().Dump (&s); + log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", module_sp.get(), s.GetData()); } else - log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", m_opaque_sp.get()); + log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", module_sp.get()); } return uuid_bytes; } @@ -175,19 +179,20 @@ SBModule::GetUUIDString () const static char uuid_string[80]; const char * uuid_c_string = NULL; - if (m_opaque_sp) - uuid_c_string = (const char *)m_opaque_sp->GetUUID().GetAsCString(uuid_string, sizeof(uuid_string)); + ModuleSP module_sp (GetSP ()); + if (module_sp) + uuid_c_string = (const char *)module_sp->GetUUID().GetAsCString(uuid_string, sizeof(uuid_string)); if (log) { if (uuid_c_string) { StreamString s; - m_opaque_sp->GetUUID().Dump (&s); - log->Printf ("SBModule(%p)::GetUUIDString () => %s", m_opaque_sp.get(), s.GetData()); + module_sp->GetUUID().Dump (&s); + log->Printf ("SBModule(%p)::GetUUIDString () => %s", module_sp.get(), s.GetData()); } else - log->Printf ("SBModule(%p)::GetUUIDString () => NULL", m_opaque_sp.get()); + log->Printf ("SBModule(%p)::GetUUIDString () => NULL", module_sp.get()); } return uuid_c_string; } @@ -225,10 +230,11 @@ SBAddress SBModule::ResolveFileAddress (lldb::addr_t vm_addr) { lldb::SBAddress sb_addr; - if (m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (module_sp) { Address addr; - if (m_opaque_sp->ResolveFileAddress (vm_addr, addr)) + if (module_sp->ResolveFileAddress (vm_addr, addr)) sb_addr.ref() = addr; } return sb_addr; @@ -238,8 +244,9 @@ SBSymbolContext SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope) { SBSymbolContext sb_sc; - if (m_opaque_sp && addr.IsValid()) - m_opaque_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc); + ModuleSP module_sp (GetSP ()); + if (module_sp && addr.IsValid()) + module_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc); return sb_sc; } @@ -248,9 +255,10 @@ SBModule::GetDescription (SBStream &description) { Stream &strm = description.ref(); - if (m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (module_sp) { - m_opaque_sp->GetDescription (&strm); + module_sp->GetDescription (&strm); } else strm.PutCString ("No value"); @@ -261,9 +269,10 @@ SBModule::GetDescription (SBStream &description) size_t SBModule::GetNumSymbols () { - if (m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (module_sp) { - ObjectFile *obj_file = m_opaque_sp->GetObjectFile(); + ObjectFile *obj_file = module_sp->GetObjectFile(); if (obj_file) { Symtab *symtab = obj_file->GetSymtab(); @@ -278,9 +287,10 @@ SBSymbol SBModule::GetSymbolAtIndex (size_t idx) { SBSymbol sb_symbol; - if (m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (module_sp) { - ObjectFile *obj_file = m_opaque_sp->GetObjectFile(); + ObjectFile *obj_file = module_sp->GetObjectFile(); if (obj_file) { Symtab *symtab = obj_file->GetSymtab(); @@ -294,9 +304,10 @@ SBModule::GetSymbolAtIndex (size_t idx) size_t SBModule::GetNumSections () { - if (m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (module_sp) { - ObjectFile *obj_file = m_opaque_sp->GetObjectFile(); + ObjectFile *obj_file = module_sp->GetObjectFile(); if (obj_file) { SectionList *section_list = obj_file->GetSectionList (); @@ -311,9 +322,10 @@ SBSection SBModule::GetSectionAtIndex (size_t idx) { SBSection sb_section; - if (m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (module_sp) { - ObjectFile *obj_file = m_opaque_sp->GetObjectFile(); + ObjectFile *obj_file = module_sp->GetObjectFile(); if (obj_file) { SectionList *section_list = obj_file->GetSectionList (); @@ -330,18 +342,19 @@ SBModule::FindFunctions (const char *name, uint32_t name_type_mask) { lldb::SBSymbolContextList sb_sc_list; - if (name && m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (name && module_sp) { const bool append = true; const bool symbols_ok = true; const bool inlines_ok = true; - m_opaque_sp->FindFunctions (ConstString(name), - NULL, - name_type_mask, - symbols_ok, - inlines_ok, - append, - *sb_sc_list); + module_sp->FindFunctions (ConstString(name), + NULL, + name_type_mask, + symbols_ok, + inlines_ok, + append, + *sb_sc_list); } return sb_sc_list; } @@ -351,14 +364,15 @@ SBValueList SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches) { SBValueList sb_value_list; - if (name && m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (name && module_sp) { VariableList variable_list; - const uint32_t match_count = m_opaque_sp->FindGlobalVariables (ConstString (name), - NULL, - false, - max_matches, - variable_list); + const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name), + NULL, + false, + max_matches, + variable_list); if (match_count > 0) { @@ -381,19 +395,20 @@ lldb::SBType SBModule::FindFirstType (const char *name_cstr) { SBType sb_type; - if (name_cstr && IsValid()) + ModuleSP module_sp (GetSP ()); + if (name_cstr && module_sp) { SymbolContext sc; TypeList type_list; uint32_t num_matches = 0; ConstString name(name_cstr); - num_matches = m_opaque_sp->FindTypes(sc, - name, - NULL, - false, - 1, - type_list); + num_matches = module_sp->FindTypes (sc, + name, + NULL, + false, + 1, + type_list); if (num_matches) sb_type = lldb::SBType(type_list.GetTypeAtIndex(0)); @@ -407,19 +422,20 @@ SBModule::FindTypes (const char *type) SBTypeList retval; - if (type && IsValid()) + ModuleSP module_sp (GetSP ()); + if (type && module_sp) { SymbolContext sc; TypeList type_list; uint32_t num_matches = 0; ConstString name(type); - num_matches = m_opaque_sp->FindTypes(sc, - name, - NULL, - false, - UINT32_MAX, - type_list); + num_matches = module_sp->FindTypes (sc, + name, + NULL, + false, + UINT32_MAX, + type_list); for (size_t idx = 0; idx < num_matches; idx++) { @@ -438,9 +454,10 @@ SBModule::FindSection (const char *sect_name) { SBSection sb_section; - if (sect_name && IsValid()) + ModuleSP module_sp (GetSP ()); + if (sect_name && module_sp) { - ObjectFile *objfile = m_opaque_sp->GetObjectFile(); + ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) { SectionList *section_list = objfile->GetSectionList(); @@ -461,17 +478,19 @@ SBModule::FindSection (const char *sect_name) lldb::ByteOrder SBModule::GetByteOrder () { - if (m_opaque_sp) - return m_opaque_sp->GetArchitecture().GetByteOrder(); + ModuleSP module_sp (GetSP ()); + if (module_sp) + return module_sp->GetArchitecture().GetByteOrder(); return eByteOrderInvalid; } const char * SBModule::GetTriple () { - if (m_opaque_sp) + ModuleSP module_sp (GetSP ()); + if (module_sp) { - std::string triple (m_opaque_sp->GetArchitecture().GetTriple().str()); + std::string triple (module_sp->GetArchitecture().GetTriple().str()); // Unique the string so we don't run into ownership issues since // the const strings put the string into the string pool once and // the strings never comes out @@ -484,8 +503,29 @@ SBModule::GetTriple () uint32_t SBModule::GetAddressByteSize() { - if (m_opaque_sp) - return m_opaque_sp->GetArchitecture().GetAddressByteSize(); + ModuleSP module_sp (GetSP ()); + if (module_sp) + return module_sp->GetArchitecture().GetAddressByteSize(); return sizeof(void*); } + +uint32_t +SBModule::GetVersion (uint32_t *versions, uint32_t num_versions) +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + ObjectFile *obj_file = module_sp->GetObjectFile(); + if (obj_file) + return obj_file->GetVersion (versions, num_versions); + } + + if (versions && num_versions) + { + for (uint32_t i=0; i<num_versions; ++i) + versions[i] = UINT32_MAX; + } + return 0; +} + diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index d233ece6cb7..3629e766973 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -2426,6 +2426,57 @@ ObjectFileMachO::CalculateStrata() } +uint32_t +ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions) +{ + lldb_private::Mutex::Locker locker(m_mutex); + struct dylib_command load_cmd; + uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); + uint32_t version_cmd = 0; + uint64_t version = 0; + uint32_t i; + for (i=0; i<m_header.ncmds; ++i) + { + const uint32_t cmd_offset = offset; + if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) + break; + + if (load_cmd.cmd == LoadCommandDylibIdent) + { + if (version_cmd == 0) + { + version_cmd = load_cmd.cmd; + if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL) + break; + version = load_cmd.dylib.current_version; + } + break; // Break for now unless there is another more complete version + // number load command in the future. + } + offset = cmd_offset + load_cmd.cmdsize; + } + + if (version_cmd == LoadCommandDylibIdent) + { + if (versions != NULL && num_versions > 0) + { + if (num_versions > 0) + versions[0] = (version & 0xFFFF0000ull) >> 16; + if (num_versions > 1) + versions[1] = (version & 0x0000FF00ull) >> 8; + if (num_versions > 2) + versions[2] = (version & 0x000000FFull); + // Fill in an remaining version numbers with invalid values + for (i=3; i<num_versions; ++i) + versions[i] = UINT32_MAX; + } + // The LC_ID_DYLIB load command has a version with 3 version numbers + // in it, so always return 3 + return 3; + } + return false; +} + bool ObjectFileMachO::GetArchitecture (ArchSpec &arch) { diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index 918b9216179..4ffc7df7961 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -139,6 +139,9 @@ public: virtual ObjectFile::Strata CalculateStrata(); + virtual uint32_t + GetVersion (uint32_t *versions, uint32_t num_versions); + protected: mutable lldb_private::Mutex m_mutex; llvm::MachO::mach_header m_header; |