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