Files
clang-p2996/lldb/source/DataFormatters/CXXFunctionPointer.cpp
Greg Clayton c4fb7180cb [lldb][NFC] Make the target's SectionLoadList private. (#113278)
Lots of code around LLDB was directly accessing the target's section
load list. This NFC patch makes the section load list private so the
Target class can access it, but everyone else now uses accessor
functions. This allows us to control the resolving of addresses and will
allow for functionality in LLDB which can lazily resolve addresses in
JIT plug-ins with a future patch.
2025-01-14 20:12:46 -08:00

87 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/Target/ABI.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Stream.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/lldb-enumerations.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->HasLoadedSections()) {
target->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) {
if (valobj.GetValueType() == lldb::eValueTypeVTableEntry)
stream.PutCString(sstr.GetData());
else
stream.Printf("(%s)", sstr.GetData());
return true;
} else
return false;
}