diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -76,6 +76,8 @@ uint64_t GetMemoryCacheLineSize() const; Args GetExtraStartupCommands() const; void SetExtraStartupCommands(const Args &args); + uint64_t GetPointerAuthenticationAddressMask() const; + void SetPointerAuthenticationAddressMask(const uint64_t mask); FileSpec GetPythonOSPluginPath() const; void SetPythonOSPluginPath(const FileSpec &file); bool GetIgnoreBreakpointsInExpressions() const; diff --git a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h --- a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h +++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h @@ -62,6 +62,8 @@ return true; } + lldb::addr_t FixCodeAddress(lldb::addr_t pc) override; + // Static Functions static void Initialize(); diff --git a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp --- a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp +++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp @@ -815,6 +815,11 @@ return return_valobj_sp; } +lldb::addr_t ABIMacOSX_arm64::FixCodeAddress(lldb::addr_t pc) { + uint64_t mask = GetProcessSP()->GetPointerAuthenticationAddressMask(); + return mask ? pc & mask : pc; +} + void ABIMacOSX_arm64::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc, CreateInstance); diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -71,6 +71,7 @@ const MinidumpMiscInfo *GetMiscInfo(); llvm::Optional GetLinuxProcStatus(); + llvm::Optional GetPointerAuthenticationAddressMask(); llvm::Optional GetPid(); diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -232,6 +232,19 @@ return LinuxProcStatus::Parse(data); } + +llvm::Optional MinidumpParser::GetPointerAuthenticationAddressMask() { + llvm::ArrayRef data = GetStream(StreamType::CrashpadInfo); + + if (data.size() == 0 || data.size() < sizeof(CrashpadInfo)) + return llvm::None; + + const CrashpadInfo* crashpad_info = + reinterpret_cast(data.data()); + + return crashpad_info->pointer_authentication_address_mask; +} + llvm::Optional MinidumpParser::GetPid() { const MinidumpMiscInfo *misc_info = GetMiscInfo(); if (misc_info != nullptr) { @@ -660,6 +673,7 @@ ENUM_TO_CSTR(ProcessVMCounters); ENUM_TO_CSTR(LastReserved); ENUM_TO_CSTR(BreakpadInfo); + ENUM_TO_CSTR(CrashpadInfo); ENUM_TO_CSTR(AssertionInfo); ENUM_TO_CSTR(LinuxCPUInfo); ENUM_TO_CSTR(LinuxProcStatus); diff --git a/lldb/source/Plugins/Process/minidump/MinidumpTypes.h b/lldb/source/Plugins/Process/minidump/MinidumpTypes.h --- a/lldb/source/Plugins/Process/minidump/MinidumpTypes.h +++ b/lldb/source/Plugins/Process/minidump/MinidumpTypes.h @@ -102,6 +102,24 @@ LinuxProcStatus() = default; }; +struct GUID { + llvm::support::ulittle32_t data1; + llvm::support::ulittle16_t data2; + llvm::support::ulittle16_t data3; + uint8_t data4[8]; +}; +static_assert(sizeof(GUID) == 16, ""); + +struct CrashpadInfo { + uint32_t version; + GUID report_id; + GUID client_id; + LocationDescriptor simple_annotations; + LocationDescriptor module_list; + uint64_t pointer_authentication_address_mask; +}; +static_assert(sizeof(CrashpadInfo) == 64, ""); + } // namespace minidump } // namespace lldb_private #endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPTYPES_H diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -302,6 +302,11 @@ } SetID(pid.getValue()); + llvm::Optional mask = m_minidump_parser->GetPointerAuthenticationAddressMask(); + if (mask) { + SetPointerAuthenticationAddressMask(mask.getValue()); + } + return error; } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -195,6 +195,16 @@ m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args); } +uint64_t ProcessProperties::GetPointerAuthenticationAddressMask() const { + const uint32_t idx = ePropertyPointerAuthenticationAddressMask; + return m_collection_sp->GetPropertyAtIndexAsUInt64(nullptr, idx, g_process_properties[idx].default_uint_value); +} + +void ProcessProperties::SetPointerAuthenticationAddressMask(const uint64_t mask) { + const uint32_t idx = ePropertyPointerAuthenticationAddressMask; + m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, mask); +} + FileSpec ProcessProperties::GetPythonOSPluginPath() const { const uint32_t idx = ePropertyPythonOSPluginPath; return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td --- a/lldb/source/Target/TargetProperties.td +++ b/lldb/source/Target/TargetProperties.td @@ -199,6 +199,9 @@ Global, DefaultTrue, Desc<"If true, errors in expression evaluation will unwind the stack back to the state before the call.">; + def PointerAuthenticationAddressMask: Property<"pointer-authentication-address-mask", "UInt64">, + DefaultUnsignedValue<0>, + Desc<"The mask to strip pointer authentication codes. `AND` this mask with the pointer to recover an address. The default value of 0 means unspecified.">; def PythonOSPluginPath: Property<"python-os-plugin-path", "FileSpec">, DefaultUnsignedValue<1>, Desc<"A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class.">; diff --git a/llvm/include/llvm/BinaryFormat/MinidumpConstants.def b/llvm/include/llvm/BinaryFormat/MinidumpConstants.def --- a/llvm/include/llvm/BinaryFormat/MinidumpConstants.def +++ b/llvm/include/llvm/BinaryFormat/MinidumpConstants.def @@ -56,6 +56,8 @@ HANDLE_MDMP_STREAM_TYPE(0x0014, JavascriptData) HANDLE_MDMP_STREAM_TYPE(0x0015, SystemMemoryInfo) HANDLE_MDMP_STREAM_TYPE(0x0016, ProcessVMCounters) +// Crashpad extension types. 0x4350 = "CP" +HANDLE_MDMP_STREAM_TYPE(0x43500001, CrashpadInfo) // Breakpad extension types. 0x4767 = "Gg" HANDLE_MDMP_STREAM_TYPE(0x47670001, BreakpadInfo) HANDLE_MDMP_STREAM_TYPE(0x47670002, AssertionInfo)