
With arm64e ARMv8.3 pointer authentication, lldb needs to know how many bits are used for addressing and how many are used for pointer auth signing. This should be determined dynamically from the inferior system / corefile, but there are some workflows where it still isn't recorded and we fall back on a default value that is correct on some Darwin environments. This patch also explicitly sets the vendor of mach-o binaries to Apple, so we select an Apple ABI instead of a random other ABI. It adds a function pointer formatter for systems where pointer authentication is in use, and we can strip the ptrauth bits off of the function pointer address and get a different value that points to an actual symbol. Differential Revision: https://reviews.llvm.org/D115431 rdar://84644661
84 lines
3.2 KiB
C++
84 lines
3.2 KiB
C++
//===-- CXXFunctionPointer.cpp---------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/DataFormatters/CXXFunctionPointer.h"
|
|
|
|
#include "lldb/Core/ValueObject.h"
|
|
#include "lldb/Target/ABI.h"
|
|
#include "lldb/Target/SectionLoadList.h"
|
|
#include "lldb/Target/Target.h"
|
|
#include "lldb/Utility/Stream.h"
|
|
|
|
#include <string>
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
using namespace lldb_private::formatters;
|
|
|
|
bool lldb_private::formatters::CXXFunctionPointerSummaryProvider(
|
|
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
|
|
std::string destination;
|
|
StreamString sstr;
|
|
AddressType func_ptr_address_type = eAddressTypeInvalid;
|
|
addr_t func_ptr_address = valobj.GetPointerValue(&func_ptr_address_type);
|
|
if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) {
|
|
switch (func_ptr_address_type) {
|
|
case eAddressTypeInvalid:
|
|
case eAddressTypeFile:
|
|
case eAddressTypeHost:
|
|
break;
|
|
|
|
case eAddressTypeLoad: {
|
|
ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
|
|
|
|
Address so_addr;
|
|
Target *target = exe_ctx.GetTargetPtr();
|
|
if (target && !target->GetSectionLoadList().IsEmpty()) {
|
|
target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address,
|
|
so_addr);
|
|
if (so_addr.GetSection() == nullptr) {
|
|
// If we have an address that doesn't correspond to any symbol,
|
|
// it might have authentication bits. Strip them & see if it
|
|
// now points to a symbol -- if so, do the SymbolContext lookup
|
|
// based on the stripped address.
|
|
// If we find a symbol with the ptrauth bits stripped, print the
|
|
// raw value into the stream, and replace the Address with the
|
|
// one that points to a symbol for a fuller description.
|
|
if (Process *process = exe_ctx.GetProcessPtr()) {
|
|
if (ABISP abi_sp = process->GetABI()) {
|
|
addr_t fixed_addr = abi_sp->FixCodeAddress(func_ptr_address);
|
|
if (fixed_addr != func_ptr_address) {
|
|
Address test_address;
|
|
test_address.SetLoadAddress(fixed_addr, target);
|
|
if (test_address.GetSection() != nullptr) {
|
|
int addrsize = target->GetArchitecture().GetAddressByteSize();
|
|
sstr.Printf("actual=0x%*.*" PRIx64 " ", addrsize * 2,
|
|
addrsize * 2, fixed_addr);
|
|
so_addr = test_address;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (so_addr.IsValid()) {
|
|
so_addr.Dump(&sstr, exe_ctx.GetBestExecutionContextScope(),
|
|
Address::DumpStyleResolvedDescription,
|
|
Address::DumpStyleSectionNameOffset);
|
|
}
|
|
}
|
|
} break;
|
|
}
|
|
}
|
|
if (sstr.GetSize() > 0) {
|
|
stream.Printf("(%s)", sstr.GetData());
|
|
return true;
|
|
} else
|
|
return false;
|
|
}
|