1 //===-- CXXFunctionPointer.cpp---------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/DataFormatters/CXXFunctionPointer.h"
11 #include "lldb/Core/ValueObject.h"
12 #include "lldb/Target/ABI.h"
13 #include "lldb/Target/SectionLoadList.h"
14 #include "lldb/Target/Target.h"
15 #include "lldb/Utility/Stream.h"
16 #include "lldb/lldb-enumerations.h"
21 using namespace lldb_private
;
22 using namespace lldb_private::formatters
;
24 bool lldb_private::formatters::CXXFunctionPointerSummaryProvider(
25 ValueObject
&valobj
, Stream
&stream
, const TypeSummaryOptions
&options
) {
26 std::string destination
;
28 AddressType func_ptr_address_type
= eAddressTypeInvalid
;
29 addr_t func_ptr_address
= valobj
.GetPointerValue(&func_ptr_address_type
);
30 if (func_ptr_address
!= 0 && func_ptr_address
!= LLDB_INVALID_ADDRESS
) {
31 switch (func_ptr_address_type
) {
32 case eAddressTypeInvalid
:
33 case eAddressTypeFile
:
34 case eAddressTypeHost
:
37 case eAddressTypeLoad
: {
38 ExecutionContext
exe_ctx(valobj
.GetExecutionContextRef());
41 Target
*target
= exe_ctx
.GetTargetPtr();
42 if (target
&& !target
->GetSectionLoadList().IsEmpty()) {
43 target
->GetSectionLoadList().ResolveLoadAddress(func_ptr_address
,
45 if (so_addr
.GetSection() == nullptr) {
46 // If we have an address that doesn't correspond to any symbol,
47 // it might have authentication bits. Strip them & see if it
48 // now points to a symbol -- if so, do the SymbolContext lookup
49 // based on the stripped address.
50 // If we find a symbol with the ptrauth bits stripped, print the
51 // raw value into the stream, and replace the Address with the
52 // one that points to a symbol for a fuller description.
53 if (Process
*process
= exe_ctx
.GetProcessPtr()) {
54 if (ABISP abi_sp
= process
->GetABI()) {
55 addr_t fixed_addr
= abi_sp
->FixCodeAddress(func_ptr_address
);
56 if (fixed_addr
!= func_ptr_address
) {
58 test_address
.SetLoadAddress(fixed_addr
, target
);
59 if (test_address
.GetSection() != nullptr) {
60 int addrsize
= target
->GetArchitecture().GetAddressByteSize();
61 sstr
.Printf("actual=0x%*.*" PRIx64
" ", addrsize
* 2,
62 addrsize
* 2, fixed_addr
);
63 so_addr
= test_address
;
70 if (so_addr
.IsValid()) {
71 so_addr
.Dump(&sstr
, exe_ctx
.GetBestExecutionContextScope(),
72 Address::DumpStyleResolvedDescription
,
73 Address::DumpStyleSectionNameOffset
);
79 if (sstr
.GetSize() > 0) {
80 if (valobj
.GetValueType() == lldb::eValueTypeVTableEntry
)
81 stream
.PutCString(sstr
.GetData());
83 stream
.Printf("(%s)", sstr
.GetData());