Coverage Report

Created: 2022-01-18 06:27

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