1 //===-- ObjectFileMachO.h ---------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_MACH_O_OBJECTFILEMACHO_H 10 #define LLDB_SOURCE_PLUGINS_OBJECTFILE_MACH_O_OBJECTFILEMACHO_H 11 12 #include "lldb/Core/Address.h" 13 #include "lldb/Core/FileSpecList.h" 14 #include "lldb/Host/SafeMachO.h" 15 #include "lldb/Symbol/ObjectFile.h" 16 #include "lldb/Utility/FileSpec.h" 17 #include "lldb/Utility/RangeMap.h" 18 #include "lldb/Utility/StreamString.h" 19 #include "lldb/Utility/UUID.h" 20 21 // This class needs to be hidden as eventually belongs in a plugin that 22 // will export the ObjectFile protocol 23 class ObjectFileMachO : public lldb_private::ObjectFile { 24 public: 25 ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, 26 lldb::offset_t data_offset, 27 const lldb_private::FileSpec *file, lldb::offset_t offset, 28 lldb::offset_t length); 29 30 ObjectFileMachO(const lldb::ModuleSP &module_sp, 31 lldb::WritableDataBufferSP data_sp, 32 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); 33 34 ~ObjectFileMachO() override = default; 35 36 // Static Functions 37 static void Initialize(); 38 39 static void Terminate(); 40 GetPluginNameStatic()41 static llvm::StringRef GetPluginNameStatic() { return "mach-o"; } 42 GetPluginDescriptionStatic()43 static llvm::StringRef GetPluginDescriptionStatic() { 44 return "Mach-o object file reader (32 and 64 bit)"; 45 } 46 47 static lldb_private::ObjectFile * 48 CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, 49 lldb::offset_t data_offset, const lldb_private::FileSpec *file, 50 lldb::offset_t file_offset, lldb::offset_t length); 51 52 static lldb_private::ObjectFile *CreateMemoryInstance( 53 const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, 54 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); 55 56 static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, 57 lldb::DataBufferSP &data_sp, 58 lldb::offset_t data_offset, 59 lldb::offset_t file_offset, 60 lldb::offset_t length, 61 lldb_private::ModuleSpecList &specs); 62 63 static bool SaveCore(const lldb::ProcessSP &process_sp, 64 const lldb_private::FileSpec &outfile, 65 lldb::SaveCoreStyle &core_style, 66 lldb_private::Status &error); 67 68 static bool MagicBytesMatch(lldb::DataBufferSP data_sp, lldb::addr_t offset, 69 lldb::addr_t length); 70 71 // LLVM RTTI support 72 static char ID; isA(const void * ClassID)73 bool isA(const void *ClassID) const override { 74 return ClassID == &ID || ObjectFile::isA(ClassID); 75 } classof(const ObjectFile * obj)76 static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } 77 78 // Member Functions 79 bool ParseHeader() override; 80 81 bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, 82 bool value_is_offset) override; 83 84 lldb::ByteOrder GetByteOrder() const override; 85 86 bool IsExecutable() const override; 87 88 bool IsDynamicLoader() const; 89 90 bool IsSharedCacheBinary() const; 91 92 uint32_t GetAddressByteSize() const override; 93 94 lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override; 95 96 void ParseSymtab(lldb_private::Symtab &symtab) override; 97 98 bool IsStripped() override; 99 100 void CreateSections(lldb_private::SectionList &unified_section_list) override; 101 102 void Dump(lldb_private::Stream *s) override; 103 104 lldb_private::ArchSpec GetArchitecture() override; 105 106 lldb_private::UUID GetUUID() override; 107 108 uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; 109 GetReExportedLibraries()110 lldb_private::FileSpecList GetReExportedLibraries() override { 111 return m_reexported_dylibs; 112 } 113 114 lldb_private::Address GetEntryPointAddress() override; 115 116 lldb_private::Address GetBaseAddress() override; 117 118 uint32_t GetNumThreadContexts() override; 119 120 std::string GetIdentifierString() override; 121 122 lldb::addr_t GetAddressMask() override; 123 124 bool GetCorefileMainBinaryInfo(lldb::addr_t &value, bool &value_is_offset, 125 lldb_private::UUID &uuid, 126 ObjectFile::BinaryType &type) override; 127 128 bool LoadCoreFileImages(lldb_private::Process &process) override; 129 130 lldb::RegisterContextSP 131 GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override; 132 133 ObjectFile::Type CalculateType() override; 134 135 ObjectFile::Strata CalculateStrata() override; 136 137 llvm::VersionTuple GetVersion() override; 138 139 llvm::VersionTuple GetMinimumOSVersion() override; 140 141 llvm::VersionTuple GetSDKVersion() override; 142 143 bool GetIsDynamicLinkEditor() override; 144 145 static bool ParseHeader(lldb_private::DataExtractor &data, 146 lldb::offset_t *data_offset_ptr, 147 llvm::MachO::mach_header &header); 148 149 bool AllowAssemblyEmulationUnwindPlans() override; 150 151 // PluginInterface protocol GetPluginName()152 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 153 154 protected: 155 static lldb_private::UUID 156 GetUUID(const llvm::MachO::mach_header &header, 157 const lldb_private::DataExtractor &data, 158 lldb::offset_t lc_offset); // Offset to the first load command 159 160 static lldb_private::ArchSpec GetArchitecture( 161 lldb::ModuleSP module_sp, const llvm::MachO::mach_header &header, 162 const lldb_private::DataExtractor &data, lldb::offset_t lc_offset); 163 164 /// Enumerate all ArchSpecs supported by this Mach-O file. 165 /// 166 /// On macOS one Mach-O slice can contain multiple load commands: 167 /// One load command for being loaded into a macOS process and one 168 /// load command for being loaded into a macCatalyst process. In 169 /// contrast to ObjectContainerUniversalMachO, this is the same 170 /// binary that can be loaded into different contexts. 171 static void GetAllArchSpecs(const llvm::MachO::mach_header &header, 172 const lldb_private::DataExtractor &data, 173 lldb::offset_t lc_offset, 174 lldb_private::ModuleSpec &base_spec, 175 lldb_private::ModuleSpecList &all_specs); 176 177 /// Intended for same-host arm device debugging where lldb needs to 178 /// detect libraries in the shared cache and augment the nlist entries 179 /// with an on-disk dyld_shared_cache file. The process will record 180 /// the shared cache UUID so the on-disk cache can be matched or rejected 181 /// correctly. 182 void GetProcessSharedCacheUUID(lldb_private::Process *, 183 lldb::addr_t &base_addr, 184 lldb_private::UUID &uuid); 185 186 /// Intended for same-host arm device debugging where lldb will read 187 /// shared cache libraries out of its own memory instead of the remote 188 /// process' memory as an optimization. If lldb's shared cache UUID 189 /// does not match the process' shared cache UUID, this optimization 190 /// should not be used. 191 void GetLLDBSharedCacheUUID(lldb::addr_t &base_addir, lldb_private::UUID &uuid); 192 193 lldb_private::Section *GetMachHeaderSection(); 194 195 lldb::addr_t CalculateSectionLoadAddressForMemoryImage( 196 lldb::addr_t mach_header_load_address, 197 const lldb_private::Section *mach_header_section, 198 const lldb_private::Section *section); 199 200 lldb_private::UUID 201 GetSharedCacheUUID(lldb_private::FileSpec dyld_shared_cache, 202 const lldb::ByteOrder byte_order, 203 const uint32_t addr_byte_size); 204 205 size_t ParseSymtab(); 206 207 typedef lldb_private::RangeVector<uint32_t, uint32_t, 8> EncryptedFileRanges; 208 EncryptedFileRanges GetEncryptedFileRanges(); 209 210 struct SegmentParsingContext; 211 void ProcessDysymtabCommand(const llvm::MachO::load_command &load_cmd, 212 lldb::offset_t offset); 213 void ProcessSegmentCommand(const llvm::MachO::load_command &load_cmd, 214 lldb::offset_t offset, uint32_t cmd_idx, 215 SegmentParsingContext &context); 216 void SanitizeSegmentCommand(llvm::MachO::segment_command_64 &seg_cmd, 217 uint32_t cmd_idx); 218 219 bool SectionIsLoadable(const lldb_private::Section *section); 220 221 /// A corefile may include metadata about all of the binaries that were 222 /// present in the process when the corefile was taken. This is only 223 /// implemented for Mach-O files for now; we'll generalize it when we 224 /// have other systems that can include the same. 225 struct MachOCorefileImageEntry { 226 std::string filename; 227 lldb_private::UUID uuid; 228 lldb::addr_t load_address = LLDB_INVALID_ADDRESS; 229 lldb::addr_t slide = 0; 230 bool currently_executing = false; 231 std::vector<std::tuple<lldb_private::ConstString, lldb::addr_t>> 232 segment_load_addresses; 233 }; 234 235 struct LCNoteEntry { LCNoteEntryLCNoteEntry236 LCNoteEntry(uint32_t addr_byte_size, lldb::ByteOrder byte_order) 237 : payload(lldb_private::Stream::eBinary, addr_byte_size, byte_order) {} 238 239 std::string name; 240 lldb::addr_t payload_file_offset = 0; 241 lldb_private::StreamString payload; 242 }; 243 244 struct MachOCorefileAllImageInfos { 245 std::vector<MachOCorefileImageEntry> all_image_infos; IsValidMachOCorefileAllImageInfos246 bool IsValid() { return all_image_infos.size() > 0; } 247 }; 248 249 /// Get the list of binary images that were present in the process 250 /// when the corefile was produced. 251 /// \return 252 /// The MachOCorefileAllImageInfos object returned will have 253 /// IsValid() == false if the information is unavailable. 254 MachOCorefileAllImageInfos GetCorefileAllImageInfos(); 255 256 llvm::MachO::mach_header m_header; 257 static lldb_private::ConstString GetSegmentNameTEXT(); 258 static lldb_private::ConstString GetSegmentNameDATA(); 259 static lldb_private::ConstString GetSegmentNameDATA_DIRTY(); 260 static lldb_private::ConstString GetSegmentNameDATA_CONST(); 261 static lldb_private::ConstString GetSegmentNameOBJC(); 262 static lldb_private::ConstString GetSegmentNameLINKEDIT(); 263 static lldb_private::ConstString GetSegmentNameDWARF(); 264 static lldb_private::ConstString GetSectionNameEHFrame(); 265 266 llvm::MachO::dysymtab_command m_dysymtab; 267 std::vector<llvm::MachO::segment_command_64> m_mach_segments; 268 std::vector<llvm::MachO::section_64> m_mach_sections; 269 llvm::Optional<llvm::VersionTuple> m_min_os_version; 270 llvm::Optional<llvm::VersionTuple> m_sdk_versions; 271 typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray; 272 lldb_private::Address m_entry_point_address; 273 FileRangeArray m_thread_context_offsets; 274 lldb::offset_t m_linkedit_original_offset = 0; 275 lldb::addr_t m_text_address = LLDB_INVALID_ADDRESS; 276 bool m_thread_context_offsets_valid; 277 lldb_private::FileSpecList m_reexported_dylibs; 278 bool m_allow_assembly_emulation_unwind_plans; 279 }; 280 281 #endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_MACH_O_OBJECTFILEMACHO_H 282