Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
Line
Count
Source (jump to first uncovered line)
1
//===-- DynamicLoaderDarwin.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_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H
10
#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H
11
12
#include <map>
13
#include <mutex>
14
#include <vector>
15
16
#include "lldb/Host/SafeMachO.h"
17
#include "lldb/Target/DynamicLoader.h"
18
#include "lldb/Target/Process.h"
19
#include "lldb/Utility/FileSpec.h"
20
#include "lldb/Utility/StructuredData.h"
21
#include "lldb/Utility/UUID.h"
22
23
#include "llvm/ADT/Triple.h"
24
25
namespace lldb_private {
26
27
class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
28
public:
29
  DynamicLoaderDarwin(lldb_private::Process *process);
30
31
  ~DynamicLoaderDarwin() override;
32
33
  /// Called after attaching a process.
34
  ///
35
  /// Allow DynamicLoader plug-ins to execute some code after
36
  /// attaching to a process.
37
  void DidAttach() override;
38
39
  void DidLaunch() override;
40
41
  lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
42
                                                  bool stop_others) override;
43
44
  void FindEquivalentSymbols(
45
      lldb_private::Symbol *original_symbol,
46
      lldb_private::ModuleList &module_list,
47
      lldb_private::SymbolContextList &equivalent_symbols) override;
48
49
  lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
50
                                  const lldb::ThreadSP thread,
51
                                  lldb::addr_t tls_file_addr) override;
52
53
  bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
54
55
  virtual void DoInitialImageFetch() = 0;
56
57
  virtual bool NeedToDoInitialImageFetch() = 0;
58
59
protected:
60
  void PrivateInitialize(lldb_private::Process *process);
61
62
  void PrivateProcessStateChanged(lldb_private::Process *process,
63
                                  lldb::StateType state);
64
65
  void Clear(bool clear_process);
66
67
  // Clear method for classes derived from this one
68
  virtual void DoClear() = 0;
69
70
  void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);
71
72
  lldb::ModuleSP GetDYLDModule();
73
74
  class Segment {
75
  public:
76
420k
    Segment() : name() {}
77
78
    lldb_private::ConstString name;
79
    lldb::addr_t vmaddr = LLDB_INVALID_ADDRESS;
80
    lldb::addr_t vmsize = 0;
81
    lldb::addr_t fileoff = 0;
82
    lldb::addr_t filesize = 0;
83
    uint32_t maxprot = 0;
84
    uint32_t initprot = 0;
85
    uint32_t nsects = 0;
86
    uint32_t flags = 0;
87
88
0
    bool operator==(const Segment &rhs) const {
89
0
      return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
90
0
    }
91
92
    void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;
93
  };
94
95
  struct ImageInfo {
96
    /// Address of mach header for this dylib.
97
    lldb::addr_t address = LLDB_INVALID_ADDRESS;
98
    /// The amount to slide all segments by if there is a global
99
    /// slide.
100
    lldb::addr_t slide = 0;
101
    /// Modification date for this dylib.
102
    lldb::addr_t mod_date = 0;
103
    /// Resolved path for this dylib.
104
    lldb_private::FileSpec file_spec;
105
    /// UUID for this dylib if it has one, else all zeros.
106
    lldb_private::UUID uuid;
107
    /// The mach header for this image.
108
    llvm::MachO::mach_header header;
109
    /// All segment vmaddr and vmsize pairs for this executable (from
110
    /// memory of inferior).
111
    std::vector<Segment> segments;
112
    /// The process stop ID that the sections for this image were
113
    /// loaded.
114
    uint32_t load_stop_id = 0;
115
    /// LC_VERSION_MIN_... load command os type.
116
    llvm::Triple::OSType os_type = llvm::Triple::OSType::UnknownOS;
117
    /// LC_VERSION_MIN_... load command os environment.
118
    llvm::Triple::EnvironmentType os_env =
119
        llvm::Triple::EnvironmentType::UnknownEnvironment;
120
    /// LC_VERSION_MIN_... SDK.
121
    std::string min_version_os_sdk;
122
123
138k
    ImageInfo() = default;
124
125
2.60k
    void Clear(bool load_cmd_data_only) {
126
2.60k
      if (!load_cmd_data_only) {
127
2.60k
        address = LLDB_INVALID_ADDRESS;
128
2.60k
        slide = 0;
129
2.60k
        mod_date = 0;
130
2.60k
        file_spec.Clear();
131
2.60k
        ::memset(&header, 0, sizeof(header));
132
2.60k
      }
133
2.60k
      uuid.Clear();
134
2.60k
      segments.clear();
135
2.60k
      load_stop_id = 0;
136
2.60k
      os_type = llvm::Triple::OSType::UnknownOS;
137
2.60k
      os_env = llvm::Triple::EnvironmentType::UnknownEnvironment;
138
2.60k
      min_version_os_sdk.clear();
139
2.60k
    }
140
141
0
    bool operator==(const ImageInfo &rhs) const {
142
0
      return address == rhs.address && slide == rhs.slide &&
143
0
             mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
144
0
             uuid == rhs.uuid &&
145
0
             memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
146
0
             segments == rhs.segments && os_type == rhs.os_type &&
147
0
             os_env == rhs.os_env;
148
0
    }
149
150
0
    bool UUIDValid() const { return uuid.IsValid(); }
151
152
0
    uint32_t GetAddressByteSize() {
153
0
      if (header.cputype) {
154
0
        if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
155
0
          return 8;
156
0
        else
157
0
          return 4;
158
0
      }
159
0
      return 0;
160
0
    }
161
162
    lldb_private::ArchSpec GetArchitecture() const;
163
164
    const Segment *FindSegment(lldb_private::ConstString name) const;
165
166
    void PutToLog(lldb_private::Log *log) const;
167
168
    typedef std::vector<ImageInfo> collection;
169
    typedef collection::iterator iterator;
170
    typedef collection::const_iterator const_iterator;
171
  };
172
173
  bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);
174
175
  bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
176
177
  lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
178
                                              bool can_create,
179
                                              bool *did_create_ptr);
180
181
  void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);
182
183
  void UnloadAllImages();
184
185
  virtual bool SetNotificationBreakpoint() = 0;
186
187
  virtual void ClearNotificationBreakpoint() = 0;
188
189
  virtual bool DidSetNotificationBreakpoint() = 0;
190
191
  typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
192
  typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
193
194
14
  std::recursive_mutex &GetMutex() const { return m_mutex; }
195
196
  lldb::ModuleSP GetPThreadLibraryModule();
197
198
  lldb_private::Address GetPthreadSetSpecificAddress();
199
200
  bool JSONImageInformationIntoImageInfo(
201
      lldb_private::StructuredData::ObjectSP image_details,
202
      ImageInfo::collection &image_infos);
203
204
  // If image_infos contains / may contain dyld or executable image, call this
205
  // method
206
  // to keep our internal record keeping of the special binaries up-to-date.
207
  void
208
  UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos);
209
210
  // if image_info is a dyld binary, call this method
211
  void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);
212
213
  // If image_infos contains / may contain executable image, call this method
214
  // to keep our internal record keeping of the special dyld binary up-to-date.
215
  void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);
216
217
  bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);
218
219
  // Whether we should use the new dyld SPI to get shared library information,
220
  // or read
221
  // it directly out of the dyld_all_image_infos.  Whether we use the (newer)
222
  // DynamicLoaderMacOS
223
  // plugin or the (older) DynamicLoaderMacOSX plugin.
224
  static bool UseDYLDSPI(lldb_private::Process *process);
225
226
  lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)
227
                                   // matches the process
228
  lldb::ModuleWP m_libpthread_module_wp;
229
  lldb_private::Address m_pthread_getspecific_addr;
230
  ThreadIDToTLSMap m_tid_to_tls_map;
231
  ImageInfo::collection
232
      m_dyld_image_infos;              // Current shared libraries information
233
  uint32_t m_dyld_image_infos_stop_id; // The process stop ID that
234
                                       // "m_dyld_image_infos" is valid for
235
  ImageInfo m_dyld;
236
  mutable std::recursive_mutex m_mutex;
237
238
private:
239
  DynamicLoaderDarwin(const DynamicLoaderDarwin &) = delete;
240
  const DynamicLoaderDarwin &operator=(const DynamicLoaderDarwin &) = delete;
241
};
242
243
} // namespace lldb_private
244
245
#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H