diff options
Diffstat (limited to 'lib/sanitizer_common/sanitizer_procmaps_mac.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_procmaps_mac.cc | 77 |
1 files changed, 67 insertions, 10 deletions
diff --git a/lib/sanitizer_common/sanitizer_procmaps_mac.cc b/lib/sanitizer_common/sanitizer_procmaps_mac.cc index 417cc908e..2b4ad5cbb 100644 --- a/lib/sanitizer_common/sanitizer_procmaps_mac.cc +++ b/lib/sanitizer_common/sanitizer_procmaps_mac.cc @@ -53,6 +53,8 @@ void MemoryMappingLayout::Reset() { current_load_cmd_addr_ = 0; current_magic_ = 0; current_filetype_ = 0; + current_arch_ = kModuleArchUnknown; + internal_memset(current_uuid_, 0, kModuleUUIDSize); } // static @@ -71,11 +73,12 @@ void MemoryMappingLayout::LoadFromCache() { // and returns the start and end addresses and file offset of the corresponding // segment. // Note that the segment addresses are not necessarily sorted. -template<u32 kLCSegment, typename SegmentCommand> -bool MemoryMappingLayout::NextSegmentLoad( - uptr *start, uptr *end, uptr *offset, - char filename[], uptr filename_size, uptr *protection) { - const char* lc = current_load_cmd_addr_; +template <u32 kLCSegment, typename SegmentCommand> +bool MemoryMappingLayout::NextSegmentLoad(uptr *start, uptr *end, uptr *offset, + char filename[], uptr filename_size, + ModuleArch *arch, u8 *uuid, + uptr *protection) { + const char *lc = current_load_cmd_addr_; current_load_cmd_addr_ += ((const load_command *)lc)->cmdsize; if (((const load_command *)lc)->cmd == kLCSegment) { const sptr dlloff = _dyld_get_image_vmaddr_slide(current_image_); @@ -97,14 +100,61 @@ bool MemoryMappingLayout::NextSegmentLoad( internal_strncpy(filename, _dyld_get_image_name(current_image_), filename_size); } + if (arch) { + *arch = current_arch_; + } + if (uuid) { + internal_memcpy(uuid, current_uuid_, kModuleUUIDSize); + } return true; } return false; } +ModuleArch ModuleArchFromCpuType(cpu_type_t cputype, cpu_subtype_t cpusubtype) { + cpusubtype = cpusubtype & ~CPU_SUBTYPE_MASK; + switch (cputype) { + case CPU_TYPE_I386: + return kModuleArchI386; + case CPU_TYPE_X86_64: + if (cpusubtype == CPU_SUBTYPE_X86_64_ALL) return kModuleArchX86_64; + if (cpusubtype == CPU_SUBTYPE_X86_64_H) return kModuleArchX86_64H; + CHECK(0 && "Invalid subtype of x86_64"); + return kModuleArchUnknown; + case CPU_TYPE_ARM: + if (cpusubtype == CPU_SUBTYPE_ARM_V6) return kModuleArchARMV6; + if (cpusubtype == CPU_SUBTYPE_ARM_V7) return kModuleArchARMV7; + if (cpusubtype == CPU_SUBTYPE_ARM_V7S) return kModuleArchARMV7S; + if (cpusubtype == CPU_SUBTYPE_ARM_V7K) return kModuleArchARMV7K; + CHECK(0 && "Invalid subtype of ARM"); + return kModuleArchUnknown; + case CPU_TYPE_ARM64: + return kModuleArchARM64; + default: + CHECK(0 && "Invalid CPU type"); + return kModuleArchUnknown; + } +} + +static void FindUUID(const load_command *first_lc, u8 *uuid_output) { + const load_command *current_lc = first_lc; + while (1) { + if (current_lc->cmd == 0) return; + if (current_lc->cmd == LC_UUID) { + const uuid_command *uuid_lc = (const uuid_command *)current_lc; + const uint8_t *uuid = &uuid_lc->uuid[0]; + internal_memcpy(uuid_output, uuid, kModuleUUIDSize); + return; + } + + current_lc = + (const load_command *)(((char *)current_lc) + current_lc->cmdsize); + } +} + bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, char filename[], uptr filename_size, - uptr *protection) { + uptr *protection, ModuleArch *arch, u8 *uuid) { for (; current_image_ >= 0; current_image_--) { const mach_header* hdr = _dyld_get_image_header(current_image_); if (!hdr) continue; @@ -113,6 +163,7 @@ bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, current_load_cmd_count_ = hdr->ncmds; current_magic_ = hdr->magic; current_filetype_ = hdr->filetype; + current_arch_ = ModuleArchFromCpuType(hdr->cputype, hdr->cpusubtype); switch (current_magic_) { #ifdef MH_MAGIC_64 case MH_MAGIC_64: { @@ -130,20 +181,24 @@ bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, } } + FindUUID((const load_command *)current_load_cmd_addr_, ¤t_uuid_[0]); + for (; current_load_cmd_count_ >= 0; current_load_cmd_count_--) { switch (current_magic_) { // current_magic_ may be only one of MH_MAGIC, MH_MAGIC_64. #ifdef MH_MAGIC_64 case MH_MAGIC_64: { if (NextSegmentLoad<LC_SEGMENT_64, struct segment_command_64>( - start, end, offset, filename, filename_size, protection)) + start, end, offset, filename, filename_size, arch, uuid, + protection)) return true; break; } #endif case MH_MAGIC: { if (NextSegmentLoad<LC_SEGMENT, struct segment_command>( - start, end, offset, filename, filename_size, protection)) + start, end, offset, filename, filename_size, arch, uuid, + protection)) return true; break; } @@ -159,9 +214,11 @@ void MemoryMappingLayout::DumpListOfModules( InternalMmapVector<LoadedModule> *modules) { Reset(); uptr cur_beg, cur_end, prot; + ModuleArch cur_arch; + u8 cur_uuid[kModuleUUIDSize]; InternalScopedString module_name(kMaxPathLength); for (uptr i = 0; Next(&cur_beg, &cur_end, 0, module_name.data(), - module_name.size(), &prot); + module_name.size(), &prot, &cur_arch, &cur_uuid[0]); i++) { const char *cur_name = module_name.data(); if (cur_name[0] == '\0') @@ -173,7 +230,7 @@ void MemoryMappingLayout::DumpListOfModules( } else { modules->push_back(LoadedModule()); cur_module = &modules->back(); - cur_module->set(cur_name, cur_beg); + cur_module->set(cur_name, cur_beg, cur_arch, cur_uuid); } cur_module->addAddressRange(cur_beg, cur_end, prot & kProtectionExecute); } |