Author: jmolenda Date: Mon Nov 9 23:21:54 2015 New Revision: 252588 URL: http://llvm.org/viewvc/llvm-project?rev=252588&view=rev Log: Add support for tvos and watchos to ObjectFileMachO. Add support for the new dyld shared cache format on ios etc devices. Small changes for classifying ObjC metadata symbols.
Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h lldb/trunk/source/Symbol/ObjectFile.cpp Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=252588&r1=252587&r2=252588&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original) +++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Mon Nov 9 23:21:54 2015 @@ -840,7 +840,11 @@ public: { return symbol_name.str(); } - + + static lldb::SymbolType + GetSymbolTypeFromName (llvm::StringRef name, + lldb::SymbolType symbol_type_hint = lldb::eSymbolTypeUndefined); + protected: //------------------------------------------------------------------ // Member variables. Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=252588&r1=252587&r2=252588&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Mon Nov 9 23:21:54 2015 @@ -62,6 +62,52 @@ using namespace lldb; using namespace lldb_private; using namespace llvm::MachO; +// Some structure definitions needed for parsing the dyld shared cache files +// found on iOS devices. + +struct lldb_copy_dyld_cache_header_v1 +{ + char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc. + uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info + uint32_t mappingCount; // number of dyld_cache_mapping_info entries + uint32_t imagesOffset; + uint32_t imagesCount; + uint64_t dyldBaseAddress; + uint64_t codeSignatureOffset; + uint64_t codeSignatureSize; + uint64_t slideInfoOffset; + uint64_t slideInfoSize; + uint64_t localSymbolsOffset; + uint64_t localSymbolsSize; + uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later +}; + +struct lldb_copy_dyld_cache_mapping_info +{ + uint64_t address; + uint64_t size; + uint64_t fileOffset; + uint32_t maxProt; + uint32_t initProt; +}; + +struct lldb_copy_dyld_cache_local_symbols_info +{ + uint32_t nlistOffset; + uint32_t nlistCount; + uint32_t stringsOffset; + uint32_t stringsSize; + uint32_t entriesOffset; + uint32_t entriesCount; +}; +struct lldb_copy_dyld_cache_local_symbols_entry +{ + uint32_t dylibOffset; + uint32_t nlistStartIndex; + uint32_t nlistCount; +}; + + class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 { public: @@ -1775,7 +1821,6 @@ ObjectFileMachO::CreateSections (Section static ConstString g_sect_name_data ("__data"); static ConstString g_sect_name_go_symtab ("__gosymtab"); - if (section_name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev; else if (section_name == g_sect_name_dwarf_debug_aranges) @@ -2151,6 +2196,31 @@ ParseTrieEntries (DataExtractor &data, return true; } +// Read the UUID out of a dyld_shared_cache file on-disk. +UUID +ObjectFileMachO::GetSharedCacheUUID (FileSpec dyld_shared_cache, const ByteOrder byte_order, const uint32_t addr_byte_size) +{ + UUID dsc_uuid; + DataBufferSP dsc_data_sp = dyld_shared_cache.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1)); + if (dsc_data_sp) + { + DataExtractor dsc_header_data (dsc_data_sp, byte_order, addr_byte_size); + + char version_str[7]; + lldb::offset_t offset = 0; + memcpy (version_str, dsc_header_data.GetData (&offset, 6), 6); + version_str[6] = '\0'; + if (strcmp (version_str, "dyld_v") == 0) + { + offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid); + uint8_t uuid_bytes[sizeof (uuid_t)]; + memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t)); + dsc_uuid.SetBytes (uuid_bytes); + } + } + return dsc_uuid; +} + size_t ObjectFileMachO::ParseSymtab () { @@ -2610,73 +2680,67 @@ ObjectFileMachO::ParseSymtab () ArchSpec header_arch; GetArchitecture(header_arch); char dsc_path[PATH_MAX]; + char dsc_path_development[PATH_MAX]; snprintf(dsc_path, sizeof(dsc_path), "%s%s%s", "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */ "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */ header_arch.GetArchitectureName()); - FileSpec dsc_filespec(dsc_path, false); + snprintf(dsc_path_development, sizeof(dsc_path), "%s%s%s%s", + "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */ + "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */ + header_arch.GetArchitectureName(), + ".development"); + + FileSpec dsc_nondevelopment_filespec(dsc_path, false); + FileSpec dsc_development_filespec(dsc_path_development, false); + FileSpec dsc_filespec; + + UUID dsc_uuid; + UUID process_shared_cache_uuid; + + if (process) + { + process_shared_cache_uuid = GetProcessSharedCacheUUID(process); + } + + // First see if we can find an exact match for the inferior process shared cache UUID in + // the development or non-development shared caches on disk. + if (process_shared_cache_uuid.IsValid()) + { + if (dsc_development_filespec.Exists()) + { + UUID dsc_development_uuid = GetSharedCacheUUID (dsc_development_filespec, byte_order, addr_byte_size); + if (dsc_development_uuid.IsValid() && dsc_development_uuid == process_shared_cache_uuid) + { + dsc_filespec = dsc_development_filespec; + dsc_uuid = dsc_development_uuid; + } + } + if (!dsc_uuid.IsValid() && dsc_nondevelopment_filespec.Exists()) + { + UUID dsc_nondevelopment_uuid = GetSharedCacheUUID (dsc_nondevelopment_filespec, byte_order, addr_byte_size); + if (dsc_nondevelopment_uuid.IsValid() && dsc_nondevelopment_uuid == process_shared_cache_uuid) + { + dsc_filespec = dsc_nondevelopment_filespec; + dsc_uuid = dsc_nondevelopment_uuid; + } + } + } - // We need definitions of two structures in the on-disk DSC, copy them here manually - struct lldb_copy_dyld_cache_header_v0 + // Failing a UUID match, prefer the development dyld_shared cache if both are present. + if (!dsc_filespec.Exists()) { - char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc. - uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info - uint32_t mappingCount; // number of dyld_cache_mapping_info entries - uint32_t imagesOffset; - uint32_t imagesCount; - uint64_t dyldBaseAddress; - uint64_t codeSignatureOffset; - uint64_t codeSignatureSize; - uint64_t slideInfoOffset; - uint64_t slideInfoSize; - uint64_t localSymbolsOffset; // file offset of where local symbols are stored - uint64_t localSymbolsSize; // size of local symbols information - }; - - struct lldb_copy_dyld_cache_header_v1 - { - char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc. - uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info - uint32_t mappingCount; // number of dyld_cache_mapping_info entries - uint32_t imagesOffset; - uint32_t imagesCount; - uint64_t dyldBaseAddress; - uint64_t codeSignatureOffset; - uint64_t codeSignatureSize; - uint64_t slideInfoOffset; - uint64_t slideInfoSize; - uint64_t localSymbolsOffset; - uint64_t localSymbolsSize; - uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later - }; - - struct lldb_copy_dyld_cache_mapping_info - { - uint64_t address; - uint64_t size; - uint64_t fileOffset; - uint32_t maxProt; - uint32_t initProt; - }; - - struct lldb_copy_dyld_cache_local_symbols_info - { - uint32_t nlistOffset; - uint32_t nlistCount; - uint32_t stringsOffset; - uint32_t stringsSize; - uint32_t entriesOffset; - uint32_t entriesCount; - }; - - struct lldb_copy_dyld_cache_local_symbols_entry - { - uint32_t dylibOffset; - uint32_t nlistStartIndex; - uint32_t nlistCount; - }; + if (dsc_development_filespec.Exists()) + { + dsc_filespec = dsc_development_filespec; + } + else + { + dsc_filespec = dsc_nondevelopment_filespec; + } + } /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset). The dyld_cache_local_symbols_info structure gives us three things: @@ -2690,46 +2754,21 @@ ObjectFileMachO::ParseSymtab () and the count of how many nlist records there are for this dylib/framework. */ - // Process the dsc header to find the unmapped symbols - // - // Save some VM space, do not map the entire cache in one shot. - - DataBufferSP dsc_data_sp; - dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1)); + // Process the dyld shared cache header to find the unmapped symbols + DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1)); + if (!dsc_uuid.IsValid()) + { + dsc_uuid = GetSharedCacheUUID (dsc_filespec, byte_order, addr_byte_size); + } if (dsc_data_sp) { - DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size); - - char version_str[17]; - int version = -1; - lldb::offset_t offset = 0; - memcpy (version_str, dsc_header_data.GetData (&offset, 16), 16); - version_str[16] = '\0'; - if (strncmp (version_str, "dyld_v", 6) == 0 && isdigit (version_str[6])) - { - int v; - if (::sscanf (version_str + 6, "%d", &v) == 1) - { - version = v; - } - } - - UUID dsc_uuid; - if (version >= 1) - { - offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid); - uint8_t uuid_bytes[sizeof (uuid_t)]; - memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t)); - dsc_uuid.SetBytes (uuid_bytes); - } + DataExtractor dsc_header_data (dsc_data_sp, byte_order, addr_byte_size); bool uuid_match = true; if (dsc_uuid.IsValid() && process) { - UUID shared_cache_uuid(GetProcessSharedCacheUUID(process)); - - if (shared_cache_uuid.IsValid() && dsc_uuid != shared_cache_uuid) + if (process_shared_cache_uuid.IsValid() && dsc_uuid != process_shared_cache_uuid) { // The on-disk dyld_shared_cache file is not the same as the one in this // process' memory, don't use it. @@ -2746,7 +2785,7 @@ ObjectFileMachO::ParseSymtab () // If the mappingOffset points to a location inside the header, we've // opened an old dyld shared cache, and should not proceed further. - if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0)) + if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1)) { DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info)); @@ -2942,7 +2981,10 @@ ObjectFileMachO::ParseSymtab () // static symbol: name,,n_sect,type,address N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx)); symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); - type = eSymbolTypeData; + if (symbol_name && symbol_name[0]) + { + type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, eSymbolTypeData); + } break; case N_LCSYM: @@ -3329,33 +3371,36 @@ ObjectFileMachO::ParseSymtab () if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name) { type = eSymbolTypeRuntime; - - if (symbol_name && - symbol_name[0] == '_' && - symbol_name[1] == 'O' && - symbol_name[2] == 'B') + + if (symbol_name) { llvm::StringRef symbol_name_ref(symbol_name); - if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) + if (symbol_name_ref.startswith("_OBJC_")) { - symbol_name_non_abi_mangled = symbol_name + 1; - symbol_name = symbol_name + g_objc_v2_prefix_class.size(); - type = eSymbolTypeObjCClass; - demangled_is_synthesized = true; - } - else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) - { - symbol_name_non_abi_mangled = symbol_name + 1; - symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); - type = eSymbolTypeObjCMetaClass; - demangled_is_synthesized = true; - } - else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) - { - symbol_name_non_abi_mangled = symbol_name + 1; - symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); - type = eSymbolTypeObjCIVar; - demangled_is_synthesized = true; + static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_"); + static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_"); + static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_"); + if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) + { + symbol_name_non_abi_mangled = symbol_name + 1; + symbol_name = symbol_name + g_objc_v2_prefix_class.size(); + type = eSymbolTypeObjCClass; + demangled_is_synthesized = true; + } + else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) + { + symbol_name_non_abi_mangled = symbol_name + 1; + symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); + type = eSymbolTypeObjCMetaClass; + demangled_is_synthesized = true; + } + else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) + { + symbol_name_non_abi_mangled = symbol_name + 1; + symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); + type = eSymbolTypeObjCIVar; + demangled_is_synthesized = true; + } } } } @@ -3791,7 +3836,10 @@ ObjectFileMachO::ParseSymtab () // static symbol: name,,n_sect,type,address N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx)); symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); - type = eSymbolTypeData; + if (symbol_name && symbol_name[0]) + { + type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, eSymbolTypeData); + } break; case N_LCSYM: @@ -4181,32 +4229,35 @@ ObjectFileMachO::ParseSymtab () { type = eSymbolTypeRuntime; - if (symbol_name && - symbol_name[0] == '_' && - symbol_name[1] == 'O' && - symbol_name[2] == 'B') + if (symbol_name) { llvm::StringRef symbol_name_ref(symbol_name); - if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) - { - symbol_name_non_abi_mangled = symbol_name + 1; - symbol_name = symbol_name + g_objc_v2_prefix_class.size(); - type = eSymbolTypeObjCClass; - demangled_is_synthesized = true; - } - else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) - { - symbol_name_non_abi_mangled = symbol_name + 1; - symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); - type = eSymbolTypeObjCMetaClass; - demangled_is_synthesized = true; - } - else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) + if (symbol_name_ref.startswith("_OBJC_")) { - symbol_name_non_abi_mangled = symbol_name + 1; - symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); - type = eSymbolTypeObjCIVar; - demangled_is_synthesized = true; + static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_"); + static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_"); + static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_"); + if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) + { + symbol_name_non_abi_mangled = symbol_name + 1; + symbol_name = symbol_name + g_objc_v2_prefix_class.size(); + type = eSymbolTypeObjCClass; + demangled_is_synthesized = true; + } + else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) + { + symbol_name_non_abi_mangled = symbol_name + 1; + symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); + type = eSymbolTypeObjCMetaClass; + demangled_is_synthesized = true; + } + else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) + { + symbol_name_non_abi_mangled = symbol_name + 1; + symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); + type = eSymbolTypeObjCIVar; + demangled_is_synthesized = true; + } } } } @@ -4793,14 +4844,22 @@ ObjectFileMachO::GetArchitecture (const switch (load_cmd.cmd) { - case LC_VERSION_MIN_IPHONEOS: + case llvm::MachO::LC_VERSION_MIN_IPHONEOS: triple.setOS (llvm::Triple::IOS); return true; - case LC_VERSION_MIN_MACOSX: + case llvm::MachO::LC_VERSION_MIN_MACOSX: triple.setOS (llvm::Triple::MacOSX); return true; + + case llvm::MachO::LC_VERSION_MIN_TVOS: + triple.setOS (llvm::Triple::TvOS); + return true; + case llvm::MachO::LC_VERSION_MIN_WATCHOS: + triple.setOS (llvm::Triple::WatchOS); + return true; + default: break; } @@ -5440,7 +5499,10 @@ ObjectFileMachO::GetMinimumOSVersion (ui version_min_command lc; if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL) break; - if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS) + if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX + || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS + || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS + || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) { if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2)) { @@ -5498,7 +5560,10 @@ ObjectFileMachO::GetSDKVersion(uint32_t version_min_command lc; if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL) break; - if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS) + if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX + || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS + || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS + || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) { if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2)) { @@ -5710,8 +5775,10 @@ ObjectFileMachO::SaveCore (const lldb::P const ArchSpec target_arch = target.GetArchitecture(); const llvm::Triple &target_triple = target_arch.GetTriple(); if (target_triple.getVendor() == llvm::Triple::Apple && - (target_triple.getOS() == llvm::Triple::MacOSX || - target_triple.getOS() == llvm::Triple::IOS)) + (target_triple.getOS() == llvm::Triple::MacOSX + || target_triple.getOS() == llvm::Triple::IOS + || target_triple.getOS() == llvm::Triple::WatchOS + || target_triple.getOS() == llvm::Triple::TvOS)) { bool make_core = false; switch (target_arch.GetMachine()) Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=252588&r1=252587&r2=252588&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Mon Nov 9 23:21:54 2015 @@ -222,6 +222,9 @@ protected: const lldb_private::Section *mach_header_section, const lldb_private::Section *section); + lldb_private::UUID + GetSharedCacheUUID (lldb_private::FileSpec dyld_shared_cache, const lldb::ByteOrder byte_order, const uint32_t addr_byte_size); + size_t ParseSymtab(); Modified: lldb/trunk/source/Symbol/ObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ObjectFile.cpp?rev=252588&r1=252587&r2=252588&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ObjectFile.cpp (original) +++ lldb/trunk/source/Symbol/ObjectFile.cpp Mon Nov 9 23:21:54 2015 @@ -626,3 +626,28 @@ ObjectFile::GetSectionList(bool update_m } return m_sections_ap.get(); } + +lldb::SymbolType +ObjectFile::GetSymbolTypeFromName (llvm::StringRef name, + lldb::SymbolType symbol_type_hint) +{ + if (!name.empty()) + { + if (name.startswith("_OBJC_")) + { + // ObjC + if (name.startswith("_OBJC_CLASS_$_")) + return lldb::eSymbolTypeObjCClass; + if (name.startswith("_OBJC_METACLASS_$_")) + return lldb::eSymbolTypeObjCMetaClass; + if (name.startswith("_OBJC_IVAR_$_")) + return lldb::eSymbolTypeObjCIVar; + } + else if (name.startswith(".objc_class_name_")) + { + // ObjC v1 + return lldb::eSymbolTypeObjCClass; + } + } + return symbol_type_hint; +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits