diff options
author | Greg Clayton <gclayton@apple.com> | 2012-02-13 23:10:39 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2012-02-13 23:10:39 +0000 |
commit | c859e2d52488ef1852e6489716ddf6147402ea64 (patch) | |
tree | 5639f72ea58d93f18e65eb6fb71f76062fbba9e6 /lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp | |
parent | 698452bc7e838e3a355029539d7f0be974d4d81d (diff) | |
download | bcm5719-llvm-c859e2d52488ef1852e6489716ddf6147402ea64.tar.gz bcm5719-llvm-c859e2d52488ef1852e6489716ddf6147402ea64.zip |
Full core file support has been added for mach-o core files.
Tracking modules down when you have a UUID and a path has been improved.
DynamicLoaderDarwinKernel no longer parses mach-o load commands and it
now uses the memory based modules now that we can load modules from memory.
Added a target setting named "target.exec-search-paths" which can be used
to supply a list of directories to use when trying to look for executables.
This allows one or more directories to be used when searching for modules
that may not exist in the SDK/PDK. The target automatically adds the directory
for the main executable to this list so this should help us in tracking down
shared libraries and other binaries.
llvm-svn: 150426
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp')
-rw-r--r-- | lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp | 580 |
1 files changed, 151 insertions, 429 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index b82d6869edf..c719654998c 100644 --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -154,246 +154,178 @@ DynamicLoaderDarwinKernel::Clear (bool clear_process) } -//---------------------------------------------------------------------- -// Load the kernel module and initialize the "m_kernel" member. Return -// true _only_ if the kernel is loaded the first time through (subsequent -// calls to this function should return false after the kernel has been -// already loaded). -//---------------------------------------------------------------------- -void -DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() -{ - if (!m_kext_summary_header_ptr_addr.IsValid()) - { - m_kernel.Clear(false); - m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); - if (m_kernel.module_sp) - { - static ConstString mach_header_name ("_mh_execute_header"); - static ConstString kext_summary_symbol ("gLoadedKextSummaries"); - const Symbol *symbol = NULL; - symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData); - if (symbol) - m_kext_summary_header_ptr_addr = symbol->GetValue(); - - symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (mach_header_name, eSymbolTypeAbsolute); - if (symbol) - { - // The "_mh_execute_header" symbol is absolute and not a section based - // symbol that will have a valid address, so we need to resolve it... - m_process->GetTarget().GetImages().ResolveFileAddress (symbol->GetValue().GetFileAddress(), m_kernel.so_address); - DataExtractor data; // Load command data - if (ReadMachHeader (m_kernel, &data)) - { - if (m_kernel.header.filetype == llvm::MachO::HeaderFileTypeExecutable) - { - if (ParseLoadCommands (data, m_kernel)) - UpdateImageLoadAddress (m_kernel); - - // Update all image infos - ReadAllKextSummaries (); - } - } - else - { - m_kernel.Clear(false); - } - } - } - } -} - bool -DynamicLoaderDarwinKernel::FindTargetModule (OSKextLoadedKextSummary &image_info, bool can_create, bool *did_create_ptr) +DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process) { - if (did_create_ptr) - *did_create_ptr = false; - - const bool image_info_uuid_is_valid = image_info.uuid.IsValid(); + if (IsLoaded()) + return true; - if (image_info.module_sp) - { - if (image_info_uuid_is_valid) - { - if (image_info.module_sp->GetUUID() == image_info.uuid) - return true; - else - image_info.module_sp.reset(); - } - else - return true; - } + bool uuid_is_valid = uuid.IsValid(); - ModuleList &target_images = m_process->GetTarget().GetImages(); - if (image_info_uuid_is_valid) - image_info.module_sp = target_images.FindModule(image_info.uuid); - - if (image_info.module_sp) - return true; - - ArchSpec arch (image_info.GetArchitecture ()); - if (can_create) + Target &target = process->GetTarget(); + ModuleSP memory_module_sp; + // Use the memory module as the module if we have one... + if (address != LLDB_INVALID_ADDRESS) { - if (image_info_uuid_is_valid) + FileSpec file_spec; + if (module_sp) + file_spec = module_sp->GetFileSpec(); + else + file_spec.SetFile (name, false); + + memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false); + if (memory_module_sp && !uuid_is_valid) { - image_info.module_sp = m_process->GetTarget().GetSharedModule (FileSpec(), - arch, - &image_info.uuid); - if (did_create_ptr) - *did_create_ptr = image_info.module_sp; + uuid = memory_module_sp->GetUUID(); + uuid_is_valid = uuid.IsValid(); } } - return image_info.module_sp; -} -bool -DynamicLoaderDarwinKernel::UpdateCommPageLoadAddress(Module *module) -{ - bool changed = false; - if (module) + if (!module_sp) { - ObjectFile *image_object_file = module->GetObjectFile(); - if (image_object_file) + bool uuid_is_valid = uuid.IsValid(); + if (uuid_is_valid) { - SectionList *section_list = image_object_file->GetSectionList (); - if (section_list) - { - uint32_t num_sections = section_list->GetSize(); - for (uint32_t i=0; i<num_sections; ++i) - { - Section* section = section_list->GetSectionAtIndex (i).get(); - if (section) - { - const addr_t new_section_load_addr = section->GetFileAddress (); - const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section); - if (old_section_load_addr == LLDB_INVALID_ADDRESS || - old_section_load_addr != new_section_load_addr) - { - if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ())) - changed = true; - } - } - } - } + ModuleList &target_images = target.GetImages(); + module_sp = target_images.FindModule(uuid); + + if (!module_sp) + module_sp = target.GetSharedModule (FileSpec(), target.GetArchitecture(), &uuid); } } - return changed; -} + -//---------------------------------------------------------------------- -// Update the load addresses for all segments in MODULE using the -// updated INFO that is passed in. -//---------------------------------------------------------------------- -bool -DynamicLoaderDarwinKernel::UpdateImageLoadAddress (OSKextLoadedKextSummary& info) -{ - Module *module = info.module_sp.get(); - bool changed = false; - if (module) + if (memory_module_sp) { - ObjectFile *image_object_file = module->GetObjectFile(); - if (image_object_file) + // Someone already supplied a file, make sure it is the right one. + if (module_sp) { - SectionList *section_list = image_object_file->GetSectionList (); - if (section_list) + if (module_sp->GetUUID() == memory_module_sp->GetUUID()) { - // We now know the slide amount, so go through all sections - // and update the load addresses with the correct values. - uint32_t num_segments = info.segments.size(); - for (uint32_t i=0; i<num_segments; ++i) + ObjectFile *ondisk_object_file = module_sp->GetObjectFile(); + ObjectFile *memory_object_file = memory_module_sp->GetObjectFile(); + if (memory_object_file && ondisk_object_file) { - const addr_t new_section_load_addr = info.segments[i].vmaddr; - if (section_list->FindSectionByName(info.segments[i].name)) + SectionList *ondisk_section_list = ondisk_object_file->GetSectionList (); + SectionList *memory_section_list = memory_object_file->GetSectionList (); + if (memory_section_list && ondisk_section_list) { - SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); - if (section_sp) + const uint32_t num_sections = ondisk_section_list->GetSize(); + // There may be CTF sections in the memory image so we can't + // always just compare the number of sections (which are actually + // segments in mach-o parlance) + uint32_t sect_idx = 0; + const Section *memory_section; + const Section *ondisk_section; + // Always use the number of sections from the on disk file + // in case there are extra sections added to the memory image. + for (sect_idx=0; sect_idx<num_sections; ++sect_idx) { - const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get()); - if (old_section_load_addr == LLDB_INVALID_ADDRESS || - old_section_load_addr != new_section_load_addr) + memory_section = memory_section_list->GetSectionAtIndex(sect_idx).get(); + ondisk_section = ondisk_section_list->GetSectionAtIndex(sect_idx).get(); + if (memory_section->GetName() != ondisk_section->GetName()) { - if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr)) - changed = true; + // Section count was the same, but the sections themselves do not match + module_sp.reset(); + break; } } - else - { - Host::SystemLog (Host::eSystemLogWarning, "warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n", - info.segments[i].name.AsCString("<invalid>"), - (uint64_t)new_section_load_addr, - image_object_file->GetFileSpec().GetDirectory().AsCString(), - image_object_file->GetFileSpec().GetFilename().AsCString()); - } - } - else - { - // The segment name is empty which means this is a .o file. - // Object files in LLDB end up getting reorganized so that - // the segment name that is in the section is promoted into - // an actual segment, so we just need to go through all sections - // and slide them by a single amount. - - uint32_t num_sections = section_list->GetSize(); - for (uint32_t i=0; i<num_sections; ++i) + if (module_sp) { - Section* section = section_list->GetSectionAtIndex (i).get(); - if (section) + for (sect_idx=0; sect_idx<num_sections; ++sect_idx) { - if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + new_section_load_addr)) - changed = true; + memory_section = memory_section_list->GetSectionAtIndex(sect_idx).get(); + ondisk_section = ondisk_section_list->GetSectionAtIndex(sect_idx).get(); + target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section, memory_section->GetFileAddress()); } + if (num_sections > 0) + load_process_stop_id = process->GetStopID(); } } + else + module_sp.reset(); // One or both section lists } + else + module_sp.reset(); // One or both object files missing } + else + module_sp.reset(); // UUID mismatch + } + + // Use the memory module as the module if we didn't like the file + // module we either found or were supplied with + if (!module_sp) + { + module_sp = memory_module_sp; + // Load the memory image in the target as all adresses are already correct + bool changed = false; + target.GetImages().Append (memory_module_sp); + if (module_sp->SetLoadAddress (target, 0, changed)) + load_process_stop_id = process->GetStopID(); } } - return changed; + bool is_loaded = IsLoaded(); + + if (so_address.IsValid()) + { + if (is_loaded) + so_address.SetLoadAddress (address, &target); + else + target.GetImages().ResolveFileAddress (address, so_address); + + } + return is_loaded; } //---------------------------------------------------------------------- -// Update the load addresses for all segments in MODULE using the -// updated INFO that is passed in. +// Load the kernel module and initialize the "m_kernel" member. Return +// true _only_ if the kernel is loaded the first time through (subsequent +// calls to this function should return false after the kernel has been +// already loaded). //---------------------------------------------------------------------- -bool -DynamicLoaderDarwinKernel::UnloadImageLoadAddress (OSKextLoadedKextSummary& info) +void +DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() { - Module *module = info.module_sp.get(); - bool changed = false; - if (module) + if (!m_kext_summary_header_ptr_addr.IsValid()) { - ObjectFile *image_object_file = module->GetObjectFile(); - if (image_object_file) + m_kernel.Clear(false); + m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); + strncpy(m_kernel.name, "mach_kernel", sizeof(m_kernel.name)); + if (m_kernel.address == LLDB_INVALID_ADDRESS) { - SectionList *section_list = image_object_file->GetSectionList (); - if (section_list) + m_kernel.address = m_process->GetImageInfoAddress (); + if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp) { - uint32_t num_segments = info.segments.size(); - for (uint32_t i=0; i<num_segments; ++i) - { - SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); - if (section_sp) - { - const addr_t old_section_load_addr = info.segments[i].vmaddr; - if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr)) - changed = true; - } - else - { - Host::SystemLog (Host::eSystemLogWarning, - "warning: unable to find and unload segment named '%s' in '%s/%s' in macosx dynamic loader plug-in.\n", - info.segments[i].name.AsCString("<invalid>"), - image_object_file->GetFileSpec().GetDirectory().AsCString(), - image_object_file->GetFileSpec().GetFilename().AsCString()); - } - } + // We didn't get a hint from the process, so we will + // try the kernel at the address that it exists at in + // the file if we have one + ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile(); + if (kernel_object_file) + m_kernel.address = kernel_object_file->GetHeaderAddress().GetFileAddress(); } } + + if (m_kernel.address != LLDB_INVALID_ADDRESS) + m_kernel.LoadImageUsingMemoryModule (m_process); + + if (m_kernel.IsLoaded()) + { + static ConstString kext_summary_symbol ("gLoadedKextSummaries"); + const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData); + if (symbol) + { + m_kext_summary_header_ptr_addr = symbol->GetValue(); + // Update all image infos + ReadAllKextSummaries (); + } + } + else + { + m_kernel.Clear(false); + } } - return changed; } - //---------------------------------------------------------------------- // Static callback function that gets called when our DYLD notification // breakpoint gets hit. We update all of our image infos and then @@ -513,18 +445,20 @@ DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, } } - DataExtractor data; // Load command data - if (ReadMachHeader (kext_summaries[i], &data)) - { - ParseLoadCommands (data, kext_summaries[i]); - } - + kext_summaries[i].LoadImageUsingMemoryModule (m_process); + if (s) { if (kext_summaries[i].module_sp) - s->Printf("\n found kext: %s/%s\n", - kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(), - kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); + { + if (kext_summaries[i].module_sp->GetFileSpec().GetDirectory()) + s->Printf("\n found kext: %s/%s\n", + kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(), + kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); + else + s->Printf("\n found kext: %s\n", + kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); + } else s->Printf (" failed to locate/load.\n"); } @@ -547,20 +481,11 @@ DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::c for (uint32_t idx = 0; idx < image_infos.size(); ++idx) { - m_kext_summaries.push_back(image_infos[idx]); + OSKextLoadedKextSummary &image_info = image_infos[idx]; + m_kext_summaries.push_back(image_info); - if (FindTargetModule (image_infos[idx], true, NULL)) - { - // UpdateImageLoadAddress will return true if any segments - // change load address. We need to check this so we don't - // mention that all loaded shared libraries are newly loaded - // each time we hit out dyld breakpoint since dyld will list all - // shared libraries each time. - if (UpdateImageLoadAddress (image_infos[idx])) - { - loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp); - } - } + if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id) + loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp); } if (loaded_module_list.GetSize() > 0) @@ -644,6 +569,14 @@ DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr, { image_infos[i].reference_list = 0; } + printf ("[%3u] %*.*s: address=0x%16.16llx, size=0x%16.16llx, version=0x%16.16llx, load_tag=0x%8.8x, flags=0x%8.8x\n", + i, + KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data, + image_infos[i].address, + image_infos[i].size, + image_infos[i].version, + image_infos[i].load_tag, + image_infos[i].flags); } if (i < image_infos.size()) image_infos.resize(i); @@ -679,215 +612,6 @@ DynamicLoaderDarwinKernel::ReadAllKextSummaries () } //---------------------------------------------------------------------- -// Read a mach_header at ADDR into HEADER, and also fill in the load -// command data into LOAD_COMMAND_DATA if it is non-NULL. -// -// Returns true if we succeed, false if we fail for any reason. -//---------------------------------------------------------------------- -bool -DynamicLoaderDarwinKernel::ReadMachHeader (OSKextLoadedKextSummary& kext_summary, DataExtractor *load_command_data) -{ - DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0); - Error error; - const bool prefer_file_cache = false; - size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary.so_address, - prefer_file_cache, - header_bytes.GetBytes(), - header_bytes.GetByteSize(), - error); - if (bytes_read == sizeof(llvm::MachO::mach_header)) - { - uint32_t offset = 0; - ::memset (&kext_summary.header, 0, sizeof(kext_summary.header)); - - // Get the magic byte unswapped so we can figure out what we are dealing with - DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), endian::InlHostByteOrder(), 4); - kext_summary.header.magic = data.GetU32(&offset); - Address load_cmd_addr = kext_summary.so_address; - data.SetByteOrder(DynamicLoaderDarwinKernel::GetByteOrderFromMagic(kext_summary.header.magic)); - switch (kext_summary.header.magic) - { - case llvm::MachO::HeaderMagic32: - case llvm::MachO::HeaderMagic32Swapped: - data.SetAddressByteSize(4); - load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header)); - break; - - case llvm::MachO::HeaderMagic64: - case llvm::MachO::HeaderMagic64Swapped: - data.SetAddressByteSize(8); - load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header_64)); - break; - - default: - return false; - } - - // Read the rest of dyld's mach header - if (data.GetU32(&offset, &kext_summary.header.cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1)) - { - if (load_command_data == NULL) - return true; // We were able to read the mach_header and weren't asked to read the load command bytes - - DataBufferSP load_cmd_data_sp(new DataBufferHeap(kext_summary.header.sizeofcmds, 0)); - - size_t load_cmd_bytes_read = m_process->GetTarget().ReadMemory (load_cmd_addr, - prefer_file_cache, - load_cmd_data_sp->GetBytes(), - load_cmd_data_sp->GetByteSize(), - error); - - if (load_cmd_bytes_read == kext_summary.header.sizeofcmds) - { - // Set the load command data and also set the correct endian - // swap settings and the correct address size - load_command_data->SetData(load_cmd_data_sp, 0, kext_summary.header.sizeofcmds); - load_command_data->SetByteOrder(data.GetByteOrder()); - load_command_data->SetAddressByteSize(data.GetAddressByteSize()); - return true; // We successfully read the mach_header and the load command data - } - - return false; // We weren't able to read the load command data - } - } - return false; // We failed the read the mach_header -} - - -//---------------------------------------------------------------------- -// Parse the load commands for an image -//---------------------------------------------------------------------- -uint32_t -DynamicLoaderDarwinKernel::ParseLoadCommands (const DataExtractor& data, OSKextLoadedKextSummary& image_info) -{ - uint32_t offset = 0; - uint32_t cmd_idx; - Segment segment; - image_info.Clear (true); - - for (cmd_idx = 0; cmd_idx < image_info.header.ncmds; cmd_idx++) - { - // Clear out any load command specific data from image_info since - // we are about to read it. - - if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command))) - { - llvm::MachO::load_command load_cmd; - uint32_t load_cmd_offset = offset; - load_cmd.cmd = data.GetU32 (&offset); - load_cmd.cmdsize = data.GetU32 (&offset); - switch (load_cmd.cmd) - { - case llvm::MachO::LoadCommandSegment32: - { - segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); - // We are putting 4 uint32_t values 4 uint64_t values so - // we have to use multiple 32 bit gets below. - segment.vmaddr = data.GetU32 (&offset); - segment.vmsize = data.GetU32 (&offset); - segment.fileoff = data.GetU32 (&offset); - segment.filesize = data.GetU32 (&offset); - // Extract maxprot, initprot, nsects and flags all at once - data.GetU32(&offset, &segment.maxprot, 4); - image_info.segments.push_back (segment); - } - break; - - case llvm::MachO::LoadCommandSegment64: - { - segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); - // Extract vmaddr, vmsize, fileoff, and filesize all at once - data.GetU64(&offset, &segment.vmaddr, 4); - // Extract maxprot, initprot, nsects and flags all at once - data.GetU32(&offset, &segment.maxprot, 4); - image_info.segments.push_back (segment); - } - break; - - case llvm::MachO::LoadCommandUUID: - image_info.uuid.SetBytes(data.GetData (&offset, 16)); - break; - - default: - break; - } - // Set offset to be the beginning of the next load command. - offset = load_cmd_offset + load_cmd.cmdsize; - } - } -#if 0 - // No slide in the kernel... - - // All sections listed in the dyld image info structure will all - // either be fixed up already, or they will all be off by a single - // slide amount that is determined by finding the first segment - // that is at file offset zero which also has bytes (a file size - // that is greater than zero) in the object file. - - // Determine the slide amount (if any) - const size_t num_sections = image_info.segments.size(); - for (size_t i = 0; i < num_sections; ++i) - { - // Iterate through the object file sections to find the - // first section that starts of file offset zero and that - // has bytes in the file... - if (image_info.segments[i].fileoff == 0 && image_info.segments[i].filesize > 0) - { - image_info.slide = image_info.address - image_info.segments[i].vmaddr; - // We have found the slide amount, so we can exit - // this for loop. - break; - } - } -#endif - if (image_info.uuid.IsValid()) - { - bool did_create = false; - if (FindTargetModule(image_info, true, &did_create)) - { - if (did_create) - image_info.module_create_stop_id = m_process->GetStopID(); - } - } - return cmd_idx; -} - -//---------------------------------------------------------------------- -// Dump a Segment to the file handle provided. -//---------------------------------------------------------------------- -void -DynamicLoaderDarwinKernel::Segment::PutToLog (Log *log, addr_t slide) const -{ - if (log) - { - if (slide == 0) - log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)", - name.AsCString(""), - vmaddr + slide, - vmaddr + slide + vmsize); - else - log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx", - name.AsCString(""), - vmaddr + slide, - vmaddr + slide + vmsize, - slide); - } -} - -const DynamicLoaderDarwinKernel::Segment * -DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::FindSegment (const ConstString &name) const -{ - const size_t num_segments = segments.size(); - for (size_t i=0; i<num_segments; ++i) - { - if (segments[i].name == name) - return &segments[i]; - } - return NULL; -} - - -//---------------------------------------------------------------------- // Dump an image info structure to the file handle provided. //---------------------------------------------------------------------- void @@ -927,8 +651,6 @@ DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const address, address+size, version, load_tag, flags, reference_list, name); } - for (uint32_t i=0; i<segments.size(); ++i) - segments[i].PutToLog(log, 0); } } @@ -971,7 +693,7 @@ DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) void DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded () { - if (m_break_id == LLDB_INVALID_BREAK_ID) + if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp) { DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); |