1 //===-- CXXFunctionPointer.cpp---------------------------------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/DataFormatters/CXXFunctionPointer.h" 10 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" 17 18 #include <string> 19 20 using namespace lldb; 21 using namespace lldb_private; 22 using namespace lldb_private::formatters; 23 24 bool lldb_private::formatters::CXXFunctionPointerSummaryProvider( 25 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { 26 std::string destination; 27 StreamString sstr; 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: 35 break; 36 37 case eAddressTypeLoad: { 38 ExecutionContext exe_ctx(valobj.GetExecutionContextRef()); 39 40 Address so_addr; 41 Target *target = exe_ctx.GetTargetPtr(); 42 if (target && !target->GetSectionLoadList().IsEmpty()) { 43 target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, 44 so_addr); 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) { 57 Address test_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; 64 } 65 } 66 } 67 } 68 } 69 70 if (so_addr.IsValid()) { 71 so_addr.Dump(&sstr, exe_ctx.GetBestExecutionContextScope(), 72 Address::DumpStyleResolvedDescription, 73 Address::DumpStyleSectionNameOffset); 74 } 75 } 76 } break; 77 } 78 } 79 if (sstr.GetSize() > 0) { 80 if (valobj.GetValueType() == lldb::eValueTypeVTableEntry) 81 stream.PutCString(sstr.GetData()); 82 else 83 stream.Printf("(%s)", sstr.GetData()); 84 return true; 85 } else 86 return false; 87 } 88