}
}
- // Now find all the modules and add them to the module list
- for (const MemoryRegion& region : m_allMemoryRegions)
+ // Get the dylinker info and enumerate all the modules
+ struct task_dyld_info dyld_info;
+ mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
+ kern_return_t result = ::task_info(Task(), TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
+ if (result != KERN_SUCCESS)
{
- bool found;
- if (!TryFindDyLinker(region.StartAddress(), region.Size(), &found)) {
- return false;
- }
- if (found) {
- break;
- }
+ TRACE("EnumerateMemoryRegions: task_info(TASK_DYLD_INFO) FAILED %x %s\n", result, mach_error_string(result));
+ return false;
+ }
+
+ // Enumerate all the modules in dyld's image cache. VisitModule is called for every module found.
+ if (!EnumerateModules(dyld_info.all_image_info_addr))
+ {
+ return false;
}
- TRACE("AllMemoryRegions %06llx native ModuleMappings %06llx\n", cbAllMemoryRegions / PAGE_SIZE, m_cbModuleMappings / PAGE_SIZE);
+
+ TRACE("EnumerateMemoryRegions: cbAllMemoryRegions %06llx native cbModuleMappings %06llx\n", cbAllMemoryRegions / PAGE_SIZE, m_cbModuleMappings / PAGE_SIZE);
return true;
}
TRACE("OtherMappings: %06llx\n", cbOtherMappings / PAGE_SIZE);
}
-bool
-CrashInfo::TryFindDyLinker(mach_vm_address_t address, mach_vm_size_t size, bool* found)
-{
- bool result = true;
- *found = false;
-
- if (size > sizeof(mach_header_64))
- {
- mach_header_64 header;
- size_t read = 0;
- if (ReadProcessMemory((void*)address, &header, sizeof(mach_header_64), &read))
- {
- if (header.magic == MH_MAGIC_64)
- {
- TRACE("TryFindDyLinker: found module header at %016llx %08llx ncmds %d sizeofcmds %08x type %02x\n",
- address,
- size,
- header.ncmds,
- header.sizeofcmds,
- header.filetype);
-
- if (header.filetype == MH_DYLINKER)
- {
- TRACE("TryFindDyLinker: found dylinker\n");
- *found = true;
-
- // Enumerate all the modules in dyld's image cache. VisitModule is called for every module found.
- result = EnumerateModules(address, &header);
- }
- }
- }
- else
- {
- TRACE("TryFindDyLinker: ReadProcessMemory header at %p %d FAILED\n", address, read);
- }
- }
-
- return result;
-}
-
void CrashInfo::VisitModule(MachOModule& module)
{
AddModuleInfo(false, module.BaseAddress(), nullptr, module.Name());
// MachO module
//--------------------------------------------------------------------
-MachOModule::MachOModule(MachOReader& reader, mach_vm_address_t baseAddress, mach_header_64* header, std::string* name) :
+MachOModule::MachOModule(MachOReader& reader, mach_vm_address_t baseAddress, std::string* name) :
m_reader(reader),
m_baseAddress(baseAddress),
m_loadBias(0),
m_nlists(nullptr),
m_strtabAddress(0)
{
- if (header != nullptr) {
- m_header = *header;
- }
if (name != nullptr) {
m_name = *name;
}
}
bool
-MachOReader::EnumerateModules(mach_vm_address_t address, mach_header_64* header)
+MachOReader::EnumerateModules(mach_vm_address_t dyldInfoAddress)
{
- _ASSERTE(header->magic == MH_MAGIC_64);
- _ASSERTE(header->filetype == MH_DYLINKER);
-
- MachOModule dylinker(*this, address, header);
-
- // Search for symbol for the dyld image info cache
- uint64_t dyldInfoAddress = 0;
- if (!dylinker.TryLookupSymbol("dyld_all_image_infos", &dyldInfoAddress))
- {
- Trace("ERROR: Can not find the _dyld_all_image_infos symbol\n");
- return false;
- }
-
// Read the all image info from the dylinker image
dyld_all_image_infos dyldInfo;
-
if (!ReadMemory((void*)dyldInfoAddress, &dyldInfo, sizeof(dyld_all_image_infos)))
{
Trace("ERROR: Failed to read dyld_all_image_infos at %p\n", (void*)dyldInfoAddress);
return false;
}
- std::string dylinkerPath;
- if (!ReadString(dyldInfo.dyldPath, dylinkerPath))
+ Trace("MOD: infoArray %p infoArrayCount %d\n", dyldInfo.infoArray, dyldInfo.infoArrayCount);
+
+ // Create the dyld module info
+ if (!CreateModule(dyldInfo.dyldImageLoadAddress, dyldInfo.dyldPath))
{
- Trace("ERROR: Failed to read name at %p\n", dyldInfo.dyldPath);
+ Trace("ERROR: Failed to read dyld header at %p\n", dyldInfo.dyldImageLoadAddress);
return false;
}
- dylinker.SetName(dylinkerPath);
- Trace("MOD: %016llx %08x %s\n", dylinker.BaseAddress(), dylinker.Header().flags, dylinker.Name().c_str());
- VisitModule(dylinker);
-
void* imageInfosAddress = (void*)dyldInfo.infoArray;
size_t imageInfosSize = dyldInfo.infoArrayCount * sizeof(dyld_image_info);
- Trace("MOD: infoArray %p infoArrayCount %d\n", dyldInfo.infoArray, dyldInfo.infoArrayCount);
-
ArrayHolder<dyld_image_info> imageInfos = new (std::nothrow) dyld_image_info[dyldInfo.infoArrayCount];
if (imageInfos == nullptr)
{
}
for (int i = 0; i < dyldInfo.infoArrayCount; i++)
{
- mach_vm_address_t imageAddress = (mach_vm_address_t)imageInfos[i].imageLoadAddress;
- const char* imageFilePathAddress = imageInfos[i].imageFilePath;
+ // Ignore any errors and continue to next module
+ CreateModule(imageInfos[i].imageLoadAddress, imageInfos[i].imageFilePath);
+ }
+ return true;
+}
- std::string imagePath;
- if (!ReadString(imageFilePathAddress, imagePath))
- {
- Trace("ERROR: Failed to read image name at %p\n", imageFilePathAddress);
- continue;
- }
- MachOModule module(*this, imageAddress, nullptr, &imagePath);
- if (!module.ReadHeader())
- {
- continue;
- }
- Trace("MOD: %016llx %08x %s\n", imageAddress, module.Header().flags, imagePath.c_str());
- VisitModule(module);
+bool
+MachOReader::CreateModule(const struct mach_header* imageAddress, const char* imageFilePathAddress)
+{
+ std::string imagePath;
+ if (!ReadString(imageFilePathAddress, imagePath))
+ {
+ return false;
+ }
+ MachOModule module(*this, (mach_vm_address_t)imageAddress, &imagePath);
+ if (!module.ReadHeader())
+ {
+ return false;
}
+ Trace("MOD: %016llx %08x %s\n", imageAddress, module.Header().flags, imagePath.c_str());
+ VisitModule(module);
return true;
}
uint64_t m_strtabAddress;
public:
- MachOModule(MachOReader& reader, mach_vm_address_t baseAddress, mach_header_64* header = nullptr, std::string* name = nullptr);
+ MachOModule(MachOReader& reader, mach_vm_address_t baseAddress, std::string* name = nullptr);
~MachOModule();
inline mach_vm_address_t BaseAddress() const { return m_baseAddress; }
bool EnumerateSegments();
private:
- inline void SetName(std::string& name) { m_name = name; }
-
bool ReadLoadCommands();
bool ReadSymbolTable();
uint64_t GetAddressFromFileOffset(uint32_t offset);
friend MachOModule;
public:
MachOReader();
- bool EnumerateModules(mach_vm_address_t address, mach_header_64* header);
+ bool EnumerateModules(mach_vm_address_t dyldInfoAddress);
private:
+ bool CreateModule(const struct mach_header* imageAddress, const char* imageFilePathAddress);
bool ReadString(const char* address, std::string& str);
virtual void VisitModule(MachOModule& module) { };
virtual void VisitSegment(MachOModule& module, const segment_command_64& segment) { };