1 //===-- DynamicLoaderDarwinKernel.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_DynamicLoaderDarwinKernel_h_ 11 #define liblldb_DynamicLoaderDarwinKernel_h_ 12 13 // C Includes 14 // C++ Includes 15 #include <map> 16 #include <vector> 17 #include <string> 18 19 // Other libraries and framework includes 20 #include "llvm/Support/MachO.h" 21 22 #include "lldb/Target/DynamicLoader.h" 23 #include "lldb/Host/FileSpec.h" 24 #include "lldb/Host/TimeValue.h" 25 #include "lldb/Core/UUID.h" 26 #include "lldb/Host/Mutex.h" 27 #include "lldb/Target/Process.h" 28 29 class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader 30 { 31 public: 32 //------------------------------------------------------------------ 33 // Static Functions 34 //------------------------------------------------------------------ 35 static void 36 Initialize(); 37 38 static void 39 Terminate(); 40 41 static const char * 42 GetPluginNameStatic(); 43 44 static const char * 45 GetPluginDescriptionStatic(); 46 47 static lldb_private::DynamicLoader * 48 CreateInstance (lldb_private::Process *process, bool force); 49 50 DynamicLoaderDarwinKernel (lldb_private::Process *process); 51 52 virtual 53 ~DynamicLoaderDarwinKernel (); 54 //------------------------------------------------------------------ 55 /// Called after attaching a process. 56 /// 57 /// Allow DynamicLoader plug-ins to execute some code after 58 /// attaching to a process. 59 //------------------------------------------------------------------ 60 virtual void 61 DidAttach (); 62 63 virtual void 64 DidLaunch (); 65 66 virtual lldb::ThreadPlanSP 67 GetStepThroughTrampolinePlan (lldb_private::Thread &thread, 68 bool stop_others); 69 70 virtual lldb_private::Error 71 CanLoadImage (); 72 73 //------------------------------------------------------------------ 74 // PluginInterface protocol 75 //------------------------------------------------------------------ 76 virtual const char * 77 GetPluginName(); 78 79 virtual const char * 80 GetShortPluginName(); 81 82 virtual uint32_t 83 GetPluginVersion(); 84 85 protected: 86 void 87 PrivateInitialize (lldb_private::Process *process); 88 89 void 90 PrivateProcessStateChanged (lldb_private::Process *process, 91 lldb::StateType state); 92 93 void 94 UpdateIfNeeded(); 95 96 void 97 LoadKernelModuleIfNeeded (); 98 99 void 100 Clear (bool clear_process); 101 102 void 103 PutToLog (lldb_private::Log *log) const; 104 105 static bool 106 BreakpointHitCallback (void *baton, 107 lldb_private::StoppointCallbackContext *context, 108 lldb::user_id_t break_id, 109 lldb::user_id_t break_loc_id); 110 111 bool 112 BreakpointHit (lldb_private::StoppointCallbackContext *context, 113 lldb::user_id_t break_id, 114 lldb::user_id_t break_loc_id); 115 uint32_t 116 GetAddrByteSize() 117 { 118 return m_kernel.GetAddressByteSize(); 119 } 120 121 static lldb::ByteOrder 122 GetByteOrderFromMagic (uint32_t magic); 123 124 enum 125 { 126 KERNEL_MODULE_MAX_NAME = 64u, 127 // Versions less than 2 didn't have an entry size, 128 // they had a 64 bit name, 16 byte UUID, 8 byte addr, 129 // 8 byte size, 8 byte version, 4 byte load tag, and 130 // 4 byte flags 131 KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u 132 }; 133 134 struct OSKextLoadedKextSummary 135 { 136 char name[KERNEL_MODULE_MAX_NAME]; 137 lldb::ModuleSP module_sp; 138 uint32_t load_process_stop_id; 139 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros 140 lldb_private::Address so_address; // The section offset address for this kext in case it can be read from object files 141 uint64_t address; 142 uint64_t size; 143 uint64_t version; 144 uint32_t load_tag; 145 uint32_t flags; 146 uint64_t reference_list; 147 148 OSKextLoadedKextSummary() : 149 module_sp (), 150 load_process_stop_id (UINT32_MAX), 151 uuid (), 152 so_address (), 153 address (LLDB_INVALID_ADDRESS), 154 size (0), 155 version (0), 156 load_tag (0), 157 flags (0), 158 reference_list (0) 159 { 160 name[0] = '\0'; 161 } 162 163 bool 164 IsLoaded () 165 { 166 return load_process_stop_id != UINT32_MAX; 167 } 168 169 void 170 Clear (bool load_cmd_data_only) 171 { 172 if (!load_cmd_data_only) 173 { 174 so_address.Clear(); 175 address = LLDB_INVALID_ADDRESS; 176 size = 0; 177 version = 0; 178 load_tag = 0; 179 flags = 0; 180 reference_list = 0; 181 name[0] = '\0'; 182 } 183 module_sp.reset(); 184 load_process_stop_id = UINT32_MAX; 185 } 186 187 bool 188 LoadImageAtFileAddress (lldb_private::Process *process); 189 190 bool 191 LoadImageUsingMemoryModule (lldb_private::Process *process); 192 193 // bool 194 // operator == (const OSKextLoadedKextSummary& rhs) const 195 // { 196 // return address == rhs.address 197 // && size == rhs.size 198 // //&& module_sp.get() == rhs.module_sp.get() 199 // && uuid == rhs.uuid 200 // && version == rhs.version 201 // && load_tag == rhs.load_tag 202 // && flags == rhs.flags 203 // && reference_list == rhs.reference_list 204 // && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0; 205 // } 206 // 207 bool 208 UUIDValid() const 209 { 210 return uuid.IsValid(); 211 } 212 213 uint32_t 214 GetAddressByteSize (); 215 216 lldb::ByteOrder 217 GetByteOrder(); 218 219 lldb_private::ArchSpec 220 GetArchitecture () const; 221 222 void 223 PutToLog (lldb_private::Log *log) const; 224 225 typedef std::vector<OSKextLoadedKextSummary> collection; 226 typedef collection::iterator iterator; 227 typedef collection::const_iterator const_iterator; 228 }; 229 230 struct OSKextLoadedKextSummaryHeader 231 { 232 uint32_t version; 233 uint32_t entry_size; 234 uint32_t entry_count; 235 lldb::addr_t image_infos_addr; 236 237 OSKextLoadedKextSummaryHeader() : 238 version (0), 239 entry_size (0), 240 entry_count (0), 241 image_infos_addr (LLDB_INVALID_ADDRESS) 242 { 243 } 244 245 uint32_t 246 GetSize() 247 { 248 switch (version) 249 { 250 case 0: return 0; // Can't know the size without a valid version 251 case 1: return 8; // Version 1 only had a version + entry_count 252 default: break; 253 } 254 // Version 2 and above has version, entry_size, entry_count, and reserved 255 return 16; 256 } 257 258 void 259 Clear() 260 { 261 version = 0; 262 entry_size = 0; 263 entry_count = 0; 264 image_infos_addr = LLDB_INVALID_ADDRESS; 265 } 266 267 bool 268 IsValid() const 269 { 270 return version >= 1 || version <= 2; 271 } 272 }; 273 274 void 275 RegisterNotificationCallbacks(); 276 277 void 278 UnregisterNotificationCallbacks(); 279 280 void 281 SetNotificationBreakpointIfNeeded (); 282 283 bool 284 ReadAllKextSummaries (); 285 286 bool 287 ReadKextSummaryHeader (); 288 289 bool 290 ParseKextSummaries (const lldb_private::Address &kext_summary_addr, 291 uint32_t count); 292 293 bool 294 AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos); 295 296 void 297 UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos, 298 uint32_t infos_count, 299 bool update_executable); 300 301 uint32_t 302 ReadKextSummaries (const lldb_private::Address &kext_summary_addr, 303 uint32_t image_infos_count, 304 OSKextLoadedKextSummary::collection &image_infos); 305 306 OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used 307 lldb_private::Address m_kext_summary_header_ptr_addr; 308 lldb_private::Address m_kext_summary_header_addr; 309 OSKextLoadedKextSummaryHeader m_kext_summary_header; 310 OSKextLoadedKextSummary::collection m_kext_summaries; 311 mutable lldb_private::Mutex m_mutex; 312 lldb::user_id_t m_break_id; 313 314 private: 315 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel); 316 }; 317 318 #endif // liblldb_DynamicLoaderDarwinKernel_h_ 319