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