1 //===-- DynamicLoaderFreeBSDKernel.cpp 2 //------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Breakpoint/StoppointCallbackContext.h" 11 #include "lldb/Core/Debugger.h" 12 #include "lldb/Core/Module.h" 13 #include "lldb/Core/ModuleSpec.h" 14 #include "lldb/Core/PluginManager.h" 15 #include "lldb/Core/Section.h" 16 #include "lldb/Host/StreamFile.h" 17 #include "lldb/Interpreter/OptionValueProperties.h" 18 #include "lldb/Symbol/ObjectFile.h" 19 #include "lldb/Target/OperatingSystem.h" 20 #include "lldb/Target/RegisterContext.h" 21 #include "lldb/Target/StackFrame.h" 22 #include "lldb/Target/Target.h" 23 #include "lldb/Target/Thread.h" 24 #include "lldb/Target/ThreadPlanRunToAddress.h" 25 #include "lldb/Utility/DataBuffer.h" 26 #include "lldb/Utility/DataBufferHeap.h" 27 #include "lldb/Utility/LLDBLog.h" 28 #include "lldb/Utility/Log.h" 29 #include "lldb/Utility/State.h" 30 31 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" 32 33 #include "DynamicLoaderFreeBSDKernel.h" 34 #include <memory> 35 #include <mutex> 36 37 using namespace lldb; 38 using namespace lldb_private; 39 40 LLDB_PLUGIN_DEFINE(DynamicLoaderFreeBSDKernel) 41 42 void DynamicLoaderFreeBSDKernel::Initialize() { 43 PluginManager::RegisterPlugin(GetPluginNameStatic(), 44 GetPluginDescriptionStatic(), CreateInstance, 45 DebuggerInit); 46 } 47 48 void DynamicLoaderFreeBSDKernel::Terminate() { 49 PluginManager::UnregisterPlugin(CreateInstance); 50 } 51 52 llvm::StringRef DynamicLoaderFreeBSDKernel::GetPluginDescriptionStatic() { 53 return "The Dynamic Loader Plugin For FreeBSD Kernel"; 54 } 55 56 static bool is_kernel(Module *module) { 57 if (!module) 58 return false; 59 60 ObjectFile *objfile = module->GetObjectFile(); 61 if (!objfile) 62 return false; 63 if (objfile->GetType() != ObjectFile::eTypeExecutable) 64 return false; 65 if (objfile->GetStrata() != ObjectFile::eStrataUnknown && 66 objfile->GetStrata() != ObjectFile::eStrataKernel) 67 return false; 68 69 return true; 70 } 71 72 static bool is_kmod(Module *module) { 73 if (!module) 74 return false; 75 if (!module->GetObjectFile()) 76 return false; 77 ObjectFile *objfile = module->GetObjectFile(); 78 if (objfile->GetType() != ObjectFile::eTypeObjectFile && 79 objfile->GetType() != ObjectFile::eTypeSharedLibrary) 80 return false; 81 82 return true; 83 } 84 85 static bool is_reloc(Module *module) { 86 if (!module) 87 return false; 88 if (!module->GetObjectFile()) 89 return false; 90 ObjectFile *objfile = module->GetObjectFile(); 91 if (objfile->GetType() != ObjectFile::eTypeObjectFile) 92 return false; 93 94 return true; 95 } 96 97 // Instantiate Function of the FreeBSD Kernel Dynamic Loader Plugin called when 98 // Register the Plugin 99 DynamicLoader * 100 DynamicLoaderFreeBSDKernel::CreateInstance(lldb_private::Process *process, 101 bool force) { 102 // Check the environment when the plugin is not force loaded 103 Module *exec = process->GetTarget().GetExecutableModulePointer(); 104 if (exec && !is_kernel(exec)) { 105 return nullptr; 106 } 107 if (!force) { 108 // Check if the target is kernel 109 const llvm::Triple &triple_ref = 110 process->GetTarget().GetArchitecture().GetTriple(); 111 if (!triple_ref.isOSFreeBSD()) { 112 return nullptr; 113 } 114 } 115 116 // At this point we have checked the target is a FreeBSD kernel and all we 117 // have to do is to find the kernel address 118 const addr_t kernel_address = FindFreeBSDKernel(process); 119 120 if (CheckForKernelImageAtAddress(process, kernel_address).IsValid()) 121 return new DynamicLoaderFreeBSDKernel(process, kernel_address); 122 123 return nullptr; 124 } 125 126 addr_t 127 DynamicLoaderFreeBSDKernel::FindFreeBSDKernel(lldb_private::Process *process) { 128 addr_t kernel_addr = process->GetImageInfoAddress(); 129 if (kernel_addr == LLDB_INVALID_ADDRESS) 130 kernel_addr = FindKernelAtLoadAddress(process); 131 return kernel_addr; 132 } 133 134 // Get the kernel address if the kernel is not loaded with a slide 135 addr_t DynamicLoaderFreeBSDKernel::FindKernelAtLoadAddress( 136 lldb_private::Process *process) { 137 Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 138 139 if (!is_kernel(exe_module)) 140 return LLDB_INVALID_ADDRESS; 141 142 ObjectFile *exe_objfile = exe_module->GetObjectFile(); 143 144 if (!exe_objfile->GetBaseAddress().IsValid()) 145 return LLDB_INVALID_ADDRESS; 146 147 if (CheckForKernelImageAtAddress( 148 process, exe_objfile->GetBaseAddress().GetFileAddress()) 149 .IsValid()) 150 return exe_objfile->GetBaseAddress().GetFileAddress(); 151 152 return LLDB_INVALID_ADDRESS; 153 } 154 155 // Read ELF header from memry and return 156 bool DynamicLoaderFreeBSDKernel::ReadELFHeader(Process *process, 157 lldb::addr_t addr, 158 llvm::ELF::Elf32_Ehdr &header, 159 bool *read_error) { 160 Status error; 161 if (read_error) 162 *read_error = false; 163 164 if (process->ReadMemory(addr, &header, sizeof(header), error) != 165 sizeof(header)) { 166 if (read_error) 167 *read_error = true; 168 return false; 169 } 170 171 if (!header.checkMagic()) 172 return false; 173 174 return true; 175 } 176 177 // Check the correctness of Kernel and return UUID 178 lldb_private::UUID DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress( 179 Process *process, lldb::addr_t addr, bool *read_error) { 180 Log *log = GetLog(LLDBLog::DynamicLoader); 181 182 if (addr == LLDB_INVALID_ADDRESS) { 183 if (read_error) 184 *read_error = true; 185 return UUID(); 186 } 187 188 LLDB_LOGF(log, 189 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: " 190 "looking for kernel binary at 0x%" PRIx64, 191 addr); 192 193 llvm::ELF::Elf32_Ehdr header; 194 if (!ReadELFHeader(process, addr, header)) { 195 *read_error = true; 196 return UUID(); 197 } 198 199 // Check header type 200 if (header.e_type != llvm::ELF::ET_EXEC) 201 return UUID(); 202 203 ModuleSP memory_module_sp = 204 process->ReadModuleFromMemory(FileSpec("temp_freebsd_kernel"), addr); 205 206 if (!memory_module_sp.get()) { 207 *read_error = true; 208 return UUID(); 209 } 210 211 ObjectFile *exe_objfile = memory_module_sp->GetObjectFile(); 212 if (exe_objfile == nullptr) { 213 LLDB_LOGF(log, 214 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress " 215 "found a binary at 0x%" PRIx64 216 " but could not create an object file from memory", 217 addr); 218 return UUID(); 219 } 220 221 // In here, I should check is_kernel for memory_module_sp 222 // However, the ReadModuleFromMemory reads wrong section so that this check 223 // will failed 224 ArchSpec kernel_arch(llvm::ELF::convertEMachineToArchName(header.e_machine)); 225 226 if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch)) 227 process->GetTarget().SetArchitecture(kernel_arch); 228 229 std::string uuid_str; 230 if (memory_module_sp->GetUUID().IsValid()) { 231 uuid_str = "with UUID "; 232 uuid_str += memory_module_sp->GetUUID().GetAsString(); 233 } else { 234 uuid_str = "and no LC_UUID found in load commands "; 235 } 236 LLDB_LOGF(log, 237 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: " 238 "kernel binary image found at 0x%" PRIx64 " with arch '%s' %s", 239 addr, kernel_arch.GetTriple().str().c_str(), uuid_str.c_str()); 240 241 return memory_module_sp->GetUUID(); 242 } 243 244 void DynamicLoaderFreeBSDKernel::DebuggerInit( 245 lldb_private::Debugger &debugger) {} 246 247 DynamicLoaderFreeBSDKernel::DynamicLoaderFreeBSDKernel(Process *process, 248 addr_t kernel_address) 249 : DynamicLoader(process), m_process(process), 250 m_linker_file_list_struct_addr(LLDB_INVALID_ADDRESS), 251 m_linker_file_head_addr(LLDB_INVALID_ADDRESS), 252 m_kernel_load_address(kernel_address), m_mutex() { 253 process->SetCanRunCode(false); 254 } 255 256 DynamicLoaderFreeBSDKernel::~DynamicLoaderFreeBSDKernel() { Clear(true); } 257 258 void DynamicLoaderFreeBSDKernel::Update() { 259 LoadKernelModules(); 260 SetNotificationBreakPoint(); 261 } 262 263 // Create in memory Module at the load address 264 bool DynamicLoaderFreeBSDKernel::KModImageInfo::ReadMemoryModule( 265 lldb_private::Process *process) { 266 Log *log = GetLog(LLDBLog::DynamicLoader); 267 if (m_memory_module_sp) 268 return true; 269 if (m_load_address == LLDB_INVALID_ADDRESS) 270 return false; 271 272 FileSpec file_spec(m_name); 273 274 ModuleSP memory_module_sp; 275 276 llvm::ELF::Elf32_Ehdr elf_eheader; 277 size_t size_to_read = 512; 278 279 if (ReadELFHeader(process, m_load_address, elf_eheader)) { 280 if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32) { 281 size_to_read = sizeof(llvm::ELF::Elf32_Ehdr) + 282 elf_eheader.e_phnum * elf_eheader.e_phentsize; 283 } else if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] == 284 llvm::ELF::ELFCLASS64) { 285 llvm::ELF::Elf64_Ehdr elf_eheader; 286 Status error; 287 if (process->ReadMemory(m_load_address, &elf_eheader, sizeof(elf_eheader), 288 error) == sizeof(elf_eheader)) 289 size_to_read = sizeof(llvm::ELF::Elf64_Ehdr) + 290 elf_eheader.e_phnum * elf_eheader.e_phentsize; 291 } 292 } 293 294 memory_module_sp = 295 process->ReadModuleFromMemory(file_spec, m_load_address, size_to_read); 296 297 if (!memory_module_sp) 298 return false; 299 300 bool this_is_kernel = is_kernel(memory_module_sp.get()); 301 302 if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid()) 303 m_uuid = memory_module_sp->GetUUID(); 304 305 m_memory_module_sp = memory_module_sp; 306 m_is_kernel = this_is_kernel; 307 308 // The kernel binary is from memory 309 if (this_is_kernel) { 310 LLDB_LOGF(log, "KextImageInfo::ReadMemoryModule read the kernel binary out " 311 "of memory"); 312 313 if (memory_module_sp->GetArchitecture().IsValid()) 314 process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture()); 315 } 316 317 return true; 318 } 319 320 bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingMemoryModule( 321 lldb_private::Process *process) { 322 Log *log = GetLog(LLDBLog::DynamicLoader); 323 324 if (IsLoaded()) 325 return true; 326 327 Target &target = process->GetTarget(); 328 329 if (IsKernel() && m_uuid.IsValid()) { 330 Stream &s = target.GetDebugger().GetOutputStream(); 331 s.Printf("Kernel UUID: %s\n", m_uuid.GetAsString().c_str()); 332 s.Printf("Load Address: 0x%" PRIx64 "\n", m_load_address); 333 } 334 335 // Test if the module is loaded into the taget, 336 // maybe the module is loaded manually by user by doing target module add 337 // So that we have to create the module manually 338 if (!m_module_sp) { 339 const ModuleList &target_images = target.GetImages(); 340 m_module_sp = target_images.FindModule(m_uuid); 341 342 // Search in the file system 343 if (!m_module_sp) { 344 ModuleSpec module_spec(FileSpec(GetPath()), target.GetArchitecture()); 345 if (IsKernel()) { 346 Status error; 347 if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error, 348 true)) { 349 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) 350 m_module_sp = std::make_shared<Module>(module_spec.GetFileSpec(), 351 target.GetArchitecture()); 352 } 353 } 354 355 if (!m_module_sp) 356 m_module_sp = target.GetOrCreateModule(module_spec, true); 357 if (IsKernel() && !m_module_sp) { 358 Stream &s = target.GetDebugger().GetOutputStream(); 359 s.Printf("WARNING: Unable to locate kernel binary on the debugger " 360 "system.\n"); 361 } 362 } 363 364 if (m_module_sp) { 365 // If the file is not kernel or kmod, the target should be loaded once and 366 // don't reload again 367 if (!IsKernel() && !is_kmod(m_module_sp.get())) { 368 ModuleSP existing_module_sp = target.GetImages().FindModule(m_uuid); 369 if (existing_module_sp && 370 existing_module_sp->IsLoadedInTarget(&target)) { 371 LLDB_LOGF(log, 372 "'%s' with UUID %s is not a kmod or kernel, and is " 373 "already registered in target, not loading.", 374 m_name.c_str(), m_uuid.GetAsString().c_str()); 375 return true; 376 } 377 } 378 m_uuid = m_module_sp->GetUUID(); 379 380 // or append to the images 381 target.GetImages().AppendIfNeeded(m_module_sp, false); 382 } 383 } 384 385 // If this file is relocatable kernel module(x86_64), adjust it's 386 // section(PT_LOAD segment) and return Because the kernel module's load 387 // address is the text section. lldb cannot create full memory module upon 388 // relocatable file So what we do is to set the load address only. 389 if (is_kmod(m_module_sp.get()) && is_reloc(m_module_sp.get())) { 390 m_stop_id = process->GetStopID(); 391 bool changed = false; 392 m_module_sp->SetLoadAddress(target, m_load_address, true, changed); 393 return true; 394 } 395 396 if (m_module_sp) 397 ReadMemoryModule(process); 398 399 // Calculate the slides of in memory module 400 if (!m_memory_module_sp || !m_module_sp) { 401 m_module_sp.reset(); 402 return false; 403 } 404 405 ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile(); 406 ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile(); 407 408 if (!ondisk_object_file || !memory_object_file) 409 m_module_sp.reset(); 410 411 // Find the slide address 412 addr_t fixed_slide = LLDB_INVALID_ADDRESS; 413 if (llvm::dyn_cast<ObjectFileELF>(memory_object_file)) { 414 addr_t load_address = memory_object_file->GetBaseAddress().GetFileAddress(); 415 416 if (load_address != LLDB_INVALID_ADDRESS && 417 m_load_address != load_address) { 418 fixed_slide = m_load_address - load_address; 419 LLDB_LOGF(log, 420 "kmod %s in-memory LOAD vmaddr is not correct, using a " 421 "fixed slide of 0x%" PRIx64, 422 m_name.c_str(), fixed_slide); 423 } 424 } 425 426 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList(); 427 SectionList *memory_section_list = memory_object_file->GetSectionList(); 428 429 if (memory_section_list && ondisk_object_file) { 430 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize(); 431 uint32_t num_load_sections = 0; 432 433 for (uint32_t section_idx = 0; section_idx < num_ondisk_sections; 434 ++section_idx) { 435 SectionSP on_disk_section_sp = 436 ondisk_section_list->GetSectionAtIndex(section_idx); 437 438 if (!on_disk_section_sp) 439 continue; 440 if (fixed_slide != LLDB_INVALID_ADDRESS) { 441 target.SetSectionLoadAddress(on_disk_section_sp, 442 on_disk_section_sp->GetFileAddress() + 443 fixed_slide); 444 445 } else { 446 const Section *memory_section = 447 memory_section_list 448 ->FindSectionByName(on_disk_section_sp->GetName()) 449 .get(); 450 if (memory_section) { 451 target.SetSectionLoadAddress(on_disk_section_sp, 452 memory_section->GetFileAddress()); 453 ++num_load_sections; 454 } 455 } 456 } 457 458 if (num_load_sections) 459 m_stop_id = process->GetStopID(); 460 else 461 m_module_sp.reset(); 462 } else { 463 m_module_sp.reset(); 464 } 465 466 if (IsLoaded() && m_module_sp && IsKernel()) { 467 Stream &s = target.GetDebugger().GetOutputStream(); 468 ObjectFile *kernel_object_file = m_module_sp->GetObjectFile(); 469 if (kernel_object_file) { 470 addr_t file_address = 471 kernel_object_file->GetBaseAddress().GetFileAddress(); 472 if (m_load_address != LLDB_INVALID_ADDRESS && 473 file_address != LLDB_INVALID_ADDRESS) { 474 s.Printf("Kernel slide 0x%" PRIx64 " in memory.\n", 475 m_load_address - file_address); 476 s.Printf("Loaded kernel file %s\n", 477 m_module_sp->GetFileSpec().GetPath().c_str()); 478 } 479 } 480 s.Flush(); 481 } 482 483 return IsLoaded(); 484 } 485 486 // This function is work for kernel file, others it wil reset load address and 487 // return false 488 bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingFileAddress( 489 lldb_private::Process *process) { 490 if (IsLoaded()) 491 return true; 492 493 if (m_module_sp) { 494 bool changed = false; 495 if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed)) 496 m_stop_id = process->GetStopID(); 497 } 498 499 return false; 500 } 501 502 // Get the head of found_list 503 bool DynamicLoaderFreeBSDKernel::ReadKmodsListHeader() { 504 std::lock_guard<decltype(m_mutex)> guard(m_mutex); 505 506 if (m_linker_file_list_struct_addr.IsValid()) { 507 // Get tqh_first struct element from linker_files 508 Status error; 509 addr_t address = m_process->ReadPointerFromMemory( 510 m_linker_file_list_struct_addr.GetLoadAddress(&m_process->GetTarget()), 511 error); 512 if (address != LLDB_INVALID_ADDRESS && error.Success()) { 513 m_linker_file_head_addr = Address(address); 514 } else { 515 m_linker_file_list_struct_addr.Clear(); 516 return false; 517 } 518 519 if (!m_linker_file_head_addr.IsValid() || 520 m_linker_file_head_addr.GetFileAddress() == 0) { 521 m_linker_file_list_struct_addr.Clear(); 522 return false; 523 } 524 } 525 return true; 526 } 527 528 // Parse Kmod info in found_list 529 bool DynamicLoaderFreeBSDKernel::ParseKmods(Address linker_files_head_addr) { 530 std::lock_guard<decltype(m_mutex)> guard(m_mutex); 531 KModImageInfo::collection_type linker_files_list; 532 Log *log = GetLog(LLDBLog::DynamicLoader); 533 534 if (!ReadAllKmods(linker_files_head_addr, linker_files_list)) 535 return false; 536 LLDB_LOGF( 537 log, 538 "Kmod-changed breakpoint hit, there are %zu kernel modules currently.\n", 539 linker_files_list.size()); 540 541 ModuleList &modules = m_process->GetTarget().GetImages(); 542 ModuleList remove_modules; 543 ModuleList add_modules; 544 545 for (ModuleSP module : modules.Modules()) { 546 if (is_kernel(module.get())) 547 continue; 548 if (is_kmod(module.get())) 549 remove_modules.AppendIfNeeded(module); 550 } 551 552 m_process->GetTarget().ModulesDidUnload(remove_modules, false); 553 554 for (KModImageInfo &image_info : linker_files_list) { 555 auto it = m_kld_name_to_uuid.find(image_info.GetName()); 556 if (it != m_kld_name_to_uuid.end()) 557 image_info.SetUUID(it->second); 558 bool failed_to_load = false; 559 if (!image_info.LoadImageUsingMemoryModule(m_process)) { 560 image_info.LoadImageUsingFileAddress(m_process); 561 failed_to_load = true; 562 } else { 563 m_linker_files_list.push_back(image_info); 564 m_kld_name_to_uuid[image_info.GetName()] = image_info.GetUUID(); 565 } 566 567 if (!failed_to_load) 568 add_modules.AppendIfNeeded(image_info.GetModule()); 569 } 570 m_process->GetTarget().ModulesDidLoad(add_modules); 571 return true; 572 } 573 574 // Read all kmod from a given arrays of list 575 bool DynamicLoaderFreeBSDKernel::ReadAllKmods( 576 Address linker_files_head_addr, 577 KModImageInfo::collection_type &kmods_list) { 578 579 // Get offset of next member and load address symbol 580 static ConstString kld_off_address_symbol_name("kld_off_address"); 581 static ConstString kld_off_next_symbol_name("kld_off_next"); 582 static ConstString kld_off_filename_symbol_name("kld_off_filename"); 583 static ConstString kld_off_pathname_symbol_name("kld_off_pathname"); 584 const Symbol *kld_off_address_symbol = 585 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType( 586 kld_off_address_symbol_name, eSymbolTypeData); 587 const Symbol *kld_off_next_symbol = 588 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType( 589 kld_off_next_symbol_name, eSymbolTypeData); 590 const Symbol *kld_off_filename_symbol = 591 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType( 592 kld_off_filename_symbol_name, eSymbolTypeData); 593 const Symbol *kld_off_pathname_symbol = 594 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType( 595 kld_off_pathname_symbol_name, eSymbolTypeData); 596 597 if (!kld_off_address_symbol || !kld_off_next_symbol || 598 !kld_off_filename_symbol || !kld_off_pathname_symbol) 599 return false; 600 601 Status error; 602 const int32_t kld_off_address = m_process->ReadSignedIntegerFromMemory( 603 kld_off_address_symbol->GetAddress().GetLoadAddress( 604 &m_process->GetTarget()), 605 4, 0, error); 606 if (error.Fail()) 607 return false; 608 const int32_t kld_off_next = m_process->ReadSignedIntegerFromMemory( 609 kld_off_next_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget()), 610 4, 0, error); 611 if (error.Fail()) 612 return false; 613 const int32_t kld_off_filename = m_process->ReadSignedIntegerFromMemory( 614 kld_off_filename_symbol->GetAddress().GetLoadAddress( 615 &m_process->GetTarget()), 616 4, 0, error); 617 if (error.Fail()) 618 return false; 619 620 const int32_t kld_off_pathname = m_process->ReadSignedIntegerFromMemory( 621 kld_off_pathname_symbol->GetAddress().GetLoadAddress( 622 &m_process->GetTarget()), 623 4, 0, error); 624 if (error.Fail()) 625 return false; 626 627 // Parse KMods 628 addr_t kld_load_addr(LLDB_INVALID_ADDRESS); 629 char kld_filename[255]; 630 char kld_pathname[255]; 631 addr_t current_kld = 632 linker_files_head_addr.GetLoadAddress(&m_process->GetTarget()); 633 634 while (current_kld != 0) { 635 addr_t kld_filename_addr = 636 m_process->ReadPointerFromMemory(current_kld + kld_off_filename, error); 637 if (error.Fail()) 638 return false; 639 addr_t kld_pathname_addr = 640 m_process->ReadPointerFromMemory(current_kld + kld_off_pathname, error); 641 if (error.Fail()) 642 return false; 643 644 m_process->ReadCStringFromMemory(kld_filename_addr, kld_filename, 645 sizeof(kld_filename), error); 646 if (error.Fail()) 647 return false; 648 m_process->ReadCStringFromMemory(kld_pathname_addr, kld_pathname, 649 sizeof(kld_pathname), error); 650 if (error.Fail()) 651 return false; 652 kld_load_addr = 653 m_process->ReadPointerFromMemory(current_kld + kld_off_address, error); 654 if (error.Fail()) 655 return false; 656 657 kmods_list.emplace_back(); 658 KModImageInfo &kmod_info = kmods_list.back(); 659 kmod_info.SetName(kld_filename); 660 kmod_info.SetLoadAddress(kld_load_addr); 661 kmod_info.SetPath(kld_pathname); 662 663 current_kld = 664 m_process->ReadPointerFromMemory(current_kld + kld_off_next, error); 665 if (kmod_info.GetName() == "kernel") 666 kmods_list.pop_back(); 667 if (error.Fail()) 668 return false; 669 } 670 671 return true; 672 } 673 674 // Read all kmods 675 void DynamicLoaderFreeBSDKernel::ReadAllKmods() { 676 std::lock_guard<decltype(m_mutex)> guard(m_mutex); 677 678 if (ReadKmodsListHeader()) { 679 if (m_linker_file_head_addr.IsValid()) { 680 if (!ParseKmods(m_linker_file_head_addr)) 681 m_linker_files_list.clear(); 682 } 683 } 684 } 685 686 // Load all Kernel Modules 687 void DynamicLoaderFreeBSDKernel::LoadKernelModules() { 688 Log *log = GetLog(LLDBLog::DynamicLoader); 689 LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules " 690 "Start loading Kernel Module"); 691 692 // Initialize Kernel Image Information at the first time 693 if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) { 694 ModuleSP module_sp = m_process->GetTarget().GetExecutableModule(); 695 if (is_kernel(module_sp.get())) { 696 m_kernel_image_info.SetModule(module_sp); 697 m_kernel_image_info.SetIsKernel(true); 698 } 699 700 // Set name for kernel 701 llvm::StringRef kernel_name("freebsd_kernel"); 702 module_sp = m_kernel_image_info.GetModule(); 703 if (module_sp.get() && module_sp->GetObjectFile() && 704 !module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty()) 705 kernel_name = module_sp->GetObjectFile() 706 ->GetFileSpec() 707 .GetFilename() 708 .GetStringRef(); 709 m_kernel_image_info.SetName(kernel_name.data()); 710 711 if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) { 712 m_kernel_image_info.SetLoadAddress(m_kernel_load_address); 713 } 714 715 // Build In memory Module 716 if (m_kernel_image_info.GetLoadAddress() != LLDB_INVALID_ADDRESS) { 717 // If the kernel is not loaded in the memory, use file to load 718 if (!m_kernel_image_info.LoadImageUsingMemoryModule(m_process)) 719 m_kernel_image_info.LoadImageUsingFileAddress(m_process); 720 } 721 } 722 723 LoadOperatingSystemPlugin(false); 724 725 if (!m_kernel_image_info.IsLoaded() || !m_kernel_image_info.GetModule()) { 726 m_kernel_image_info.Clear(); 727 return; 728 } 729 730 static ConstString modlist_symbol_name("linker_files"); 731 732 const Symbol *symbol = 733 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType( 734 modlist_symbol_name, lldb::eSymbolTypeData); 735 736 if (symbol) { 737 m_linker_file_list_struct_addr = symbol->GetAddress(); 738 ReadAllKmods(); 739 } else { 740 LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules " 741 "cannot file modlist symbol"); 742 } 743 } 744 745 // Update symbol when use kldload by setting callback function on kldload 746 void DynamicLoaderFreeBSDKernel::SetNotificationBreakPoint() {} 747 748 // Hook called when attach to a process 749 void DynamicLoaderFreeBSDKernel::DidAttach() { 750 PrivateInitialize(m_process); 751 Update(); 752 } 753 754 // Hook called after attach to a process 755 void DynamicLoaderFreeBSDKernel::DidLaunch() { 756 PrivateInitialize(m_process); 757 Update(); 758 } 759 760 // Clear all member except kernel address 761 void DynamicLoaderFreeBSDKernel::Clear(bool clear_process) { 762 std::lock_guard<decltype(m_mutex)> guard(m_mutex); 763 if (clear_process) 764 m_process = nullptr; 765 m_linker_file_head_addr.Clear(); 766 m_linker_file_list_struct_addr.Clear(); 767 m_kernel_image_info.Clear(); 768 m_linker_files_list.clear(); 769 } 770 771 // Reinitialize class 772 void DynamicLoaderFreeBSDKernel::PrivateInitialize(Process *process) { 773 Clear(true); 774 m_process = process; 775 } 776 777 ThreadPlanSP DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan( 778 lldb_private::Thread &thread, bool stop_others) { 779 Log *log = GetLog(LLDBLog::Step); 780 LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan is " 781 "not yet implemented."); 782 return {}; 783 } 784 785 Status DynamicLoaderFreeBSDKernel::CanLoadImage() { 786 return Status::FromErrorString("shared object cannot be loaded into kernel"); 787 } 788