mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
mac: Update the dyld_all_image_infos structure for 10.12
BUG=crashpad:120 Change-Id: I7b2df5f2de13517b2586569ce267bcb0ae845101 Reviewed-on: https://chromium-review.googlesource.com/353830 Reviewed-by: Robert Sesek <rsesek@chromium.org>
This commit is contained in:
parent
495a64fcdb
commit
c281e30f93
@ -47,4 +47,10 @@
|
||||
#define MAC_OS_X_VERSION_10_11 101100
|
||||
#endif
|
||||
|
||||
// 10.12 SDK
|
||||
|
||||
#ifndef MAC_OS_X_VERSION_10_12
|
||||
#define MAC_OS_X_VERSION_10_12 101200
|
||||
#endif
|
||||
|
||||
#endif // CRASHPAD_COMPAT_MAC_AVAILABILITYMACROS_H_
|
||||
|
@ -444,6 +444,9 @@ void ProcessReader::InitializeModules() {
|
||||
if (all_image_infos.version >= 2 && all_image_infos.dyldImageLoadAddress &&
|
||||
image_info.imageLoadAddress == all_image_infos.dyldImageLoadAddress) {
|
||||
found_dyld = true;
|
||||
LOG(WARNING) << base::StringPrintf(
|
||||
"found dylinker (%s) in dyld_all_image_infos::infoArray",
|
||||
module.name.c_str());
|
||||
|
||||
LOG_IF(WARNING, file_type != MH_DYLINKER)
|
||||
<< base::StringPrintf("dylinker (%s) has unexpected Mach-O type %d",
|
||||
|
@ -56,6 +56,8 @@ namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
const char kDyldPath[] = "/usr/lib/dyld";
|
||||
|
||||
TEST(ProcessReader, SelfBasic) {
|
||||
ProcessReader process_reader;
|
||||
ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
|
||||
@ -690,7 +692,7 @@ TEST(ProcessReader, SelfModules) {
|
||||
EXPECT_EQ(ExpectCLKernels(), found_cl_kernels);
|
||||
|
||||
size_t index = modules.size() - 1;
|
||||
EXPECT_EQ("/usr/lib/dyld", modules[index].name);
|
||||
EXPECT_EQ(kDyldPath, modules[index].name);
|
||||
|
||||
// dyld didn’t load itself either, so it couldn’t record its timestamp, and it
|
||||
// is also reported as 0.
|
||||
@ -800,7 +802,7 @@ class ProcessReaderModulesChild final : public MachMultiprocess {
|
||||
dyld_image_address =
|
||||
reinterpret_cast<mach_vm_address_t>(_dyld_get_image_header(index));
|
||||
} else {
|
||||
dyld_image_name = "/usr/lib/dyld";
|
||||
dyld_image_name = kDyldPath;
|
||||
dyld_image_address = reinterpret_cast<mach_vm_address_t>(
|
||||
dyld_image_infos->dyldImageLoadAddress);
|
||||
}
|
||||
|
@ -36,44 +36,39 @@ inline void Assign(DestinationType* destination, const SourceType& source) {
|
||||
*destination = source;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline void Assign(Type* destination, const Type& source) {
|
||||
memcpy(destination, &source, sizeof(source));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void Assign<process_types::internal::Reserved64Only64,
|
||||
process_types::internal::Reserved64Only32>(
|
||||
process_types::internal::Reserved64Only64* destination,
|
||||
const process_types::internal::Reserved64Only32& source) {
|
||||
// Reserved64Only32 carries no data.
|
||||
inline void Assign<process_types::internal::Reserved32_64Only64,
|
||||
process_types::internal::Reserved32_64Only32>(
|
||||
process_types::internal::Reserved32_64Only64* destination,
|
||||
const process_types::internal::Reserved32_64Only32& source) {
|
||||
// Reserved32_64Only32 carries no data.
|
||||
*destination = 0;
|
||||
}
|
||||
|
||||
using CharArray16 = char[16];
|
||||
template <>
|
||||
inline void Assign<CharArray16, CharArray16>(CharArray16* destination,
|
||||
const CharArray16& source) {
|
||||
memcpy(destination, &source, sizeof(source));
|
||||
inline void Assign<process_types::internal::Reserved64_64Only64,
|
||||
process_types::internal::Reserved64_64Only32>(
|
||||
process_types::internal::Reserved64_64Only64* destination,
|
||||
const process_types::internal::Reserved64_64Only32& source) {
|
||||
// Reserved64_64Only32 carries no data.
|
||||
*destination = 0;
|
||||
}
|
||||
|
||||
using UInt64Array16 = uint64_t[16];
|
||||
using UInt32Array10 = uint32_t[10];
|
||||
using UInt64Array10 = uint64_t[10];
|
||||
template <>
|
||||
inline void Assign<UInt64Array16, UInt64Array16>(UInt64Array16* destination,
|
||||
const UInt64Array16& source) {
|
||||
memcpy(destination, &source, sizeof(source));
|
||||
}
|
||||
|
||||
using UInt32Array16 = uint32_t[16];
|
||||
template <>
|
||||
inline void Assign<UInt64Array16, UInt32Array16>(UInt64Array16* destination,
|
||||
const UInt32Array16& source) {
|
||||
inline void Assign<UInt64Array10, UInt32Array10>(UInt64Array10* destination,
|
||||
const UInt32Array10& source) {
|
||||
for (size_t index = 0; index < arraysize(source); ++index) {
|
||||
(*destination)[index] = source[index];
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void Assign<uuid_t, uuid_t>(uuid_t* destination, const uuid_t& source) {
|
||||
// uuid_t is a type alias for unsigned char[16].
|
||||
memcpy(destination, &source, sizeof(source));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace crashpad
|
||||
|
||||
|
@ -29,10 +29,12 @@ namespace internal {
|
||||
|
||||
// Some structure definitions differ in 32-bit and 64-bit environments by having
|
||||
// additional “reserved” padding fields present only in the 64-bit environment.
|
||||
// These Reserved64Only* types allow the process_types system to replicate these
|
||||
// structures more precisely.
|
||||
using Reserved64Only32 = char[0];
|
||||
using Reserved64Only64 = uint32_t;
|
||||
// These Reserved*_64Only* types allow the process_types system to replicate
|
||||
// these structures more precisely.
|
||||
using Reserved32_64Only32 = char[0];
|
||||
using Reserved32_64Only64 = uint32_t;
|
||||
using Reserved64_64Only32 = char[0];
|
||||
using Reserved64_64Only64 = uint64_t;
|
||||
|
||||
} // namespace internal
|
||||
} // namespace process_types
|
||||
@ -61,7 +63,8 @@ DECLARE_PROCESS_TYPE_TRAITS_CLASS(Generic, 64)
|
||||
using Pointer = internal::TraitsGeneric::Pointer; \
|
||||
using IntPtr = internal::TraitsGeneric::IntPtr; \
|
||||
using UIntPtr = internal::TraitsGeneric::UIntPtr; \
|
||||
using Reserved64Only = internal::TraitsGeneric::Reserved64Only; \
|
||||
using Reserved32_64Only = internal::TraitsGeneric::Reserved32_64Only; \
|
||||
using Reserved64_64Only = internal::TraitsGeneric::Reserved64_64Only; \
|
||||
\
|
||||
/* Initializes an object with data read from |process_reader| at \
|
||||
* |address|, properly genericized. */ \
|
||||
@ -150,7 +153,8 @@ DECLARE_PROCESS_TYPE_TRAITS_CLASS(Generic, 64)
|
||||
using Pointer = typename Traits::Pointer; \
|
||||
using IntPtr = typename Traits::IntPtr; \
|
||||
using UIntPtr = typename Traits::UIntPtr; \
|
||||
using Reserved64Only = typename Traits::Reserved64Only; \
|
||||
using Reserved32_64Only = typename Traits::Reserved32_64Only; \
|
||||
using Reserved64_64Only = typename Traits::Reserved64_64Only; \
|
||||
\
|
||||
/* Read(), ReadArrayInto(), and Size() are as in the generic user-visible \
|
||||
* struct above. */ \
|
||||
|
@ -64,7 +64,7 @@ size_t dyld_all_image_infos<Traits>::ExpectedSizeForVersion(
|
||||
return sizeof(dyld_all_image_infos<Traits>);
|
||||
}
|
||||
if (version >= 13) {
|
||||
return offsetof(dyld_all_image_infos<Traits>, reserved);
|
||||
return offsetof(dyld_all_image_infos<Traits>, infoArrayChangeTimestamp);
|
||||
}
|
||||
if (version >= 12) {
|
||||
return offsetof(dyld_all_image_infos<Traits>, sharedCacheUUID);
|
||||
|
@ -61,7 +61,7 @@ PROCESS_TYPE_STRUCT_BEGIN(dyld_all_image_infos)
|
||||
// of the process_types structure matches the genuine 64-bit structure. This
|
||||
// is required because the alignment constraints on 64-bit types are more
|
||||
// stringent in 64-bit mode.
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64Only, alignment)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved32_64Only, alignment)
|
||||
|
||||
// const mach_header*
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Pointer, dyldImageLoadAddress)
|
||||
@ -80,31 +80,46 @@ PROCESS_TYPE_STRUCT_BEGIN(dyld_all_image_infos)
|
||||
// Version 7 (Mac OS X 10.6)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, systemOrderFlag)
|
||||
|
||||
// Version 8 (Mac OS X 10.7)
|
||||
// Version 8 (OS X 10.7)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, uuidArrayCount)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Pointer, uuidArray) // const dyld_uuid_info*
|
||||
|
||||
// Version 9 (Mac OS X 10.7)
|
||||
// Version 9 (OS X 10.7)
|
||||
// dyld_all_image_infos*
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Pointer, dyldAllImageInfosAddress)
|
||||
|
||||
// Version 10 (Mac OS X 10.7)
|
||||
// Version 10 (OS X 10.7)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, initialImageCount)
|
||||
|
||||
// Version 11 (Mac OS X 10.7)
|
||||
// Version 11 (OS X 10.7)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, errorKind)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Pointer, errorClientOfDylibPath) // const char*
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Pointer, errorTargetDylibPath) // const char*
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Pointer, errorSymbol) // const char*
|
||||
|
||||
// Version 12 (Mac OS X 10.7)
|
||||
// Version 12 (OS X 10.7)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, sharedCacheSlide)
|
||||
|
||||
// Version 13 (Mac OS X 10.9)
|
||||
// Version 13 (OS X 10.9)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(uint8_t, sharedCacheUUID, [16])
|
||||
|
||||
// Version 14 (Mac OS X 10.9)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, reserved, [16])
|
||||
// Version 15 (macOS 10.12)
|
||||
// This space is also allocated in version 14 (OS X 10.9) as part of the
|
||||
// “reserved” member.
|
||||
PROCESS_TYPE_STRUCT_MEMBER(uint64_t, infoArrayChangeTimestamp)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, sharedCacheBaseAddress)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Pointer, dyldPath) // const char*
|
||||
|
||||
// These should be considered mach_port_name_t when interacting with them from
|
||||
// another Mach IPC namespace (process).
|
||||
PROCESS_TYPE_STRUCT_MEMBER(mach_port_t, notifyPorts, [2])
|
||||
|
||||
// Version 14 (OS X 10.9)
|
||||
// As of the 10.12 SDK, this is declared as reserved[10] for 64-bit platforms
|
||||
// and reserved[12] for 32-bit platforms.
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, reserved, [10])
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_10)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_11)
|
||||
PROCESS_TYPE_STRUCT_END(dyld_all_image_infos)
|
||||
|
||||
#endif // ! PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO &&
|
||||
|
@ -36,7 +36,7 @@ PROCESS_TYPE_STRUCT_BEGIN(mach_header) // 64-bit: mach_header_64
|
||||
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, ncmds)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, sizeofcmds)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, flags)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64Only, reserved)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved32_64Only, reserved)
|
||||
PROCESS_TYPE_STRUCT_END(mach_header)
|
||||
|
||||
PROCESS_TYPE_STRUCT_BEGIN(load_command)
|
||||
@ -136,5 +136,5 @@ PROCESS_TYPE_STRUCT_BEGIN(section) // 64-bit: section_64
|
||||
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, flags)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, reserved1)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, reserved2)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64Only, reserved3)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved32_64Only, reserved3)
|
||||
PROCESS_TYPE_STRUCT_END(section)
|
||||
|
@ -22,9 +22,9 @@
|
||||
// DECLARE_PROCESS_TYPE_TRAITS_CLASS before #including this file again and after
|
||||
// the last #include of this file.
|
||||
//
|
||||
// |Reserved| is used for padding fields that may be zero-length, and thus
|
||||
// |Reserved*| are used for padding fields that may be zero-length, and thus
|
||||
// __VA_ARGS__, which is intended to set the alignment of the 64-bit types, is
|
||||
// not used for that type alias.
|
||||
// not used for those type aliases.
|
||||
#define DECLARE_PROCESS_TYPE_TRAITS_CLASS(traits_name, lp_bits, ...) \
|
||||
namespace crashpad { \
|
||||
namespace process_types { \
|
||||
@ -35,7 +35,8 @@
|
||||
using Pointer = uint##lp_bits##_t __VA_ARGS__; \
|
||||
using IntPtr = int##lp_bits##_t __VA_ARGS__; \
|
||||
using UIntPtr = uint##lp_bits##_t __VA_ARGS__; \
|
||||
using Reserved64Only = Reserved64Only##lp_bits; \
|
||||
using Reserved32_64Only = Reserved32_64Only##lp_bits; \
|
||||
using Reserved64_64Only = Reserved64_64Only##lp_bits; \
|
||||
}; \
|
||||
} \
|
||||
} \
|
||||
|
@ -47,7 +47,9 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
const struct dyld_all_image_infos* self_image_infos =
|
||||
_dyld_get_all_image_infos();
|
||||
int mac_os_x_minor_version = MacOSXMinorVersion();
|
||||
if (mac_os_x_minor_version >= 9) {
|
||||
if (mac_os_x_minor_version >= 12) {
|
||||
EXPECT_GE(self_image_infos->version, 15u);
|
||||
} else if (mac_os_x_minor_version >= 9) {
|
||||
EXPECT_GE(self_image_infos->version, 13u);
|
||||
} else if (mac_os_x_minor_version >= 7) {
|
||||
EXPECT_GE(self_image_infos->version, 8u);
|
||||
@ -96,6 +98,24 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
ProcessReader process_reader;
|
||||
ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
|
||||
const uint32_t kDyldAllImageInfosVersionInSDK = 15;
|
||||
#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
|
||||
const uint32_t kDyldAllImageInfosVersionInSDK = 14;
|
||||
#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
|
||||
const uint32_t kDyldAllImageInfosVersionInSDK = 12;
|
||||
#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||
const uint32_t kDyldAllImageInfosVersionInSDK = 7;
|
||||
#else
|
||||
const uint32_t kDyldAllImageInfosVersionInSDK = 1;
|
||||
#endif
|
||||
|
||||
// Make sure that the size of the structure as declared in the SDK matches the
|
||||
// size expected for the version of the structure that the SDK describes.
|
||||
EXPECT_EQ(sizeof(dyld_all_image_infos),
|
||||
process_types::dyld_all_image_infos::ExpectedSizeForVersion(
|
||||
&process_reader, kDyldAllImageInfosVersionInSDK));
|
||||
|
||||
process_types::dyld_all_image_infos proctype_image_infos;
|
||||
ASSERT_TRUE(proctype_image_infos.Read(&process_reader,
|
||||
dyld_info.all_image_info_addr));
|
||||
@ -194,13 +214,46 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
proctype_image_infos.sharedCacheUUID,
|
||||
sizeof(self_image_infos->sharedCacheUUID)));
|
||||
}
|
||||
#endif
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
|
||||
if (proctype_image_infos.version >= 15) {
|
||||
EXPECT_EQ(self_image_infos->infoArrayChangeTimestamp,
|
||||
proctype_image_infos.infoArrayChangeTimestamp);
|
||||
EXPECT_EQ(self_image_infos->sharedCacheBaseAddress,
|
||||
proctype_image_infos.sharedCacheBaseAddress);
|
||||
EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_infos->dyldPath),
|
||||
proctype_image_infos.dyldPath);
|
||||
for (size_t index = 0;
|
||||
index < arraysize(self_image_infos->notifyPorts);
|
||||
++index) {
|
||||
EXPECT_EQ(self_image_infos->notifyPorts[index],
|
||||
proctype_image_infos.notifyPorts[index]) << "index " << index;
|
||||
}
|
||||
|
||||
TEST_STRING(
|
||||
process_reader, self_image_infos, proctype_image_infos, dyldPath);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
|
||||
// As dyld_all_image_infos has evolved over time, new fields were added to the
|
||||
// reserved region. process_types::dyld_all_image_infos declares a recent
|
||||
// version of the structure, but an older SDK may declare an older version
|
||||
// whose |reserved| member appears at a different (smaller) offset than the
|
||||
// process_types version. It’s difficult to compare the reserved fields in
|
||||
// these older SDKs, so only do it where the declarations match.
|
||||
if (proctype_image_infos.version >= 14) {
|
||||
for (size_t index = 0; index < arraysize(self_image_infos->reserved);
|
||||
for (size_t index = 0;
|
||||
index < arraysize(proctype_image_infos.reserved);
|
||||
++index) {
|
||||
EXPECT_EQ(implicit_cast<uint64_t>(self_image_infos->reserved[index]),
|
||||
proctype_image_infos.reserved[index])
|
||||
<< "index " << index;
|
||||
}
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
EXPECT_EQ(self_image_infos->reserved[10], proctype_image_infos.reserved_10);
|
||||
EXPECT_EQ(self_image_infos->reserved[11], proctype_image_infos.reserved_11);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -213,7 +266,8 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
proctype_image_info_vector.size(),
|
||||
&proctype_image_info_vector[0]));
|
||||
|
||||
for (size_t index = 0; index < proctype_image_infos.infoArrayCount;
|
||||
for (size_t index = 0;
|
||||
index < proctype_image_infos.infoArrayCount;
|
||||
++index) {
|
||||
const dyld_image_info* self_image_info =
|
||||
&self_image_infos->infoArray[index];
|
||||
@ -245,7 +299,8 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
proctype_uuid_info_vector.size(),
|
||||
&proctype_uuid_info_vector[0]));
|
||||
|
||||
for (size_t index = 0; index < proctype_image_infos.uuidArrayCount;
|
||||
for (size_t index = 0;
|
||||
index < proctype_image_infos.uuidArrayCount;
|
||||
++index) {
|
||||
const dyld_uuid_info* self_uuid_info =
|
||||
&self_image_infos->uuidArray[index];
|
||||
|
Loading…
x
Reference in New Issue
Block a user