Coverage Report

Created: 2022-01-22 13:19

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
Line
Count
Source (jump to first uncovered line)
1
//===-- DynamicLoaderMacOSXDYLD.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
// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
10
// watchOS / BridgeOS)
11
// platforms earlier than 2016, where lldb would read the "dyld_all_image_infos"
12
// dyld internal structure to understand where things were loaded and the
13
// solib loaded/unloaded notification function we put a breakpoint on gives us
14
// an array of (load address, mod time, file path) tuples.
15
//
16
// As of late 2016, the new DynamicLoaderMacOS plugin should be used, which uses
17
// dyld SPI functions to get the same information without reading internal dyld
18
// data structures.
19
20
#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOSXDYLD_H
21
#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOSXDYLD_H
22
23
#include <mutex>
24
#include <vector>
25
26
#include "lldb/Host/SafeMachO.h"
27
#include "lldb/Target/DynamicLoader.h"
28
#include "lldb/Target/Process.h"
29
#include "lldb/Utility/FileSpec.h"
30
#include "lldb/Utility/StructuredData.h"
31
#include "lldb/Utility/UUID.h"
32
33
#include "DynamicLoaderDarwin.h"
34
35
class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin {
36
public:
37
  DynamicLoaderMacOSXDYLD(lldb_private::Process *process);
38
39
  ~DynamicLoaderMacOSXDYLD() override;
40
41
  // Static Functions
42
  static void Initialize();
43
44
  static void Terminate();
45
46
3.45k
  static llvm::StringRef GetPluginNameStatic() { return "macosx-dyld"; }
47
48
  static llvm::StringRef GetPluginDescriptionStatic();
49
50
  static lldb_private::DynamicLoader *
51
  CreateInstance(lldb_private::Process *process, bool force);
52
53
  /// Called after attaching a process.
54
  ///
55
  /// Allow DynamicLoader plug-ins to execute some code after
56
  /// attaching to a process.
57
  bool ProcessDidExec() override;
58
59
  lldb_private::Status CanLoadImage() override;
60
61
  bool GetSharedCacheInformation(
62
      lldb::addr_t &base_address, lldb_private::UUID &uuid,
63
      lldb_private::LazyBool &using_shared_cache,
64
      lldb_private::LazyBool &private_shared_cache) override;
65
66
  // PluginInterface protocol
67
0
  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
68
69
  bool IsFullyInitialized() override;
70
71
protected:
72
  void PutToLog(lldb_private::Log *log) const;
73
74
  void DoInitialImageFetch() override;
75
76
  bool NeedToDoInitialImageFetch() override;
77
78
  bool DidSetNotificationBreakpoint() override;
79
80
  void DoClear() override;
81
82
  bool ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr);
83
84
  static bool
85
  NotifyBreakpointHit(void *baton,
86
                      lldb_private::StoppointCallbackContext *context,
87
                      lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
88
89
  uint32_t AddrByteSize();
90
91
  bool ReadMachHeader(lldb::addr_t addr, llvm::MachO::mach_header *header,
92
                      lldb_private::DataExtractor *load_command_data);
93
94
  uint32_t ParseLoadCommands(const lldb_private::DataExtractor &data,
95
                             ImageInfo &dylib_info,
96
                             lldb_private::FileSpec *lc_id_dylinker);
97
98
  struct DYLDAllImageInfos {
99
    uint32_t version = 0;
100
    uint32_t dylib_info_count = 0;                            // Version >= 1
101
    lldb::addr_t dylib_info_addr = LLDB_INVALID_ADDRESS;      // Version >= 1
102
    lldb::addr_t notification = LLDB_INVALID_ADDRESS;         // Version >= 1
103
    bool processDetachedFromSharedRegion = false;             // Version >= 1
104
    bool libSystemInitialized = false;                        // Version >= 2
105
    lldb::addr_t dyldImageLoadAddress = LLDB_INVALID_ADDRESS; // Version >= 2
106
107
9
    DYLDAllImageInfos() = default;
108
109
0
    void Clear() {
110
0
      version = 0;
111
0
      dylib_info_count = 0;
112
0
      dylib_info_addr = LLDB_INVALID_ADDRESS;
113
0
      notification = LLDB_INVALID_ADDRESS;
114
0
      processDetachedFromSharedRegion = false;
115
0
      libSystemInitialized = false;
116
0
      dyldImageLoadAddress = LLDB_INVALID_ADDRESS;
117
0
    }
118
119
0
    bool IsValid() const { return version >= 1 && version <= 6; }
120
  };
121
122
  static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
123
124
  bool SetNotificationBreakpoint() override;
125
126
  void ClearNotificationBreakpoint() override;
127
128
  // There is a little tricky bit where you might initially attach while dyld is
129
  // updating
130
  // the all_image_infos, and you can't read the infos, so you have to continue
131
  // and pick it
132
  // up when you hit the update breakpoint.  At that point, you need to run this
133
  // initialize
134
  // function, but when you do it that way you DON'T need to do the extra work
135
  // you would at
136
  // the breakpoint.
137
  // So this function will only do actual work if the image infos haven't been
138
  // read yet.
139
  // If it does do any work, then it will return true, and false otherwise.
140
  // That way you can
141
  // call it in the breakpoint action, and if it returns true you're done.
142
  bool InitializeFromAllImageInfos();
143
144
  bool ReadAllImageInfosStructure();
145
146
  bool AddModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr,
147
                                        uint32_t image_infos_count);
148
149
  bool RemoveModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr,
150
                                           uint32_t image_infos_count);
151
152
  void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
153
                                             uint32_t infos_count,
154
                                             bool update_executable);
155
156
  bool ReadImageInfos(lldb::addr_t image_infos_addr, uint32_t image_infos_count,
157
                      ImageInfo::collection &image_infos);
158
159
  lldb::addr_t m_dyld_all_image_infos_addr;
160
  DYLDAllImageInfos m_dyld_all_image_infos;
161
  uint32_t m_dyld_all_image_infos_stop_id;
162
  lldb::user_id_t m_break_id;
163
  mutable std::recursive_mutex m_mutex;
164
  bool m_process_image_addr_is_all_images_infos;
165
166
private:
167
  DynamicLoaderMacOSXDYLD(const DynamicLoaderMacOSXDYLD &) = delete;
168
  const DynamicLoaderMacOSXDYLD &
169
  operator=(const DynamicLoaderMacOSXDYLD &) = delete;
170
};
171
172
#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOSXDYLD_H