diff options
Diffstat (limited to 'source/Plugins')
252 files changed, 11181 insertions, 10492 deletions
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp index 362a80be4b0d..9dff12bcc748 100644 --- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp +++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp @@ -1326,7 +1326,8 @@ ABIMacOSX_arm::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { if (vendor_type == llvm::Triple::Apple) { if ((arch_type == llvm::Triple::arm) || (arch_type == llvm::Triple::thumb)) { - return ABISP(new ABIMacOSX_arm(process_sp)); + return ABISP( + new ABIMacOSX_arm(std::move(process_sp), MakeMCRegisterInfo(arch))); } } @@ -1846,6 +1847,7 @@ bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("arm-apple-ios default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h index ac9ba00b9d91..e512651f86e5 100644 --- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h +++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h @@ -85,7 +85,9 @@ protected: lldb_private::CompilerType &ast_type) const override; private: - ABIMacOSX_arm(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABIMacOSX_arm(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp index 368e37213249..6473ccf9a19a 100644 --- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp +++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp @@ -1665,8 +1665,10 @@ ABIMacOSX_arm64::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor(); if (vendor_type == llvm::Triple::Apple) { - if (arch_type == llvm::Triple::aarch64) { - return ABISP(new ABIMacOSX_arm64(process_sp)); + if (arch_type == llvm::Triple::aarch64 || + arch_type == llvm::Triple::aarch64_32) { + return ABISP( + new ABIMacOSX_arm64(std::move(process_sp), MakeMCRegisterInfo(arch))); } } @@ -1710,9 +1712,8 @@ bool ABIMacOSX_arm64::PrepareTrivialCall( for (size_t i = 0; i < args.size(); ++i) { const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); - if (log) - log->Printf("About to write arg%d (0x%" PRIx64 ") into %s", - static_cast<int>(i + 1), args[i], reg_info->name); + LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s", + static_cast<int>(i + 1), args[i], reg_info->name); if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) return false; } @@ -2011,6 +2012,7 @@ bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h index bfacbcd54a94..c7a91ba9c468 100644 --- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h +++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h @@ -93,7 +93,9 @@ protected: lldb_private::CompilerType &ast_type) const override; private: - ABIMacOSX_arm64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABIMacOSX_arm64(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index 67371b432ff8..76ebd6476ffd 100644 --- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -710,7 +710,8 @@ ABIMacOSX_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) if ((arch.GetTriple().getArch() == llvm::Triple::x86) && (arch.GetTriple().isMacOSX() || arch.GetTriple().isiOS() || arch.GetTriple().isWatchOS())) { - return ABISP(new ABIMacOSX_i386(process_sp)); + return ABISP( + new ABIMacOSX_i386(std::move(process_sp), MakeMCRegisterInfo(arch))); } return ABISP(); } @@ -1055,6 +1056,7 @@ bool ABIMacOSX_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("i386 default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h index 57def683283f..50062b84d878 100644 --- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h +++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h @@ -92,7 +92,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABIMacOSX_i386(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABIMacOSX_i386(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp b/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp new file mode 100644 index 000000000000..715b5e5d2b95 --- /dev/null +++ b/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp @@ -0,0 +1,614 @@ +//===-- ABISysV_arc.cpp ---------------------------------------*- C++ -*-===// +// +// 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 "ABISysV_arc.h" + +// C Includes +// C++ Includes +#include <array> +#include <limits> +#include <type_traits> + +// Other libraries and framework includes +#include "llvm/ADT/Triple.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/Support/MathExtras.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +#define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString() +#define DEFINE_REG_NAME_STR(reg_name) ConstString(reg_name).GetCString() + +// The ABI is not a source of such information as size, offset, encoding, etc. +// of a register. Just provides correct dwarf and eh_frame numbers. + +#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num) \ + { \ + DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name), \ + 0, 0, eEncodingInvalid, eFormatDefault, \ + { dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num }, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEFINE_REGISTER_STUB(dwarf_num, str_name) \ + DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, LLDB_INVALID_REGNUM) + +using namespace lldb; +using namespace lldb_private; + +namespace { +namespace dwarf { +enum regnums { + r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, + r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, + r27, fp = r27, r28, sp = r28, r29, r30, r31, blink = r31, + r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, + r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60, + /*reserved,*/ /*limm indicator,*/ r63 = 63, pc = 70, status32 = 74 +}; + +static const std::array<RegisterInfo, 64> g_register_infos = { { + DEFINE_GENERIC_REGISTER_STUB(r0, nullptr, LLDB_REGNUM_GENERIC_ARG1), + DEFINE_GENERIC_REGISTER_STUB(r1, nullptr, LLDB_REGNUM_GENERIC_ARG2), + DEFINE_GENERIC_REGISTER_STUB(r2, nullptr, LLDB_REGNUM_GENERIC_ARG3), + DEFINE_GENERIC_REGISTER_STUB(r3, nullptr, LLDB_REGNUM_GENERIC_ARG4), + DEFINE_GENERIC_REGISTER_STUB(r4, nullptr, LLDB_REGNUM_GENERIC_ARG5), + DEFINE_GENERIC_REGISTER_STUB(r5, nullptr, LLDB_REGNUM_GENERIC_ARG6), + DEFINE_GENERIC_REGISTER_STUB(r6, nullptr, LLDB_REGNUM_GENERIC_ARG7), + DEFINE_GENERIC_REGISTER_STUB(r7, nullptr, LLDB_REGNUM_GENERIC_ARG8), + DEFINE_REGISTER_STUB(r8, nullptr), + DEFINE_REGISTER_STUB(r9, nullptr), + DEFINE_REGISTER_STUB(r10, nullptr), + DEFINE_REGISTER_STUB(r11, nullptr), + DEFINE_REGISTER_STUB(r12, nullptr), + DEFINE_REGISTER_STUB(r13, nullptr), + DEFINE_REGISTER_STUB(r14, nullptr), + DEFINE_REGISTER_STUB(r15, nullptr), + DEFINE_REGISTER_STUB(r16, nullptr), + DEFINE_REGISTER_STUB(r17, nullptr), + DEFINE_REGISTER_STUB(r18, nullptr), + DEFINE_REGISTER_STUB(r19, nullptr), + DEFINE_REGISTER_STUB(r20, nullptr), + DEFINE_REGISTER_STUB(r21, nullptr), + DEFINE_REGISTER_STUB(r22, nullptr), + DEFINE_REGISTER_STUB(r23, nullptr), + DEFINE_REGISTER_STUB(r24, nullptr), + DEFINE_REGISTER_STUB(r25, nullptr), + DEFINE_REGISTER_STUB(r26, "gp"), + DEFINE_GENERIC_REGISTER_STUB(r27, "fp", LLDB_REGNUM_GENERIC_FP), + DEFINE_GENERIC_REGISTER_STUB(r28, "sp", LLDB_REGNUM_GENERIC_SP), + DEFINE_REGISTER_STUB(r29, "ilink"), + DEFINE_REGISTER_STUB(r30, nullptr), + DEFINE_GENERIC_REGISTER_STUB(r31, "blink", LLDB_REGNUM_GENERIC_RA), + DEFINE_REGISTER_STUB(r32, nullptr), + DEFINE_REGISTER_STUB(r33, nullptr), + DEFINE_REGISTER_STUB(r34, nullptr), + DEFINE_REGISTER_STUB(r35, nullptr), + DEFINE_REGISTER_STUB(r36, nullptr), + DEFINE_REGISTER_STUB(r37, nullptr), + DEFINE_REGISTER_STUB(r38, nullptr), + DEFINE_REGISTER_STUB(r39, nullptr), + DEFINE_REGISTER_STUB(r40, nullptr), + DEFINE_REGISTER_STUB(r41, nullptr), + DEFINE_REGISTER_STUB(r42, nullptr), + DEFINE_REGISTER_STUB(r43, nullptr), + DEFINE_REGISTER_STUB(r44, nullptr), + DEFINE_REGISTER_STUB(r45, nullptr), + DEFINE_REGISTER_STUB(r46, nullptr), + DEFINE_REGISTER_STUB(r47, nullptr), + DEFINE_REGISTER_STUB(r48, nullptr), + DEFINE_REGISTER_STUB(r49, nullptr), + DEFINE_REGISTER_STUB(r50, nullptr), + DEFINE_REGISTER_STUB(r51, nullptr), + DEFINE_REGISTER_STUB(r52, nullptr), + DEFINE_REGISTER_STUB(r53, nullptr), + DEFINE_REGISTER_STUB(r54, nullptr), + DEFINE_REGISTER_STUB(r55, nullptr), + DEFINE_REGISTER_STUB(r56, nullptr), + DEFINE_REGISTER_STUB(r57, nullptr), + DEFINE_REGISTER_STUB(r58, "accl"), + DEFINE_REGISTER_STUB(r59, "acch"), + DEFINE_REGISTER_STUB(r60, "lp_count"), + DEFINE_REGISTER_STUB(r63, "pcl"), + DEFINE_GENERIC_REGISTER_STUB(pc, nullptr, LLDB_REGNUM_GENERIC_PC), + DEFINE_GENERIC_REGISTER_STUB(status32, nullptr, LLDB_REGNUM_GENERIC_FLAGS)} }; +} // namespace dwarf +} // namespace + +const RegisterInfo *ABISysV_arc::GetRegisterInfoArray(uint32_t &count) { + count = dwarf::g_register_infos.size(); + return dwarf::g_register_infos.data(); +} + +size_t ABISysV_arc::GetRedZoneSize() const { return 0; } + +bool ABISysV_arc::IsRegisterFileReduced(RegisterContext ®_ctx) const { + if (!m_is_reg_file_reduced) { + const auto *const rf_build_reg = reg_ctx.GetRegisterInfoByName("rf_build"); + + const auto reg_value = reg_ctx.ReadRegisterAsUnsigned(rf_build_reg, + /*fail_value*/ 0); + // RF_BUILD "Number of Entries" bit. + const uint32_t rf_entries_bit = 1U << 9U; + m_is_reg_file_reduced = (reg_value | rf_entries_bit) != 0; + } + + return m_is_reg_file_reduced.getValueOr(false); +} + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ + +ABISP ABISysV_arc::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { + return llvm::Triple::arc == arch.GetTriple().getArch() ? + ABISP(new ABISysV_arc(std::move(process_sp), MakeMCRegisterInfo(arch))) : + ABISP(); +} + +namespace { +const size_t word_size = 4U; +const size_t reg_size = word_size; + +inline size_t AugmentArgSize(size_t size_in_bytes) { + return llvm::alignTo(size_in_bytes, word_size); +} + +size_t TotalArgsSizeInWords(const llvm::ArrayRef<ABI::CallArgument> &args) { + size_t total_size = 0; + for (const auto &arg : args) + total_size += + (ABI::CallArgument::TargetValue == arg.type ? AugmentArgSize(arg.size) + : reg_size) / + word_size; + + return total_size; +} +} // namespace + +bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef<addr_t> args) const { + // We don't use the traditional trivial call specialized for jit. + return false; +} + +bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t pc, + addr_t ra, llvm::Type &prototype, + llvm::ArrayRef<ABI::CallArgument> args) const { + auto reg_ctx = thread.GetRegisterContext(); + if (!reg_ctx) + return false; + + uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + if (pc_reg == LLDB_INVALID_REGNUM) + return false; + + uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + if (ra_reg == LLDB_INVALID_REGNUM) + return false; + + uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + if (sp_reg == LLDB_INVALID_REGNUM) + return false; + + Status error; + ProcessSP process = thread.GetProcess(); + if (!process) + return false; + + // Push host data onto target. + for (const auto &arg : args) { + // Skip over target values. + if (arg.type == ABI::CallArgument::TargetValue) + continue; + + // Create space on the stack for this data 4-byte aligned. + sp -= AugmentArgSize(arg.size); + + if (process->WriteMemory(sp, arg.data_up.get(), arg.size, error) < arg.size + || error.Fail()) + return false; + + // Update the argument with the target pointer. + *const_cast<addr_t *>(&arg.value) = sp; + } + + // Make sure number of parameters matches prototype. + assert(!prototype.isFunctionVarArg()); + assert(prototype.getFunctionNumParams() == args.size()); + + const size_t regs_for_args_count = IsRegisterFileReduced(*reg_ctx) ? 4U : 8U; + + // Number of arguments passed on stack. + auto args_size = TotalArgsSizeInWords(args); + auto on_stack = + args_size <= regs_for_args_count ? 0 : args_size - regs_for_args_count; + auto offset = on_stack * word_size; + + uint8_t reg_value[reg_size]; + size_t reg_index = LLDB_REGNUM_GENERIC_ARG1; + + for (const auto &arg : args) { + auto value = reinterpret_cast<const uint8_t *>(&arg.value); + auto size = + ABI::CallArgument::TargetValue == arg.type ? arg.size : reg_size; + + // Pass arguments via registers. + while (size > 0 && reg_index < regs_for_args_count) { + size_t byte_index = 0; + auto end = size < reg_size ? size : reg_size; + + while (byte_index < end) { + reg_value[byte_index++] = *(value++); + --size; + } + + while (byte_index < reg_size) { + reg_value[byte_index++] = 0; + } + + RegisterValue reg_val_obj(reg_value, reg_size, eByteOrderLittle); + if (!reg_ctx->WriteRegister( + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_index), + reg_val_obj)) + return false; + + // NOTE: It's unsafe to iterate through LLDB_REGNUM_GENERICs. + ++reg_index; + } + + if (reg_index < regs_for_args_count || size == 0) + continue; + + // Remaining arguments are passed on the stack. + if (process->WriteMemory(sp - offset, value, size, error) < size || + !error.Success()) + return false; + + offset -= AugmentArgSize(size); + } + + // Set stack pointer immediately below arguments. + sp -= on_stack * word_size; + + // Update registers with current function call state. + reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc); + reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra); + reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp); + + return true; +} + +bool ABISysV_arc::GetArgumentValues(Thread &thread, ValueList &values) const { + return false; +} + +Status ABISysV_arc::SetReturnValueObject(StackFrameSP &frame_sp, + ValueObjectSP &new_value_sp) { + Status result; + if (!new_value_sp) { + result.SetErrorString("Empty value object for return value."); + return result; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + result.SetErrorString("Null clang type for return value."); + return result; + } + + auto ®_ctx = *frame_sp->GetThread()->GetRegisterContext(); + + bool is_signed = false; + if (!compiler_type.IsIntegerOrEnumerationType(is_signed) && + !compiler_type.IsPointerType()) { + result.SetErrorString("We don't support returning other types at present"); + return result; + } + + DataExtractor data; + size_t num_bytes = new_value_sp->GetData(data, result); + + if (result.Fail()) { + result.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", result.AsCString()); + return result; + } + + if (num_bytes <= 2 * reg_size) { + offset_t offset = 0; + uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); + + auto reg_info = + reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) { + result.SetErrorStringWithFormat("Couldn't write value to register %s", + reg_info->name); + return result; + } + + if (num_bytes <= reg_size) + return result; // Successfully written. + + raw_value >>= 32; + reg_info = + reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); + if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) { + result.SetErrorStringWithFormat("Couldn't write value to register %s", + reg_info->name); + } + + return result; + } + + result.SetErrorString( + "We don't support returning large integer values at present."); + return result; +} + +namespace { +template <typename T> +void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) { + raw_value &= std::numeric_limits<T>::max(); + if (is_signed) + scalar = static_cast<typename std::make_signed<T>::type>(raw_value); + else + scalar = static_cast<T>(raw_value); +} + +bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes, + bool is_signed) { + switch (size_in_bytes) { + default: + return false; + + case sizeof(uint64_t): + SetInteger<uint64_t>(scalar, raw_value, is_signed); + break; + + case sizeof(uint32_t): + SetInteger<uint32_t>(scalar, raw_value, is_signed); + break; + + case sizeof(uint16_t): + SetInteger<uint16_t>(scalar, raw_value, is_signed); + break; + + case sizeof(uint8_t): + SetInteger<uint8_t>(scalar, raw_value, is_signed); + break; + } + + return true; +} + +bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes) { + switch (size_in_bytes) { + default: + return false; + + case sizeof(uint64_t): + scalar = *reinterpret_cast<double *>(&raw_value); + break; + + case sizeof(uint32_t): + scalar = *reinterpret_cast<float *>(&raw_value); + break; + } + + return true; +} + +uint64_t ReadRawValue(const RegisterContextSP ®_ctx, uint8_t size_in_bytes) { + auto reg_info_r0 = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + + // Extract the register context so we can read arguments from registers. + uint64_t raw_value = + reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0) & UINT32_MAX; + + if (sizeof(uint64_t) == size_in_bytes) + raw_value |= (reg_ctx->ReadRegisterAsUnsigned( + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG2), 0) & + UINT64_MAX) << 32U; + + return raw_value; +} +} // namespace + +ValueObjectSP +ABISysV_arc::GetReturnValueObjectSimple(Thread &thread, + CompilerType &compiler_type) const { + if (!compiler_type) + return ValueObjectSP(); + + auto reg_ctx = thread.GetRegisterContext(); + if (!reg_ctx) + return ValueObjectSP(); + + Value value; + value.SetCompilerType(compiler_type); + + const uint32_t type_flags = compiler_type.GetTypeInfo(); + // Integer return type. + if (type_flags & eTypeIsInteger) { + const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0); + auto raw_value = ReadRawValue(reg_ctx, byte_size); + + const bool is_signed = (type_flags & eTypeIsSigned) != 0; + if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed)) + return ValueObjectSP(); + + value.SetValueType(Value::eValueTypeScalar); + } + // Pointer return type. + else if (type_flags & eTypeIsPointer) { + auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1); + value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0); + + value.SetValueType(Value::eValueTypeScalar); + } + // Floating point return type. + else if (type_flags & eTypeIsFloat) { + uint32_t float_count = 0; + bool is_complex = false; + + if (compiler_type.IsFloatingPointType(float_count, is_complex) && + 1 == float_count && !is_complex) { + const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0); + auto raw_value = ReadRawValue(reg_ctx, byte_size); + + if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size)) + return ValueObjectSP(); + } + } + // Unsupported return type. + else + return ValueObjectSP(); + + return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), + value, ConstString("")); +} + +ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + + if (!return_compiler_type) + return return_valobj_sp; + + ExecutionContext exe_ctx(thread.shared_from_this()); + return GetReturnValueObjectSimple(thread, return_compiler_type); +} + +ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(Thread &thread, + llvm::Type &retType) const { + auto reg_ctx = thread.GetRegisterContext(); + if (!reg_ctx) + return ValueObjectSP(); + + Value value; + // Void return type. + if (retType.isVoidTy()) { + value.GetScalar() = 0; + } + // Integer return type. + else if (retType.isIntegerTy()) { + size_t byte_size = retType.getPrimitiveSizeInBits(); + if (1 != byte_size) // For boolian type. + byte_size /= CHAR_BIT; + + auto raw_value = ReadRawValue(reg_ctx, byte_size); + + const bool is_signed = false; // IR Type doesn't provide this info. + if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed)) + return ValueObjectSP(); + } + // Pointer return type. + else if (retType.isPointerTy()) { + auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1); + value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0); + value.SetValueType(Value::eValueTypeScalar); + } + // Floating point return type. + else if (retType.isFloatingPointTy()) { + const size_t byte_size = retType.getPrimitiveSizeInBits() / CHAR_BIT; + auto raw_value = ReadRawValue(reg_ctx, byte_size); + + if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size)) + return ValueObjectSP(); + } + // Unsupported return type. + else + return ValueObjectSP(); + + return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), + value, ConstString("")); +} + +bool ABISysV_arc::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value. + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf::sp, 0); + + // The previous PC is in the BLINK. + row->SetRegisterLocationToRegister(dwarf::pc, dwarf::blink, true); + unwind_plan.AppendRow(row); + + // All other registers are the same. + unwind_plan.SetSourceName("arc at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + + return true; +} + +bool ABISysV_arc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + return false; +} + +bool ABISysV_arc::RegisterIsVolatile(const RegisterInfo *reg_info) { + if (nullptr == reg_info) + return false; + + // Volatile registers are: r0..r12. + uint32_t regnum = reg_info->kinds[eRegisterKindDWARF]; + if (regnum <= 12) + return true; + + static const std::string ra_reg_name = "blink"; + return ra_reg_name == reg_info->name; +} + +void ABISysV_arc::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "System V ABI for ARC targets", CreateInstance); +} + +void ABISysV_arc::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ConstString ABISysV_arc::GetPluginNameStatic() { + static ConstString g_name("sysv-arc"); + return g_name; +} + +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ + +ConstString ABISysV_arc::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_arc::GetPluginVersion() { return 1; } diff --git a/source/Plugins/ABI/SysV-arc/ABISysV_arc.h b/source/Plugins/ABI/SysV-arc/ABISysV_arc.h new file mode 100644 index 000000000000..c4b26a54158c --- /dev/null +++ b/source/Plugins/ABI/SysV-arc/ABISysV_arc.h @@ -0,0 +1,106 @@ +//===-- ArchitectureArc.h ---------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ABISysV_arc_h_ +#define liblldb_ABISysV_arc_h_ + +// Other libraries and framework includes +#include <llvm/ADT/Optional.h> + +// Project includes +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_arc : public lldb_private::ABI { +public: + ~ABISysV_arc() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef<lldb::addr_t> args) const override; + + // Special thread plan for GDB style non-jit function calls. + bool + PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, lldb::addr_t returnAddress, + llvm::Type &prototype, + llvm::ArrayRef<ABI::CallArgument> args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + // Specialized to work with llvm IR types. + lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, + llvm::Type &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Stack call frame address must be 4 byte aligned. + return (cfa & 0x3ull) == 0; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // Code addresse must be 2 byte aligned. + return (pc & 1ull) == 0; + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, + const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +private: + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool IsRegisterFileReduced(lldb_private::RegisterContext ®_ctx) const; + + using lldb_private::ABI::ABI; // Call CreateInstance instead. + + using RegisterFileFlag = llvm::Optional<bool>; + mutable RegisterFileFlag m_is_reg_file_reduced; +}; + +#endif // liblldb_ABISysV_arc_h_ diff --git a/source/Plugins/ABI/SysV-arc/CMakeLists.txt b/source/Plugins/ABI/SysV-arc/CMakeLists.txt new file mode 100644 index 000000000000..3dc0d1c65b46 --- /dev/null +++ b/source/Plugins/ABI/SysV-arc/CMakeLists.txt @@ -0,0 +1,11 @@ +add_lldb_library(lldbPluginABISysV_arc PLUGIN + ABISysV_arc.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + lldbPluginProcessUtility + LINK_COMPONENTS + Support + ) diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp index dd47ac7cbe3c..b6e8f8806829 100644 --- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp +++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp @@ -1327,7 +1327,8 @@ ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { if (vendor_type != llvm::Triple::Apple) { if ((arch_type == llvm::Triple::arm) || (arch_type == llvm::Triple::thumb)) { - return ABISP(new ABISysV_arm(process_sp)); + return ABISP( + new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch))); } } @@ -1960,6 +1961,7 @@ bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("arm default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h index a0f00c8f227d..60fb14be5f7b 100644 --- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h +++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h @@ -85,7 +85,9 @@ protected: lldb_private::CompilerType &ast_type) const override; private: - ABISysV_arm(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_arm(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp index 1d547121e231..89a1f2b3cf04 100644 --- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp +++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp @@ -1668,8 +1668,10 @@ ABISysV_arm64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor(); if (vendor_type != llvm::Triple::Apple) { - if (arch_type == llvm::Triple::aarch64) { - return ABISP(new ABISysV_arm64(process_sp)); + if (arch_type == llvm::Triple::aarch64 || + arch_type == llvm::Triple::aarch64_32) { + return ABISP( + new ABISysV_arm64(std::move(process_sp), MakeMCRegisterInfo(arch))); } } @@ -1706,9 +1708,8 @@ bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp, for (size_t i = 0; i < args.size(); ++i) { const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); - if (log) - log->Printf("About to write arg%d (0x%" PRIx64 ") into %s", - static_cast<int>(i + 1), args[i], reg_info->name); + LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s", + static_cast<int>(i + 1), args[i], reg_info->name); if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) return false; } @@ -1958,6 +1959,7 @@ bool ABISysV_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("arm64 at-func-entry default"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } @@ -1982,6 +1984,7 @@ bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("arm64 default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h index 1fbdc793ed6e..1bf5773e2db3 100644 --- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h +++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h @@ -92,7 +92,9 @@ protected: lldb_private::CompilerType &ast_type) const override; private: - ABISysV_arm64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_arm64(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp index 93647564fe25..34d9258ccb92 100644 --- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp +++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp @@ -1014,7 +1014,8 @@ size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; } ABISP ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { if (arch.GetTriple().getArch() == llvm::Triple::hexagon) { - return ABISP(new ABISysV_hexagon(process_sp)); + return ABISP( + new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch))); } return ABISP(); } @@ -1247,6 +1248,7 @@ bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("hexagon default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h index 459b6315dba2..bef64a22d95f 100644 --- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h +++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h @@ -97,7 +97,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABISysV_hexagon(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_hexagon(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp index 05f5dba90687..69e4cff90ebf 100644 --- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp +++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp @@ -198,7 +198,8 @@ ABISP ABISysV_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { if (arch.GetTriple().getVendor() != llvm::Triple::Apple) { if (arch.GetTriple().getArch() == llvm::Triple::x86) { - return ABISP(new ABISysV_i386(process_sp)); + return ABISP( + new ABISysV_i386(std::move(process_sp), MakeMCRegisterInfo(arch))); } } return ABISP(); @@ -785,6 +786,7 @@ bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("i386 default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h index 982bdd676b74..2362e9adda98 100644 --- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h +++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h @@ -100,7 +100,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABISysV_i386(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_i386(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp index 121c7300b968..416db9f5ae87 100644 --- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp +++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp @@ -556,7 +556,8 @@ ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); if ((arch_type == llvm::Triple::mips) || (arch_type == llvm::Triple::mipsel)) { - return ABISP(new ABISysV_mips(process_sp)); + return ABISP( + new ABISysV_mips(std::move(process_sp), MakeMCRegisterInfo(arch))); } return ABISP(); } @@ -600,9 +601,8 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp, reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); - if (log) - log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, - args[i], reg_info->name); + LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, + args[i], reg_info->name); if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) return false; @@ -630,9 +630,8 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp, size_t i = 4; for (; ai != ae; ++ai) { reg_value.SetUInt32(*ai); - if (log) - log->Printf("About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "", - i + 1, args[i], arg_pos); + LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "", + i + 1, args[i], arg_pos); if (reg_ctx ->WriteRegisterValueToMemory(reg_info, arg_pos, @@ -654,8 +653,7 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp, const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0); const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0); - if (log) - log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0); + LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0); /* Write r0 with 0, in case we are stopped in syscall, * such setting prevents automatic decrement of the PC. @@ -664,29 +662,25 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp, if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0)) return false; - if (log) - log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp); + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); // Set "sp" to the requested value if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) return false; - if (log) - log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr); + LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr); // Set "ra" to the return address if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr)) return false; - if (log) - log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr); // Set pc to the address of the called function. if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) return false; - if (log) - log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr); // All callers of position independent functions must place the address of // the called function in t9 (r25) @@ -997,6 +991,7 @@ bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("mips default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h index 6cd9c19c22ac..8143f552fc4d 100644 --- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h +++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h @@ -87,7 +87,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABISysV_mips(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_mips(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp index 18011cfb6b9e..72ec0715b6cd 100644 --- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp +++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp @@ -554,7 +554,8 @@ size_t ABISysV_mips64::GetRedZoneSize() const { return 0; } ABISP ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { if (arch.GetTriple().isMIPS64()) - return ABISP(new ABISysV_mips64(process_sp)); + return ABISP( + new ABISysV_mips64(std::move(process_sp), MakeMCRegisterInfo(arch))); return ABISP(); } @@ -589,18 +590,16 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp, for (size_t i = 0; i < args.size(); ++i) { reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); - if (log) - log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, - args[i], reg_info->name); + LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, + args[i], reg_info->name); if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) return false; } // First, align the SP - if (log) - log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, - (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); sp &= ~(0xfull); // 16-byte alignment @@ -614,8 +613,7 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp, const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0); const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0); - if (log) - log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0); + LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0); /* Write r0 with 0, in case we are stopped in syscall, * such setting prevents automatic decrement of the PC. @@ -624,29 +622,25 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp, if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0)) return false; - if (log) - log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp); + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); // Set "sp" to the requested value if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) return false; - if (log) - log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr); + LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr); // Set "ra" to the return address if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr)) return false; - if (log) - log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr); // Set pc to the address of the called function. if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) return false; - if (log) - log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr); // All callers of position independent functions must place the address of // the called function in t9 (r25) @@ -1168,6 +1162,7 @@ bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("mips64 default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h index 7da71b36b4b7..76c3c5413b92 100644 --- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h +++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h @@ -100,7 +100,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABISysV_mips64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_mips64(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp index faa995033ac2..857b7fee10e3 100644 --- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp +++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp @@ -218,7 +218,8 @@ size_t ABISysV_ppc::GetRedZoneSize() const { return 224; } ABISP ABISysV_ppc::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { if (arch.GetTriple().getArch() == llvm::Triple::ppc) { - return ABISP(new ABISysV_ppc(process_sp)); + return ABISP( + new ABISysV_ppc(std::move(process_sp), MakeMCRegisterInfo(arch))); } return ABISP(); } @@ -255,18 +256,16 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp, for (size_t i = 0; i < args.size(); ++i) { reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); - if (log) - log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", - static_cast<uint64_t>(i + 1), args[i], reg_info->name); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast<uint64_t>(i + 1), args[i], reg_info->name); if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) return false; } // First, align the SP - if (log) - log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, - (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); sp &= ~(0xfull); // 16-byte alignment @@ -281,10 +280,10 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp, RegisterValue reg_value; - if (log) - log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 - ": 0x%" PRIx64, - (uint64_t)sp, (uint64_t)return_addr); + LLDB_LOGF(log, + "Pushing the return address onto the stack: 0x%" PRIx64 + ": 0x%" PRIx64, + (uint64_t)sp, (uint64_t)return_addr); // Save return address onto the stack if (!process_sp->WritePointerToMemory(sp, return_addr, error)) @@ -292,16 +291,14 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp, // %r1 is set to the actual stack value. - if (log) - log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp); + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) return false; // %pc is set to the address of the called function. - if (log) - log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr); if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) return false; @@ -910,6 +907,7 @@ bool ABISysV_ppc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("ppc default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); unwind_plan.SetReturnAddressRegister(dwarf_lr); return true; } diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h index 3b199852c30d..59907c4648ba 100644 --- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h +++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h @@ -96,7 +96,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABISysV_ppc(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_ppc(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp index aa7907550f29..935353c38ca4 100644 --- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp +++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp @@ -70,7 +70,8 @@ ABISP ABISysV_ppc64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { if (arch.GetTriple().isPPC64()) - return ABISP(new ABISysV_ppc64(process_sp)); + return ABISP( + new ABISysV_ppc64(std::move(process_sp), MakeMCRegisterInfo(arch))); return ABISP(); } @@ -106,18 +107,16 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp, for (size_t i = 0; i < args.size(); ++i) { reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); - if (log) - log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", - static_cast<uint64_t>(i + 1), args[i], reg_info->name); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast<uint64_t>(i + 1), args[i], reg_info->name); if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) return false; } // First, align the SP - if (log) - log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, - (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); sp &= ~(0xfull); // 16-byte alignment @@ -136,22 +135,20 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp, const RegisterInfo *r12_reg_info = reg_ctx->GetRegisterInfoAtIndex(12); // Save return address onto the stack. - if (log) - log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 - "(+16): 0x%" PRIx64, - (uint64_t)sp, (uint64_t)return_addr); + LLDB_LOGF(log, + "Pushing the return address onto the stack: 0x%" PRIx64 + "(+16): 0x%" PRIx64, + (uint64_t)sp, (uint64_t)return_addr); if (!process_sp->WritePointerToMemory(sp + 16, return_addr, error)) return false; // Write the return address to link register. - if (log) - log->Printf("Writing LR: 0x%" PRIx64, (uint64_t)return_addr); + LLDB_LOGF(log, "Writing LR: 0x%" PRIx64, (uint64_t)return_addr); if (!reg_ctx->WriteRegisterFromUnsigned(lr_reg_info, return_addr)) return false; // Write target address to %r12 register. - if (log) - log->Printf("Writing R12: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing R12: 0x%" PRIx64, (uint64_t)func_addr); if (!reg_ctx->WriteRegisterFromUnsigned(r12_reg_info, func_addr)) return false; @@ -165,10 +162,9 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp, else stack_offset = 40; - if (log) - log->Printf("Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64, - (uint64_t)(sp + stack_offset), (int)stack_offset, - (uint64_t)reg_value); + LLDB_LOGF(log, "Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64, + (uint64_t)(sp + stack_offset), (int)stack_offset, + (uint64_t)reg_value); if (!process_sp->WritePointerToMemory(sp + stack_offset, reg_value, error)) return false; @@ -176,23 +172,20 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp, reg_value = reg_ctx->ReadRegisterAsUnsigned(sp_reg_info, 0); // Save current SP onto the stack. - if (log) - log->Printf("Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp, - (uint64_t)reg_value); + LLDB_LOGF(log, "Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp, + (uint64_t)reg_value); if (!process_sp->WritePointerToMemory(sp, reg_value, error)) return false; // %r1 is set to the actual stack value. - if (log) - log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp); + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) return false; // %pc is set to the address of the called function. - if (log) - log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr); if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) return false; @@ -1017,6 +1010,7 @@ bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("ppc64 default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); unwind_plan.SetReturnAddressRegister(pc_reg_num); return true; } diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h index d5fb09eec0d0..1b58975dd9d9 100644 --- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h +++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h @@ -96,7 +96,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABISysV_ppc64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_ppc64(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp index abe847b386a8..f4f803a8277d 100644 --- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp +++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp @@ -200,7 +200,7 @@ size_t ABISysV_s390x::GetRedZoneSize() const { return 0; } ABISP ABISysV_s390x::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { if (arch.GetTriple().getArch() == llvm::Triple::systemz) { - return ABISP(new ABISysV_s390x(process_sp)); + return ABISP(new ABISysV_s390x(std::move(process_sp), MakeMCRegisterInfo(arch))); } return ABISP(); } @@ -252,16 +252,14 @@ bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp, if (i < 5) { const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); - if (log) - log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", - static_cast<uint64_t>(i + 1), args[i], reg_info->name); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast<uint64_t>(i + 1), args[i], reg_info->name); if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) return false; } else { Status error; - if (log) - log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack", - static_cast<uint64_t>(i + 1), args[i]); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack", + static_cast<uint64_t>(i + 1), args[i]); if (!process_sp->WritePointerToMemory(arg_pos, args[i], error)) return false; arg_pos += 8; @@ -270,24 +268,21 @@ bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp, // %r14 is set to the return address - if (log) - log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr); + LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr); if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr)) return false; // %r15 is set to the actual stack value. - if (log) - log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp); + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) return false; // %pc is set to the address of the called function. - if (log) - log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr); if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) return false; diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h index 13df477e84bc..671d6a18260e 100644 --- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h +++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h @@ -88,7 +88,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABISysV_s390x(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_s390x(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp index 6c7b45f63399..bf1c48f778e1 100644 --- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp +++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp @@ -222,17 +222,35 @@ ABISP ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); const llvm::Triple::OSType os_type = arch.GetTriple().getOS(); + const llvm::Triple::EnvironmentType os_env = + arch.GetTriple().getEnvironment(); if (arch_type == llvm::Triple::x86_64) { switch(os_type) { - case llvm::Triple::OSType::MacOSX: - case llvm::Triple::OSType::Linux: - case llvm::Triple::OSType::FreeBSD: - case llvm::Triple::OSType::NetBSD: - case llvm::Triple::OSType::Solaris: - case llvm::Triple::OSType::UnknownOS: - return ABISP(new ABISysV_x86_64(process_sp)); - default: + case llvm::Triple::OSType::IOS: + case llvm::Triple::OSType::TvOS: + case llvm::Triple::OSType::WatchOS: + switch (os_env) { + case llvm::Triple::EnvironmentType::MacABI: + case llvm::Triple::EnvironmentType::Simulator: + case llvm::Triple::EnvironmentType::UnknownEnvironment: + // UnknownEnvironment is needed for older compilers that don't + // support the simulator environment. + return ABISP(new ABISysV_x86_64(std::move(process_sp), + MakeMCRegisterInfo(arch))); + default: return ABISP(); + } + case llvm::Triple::OSType::Darwin: + case llvm::Triple::OSType::FreeBSD: + case llvm::Triple::OSType::Linux: + case llvm::Triple::OSType::MacOSX: + case llvm::Triple::OSType::NetBSD: + case llvm::Triple::OSType::Solaris: + case llvm::Triple::OSType::UnknownOS: + return ABISP( + new ABISysV_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch))); + default: + return ABISP(); } } return ABISP(); @@ -270,18 +288,16 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, for (size_t i = 0; i < args.size(); ++i) { reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); - if (log) - log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", - static_cast<uint64_t>(i + 1), args[i], reg_info->name); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast<uint64_t>(i + 1), args[i], reg_info->name); if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) return false; } // First, align the SP - if (log) - log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, - (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); sp &= ~(0xfull); // 16-byte alignment @@ -295,10 +311,10 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, ProcessSP process_sp(thread.GetProcess()); RegisterValue reg_value; - if (log) - log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 - ": 0x%" PRIx64, - (uint64_t)sp, (uint64_t)return_addr); + LLDB_LOGF(log, + "Pushing the return address onto the stack: 0x%" PRIx64 + ": 0x%" PRIx64, + (uint64_t)sp, (uint64_t)return_addr); // Save return address onto the stack if (!process_sp->WritePointerToMemory(sp, return_addr, error)) @@ -306,16 +322,14 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, // %rsp is set to the actual stack value. - if (log) - log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp); + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) return false; // %rip is set to the address of the called function. - if (log) - log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr); if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) return false; @@ -1034,6 +1048,7 @@ bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("x86_64 default unwind plan"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); return true; } diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h index f6704aff348c..d445d8f4142a 100644 --- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h +++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h @@ -98,7 +98,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABISysV_x86_64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABISysV_x86_64(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp index 5dc7717d865d..ac24426914e1 100644 --- a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp +++ b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp @@ -1092,7 +1092,8 @@ ABISP ABIWindows_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { if (arch.GetTriple().getArch() == llvm::Triple::x86_64 && arch.GetTriple().isOSWindows()) { - return ABISP(new ABIWindows_x86_64(process_sp)); + return ABISP( + new ABIWindows_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch))); } return ABISP(); } @@ -1129,18 +1130,16 @@ bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, for (size_t i = 0; i < args.size(); ++i) { reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); - if (log) - log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", - static_cast<uint64_t>(i + 1), args[i], reg_info->name); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast<uint64_t>(i + 1), args[i], reg_info->name); if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) return false; } // First, align the SP - if (log) - log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, - (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); sp &= ~(0xfull); // 16-byte alignment @@ -1154,10 +1153,10 @@ bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, ProcessSP process_sp(thread.GetProcess()); RegisterValue reg_value; - if (log) - log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 - ": 0x%" PRIx64, - (uint64_t)sp, (uint64_t)return_addr); + LLDB_LOGF(log, + "Pushing the return address onto the stack: 0x%" PRIx64 + ": 0x%" PRIx64, + (uint64_t)sp, (uint64_t)return_addr); // Save return address onto the stack if (!process_sp->WritePointerToMemory(sp, return_addr, error)) @@ -1165,16 +1164,14 @@ bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, // %rsp is set to the actual stack value. - if (log) - log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp); + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) return false; // %rip is set to the address of the called function. - if (log) - log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr); + LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr); if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) return false; diff --git a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h index 9f6b2ceef299..2366566d7809 100644 --- a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h +++ b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h @@ -91,7 +91,9 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - ABIWindows_x86_64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) { + ABIWindows_x86_64(lldb::ProcessSP process_sp, + std::unique_ptr<llvm::MCRegisterInfo> info_up) + : lldb_private::ABI(std::move(process_sp), std::move(info_up)) { // Call CreateInstance instead. } }; diff --git a/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/source/Plugins/Architecture/Mips/ArchitectureMips.cpp index 60f1a2eb7572..5f2f6eeb8261 100644 --- a/source/Plugins/Architecture/Mips/ArchitectureMips.cpp +++ b/source/Plugins/Architecture/Mips/ArchitectureMips.cpp @@ -127,10 +127,10 @@ lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr, // Adjust the breakable address uint64_t breakable_addr = addr - insn->GetOpcode().GetByteSize(); - if (log) - log->Printf("Target::%s Breakpoint at 0x%8.8" PRIx64 - " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n", - __FUNCTION__, addr, breakable_addr); + LLDB_LOGF(log, + "Target::%s Breakpoint at 0x%8.8" PRIx64 + " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n", + __FUNCTION__, addr, breakable_addr); return breakable_addr; } diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index 44c75fc953c8..28c9de2c1e96 100644 --- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -381,11 +381,10 @@ public: static RegularExpression s_regex( llvm::StringRef("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?")); - RegularExpression::Match matches(3); - + llvm::SmallVector<llvm::StringRef, 4> matches; if (s_regex.Execute(out_string, &matches)) { - matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name); - matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics); + m_opcode_name = matches[1].str(); + m_mnemonics = matches[2].str(); } } } @@ -1190,10 +1189,12 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, // If any AArch64 variant, enable the ARMv8.5 ISA with SVE extensions so we // can disassemble newer instructions. - if (triple.getArch() == llvm::Triple::aarch64) + if (triple.getArch() == llvm::Triple::aarch64 || + triple.getArch() == llvm::Triple::aarch64_32) features_str += "+v8.5a,+sve2"; - if (triple.getArch() == llvm::Triple::aarch64 + if ((triple.getArch() == llvm::Triple::aarch64 || + triple.getArch() == llvm::Triple::aarch64_32) && triple.getVendor() == llvm::Triple::Apple) { cpu = "apple-latest"; } diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp index 23c8416f4986..5b19647a27ba 100644 --- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp +++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp @@ -277,8 +277,7 @@ bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() { // Do not try to set the breakpoint if we don't know where to put it if (break_addr == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf("Unable to locate _rtld_debug_state breakpoint address"); + LLDB_LOGF(log, "Unable to locate _rtld_debug_state breakpoint address"); return false; } @@ -301,7 +300,7 @@ bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() { .GetID() == m_dyld_bid); if (log && dyld_break == nullptr) - log->Printf("Failed to create _rtld_debug_state breakpoint"); + LLDB_LOGF(log, "Failed to create _rtld_debug_state breakpoint"); // check we have successfully set bp return (dyld_break != nullptr); @@ -316,8 +315,7 @@ bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit( user_id_t break_loc_id) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf("Rendezvous breakpoint hit!"); + LLDB_LOGF(log, "Rendezvous breakpoint hit!"); DynamicLoaderHexagonDYLD *dyld_instance = nullptr; dyld_instance = static_cast<DynamicLoaderHexagonDYLD *>(baton); @@ -333,11 +331,9 @@ bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit( if (structAddr != LLDB_INVALID_ADDRESS) { dyld_instance->m_rendezvous.SetRendezvousAddress(structAddr); - if (log) - log->Printf("Found _rtld_debug structure @ 0x%08" PRIx64, structAddr); + LLDB_LOGF(log, "Found _rtld_debug structure @ 0x%08" PRIx64, structAddr); } else { - if (log) - log->Printf("Unable to resolve the _rtld_debug structure"); + LLDB_LOGF(log, "Unable to resolve the _rtld_debug structure"); } } @@ -375,11 +371,11 @@ void DynamicLoaderHexagonDYLD::RefreshModules() { } if (log) { - log->Printf("Target is loading '%s'", I->path.c_str()); + LLDB_LOGF(log, "Target is loading '%s'", I->path.c_str()); if (!module_sp.get()) - log->Printf("LLDB failed to load '%s'", I->path.c_str()); + LLDB_LOGF(log, "LLDB failed to load '%s'", I->path.c_str()); else - log->Printf("LLDB successfully loaded '%s'", I->path.c_str()); + LLDB_LOGF(log, "LLDB successfully loaded '%s'", I->path.c_str()); } } m_process->GetTarget().ModulesDidLoad(new_modules); @@ -400,8 +396,7 @@ void DynamicLoaderHexagonDYLD::RefreshModules() { UnloadSections(module_sp); } - if (log) - log->Printf("Target is unloading '%s'", I->path.c_str()); + LLDB_LOGF(log, "Target is unloading '%s'", I->path.c_str()); } loaded_modules.Remove(old_modules); m_process->GetTarget().ModulesDidUnload(old_modules, false); @@ -472,10 +467,10 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() { if (!m_rendezvous.Resolve()) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf( - "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address", - __FUNCTION__); + LLDB_LOGF( + log, + "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address", + __FUNCTION__); return; } @@ -493,10 +488,10 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() { module_list.Append(module_sp); } else { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf("DynamicLoaderHexagonDYLD::%s failed loading module %s at " - "0x%" PRIx64, - __FUNCTION__, module_path, I->base_addr); + LLDB_LOGF(log, + "DynamicLoaderHexagonDYLD::%s failed loading module %s at " + "0x%" PRIx64, + __FUNCTION__, module_path, I->base_addr); } } @@ -604,12 +599,11 @@ DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module, Module *mod = module.get(); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf("DynamicLoaderHexagonDYLD::Performed TLS lookup: " - "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 - ", modid=%i, tls_block=0x%" PRIx64, - mod->GetObjectName().AsCString(""), link_map, tp, modid, - tls_block); + LLDB_LOGF(log, + "DynamicLoaderHexagonDYLD::Performed TLS lookup: " + "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 + ", modid=%i, tls_block=0x%" PRIx64, + mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block); if (tls_block == LLDB_INVALID_ADDRESS) return LLDB_INVALID_ADDRESS; diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp index 844a06c2b37d..f4788816d4ea 100644 --- a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp +++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp @@ -290,8 +290,9 @@ bool HexagonDYLDRendezvous::FindMetadata(const char *name, PThreadField field, Target &target = m_process->GetTarget(); SymbolContextList list; - if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name), - eSymbolTypeAny, list)) + target.GetImages().FindSymbolsWithNameAndType(ConstString(name), + eSymbolTypeAny, list); + if (list.IsEmpty()) return false; Address address = list[0].symbol->GetAddress(); @@ -339,16 +340,16 @@ void HexagonDYLDRendezvous::DumpToLog(Log *log) const { return; log->PutCString("HexagonDYLDRendezvous:"); - log->Printf(" Address: %" PRIx64, GetRendezvousAddress()); - log->Printf(" Version: %" PRIu64, GetVersion()); - log->Printf(" Link : %" PRIx64, GetLinkMapAddress()); - log->Printf(" Break : %" PRIx64, GetBreakAddress()); - log->Printf(" LDBase : %" PRIx64, GetLDBase()); - log->Printf(" State : %s", - (state == eConsistent) - ? "consistent" - : (state == eAdd) ? "add" : (state == eDelete) ? "delete" - : "unknown"); + LLDB_LOGF(log, " Address: %" PRIx64, GetRendezvousAddress()); + LLDB_LOGF(log, " Version: %" PRIu64, GetVersion()); + LLDB_LOGF(log, " Link : %" PRIx64, GetLinkMapAddress()); + LLDB_LOGF(log, " Break : %" PRIx64, GetBreakAddress()); + LLDB_LOGF(log, " LDBase : %" PRIx64, GetLDBase()); + LLDB_LOGF(log, " State : %s", + (state == eConsistent) + ? "consistent" + : (state == eAdd) ? "add" + : (state == eDelete) ? "delete" : "unknown"); iterator I = begin(); iterator E = end(); @@ -357,11 +358,11 @@ void HexagonDYLDRendezvous::DumpToLog(Log *log) const { log->PutCString("HexagonDYLDRendezvous SOEntries:"); for (int i = 1; I != E; ++I, ++i) { - log->Printf("\n SOEntry [%d] %s", i, I->path.c_str()); - log->Printf(" Base : %" PRIx64, I->base_addr); - log->Printf(" Path : %" PRIx64, I->path_addr); - log->Printf(" Dyn : %" PRIx64, I->dyn_addr); - log->Printf(" Next : %" PRIx64, I->next); - log->Printf(" Prev : %" PRIx64, I->prev); + LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->path.c_str()); + LLDB_LOGF(log, " Base : %" PRIx64, I->base_addr); + LLDB_LOGF(log, " Path : %" PRIx64, I->path_addr); + LLDB_LOGF(log, " Dyn : %" PRIx64, I->dyn_addr); + LLDB_LOGF(log, " Next : %" PRIx64, I->next); + LLDB_LOGF(log, " Prev : %" PRIx64, I->prev); } } diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index 0d736738ebb5..737599303a60 100644 --- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -33,16 +33,14 @@ static addr_t ResolveRendezvousAddress(Process *process) { Status error; if (!process) { - if (log) - log->Printf("%s null process provided", __FUNCTION__); + LLDB_LOGF(log, "%s null process provided", __FUNCTION__); return LLDB_INVALID_ADDRESS; } // Try to get it from our process. This might be a remote process and might // grab it via some remote-specific mechanism. info_location = process->GetImageInfoAddress(); - if (log) - log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location); + LLDB_LOGF(log, "%s info_location = 0x%" PRIx64, __FUNCTION__, info_location); // If the process fails to return an address, fall back to seeing if the // local object file can help us find it. @@ -54,42 +52,38 @@ static addr_t ResolveRendezvousAddress(Process *process) { if (addr.IsValid()) { info_location = addr.GetLoadAddress(target); - if (log) - log->Printf( - "%s resolved via direct object file approach to 0x%" PRIx64, - __FUNCTION__, info_location); + LLDB_LOGF(log, + "%s resolved via direct object file approach to 0x%" PRIx64, + __FUNCTION__, info_location); } else { - if (log) - log->Printf("%s FAILED - direct object file approach did not yield a " - "valid address", - __FUNCTION__); + LLDB_LOGF(log, + "%s FAILED - direct object file approach did not yield a " + "valid address", + __FUNCTION__); } } } if (info_location == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf("%s FAILED - invalid info address", __FUNCTION__); + LLDB_LOGF(log, "%s FAILED - invalid info address", __FUNCTION__); return LLDB_INVALID_ADDRESS; } - if (log) - log->Printf("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64, - __FUNCTION__, process->GetAddressByteSize(), info_location); + LLDB_LOGF(log, "%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64, + __FUNCTION__, process->GetAddressByteSize(), info_location); info_addr = process->ReadPointerFromMemory(info_location, error); if (error.Fail()) { - if (log) - log->Printf("%s FAILED - could not read from the info location: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, "%s FAILED - could not read from the info location: %s", + __FUNCTION__, error.AsCString()); return LLDB_INVALID_ADDRESS; } if (info_addr == 0) { - if (log) - log->Printf("%s FAILED - the rendezvous address contained at 0x%" PRIx64 - " returned a null value", - __FUNCTION__, info_location); + LLDB_LOGF(log, + "%s FAILED - the rendezvous address contained at 0x%" PRIx64 + " returned a null value", + __FUNCTION__, info_location); return LLDB_INVALID_ADDRESS; } @@ -109,14 +103,13 @@ DYLDRendezvous::DYLDRendezvous(Process *process) Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer(); if (exe_mod) { m_exe_file_spec = exe_mod->GetPlatformFileSpec(); - if (log) - log->Printf("DYLDRendezvous::%s exe module executable path set: '%s'", - __FUNCTION__, m_exe_file_spec.GetCString()); + LLDB_LOGF(log, "DYLDRendezvous::%s exe module executable path set: '%s'", + __FUNCTION__, m_exe_file_spec.GetCString()); } else { - if (log) - log->Printf("DYLDRendezvous::%s cannot cache exe module path: null " - "executable module pointer", - __FUNCTION__); + LLDB_LOGF(log, + "DYLDRendezvous::%s cannot cache exe module path: null " + "executable module pointer", + __FUNCTION__); } } } @@ -133,17 +126,16 @@ bool DYLDRendezvous::Resolve() { address_size = m_process->GetAddressByteSize(); padding = address_size - word_size; - if (log) - log->Printf("DYLDRendezvous::%s address size: %" PRIu64 - ", padding %" PRIu64, - __FUNCTION__, uint64_t(address_size), uint64_t(padding)); + LLDB_LOGF(log, + "DYLDRendezvous::%s address size: %" PRIu64 ", padding %" PRIu64, + __FUNCTION__, uint64_t(address_size), uint64_t(padding)); if (m_rendezvous_addr == LLDB_INVALID_ADDRESS) cursor = info_addr = ResolveRendezvousAddress(m_process); else cursor = info_addr = m_rendezvous_addr; - if (log) - log->Printf("DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, cursor); + LLDB_LOGF(log, "DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, + cursor); if (cursor == LLDB_INVALID_ADDRESS) return false; @@ -168,7 +160,10 @@ bool DYLDRendezvous::Resolve() { m_previous = m_current; m_current = info; - if (UpdateSOEntries(true)) + if (m_current.map_addr == 0) + return false; + + if (UpdateSOEntriesFromRemote()) return true; return UpdateSOEntries(); @@ -178,53 +173,91 @@ bool DYLDRendezvous::IsValid() { return m_rendezvous_addr != LLDB_INVALID_ADDRESS; } -bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) { - SOEntry entry; - LoadedModuleInfoList module_list; +DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const { + switch (m_current.state) { + + case eConsistent: + switch (m_previous.state) { + // When the previous and current states are consistent this is the first + // time we have been asked to update. Just take a snapshot of the + // currently loaded modules. + case eConsistent: + return eTakeSnapshot; + // If we are about to add or remove a shared object clear out the current + // state and take a snapshot of the currently loaded images. + case eAdd: + return eAddModules; + case eDelete: + return eRemoveModules; + } + break; - // If we can't get the SO info from the remote, return failure. - if (fromRemote && m_process->LoadModules(module_list) == 0) - return false; + case eAdd: + case eDelete: + // Some versions of the android dynamic linker might send two + // notifications with state == eAdd back to back. Ignore them until we + // get an eConsistent notification. + if (!(m_previous.state == eConsistent || + (m_previous.state == eAdd && m_current.state == eDelete))) + return eNoAction; + + return eTakeSnapshot; + } + + return eNoAction; +} + +bool DYLDRendezvous::UpdateSOEntriesFromRemote() { + auto action = GetAction(); - if (!fromRemote && m_current.map_addr == 0) + if (action == eNoAction) return false; - // When the previous and current states are consistent this is the first time - // we have been asked to update. Just take a snapshot of the currently - // loaded modules. - if (m_previous.state == eConsistent && m_current.state == eConsistent) - return fromRemote ? SaveSOEntriesFromRemote(module_list) - : TakeSnapshot(m_soentries); - - // If we are about to add or remove a shared object clear out the current - // state and take a snapshot of the currently loaded images. - if (m_current.state == eAdd || m_current.state == eDelete) { - // Some versions of the android dynamic linker might send two notifications - // with state == eAdd back to back. Ignore them until we get an eConsistent - // notification. - if (!(m_previous.state == eConsistent || - (m_previous.state == eAdd && m_current.state == eDelete))) - return false; + if (action == eTakeSnapshot) { + m_added_soentries.clear(); + m_removed_soentries.clear(); + // We already have the loaded list from the previous update so no need to + // find all the modules again. + if (!m_loaded_modules.m_list.empty()) + return true; + } + + llvm::Expected<LoadedModuleInfoList> module_list = + m_process->GetLoadedModuleList(); + if (!module_list) { + llvm::consumeError(module_list.takeError()); + return false; + } + switch (action) { + case eTakeSnapshot: m_soentries.clear(); - if (fromRemote) - return SaveSOEntriesFromRemote(module_list); + return SaveSOEntriesFromRemote(*module_list); + case eAddModules: + return AddSOEntriesFromRemote(*module_list); + case eRemoveModules: + return RemoveSOEntriesFromRemote(*module_list); + case eNoAction: + return false; + } + llvm_unreachable("Fully covered switch above!"); +} +bool DYLDRendezvous::UpdateSOEntries() { + switch (GetAction()) { + case eTakeSnapshot: + m_soentries.clear(); m_added_soentries.clear(); m_removed_soentries.clear(); return TakeSnapshot(m_soentries); + case eAddModules: + return AddSOEntries(); + case eRemoveModules: + return RemoveSOEntries(); + case eNoAction: + return false; } - assert(m_current.state == eConsistent); - - // Otherwise check the previous state to determine what to expect and update - // accordingly. - if (m_previous.state == eAdd) - return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries(); - else if (m_previous.state == eDelete) - return fromRemote ? RemoveSOEntriesFromRemote(module_list) - : RemoveSOEntries(); - - return false; + llvm_unreachable("Fully covered switch above!"); } bool DYLDRendezvous::FillSOEntryFromModuleInfo( @@ -255,7 +288,7 @@ bool DYLDRendezvous::FillSOEntryFromModuleInfo( } bool DYLDRendezvous::SaveSOEntriesFromRemote( - LoadedModuleInfoList &module_list) { + const LoadedModuleInfoList &module_list) { for (auto const &modInfo : module_list.m_list) { SOEntry entry; if (!FillSOEntryFromModuleInfo(modInfo, entry)) @@ -270,7 +303,8 @@ bool DYLDRendezvous::SaveSOEntriesFromRemote( return true; } -bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) { +bool DYLDRendezvous::AddSOEntriesFromRemote( + const LoadedModuleInfoList &module_list) { for (auto const &modInfo : module_list.m_list) { bool found = false; for (auto const &existing : m_loaded_modules.m_list) { @@ -288,8 +322,10 @@ bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) { return false; // Only add shared libraries and not the executable. - if (!SOEntryIsMainExecutable(entry)) + if (!SOEntryIsMainExecutable(entry)) { m_soentries.push_back(entry); + m_added_soentries.push_back(entry); + } } m_loaded_modules = module_list; @@ -297,7 +333,7 @@ bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) { } bool DYLDRendezvous::RemoveSOEntriesFromRemote( - LoadedModuleInfoList &module_list) { + const LoadedModuleInfoList &module_list) { for (auto const &existing : m_loaded_modules.m_list) { bool found = false; for (auto const &modInfo : module_list.m_list) { @@ -321,6 +357,7 @@ bool DYLDRendezvous::RemoveSOEntriesFromRemote( return false; m_soentries.erase(pos); + m_removed_soentries.push_back(entry); } } @@ -521,9 +558,10 @@ bool DYLDRendezvous::FindMetadata(const char *name, PThreadField field, Target &target = m_process->GetTarget(); SymbolContextList list; - if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name), - eSymbolTypeAny, list)) - return false; + target.GetImages().FindSymbolsWithNameAndType(ConstString(name), + eSymbolTypeAny, list); + if (list.IsEmpty()) + return false; Address address = list[0].symbol->GetAddress(); addr_t addr = address.GetLoadAddress(&target); @@ -569,16 +607,16 @@ void DYLDRendezvous::DumpToLog(Log *log) const { return; log->PutCString("DYLDRendezvous:"); - log->Printf(" Address: %" PRIx64, GetRendezvousAddress()); - log->Printf(" Version: %" PRIu64, GetVersion()); - log->Printf(" Link : %" PRIx64, GetLinkMapAddress()); - log->Printf(" Break : %" PRIx64, GetBreakAddress()); - log->Printf(" LDBase : %" PRIx64, GetLDBase()); - log->Printf(" State : %s", - (state == eConsistent) - ? "consistent" - : (state == eAdd) ? "add" : (state == eDelete) ? "delete" - : "unknown"); + LLDB_LOGF(log, " Address: %" PRIx64, GetRendezvousAddress()); + LLDB_LOGF(log, " Version: %" PRIu64, GetVersion()); + LLDB_LOGF(log, " Link : %" PRIx64, GetLinkMapAddress()); + LLDB_LOGF(log, " Break : %" PRIx64, GetBreakAddress()); + LLDB_LOGF(log, " LDBase : %" PRIx64, GetLDBase()); + LLDB_LOGF(log, " State : %s", + (state == eConsistent) + ? "consistent" + : (state == eAdd) ? "add" + : (state == eDelete) ? "delete" : "unknown"); iterator I = begin(); iterator E = end(); @@ -587,11 +625,11 @@ void DYLDRendezvous::DumpToLog(Log *log) const { log->PutCString("DYLDRendezvous SOEntries:"); for (int i = 1; I != E; ++I, ++i) { - log->Printf("\n SOEntry [%d] %s", i, I->file_spec.GetCString()); - log->Printf(" Base : %" PRIx64, I->base_addr); - log->Printf(" Path : %" PRIx64, I->path_addr); - log->Printf(" Dyn : %" PRIx64, I->dyn_addr); - log->Printf(" Next : %" PRIx64, I->next); - log->Printf(" Prev : %" PRIx64, I->prev); + LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->file_spec.GetCString()); + LLDB_LOGF(log, " Base : %" PRIx64, I->base_addr); + LLDB_LOGF(log, " Path : %" PRIx64, I->path_addr); + LLDB_LOGF(log, " Dyn : %" PRIx64, I->dyn_addr); + LLDB_LOGF(log, " Next : %" PRIx64, I->next); + LLDB_LOGF(log, " Prev : %" PRIx64, I->prev); } } diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h index 993e62f5e9f9..536eeeaaf334 100644 --- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h +++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h @@ -222,16 +222,20 @@ protected: /// Updates the current set of SOEntries, the set of added entries, and the /// set of removed entries. - bool UpdateSOEntries(bool fromRemote = false); + bool UpdateSOEntries(); + + /// Same as UpdateSOEntries but it gets the list of loaded modules from the + /// remote debug server (faster when supported). + bool UpdateSOEntriesFromRemote(); bool FillSOEntryFromModuleInfo( LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry); - bool SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list); + bool SaveSOEntriesFromRemote(const LoadedModuleInfoList &module_list); - bool AddSOEntriesFromRemote(LoadedModuleInfoList &module_list); + bool AddSOEntriesFromRemote(const LoadedModuleInfoList &module_list); - bool RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list); + bool RemoveSOEntriesFromRemote(const LoadedModuleInfoList &module_list); bool AddSOEntries(); @@ -248,6 +252,17 @@ protected: enum PThreadField { eSize, eNElem, eOffset }; bool FindMetadata(const char *name, PThreadField field, uint32_t &value); + + enum RendezvousAction { + eNoAction, + eTakeSnapshot, + eAddModules, + eRemoveModules + }; + + /// Returns the current action to be taken given the current and previous + /// state + RendezvousAction GetAction() const; }; #endif diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index b55660899d0d..9d61c8feb923 100644 --- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -85,32 +85,31 @@ DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() { void DynamicLoaderPOSIXDYLD::DidAttach() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__, - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); - m_auxv = llvm::make_unique<AuxVector>(m_process->GetAuxvData()); + LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); + m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData()); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data", - __FUNCTION__, - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); + LLDB_LOGF( + log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data", + __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); // ask the process if it can load any of its own modules - m_process->LoadModules(); + auto error = m_process->LoadModules(); + LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}"); ModuleSP executable_sp = GetTargetExecutable(); ResolveExecutableModule(executable_sp); // find the main process load offset addr_t load_offset = ComputeLoadOffset(); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 - " executable '%s', load_offset 0x%" PRIx64, - __FUNCTION__, - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, - executable_sp ? executable_sp->GetFileSpec().GetPath().c_str() - : "<null executable>", - load_offset); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 + " executable '%s', load_offset 0x%" PRIx64, + __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, + executable_sp ? executable_sp->GetFileSpec().GetPath().c_str() + : "<null executable>", + load_offset); EvalSpecialModulesStatus(); @@ -137,12 +136,12 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { ModuleList module_list; module_list.Append(executable_sp); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 - " added executable '%s' to module load list", - __FUNCTION__, - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, - executable_sp->GetFileSpec().GetPath().c_str()); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 + " added executable '%s' to module load list", + __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, + executable_sp->GetFileSpec().GetPath().c_str()); UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset, true); @@ -151,14 +150,15 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { m_process->GetTarget().ModulesDidLoad(module_list); if (log) { - log->Printf("DynamicLoaderPOSIXDYLD::%s told the target about the " - "modules that loaded:", - __FUNCTION__); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s told the target about the " + "modules that loaded:", + __FUNCTION__); for (auto module_sp : module_list.Modules()) { - log->Printf("-- [module] %s (pid %" PRIu64 ")", - module_sp ? module_sp->GetFileSpec().GetPath().c_str() - : "<null>", - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); + LLDB_LOGF(log, "-- [module] %s (pid %" PRIu64 ")", + module_sp ? module_sp->GetFileSpec().GetPath().c_str() + : "<null>", + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); } } } @@ -174,13 +174,12 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { void DynamicLoaderPOSIXDYLD::DidLaunch() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__); + LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__); ModuleSP executable; addr_t load_offset; - m_auxv = llvm::make_unique<AuxVector>(m_process->GetAuxvData()); + m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData()); executable = GetTargetExecutable(); load_offset = ComputeLoadOffset(); @@ -191,9 +190,8 @@ void DynamicLoaderPOSIXDYLD::DidLaunch() { module_list.Append(executable); UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()", - __FUNCTION__); + LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()", + __FUNCTION__); if (!SetRendezvousBreakpoint()) { // If we cannot establish rendezvous breakpoint right now we'll try again @@ -227,22 +225,20 @@ void DynamicLoaderPOSIXDYLD::ProbeEntry() { const addr_t entry = GetEntryPoint(); if (entry == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf( - "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 - " GetEntryPoint() returned no address, not setting entry breakpoint", - __FUNCTION__, - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); + LLDB_LOGF( + log, + "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 + " GetEntryPoint() returned no address, not setting entry breakpoint", + __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); return; } - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 - " GetEntryPoint() returned address 0x%" PRIx64 - ", setting entry breakpoint", - __FUNCTION__, - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, - entry); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 + " GetEntryPoint() returned address 0x%" PRIx64 + ", setting entry breakpoint", + __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, entry); if (m_process) { Breakpoint *const entry_break = @@ -271,11 +267,10 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast<DynamicLoaderPOSIXDYLD *>(baton); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, - __FUNCTION__, - dyld_instance->m_process ? dyld_instance->m_process->GetID() - : LLDB_INVALID_PROCESS_ID); + LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, + __FUNCTION__, + dyld_instance->m_process ? dyld_instance->m_process->GetID() + : LLDB_INVALID_PROCESS_ID); // Disable the breakpoint --- if a stop happens right after this, which we've // seen on occasion, we don't want the breakpoint stepping thread-plan logic @@ -287,22 +282,22 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( BreakpointSP breakpoint_sp = dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id); if (breakpoint_sp) { - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 - " disabling breakpoint id %" PRIu64, - __FUNCTION__, dyld_instance->m_process->GetID(), break_id); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 + " disabling breakpoint id %" PRIu64, + __FUNCTION__, dyld_instance->m_process->GetID(), break_id); breakpoint_sp->SetEnabled(false); } else { - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 - " failed to find breakpoint for breakpoint id %" PRIu64, - __FUNCTION__, dyld_instance->m_process->GetID(), break_id); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 + " failed to find breakpoint for breakpoint id %" PRIu64, + __FUNCTION__, dyld_instance->m_process->GetID(), break_id); } } else { - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64 - " no Process instance! Cannot disable breakpoint", - __FUNCTION__, break_id); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64 + " no Process instance! Cannot disable breakpoint", + __FUNCTION__, break_id); } dyld_instance->LoadAllCurrentModules(); @@ -393,23 +388,22 @@ bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit( Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast<DynamicLoaderPOSIXDYLD *>(baton); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, - __FUNCTION__, - dyld_instance->m_process ? dyld_instance->m_process->GetID() - : LLDB_INVALID_PROCESS_ID); + LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, + __FUNCTION__, + dyld_instance->m_process ? dyld_instance->m_process->GetID() + : LLDB_INVALID_PROCESS_ID); dyld_instance->RefreshModules(); // Return true to stop the target, false to just let the target run. const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange(); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 - " stop_when_images_change=%s", - __FUNCTION__, - dyld_instance->m_process ? dyld_instance->m_process->GetID() - : LLDB_INVALID_PROCESS_ID, - stop_when_images_change ? "true" : "false"); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 + " stop_when_images_change=%s", + __FUNCTION__, + dyld_instance->m_process ? dyld_instance->m_process->GetID() + : LLDB_INVALID_PROCESS_ID, + stop_when_images_change ? "true" : "false"); return stop_when_images_change; } @@ -562,10 +556,10 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { LoadVDSO(); if (!m_rendezvous.Resolve()) { - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD " - "rendezvous address", - __FUNCTION__); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD " + "rendezvous address", + __FUNCTION__); return; } @@ -589,10 +583,10 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { module_list.Append(module_sp); } else { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf( - "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64, - __FUNCTION__, I->file_spec.GetCString(), I->base_addr); + LLDB_LOGF( + log, + "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64, + __FUNCTION__, I->file_spec.GetCString(), I->base_addr); } } @@ -697,12 +691,12 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: " - "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 - ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n", - module_sp->GetObjectName().AsCString(""), link_map, tp, - (int64_t)modid, tls_block); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::Performed TLS lookup: " + "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 + ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n", + module_sp->GetObjectName().AsCString(""), link_map, tp, + (int64_t)modid, tls_block); if (tls_block == LLDB_INVALID_ADDRESS) return LLDB_INVALID_ADDRESS; @@ -722,18 +716,17 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( ProcessInstanceInfo process_info; if (!m_process->GetProcessInfo(process_info)) { - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to get process info for " - "pid %" PRIu64, - __FUNCTION__, m_process->GetID()); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s - failed to get process info for " + "pid %" PRIu64, + __FUNCTION__, m_process->GetID()); return; } - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 - ": %s", - __FUNCTION__, m_process->GetID(), - process_info.GetExecutableFile().GetPath().c_str()); + LLDB_LOGF( + log, "DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s", + __FUNCTION__, m_process->GetID(), + process_info.GetExecutableFile().GetPath().c_str()); ModuleSpec module_spec(process_info.GetExecutableFile(), process_info.GetArchitecture()); @@ -748,10 +741,10 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( StreamString stream; module_spec.Dump(stream); - if (log) - log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable " - "with module spec \"%s\": %s", - __FUNCTION__, stream.GetData(), error.AsCString()); + LLDB_LOGF(log, + "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable " + "with module spec \"%s\": %s", + __FUNCTION__, stream.GetData(), error.AsCString()); return; } diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp index fa3fbe0d9fa6..25ab30e9db9c 100644 --- a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp +++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp @@ -122,38 +122,37 @@ lldb::addr_t DynamicLoaderWindowsDYLD::GetLoadAddress(ModuleSP executable) { void DynamicLoaderWindowsDYLD::DidAttach() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); + LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); - ModuleSP executable = GetTargetExecutable(); + ModuleSP executable = GetTargetExecutable(); - if (!executable.get()) - return; + if (!executable.get()) + return; - // Try to fetch the load address of the file from the process, since there - // could be randomization of the load address. - lldb::addr_t load_addr = GetLoadAddress(executable); - if (load_addr == LLDB_INVALID_ADDRESS) - return; + // Try to fetch the load address of the file from the process, since there + // could be randomization of the load address. + lldb::addr_t load_addr = GetLoadAddress(executable); + if (load_addr == LLDB_INVALID_ADDRESS) + return; - // Request the process base address. - lldb::addr_t image_base = m_process->GetImageInfoAddress(); - if (image_base == load_addr) - return; + // Request the process base address. + lldb::addr_t image_base = m_process->GetImageInfoAddress(); + if (image_base == load_addr) + return; - // Rebase the process's modules if there is a mismatch. - UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false); + // Rebase the process's modules if there is a mismatch. + UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false); - ModuleList module_list; - module_list.Append(executable); - m_process->GetTarget().ModulesDidLoad(module_list); - m_process->LoadModules(); + ModuleList module_list; + module_list.Append(executable); + m_process->GetTarget().ModulesDidLoad(module_list); + auto error = m_process->LoadModules(); + LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}"); } void DynamicLoaderWindowsDYLD::DidLaunch() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) - log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); + LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); ModuleSP executable = GetTargetExecutable(); if (!executable.get()) @@ -167,7 +166,8 @@ void DynamicLoaderWindowsDYLD::DidLaunch() { ModuleList module_list; module_list.Append(executable); m_process->GetTarget().ModulesDidLoad(module_list); - m_process->LoadModules(); + auto error = m_process->LoadModules(); + LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}"); } } diff --git a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp index 369f88327dd9..f33a713cc0b2 100644 --- a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp +++ b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp @@ -75,8 +75,6 @@ ASTDumper::ASTDumper(const CompilerType &compiler_type) { const char *ASTDumper::GetCString() { return m_dump.c_str(); } -void ASTDumper::ToSTDERR() { fprintf(stderr, "%s\n", m_dump.c_str()); } - void ASTDumper::ToLog(Log *log, const char *prefix) { size_t len = m_dump.length() + 1; @@ -92,7 +90,7 @@ void ASTDumper::ToLog(Log *log, const char *prefix) { while (end) { *end = '\0'; - log->Printf("%s%s", prefix, str); + LLDB_LOGF(log, "%s%s", prefix, str); *end = '\n'; @@ -100,9 +98,7 @@ void ASTDumper::ToLog(Log *log, const char *prefix) { end = strchr(str, '\n'); } - log->Printf("%s%s", prefix, str); + LLDB_LOGF(log, "%s%s", prefix, str); free(alloc); } - -void ASTDumper::ToStream(lldb::StreamSP &stream) { stream->PutCString(m_dump); } diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp index 526ef90782ef..68eaad33f51c 100644 --- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp +++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp @@ -58,13 +58,13 @@ void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) { if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) { if (log && log->GetVerbose()) { if (named_decl->getIdentifier()) - log->Printf("TransformTopLevelDecl(%s)", - named_decl->getIdentifier()->getNameStart()); + LLDB_LOGF(log, "TransformTopLevelDecl(%s)", + named_decl->getIdentifier()->getNameStart()); else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D)) - log->Printf("TransformTopLevelDecl(%s)", - method_decl->getSelector().getAsString().c_str()); + LLDB_LOGF(log, "TransformTopLevelDecl(%s)", + method_decl->getSelector().getAsString().c_str()); else - log->Printf("TransformTopLevelDecl(<complex>)"); + LLDB_LOGF(log, "TransformTopLevelDecl(<complex>)"); } if (m_top_level) { @@ -130,7 +130,7 @@ bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) { os.flush(); - log->Printf("Untransformed function AST:\n%s", s.c_str()); + LLDB_LOGF(log, "Untransformed function AST:\n%s", s.c_str()); } Stmt *function_body = function_decl->getBody(); @@ -146,7 +146,7 @@ bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) { os.flush(); - log->Printf("Transformed function AST:\n%s", s.c_str()); + LLDB_LOGF(log, "Transformed function AST:\n%s", s.c_str()); } return ret; @@ -170,7 +170,7 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult( os.flush(); - log->Printf("Untransformed method AST:\n%s", s.c_str()); + LLDB_LOGF(log, "Untransformed method AST:\n%s", s.c_str()); } Stmt *method_body = MethodDecl->getBody(); @@ -190,7 +190,7 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult( os.flush(); - log->Printf("Transformed method AST:\n%s", s.c_str()); + LLDB_LOGF(log, "Transformed method AST:\n%s", s.c_str()); } return ret; @@ -308,8 +308,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body, if (log) { std::string s = expr_qual_type.getAsString(); - log->Printf("Last statement is an %s with type: %s", - (is_lvalue ? "lvalue" : "rvalue"), s.c_str()); + LLDB_LOGF(log, "Last statement is an %s with type: %s", + (is_lvalue ? "lvalue" : "rvalue"), s.c_str()); } clang::VarDecl *result_decl = nullptr; @@ -422,8 +422,7 @@ void ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) { ConstString name_cs(name.str().c_str()); - if (log) - log->Printf("Recording persistent type %s\n", name_cs.GetCString()); + LLDB_LOGF(log, "Recording persistent type %s\n", name_cs.GetCString()); m_decls.push_back(D); } @@ -443,8 +442,7 @@ void ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) { ConstString name_cs(name.str().c_str()); - if (log) - log->Printf("Recording persistent decl %s\n", name_cs.GetCString()); + LLDB_LOGF(log, "Recording persistent decl %s\n", name_cs.GetCString()); m_decls.push_back(D); } @@ -467,7 +465,7 @@ void ASTResultSynthesizer::CommitPersistentDecls() { decl->dump(ss); ss.flush(); - log->Printf("Couldn't commit persistent decl: %s\n", s.c_str()); + LLDB_LOGF(log, "Couldn't commit persistent decl: %s\n", s.c_str()); } continue; diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index c5778f86bb62..372c2439ebf0 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -9,6 +9,7 @@ #include "ClangASTSource.h" #include "ASTDumper.h" +#include "ClangDeclVendor.h" #include "ClangModulesDeclVendor.h" #include "lldb/Core/Module.h" @@ -18,7 +19,6 @@ #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" @@ -74,14 +74,19 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context, file_manager}; std::vector<clang::ExternalASTMerger::ImporterSource> sources; for (lldb::ModuleSP module_sp : m_target->GetImages().Modules()) { - if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>( - module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC))) { + auto type_system_or_err = + module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR( + lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS), + std::move(err), "Failed to get ClangASTContext"); + } else if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>( + &type_system_or_err.get())) { lldbassert(module_ast_ctx->getASTContext()); lldbassert(module_ast_ctx->getFileManager()); - sources.push_back({*module_ast_ctx->getASTContext(), - *module_ast_ctx->getFileManager(), - module_ast_ctx->GetOriginMap() - }); + sources.emplace_back(*module_ast_ctx->getASTContext(), + *module_ast_ctx->getFileManager(), + module_ast_ctx->GetOriginMap()); } } @@ -96,17 +101,14 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context, if (!language_runtime) break; - DeclVendor *runtime_decl_vendor = language_runtime->GetDeclVendor(); - - if (!runtime_decl_vendor) - break; - - sources.push_back(runtime_decl_vendor->GetImporterSource()); + if (auto *runtime_decl_vendor = llvm::dyn_cast_or_null<ClangDeclVendor>( + language_runtime->GetDeclVendor())) { + sources.push_back(runtime_decl_vendor->GetImporterSource()); + } } while (false); do { - DeclVendor *modules_decl_vendor = - m_target->GetClangModulesDeclVendor(); + auto *modules_decl_vendor = m_target->GetClangModulesDeclVendor(); if (!modules_decl_vendor) break; @@ -127,11 +129,9 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context, *scratch_ast_context->getFileManager(), scratch_ast_context->GetOriginMap()}); } - while (false) - ; m_merger_up = - llvm::make_unique<clang::ExternalASTMerger>(target, sources); + std::make_unique<clang::ExternalASTMerger>(target, sources); } else { m_ast_importer_sp->InstallMapCompleter(&ast_context, *this); } @@ -273,13 +273,13 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { unsigned int current_id = invocation_id++; if (log) { - log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing " - "(TagDecl*)%p named %s", - current_id, static_cast<void *>(m_ast_context), - static_cast<void *>(tag_decl), - tag_decl->getName().str().c_str()); + LLDB_LOGF(log, + " CompleteTagDecl[%u] on (ASTContext*)%p Completing " + "(TagDecl*)%p named %s", + current_id, static_cast<void *>(m_ast_context), + static_cast<void *>(tag_decl), tag_decl->getName().str().c_str()); - log->Printf(" CTD[%u] Before:", current_id); + LLDB_LOGF(log, " CTD[%u] Before:", current_id); ASTDumper dumper((Decl *)tag_decl); dumper.ToLog(log, " [CTD] "); } @@ -301,10 +301,10 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { // We couldn't complete the type. Maybe there's a definition somewhere // else that can be completed. - if (log) - log->Printf(" CTD[%u] Type could not be completed in the module in " - "which it was first found.", - current_id); + LLDB_LOGF(log, + " CTD[%u] Type could not be completed in the module in " + "which it was first found.", + current_id); bool found = false; @@ -316,9 +316,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { m_ast_importer_sp->GetNamespaceMap(namespace_context); if (log && log->GetVerbose()) - log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)", - current_id, static_cast<void *>(namespace_map.get()), - static_cast<int>(namespace_map->size())); + LLDB_LOGF(log, " CTD[%u] Inspecting namespace map %p (%d entries)", + current_id, static_cast<void *>(namespace_map.get()), + static_cast<int>(namespace_map->size())); if (!namespace_map) return; @@ -326,10 +326,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); i != e && !found; ++i) { - if (log) - log->Printf(" CTD[%u] Searching namespace %s in module %s", - current_id, i->second.GetName().AsCString(), - i->first->GetFileSpec().GetFilename().GetCString()); + LLDB_LOGF(log, " CTD[%u] Searching namespace %s in module %s", + current_id, i->second.GetName().AsCString(), + i->first->GetFileSpec().GetFilename().GetCString()); TypeList types; @@ -409,7 +408,7 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { } if (log) { - log->Printf(" [CTD] After:"); + LLDB_LOGF(log, " [CTD] After:"); ASTDumper dumper((Decl *)tag_decl); dumper.ToLog(log, " [CTD] "); } @@ -419,11 +418,12 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); if (log) { - log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing " - "an ObjCInterfaceDecl named %s", - static_cast<void *>(m_ast_context), - interface_decl->getName().str().c_str()); - log->Printf(" [COID] Before:"); + LLDB_LOGF(log, + " [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing " + "an ObjCInterfaceDecl named %s", + static_cast<void *>(m_ast_context), + interface_decl->getName().str().c_str()); + LLDB_LOGF(log, " [COID] Before:"); ASTDumper dumper((Decl *)interface_decl); dumper.ToLog(log, " [COID] "); } @@ -467,7 +467,7 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { CompleteType(interface_decl->getSuperClass()); if (log) { - log->Printf(" [COID] After:"); + LLDB_LOGF(log, " [COID] After:"); ASTDumper dumper((Decl *)interface_decl); dumper.ToLog(log, " [COID] "); } @@ -554,20 +554,22 @@ void ClangASTSource::FindExternalLexicalDecls( if (log) { if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl)) - log->Printf( + LLDB_LOGF( + log, "FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p", current_id, static_cast<void *>(m_ast_context), context_named_decl->getNameAsString().c_str(), context_decl->getDeclKindName(), static_cast<const void *>(context_decl)); else if (context_decl) - log->Printf( - "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p", + LLDB_LOGF( + log, "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p", current_id, static_cast<void *>(m_ast_context), context_decl->getDeclKindName(), static_cast<const void *>(context_decl)); else - log->Printf( + LLDB_LOGF( + log, "FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context", current_id, static_cast<const void *>(m_ast_context)); } @@ -580,9 +582,9 @@ void ClangASTSource::FindExternalLexicalDecls( return; if (log) { - log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", - current_id, static_cast<void *>(original_ctx), - static_cast<void *>(original_decl)); + LLDB_LOGF( + log, " FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", current_id, + static_cast<void *>(original_ctx), static_cast<void *>(original_decl)); ASTDumper(original_decl).ToLog(log, " "); } @@ -626,13 +628,13 @@ void ClangASTSource::FindExternalLexicalDecls( ASTDumper ast_dumper(decl); if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl)) - log->Printf(" FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s", - current_id, context_named_decl->getDeclKindName(), - context_named_decl->getNameAsString().c_str(), - decl->getDeclKindName(), ast_dumper.GetCString()); + LLDB_LOGF(log, " FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s", + current_id, context_named_decl->getDeclKindName(), + context_named_decl->getNameAsString().c_str(), + decl->getDeclKindName(), ast_dumper.GetCString()); else - log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id, - decl->getDeclKindName(), ast_dumper.GetCString()); + LLDB_LOGF(log, " FELD[%d] Adding lexical %sDecl %s", current_id, + decl->getDeclKindName(), ast_dumper.GetCString()); } Decl *copied_decl = CopyDecl(decl); @@ -645,6 +647,20 @@ void ClangASTSource::FindExternalLexicalDecls( m_ast_importer_sp->RequireCompleteType(copied_field_type); } + auto decl_context_non_const = const_cast<DeclContext *>(decl_context); + + // The decl ended up in the wrong DeclContext. Let's fix that so + // the decl we copied will actually be found. + // FIXME: This is a horrible hack that shouldn't be necessary. However + // it seems our current setup sometimes fails to copy decls to the right + // place. See rdar://55129537. + if (copied_decl->getDeclContext() != decl_context) { + assert(copied_decl->getDeclContext()->containsDecl(copied_decl)); + copied_decl->getDeclContext()->removeDecl(copied_decl); + copied_decl->setDeclContext(decl_context_non_const); + assert(!decl_context_non_const->containsDecl(copied_decl)); + decl_context_non_const->addDeclInternal(copied_decl); + } } else { SkippedDecls = true; } @@ -678,22 +694,25 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { if (log) { if (!context.m_decl_context) - log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on " - "(ASTContext*)%p for '%s' in a NULL DeclContext", - current_id, static_cast<void *>(m_ast_context), - name.GetCString()); + LLDB_LOGF(log, + "ClangASTSource::FindExternalVisibleDecls[%u] on " + "(ASTContext*)%p for '%s' in a NULL DeclContext", + current_id, static_cast<void *>(m_ast_context), + name.GetCString()); else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context)) - log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on " - "(ASTContext*)%p for '%s' in '%s'", - current_id, static_cast<void *>(m_ast_context), - name.GetCString(), - context_named_decl->getNameAsString().c_str()); + LLDB_LOGF(log, + "ClangASTSource::FindExternalVisibleDecls[%u] on " + "(ASTContext*)%p for '%s' in '%s'", + current_id, static_cast<void *>(m_ast_context), + name.GetCString(), + context_named_decl->getNameAsString().c_str()); else - log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on " - "(ASTContext*)%p for '%s' in a '%s'", - current_id, static_cast<void *>(m_ast_context), - name.GetCString(), context.m_decl_context->getDeclKindName()); + LLDB_LOGF(log, + "ClangASTSource::FindExternalVisibleDecls[%u] on " + "(ASTContext*)%p for '%s' in a '%s'", + current_id, static_cast<void *>(m_ast_context), + name.GetCString(), context.m_decl_context->getDeclKindName()); } if (HasMerger() && !isa<TranslationUnitDecl>(context.m_decl_context) @@ -723,9 +742,9 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr; if (log && log->GetVerbose()) - log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)", - current_id, static_cast<void *>(namespace_map.get()), - static_cast<int>(namespace_map->size())); + LLDB_LOGF(log, " CAS::FEVD[%u] Inspecting namespace map %p (%d entries)", + current_id, static_cast<void *>(namespace_map.get()), + static_cast<int>(namespace_map->size())); if (!namespace_map) return; @@ -733,10 +752,9 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); i != e; ++i) { - if (log) - log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s", - current_id, i->second.GetName().AsCString(), - i->first->GetFileSpec().GetFilename().GetCString()); + LLDB_LOGF(log, " CAS::FEVD[%u] Searching namespace %s in module %s", + current_id, i->second.GetName().AsCString(), + i->first->GetFileSpec().GetFilename().GetCString()); FindExternalVisibleDecls(context, i->first, i->second, current_id); } @@ -748,8 +766,7 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { } else { CompilerDeclContext namespace_decl; - if (log) - log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id); + LLDB_LOGF(log, " CAS::FEVD[%u] Searching the root namespace", current_id); FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl, current_id); @@ -757,10 +774,10 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { if (!context.m_namespace_map->empty()) { if (log && log->GetVerbose()) - log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)", - current_id, - static_cast<void *>(context.m_namespace_map.get()), - static_cast<int>(context.m_namespace_map->size())); + LLDB_LOGF(log, + " CAS::FEVD[%u] Registering namespace map %p (%d entries)", + current_id, static_cast<void *>(context.m_namespace_map.get()), + static_cast<int>(context.m_namespace_map->size())); NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map); @@ -807,21 +824,17 @@ void ClangASTSource::FindExternalVisibleDecls( if (module_sp && namespace_decl) { CompilerDeclContext found_namespace_decl; - SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); - - if (symbol_vendor) { - found_namespace_decl = - symbol_vendor->FindNamespace(name, &namespace_decl); + if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) { + found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl); if (found_namespace_decl) { context.m_namespace_map->push_back( std::pair<lldb::ModuleSP, CompilerDeclContext>( module_sp, found_namespace_decl)); - if (log) - log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s", - current_id, name.GetCString(), - module_sp->GetFileSpec().GetFilename().GetCString()); + LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s", + current_id, name.GetCString(), + module_sp->GetFileSpec().GetFilename().GetCString()); } } } else if (!HasMerger()) { @@ -836,23 +849,21 @@ void ClangASTSource::FindExternalVisibleDecls( CompilerDeclContext found_namespace_decl; - SymbolVendor *symbol_vendor = image->GetSymbolVendor(); + SymbolFile *symbol_file = image->GetSymbolFile(); - if (!symbol_vendor) + if (!symbol_file) continue; - found_namespace_decl = - symbol_vendor->FindNamespace(name, &namespace_decl); + found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl); if (found_namespace_decl) { context.m_namespace_map->push_back( std::pair<lldb::ModuleSP, CompilerDeclContext>( image, found_namespace_decl)); - if (log) - log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s", - current_id, name.GetCString(), - image->GetFileSpec().GetFilename().GetCString()); + LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s", + current_id, name.GetCString(), + image->GetFileSpec().GetFilename().GetCString()); } } } @@ -878,9 +889,9 @@ void ClangASTSource::FindExternalVisibleDecls( if (log) { const char *name_string = type_sp->GetName().GetCString(); - log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s", - current_id, name.GetCString(), - (name_string ? name_string : "<anonymous>")); + LLDB_LOGF(log, " CAS::FEVD[%u] Matching type found for \"%s\": %s", + current_id, name.GetCString(), + (name_string ? name_string : "<anonymous>")); } CompilerType full_type = type_sp->GetFullCompilerType(); @@ -888,8 +899,8 @@ void ClangASTSource::FindExternalVisibleDecls( CompilerType copied_clang_type(GuardedCopyType(full_type)); if (!copied_clang_type) { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a type", current_id); + LLDB_LOGF(log, " CAS::FEVD[%u] - Couldn't export a type", + current_id); continue; } @@ -915,9 +926,10 @@ void ClangASTSource::FindExternalVisibleDecls( break; if (log) { - log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in " - "the modules", - current_id, name.GetCString()); + LLDB_LOGF(log, + " CAS::FEVD[%u] Matching entity found for \"%s\" in " + "the modules", + current_id, name.GetCString()); } clang::NamedDecl *const decl_from_modules = decls[0]; @@ -930,10 +942,10 @@ void ClangASTSource::FindExternalVisibleDecls( copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; if (!copied_named_decl) { - if (log) - log->Printf( - " CAS::FEVD[%u] - Couldn't export a type from the modules", - current_id); + LLDB_LOGF( + log, + " CAS::FEVD[%u] - Couldn't export a type from the modules", + current_id); break; } @@ -971,11 +983,13 @@ void ClangASTSource::FindExternalVisibleDecls( uint32_t max_matches = 1; std::vector<clang::NamedDecl *> decls; - if (!decl_vendor->FindDecls(name, append, max_matches, decls)) + auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor); + if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls)) break; if (log) { - log->Printf( + LLDB_LOGF( + log, " CAS::FEVD[%u] Matching type found for \"%s\" in the runtime", current_id, name.GetCString()); } @@ -985,10 +999,9 @@ void ClangASTSource::FindExternalVisibleDecls( copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; if (!copied_named_decl) { - if (log) - log->Printf( - " CAS::FEVD[%u] - Couldn't export a type from the runtime", - current_id); + LLDB_LOGF(log, + " CAS::FEVD[%u] - Couldn't export a type from the runtime", + current_id); break; } @@ -1126,8 +1139,8 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin( if (log) { ASTDumper dumper((Decl *)copied_method_decl); - log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info, - dumper.GetCString()); + LLDB_LOGF(log, " CAS::FOMD[%d] found (%s) %s", current_id, log_info, + dumper.GetCString()); } context.AddNamedDecl(copied_method_decl); @@ -1205,17 +1218,16 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ConstString selector_name(ss.GetString()); - if (log) - log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p " - "for selector [%s %s]", - current_id, static_cast<void *>(m_ast_context), - interface_decl->getNameAsString().c_str(), - selector_name.AsCString()); + LLDB_LOGF(log, + "ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p " + "for selector [%s %s]", + current_id, static_cast<void *>(m_ast_context), + interface_decl->getNameAsString().c_str(), + selector_name.AsCString()); SymbolContextList sc_list; const bool include_symbols = false; const bool include_inlines = false; - const bool append = false; std::string interface_name = interface_decl->getNameAsString(); @@ -1225,9 +1237,10 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ms.Flush(); ConstString instance_method_name(ms.GetString()); + sc_list.Clear(); m_target->GetImages().FindFunctions( instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, - include_inlines, append, sc_list); + include_inlines, sc_list); if (sc_list.GetSize()) break; @@ -1237,9 +1250,10 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ms.Flush(); ConstString class_method_name(ms.GetString()); + sc_list.Clear(); m_target->GetImages().FindFunctions( class_method_name, lldb::eFunctionNameTypeFull, include_symbols, - include_inlines, append, sc_list); + include_inlines, sc_list); if (sc_list.GetSize()) break; @@ -1252,7 +1266,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { m_target->GetImages().FindFunctions( selector_name, lldb::eFunctionNameTypeSelector, include_symbols, - include_inlines, append, candidate_sc_list); + include_inlines, candidate_sc_list); for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) { SymbolContext candidate_sc; @@ -1331,8 +1345,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { if (log) { ASTDumper dumper((Decl *)copied_method_decl); - log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, - dumper.GetCString()); + LLDB_LOGF(log, " CAS::FOMD[%d] found (in symbols) %s", current_id, + dumper.GetCString()); } context.AddNamedDecl(copied_method_decl); @@ -1360,11 +1374,11 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { if (complete_interface_decl == interface_decl) break; // already checked this one - if (log) - log->Printf("CAS::FOPD[%d] trying origin " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, static_cast<void *>(complete_interface_decl), - static_cast<void *>(&complete_iface_decl->getASTContext())); + LLDB_LOGF(log, + "CAS::FOPD[%d] trying origin " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", + current_id, static_cast<void *>(complete_interface_decl), + static_cast<void *>(&complete_iface_decl->getASTContext())); FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl, "in debug info"); @@ -1423,7 +1437,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { uint32_t max_matches = 1; std::vector<clang::NamedDecl *> decls; - if (!decl_vendor->FindDecls(interface_name, append, max_matches, decls)) + auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor); + if (!clang_decl_vendor->FindDecls(interface_name, append, max_matches, + decls)) break; ObjCInterfaceDecl *runtime_interface_decl = @@ -1462,8 +1478,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( if (parser_property_decl.IsValid()) { if (log) { ASTDumper dumper((Decl *)parser_property_decl.decl); - log->Printf(" CAS::FOPD[%d] found %s", current_id, - dumper.GetCString()); + LLDB_LOGF(log, " CAS::FOPD[%d] found %s", current_id, + dumper.GetCString()); } context.AddNamedDecl(parser_property_decl.decl); @@ -1480,8 +1496,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( if (parser_ivar_decl.IsValid()) { if (log) { ASTDumper dumper((Decl *)parser_ivar_decl.decl); - log->Printf(" CAS::FOPD[%d] found %s", current_id, - dumper.GetCString()); + LLDB_LOGF(log, " CAS::FOPD[%d] found %s", current_id, + dumper.GetCString()); } context.AddNamedDecl(parser_ivar_decl.decl); @@ -1505,23 +1521,23 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { ConstString class_name(parser_iface_decl->getNameAsString().c_str()); - if (log) - log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on " - "(ASTContext*)%p for '%s.%s'", - current_id, static_cast<void *>(m_ast_context), - parser_iface_decl->getNameAsString().c_str(), - context.m_decl_name.getAsString().c_str()); + LLDB_LOGF(log, + "ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on " + "(ASTContext*)%p for '%s.%s'", + current_id, static_cast<void *>(m_ast_context), + parser_iface_decl->getNameAsString().c_str(), + context.m_decl_name.getAsString().c_str()); if (FindObjCPropertyAndIvarDeclsWithOrigin( current_id, context, *this, origin_iface_decl)) return; - if (log) - log->Printf("CAS::FOPD[%d] couldn't find the property on origin " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching " - "elsewhere...", - current_id, static_cast<const void *>(origin_iface_decl.decl), - static_cast<void *>(&origin_iface_decl->getASTContext())); + LLDB_LOGF(log, + "CAS::FOPD[%d] couldn't find the property on origin " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching " + "elsewhere...", + current_id, static_cast<const void *>(origin_iface_decl.decl), + static_cast<void *>(&origin_iface_decl->getASTContext())); SymbolContext null_sc; TypeList type_list; @@ -1542,12 +1558,11 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { if (complete_iface_decl.decl == origin_iface_decl.decl) break; // already checked this one - if (log) - log->Printf("CAS::FOPD[%d] trying origin " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, - static_cast<const void *>(complete_iface_decl.decl), - static_cast<void *>(&complete_iface_decl->getASTContext())); + LLDB_LOGF(log, + "CAS::FOPD[%d] trying origin " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", + current_id, static_cast<const void *>(complete_iface_decl.decl), + static_cast<void *>(&complete_iface_decl->getASTContext())); FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this, complete_iface_decl); @@ -1578,13 +1593,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { if (!interface_decl_from_modules.IsValid()) break; - if (log) - log->Printf( - "CAS::FOPD[%d] trying module " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, - static_cast<const void *>(interface_decl_from_modules.decl), - static_cast<void *>(&interface_decl_from_modules->getASTContext())); + LLDB_LOGF( + log, + "CAS::FOPD[%d] trying module " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", + current_id, static_cast<const void *>(interface_decl_from_modules.decl), + static_cast<void *>(&interface_decl_from_modules->getASTContext())); if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this, interface_decl_from_modules)) @@ -1614,7 +1628,8 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { uint32_t max_matches = 1; std::vector<clang::NamedDecl *> decls; - if (!decl_vendor->FindDecls(class_name, append, max_matches, decls)) + auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor); + if (!clang_decl_vendor->FindDecls(class_name, append, max_matches, decls)) break; DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime( @@ -1623,13 +1638,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { if (!interface_decl_from_runtime.IsValid()) break; - if (log) - log->Printf( - "CAS::FOPD[%d] trying runtime " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, - static_cast<const void *>(interface_decl_from_runtime.decl), - static_cast<void *>(&interface_decl_from_runtime->getASTContext())); + LLDB_LOGF( + log, + "CAS::FOPD[%d] trying runtime " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", + current_id, static_cast<const void *>(interface_decl_from_runtime.decl), + static_cast<void *>(&interface_decl_from_runtime->getASTContext())); if (FindObjCPropertyAndIvarDeclsWithOrigin( current_id, context, *this, interface_decl_from_runtime)) @@ -1729,12 +1743,12 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p " - "[name = '%s']", - current_id, static_cast<void *>(m_ast_context), - static_cast<const void *>(record), - record->getNameAsString().c_str()); + LLDB_LOGF(log, + "LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p " + "[name = '%s']", + current_id, static_cast<void *>(m_ast_context), + static_cast<const void *>(record), + record->getNameAsString().c_str()); DeclFromParser<const RecordDecl> parser_record(record); DeclFromUser<const RecordDecl> origin_record( @@ -1798,24 +1812,25 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, m_ast_context->getCharWidth(); if (log) { - log->Printf("LRT[%u] returned:", current_id); - log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id, - static_cast<const void *>(origin_record.decl)); - log->Printf("LRT[%u] Size = %" PRId64, current_id, size); - log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment); - log->Printf("LRT[%u] Fields:", current_id); + LLDB_LOGF(log, "LRT[%u] returned:", current_id); + LLDB_LOGF(log, "LRT[%u] Original = (RecordDecl*)%p", current_id, + static_cast<const void *>(origin_record.decl)); + LLDB_LOGF(log, "LRT[%u] Size = %" PRId64, current_id, size); + LLDB_LOGF(log, "LRT[%u] Alignment = %" PRId64, current_id, alignment); + LLDB_LOGF(log, "LRT[%u] Fields:", current_id); for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end(); fi != fe; ++fi) { - log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 - " bits", - current_id, static_cast<void *>(*fi), - fi->getNameAsString().c_str(), field_offsets[*fi]); + LLDB_LOGF(log, + "LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 + " bits", + current_id, static_cast<void *>(*fi), + fi->getNameAsString().c_str(), field_offsets[*fi]); } DeclFromParser<const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record); if (parser_cxx_record.IsValid()) { - log->Printf("LRT[%u] Bases:", current_id); + LLDB_LOGF(log, "LRT[%u] Bases:", current_id); for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end(); @@ -1828,7 +1843,8 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, DeclFromParser<CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record); - log->Printf( + LLDB_LOGF( + log, "LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars", current_id, (is_virtual ? "Virtual " : ""), @@ -1839,7 +1855,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, : base_offsets[base_cxx_record.decl].getQuantity())); } } else { - log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id); + LLDB_LOGF(log, "LRD[%u] Not a CXXRecord, so no bases", current_id); } } @@ -1856,16 +1872,18 @@ void ClangASTSource::CompleteNamespaceMap( if (log) { if (parent_map && parent_map->size()) - log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for " - "namespace %s in namespace %s", - current_id, static_cast<void *>(m_ast_context), - name.GetCString(), - parent_map->begin()->second.GetName().AsCString()); + LLDB_LOGF(log, + "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for " + "namespace %s in namespace %s", + current_id, static_cast<void *>(m_ast_context), + name.GetCString(), + parent_map->begin()->second.GetName().AsCString()); else - log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for " - "namespace %s", - current_id, static_cast<void *>(m_ast_context), - name.GetCString()); + LLDB_LOGF(log, + "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for " + "namespace %s", + current_id, static_cast<void *>(m_ast_context), + name.GetCString()); } if (parent_map) { @@ -1877,13 +1895,13 @@ void ClangASTSource::CompleteNamespaceMap( lldb::ModuleSP module_sp = i->first; CompilerDeclContext module_parent_namespace_decl = i->second; - SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); + SymbolFile *symbol_file = module_sp->GetSymbolFile(); - if (!symbol_vendor) + if (!symbol_file) continue; found_namespace_decl = - symbol_vendor->FindNamespace(name, &module_parent_namespace_decl); + symbol_file->FindNamespace(name, &module_parent_namespace_decl); if (!found_namespace_decl) continue; @@ -1891,10 +1909,9 @@ void ClangASTSource::CompleteNamespaceMap( namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>( module_sp, found_namespace_decl)); - if (log) - log->Printf(" CMN[%u] Found namespace %s in module %s", current_id, - name.GetCString(), - module_sp->GetFileSpec().GetFilename().GetCString()); + LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id, + name.GetCString(), + module_sp->GetFileSpec().GetFilename().GetCString()); } } else { const ModuleList &target_images = m_target->GetImages(); @@ -1910,13 +1927,13 @@ void ClangASTSource::CompleteNamespaceMap( CompilerDeclContext found_namespace_decl; - SymbolVendor *symbol_vendor = image->GetSymbolVendor(); + SymbolFile *symbol_file = image->GetSymbolFile(); - if (!symbol_vendor) + if (!symbol_file) continue; found_namespace_decl = - symbol_vendor->FindNamespace(name, &null_namespace_decl); + symbol_file->FindNamespace(name, &null_namespace_decl); if (!found_namespace_decl) continue; @@ -1924,10 +1941,9 @@ void ClangASTSource::CompleteNamespaceMap( namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>( image, found_namespace_decl)); - if (log) - log->Printf(" CMN[%u] Found namespace %s in module %s", current_id, - name.GetCString(), - image->GetFileSpec().GetFilename().GetCString()); + LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id, + name.GetCString(), + image->GetFileSpec().GetFilename().GetCString()); } } } @@ -2065,7 +2081,8 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) { // seems to be generating bad types on occasion. return CompilerType(); - return CompilerType(m_ast_context, copied_qual_type); + return CompilerType(ClangASTContext::GetASTContext(m_ast_context), + copied_qual_type.getAsOpaquePtr()); } clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) { @@ -2162,8 +2179,7 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, } else { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("Function type wasn't a FunctionProtoType"); + LLDB_LOGF(log, "Function type wasn't a FunctionProtoType"); } // If this is an operator (e.g. operator new or operator==), only insert the @@ -2194,7 +2210,9 @@ clang::NamedDecl *NameSearchContext::AddGenericFunDecl() { proto_info)); return AddFunDecl( - CompilerType(m_ast_source.m_ast_context, generic_function_type), true); + CompilerType(ClangASTContext::GetASTContext(m_ast_source.m_ast_context), + generic_function_type.getAsOpaquePtr()), + true); } clang::NamedDecl * diff --git a/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp new file mode 100644 index 000000000000..c59722b7b4f8 --- /dev/null +++ b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp @@ -0,0 +1,30 @@ +//===-- ClangDeclVendor.cpp -------------------------------------*- C++ -*-===// +// +// 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 "Plugins/ExpressionParser/Clang/ClangDeclVendor.h" + +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Utility/ConstString.h" + +using namespace lldb_private; + +uint32_t ClangDeclVendor::FindDecls(ConstString name, bool append, + uint32_t max_matches, + std::vector<CompilerDecl> &decls) { + if (!append) + decls.clear(); + + std::vector<clang::NamedDecl *> named_decls; + uint32_t ret = FindDecls(name, /*append*/ false, max_matches, named_decls); + for (auto *named_decl : named_decls) { + decls.push_back(CompilerDecl( + ClangASTContext::GetASTContext(&named_decl->getASTContext()), + named_decl)); + } + return ret; +} diff --git a/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h new file mode 100644 index 000000000000..90b715f37cba --- /dev/null +++ b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h @@ -0,0 +1,50 @@ +//===-- ClangDeclVendor.h ---------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangDeclVendor_h_ +#define liblldb_ClangDeclVendor_h_ + +#include "lldb/Core/ClangForward.h" +#include "lldb/Symbol/DeclVendor.h" + +#include "clang/AST/ExternalASTMerger.h" + +namespace lldb_private { + +// A clang specialized extension to DeclVendor. +class ClangDeclVendor : public DeclVendor { +public: + ClangDeclVendor(DeclVendorKind kind) : DeclVendor(kind) {} + + virtual ~ClangDeclVendor() {} + + /// Interface for ExternalASTMerger. Returns an ImporterSource allowing type + /// completion. + /// + /// \return + /// An ImporterSource for this ClangDeclVendor. + virtual clang::ExternalASTMerger::ImporterSource GetImporterSource() = 0; + + uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches, + std::vector<CompilerDecl> &decls) override; + + virtual uint32_t FindDecls(ConstString name, bool append, + uint32_t max_matches, + std::vector<clang::NamedDecl *> &decls) = 0; + + static bool classof(const DeclVendor *vendor) { + return vendor->GetKind() >= eClangDeclVendor && + vendor->GetKind() < eLastClangDeclVendor; + } + +private: + DISALLOW_COPY_AND_ASSIGN(ClangDeclVendor); +}; +} // namespace lldb_private + +#endif diff --git a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h index db50c2aa3e90..48cd1c4b99fa 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h +++ b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h @@ -29,7 +29,7 @@ public: return diag->getKind() == eDiagnosticOriginClang; } - ClangDiagnostic(const char *message, DiagnosticSeverity severity, + ClangDiagnostic(llvm::StringRef message, DiagnosticSeverity severity, uint32_t compiler_id) : Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id) {} @@ -42,6 +42,7 @@ public: } const FixItList &FixIts() const { return m_fixit_vec; } +private: FixItList m_fixit_vec; }; diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index a49a7029e0d2..f4457fc1b740 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -180,98 +180,20 @@ ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() { return ret; } -namespace { -/// This class walks an AST and ensures that all DeclContexts defined inside the -/// current source file are properly complete. -/// -/// This is used to ensure that persistent types defined in the current source -/// file migrate completely to the persistent AST context before they are -/// reused. If that didn't happen, it would be impoossible to complete them -/// because their origin would be gone. -/// -/// The stragtegy used by this class is to check the SourceLocation (to be -/// specific, the FileID) and see if it's the FileID for the current expression. -/// Alternate strategies could include checking whether an ExternalASTMerger, -/// set up to not have the current context as a source, can find an original for -/// the type. -class Completer : public clang::RecursiveASTVisitor<Completer> { -private: - clang::ASTImporter &m_exporter; /// Used to import Decl contents - clang::FileID m_file; /// The file that's going away - llvm::DenseSet<clang::Decl *> m_completed; /// Visited Decls, to avoid cycles - - bool ImportAndCheckCompletable(clang::Decl *decl) { - (void)m_exporter.Import(decl); - if (m_completed.count(decl)) - return false; - if (!llvm::isa<DeclContext>(decl)) - return false; - const clang::SourceLocation loc = decl->getLocation(); - if (!loc.isValid()) - return false; - const clang::FileID file = - m_exporter.getFromContext().getSourceManager().getFileID(loc); - if (file != m_file) - return false; - // We are assuming the Decl was parsed in this very expression, so it - // should not have external storage. - lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage()); - return true; - } - - void Complete(clang::Decl *decl) { - m_completed.insert(decl); - auto *decl_context = llvm::cast<DeclContext>(decl); - (void)m_exporter.Import(decl); - m_exporter.CompleteDecl(decl); - for (Decl *child : decl_context->decls()) - if (ImportAndCheckCompletable(child)) - Complete(child); - } - - void MaybeComplete(clang::Decl *decl) { - if (ImportAndCheckCompletable(decl)) - Complete(decl); - } - -public: - Completer(clang::ASTImporter &exporter, clang::FileID file) - : m_exporter(exporter), m_file(file) {} - - // Implements the RecursiveASTVisitor's core API. It is called on each Decl - // that the RecursiveASTVisitor encounters, and returns true if the traversal - // should continue. - bool VisitDecl(clang::Decl *decl) { - MaybeComplete(decl); - return true; - } -}; -} - -static void CompleteAllDeclContexts(clang::ASTImporter &exporter, - clang::FileID file, - clang::QualType root) { - clang::QualType canonical_type = root.getCanonicalType(); - if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) { - Completer(exporter, file).TraverseDecl(tag_decl); - } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>( - canonical_type.getTypePtr())) { - Completer(exporter, file).TraverseDecl(interface_type->getDecl()); - } else { - Completer(exporter, file).TraverseType(canonical_type); - } -} - static clang::QualType ExportAllDeclaredTypes( - clang::ExternalASTMerger &merger, + clang::ExternalASTMerger &parent_merger, clang::ExternalASTMerger &merger, clang::ASTContext &source, clang::FileManager &source_file_manager, const clang::ExternalASTMerger::OriginMap &source_origin_map, clang::FileID file, clang::QualType root) { - clang::ExternalASTMerger::ImporterSource importer_source = - { source, source_file_manager, source_origin_map }; + // Mark the source as temporary to make sure all declarations from the + // AST are exported. Also add the parent_merger as the merger into the + // source AST so that the merger can track back any declarations from + // the persistent ASTs we used as sources. + clang::ExternalASTMerger::ImporterSource importer_source( + source, source_file_manager, source_origin_map, /*Temporary*/ true, + &parent_merger); merger.AddSources(importer_source); clang::ASTImporter &exporter = merger.ImporterForOrigin(source); - CompleteAllDeclContexts(exporter, file, root); llvm::Expected<clang::QualType> ret_or_error = exporter.Import(root); merger.RemoveSources(importer_source); if (ret_or_error) { @@ -286,10 +208,10 @@ static clang::QualType ExportAllDeclaredTypes( TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target, ClangASTContext &source, TypeFromParser parser_type) { - assert (&target == m_target->GetScratchClangASTContext()); - assert ((TypeSystem*)&source == parser_type.GetTypeSystem()); - assert (source.getASTContext() == m_ast_context); - + assert(&target == m_target->GetScratchClangASTContext()); + assert((TypeSystem *)&source == parser_type.GetTypeSystem()); + assert(source.getASTContext() == m_ast_context); + if (m_ast_importer_sp) { return TypeFromUser(m_ast_importer_sp->DeportType( target.getASTContext(), source.getASTContext(), @@ -299,13 +221,12 @@ TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target, clang::FileID source_file = source.getASTContext()->getSourceManager().getFileID( source.getASTContext()->getTranslationUnitDecl()->getLocation()); - auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>( + auto scratch_ast_context = static_cast<ClangASTContextForExpressions *>( m_target->GetScratchClangASTContext()); clang::QualType exported_type = ExportAllDeclaredTypes( - scratch_ast_context->GetMergerUnchecked(), + *m_merger_up.get(), scratch_ast_context->GetMergerUnchecked(), *source.getASTContext(), *source.getFileManager(), - m_merger_up->GetOrigins(), - source_file, + m_merger_up->GetOrigins(), source_file, clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType())); return TypeFromUser(exported_type.getAsOpaquePtr(), &target); } else { @@ -375,8 +296,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, TypeFromUser user_type = DeportType(*context, *ast, parser_type); if (!user_type.GetOpaqueQualType()) { - if (log) - log->Printf("Persistent variable's type wasn't copied successfully"); + LLDB_LOGF(log, "Persistent variable's type wasn't copied successfully"); return false; } @@ -415,8 +335,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, var->m_flags |= ClangExpressionVariable::EVKeepInTarget; } - if (log) - log->Printf("Created persistent variable with flags 0x%hx", var->m_flags); + LLDB_LOGF(log, "Created persistent variable with flags 0x%hx", var->m_flags); var->EnableParserVars(GetParserID()); @@ -458,10 +377,9 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, if (!var) return false; - if (log) - log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure", - static_cast<const void *>(decl), name.GetCString(), - var->GetName().GetCString()); + LLDB_LOGF(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure", + static_cast<const void *>(decl), name.GetCString(), + var->GetName().GetCString()); // We know entity->m_parser_vars is valid because we used a parser variable // to find it @@ -475,9 +393,8 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) { // We already laid this out; do not touch - if (log) - log->Printf("Already placed at 0x%llx", - (unsigned long long)jit_vars->m_offset); + LLDB_LOGF(log, "Already placed at 0x%llx", + (unsigned long long)jit_vars->m_offset); } llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID()); @@ -512,8 +429,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, if (!err.Success()) return false; - if (log) - log->Printf("Placed at 0x%llx", (unsigned long long)offset); + LLDB_LOGF(log, "Placed at 0x%llx", (unsigned long long)offset); jit_vars->m_offset = offset; // TODO DoStructLayout() should not change this. @@ -779,7 +695,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (GetImportInProgress()) { if (log && log->GetVerbose()) - log->Printf("Ignoring a query during an import"); + LLDB_LOGF(log, "Ignoring a query during an import"); return; } @@ -788,20 +704,23 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (log) { if (!context.m_decl_context) - log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " - "'%s' in a NULL DeclContext", - current_id, name.GetCString()); + LLDB_LOGF(log, + "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " + "'%s' in a NULL DeclContext", + current_id, name.GetCString()); else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context)) - log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " - "'%s' in '%s'", - current_id, name.GetCString(), - context_named_decl->getNameAsString().c_str()); + LLDB_LOGF(log, + "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " + "'%s' in '%s'", + current_id, name.GetCString(), + context_named_decl->getNameAsString().c_str()); else - log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " - "'%s' in a '%s'", - current_id, name.GetCString(), - context.m_decl_context->getDeclKindName()); + LLDB_LOGF(log, + "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " + "'%s' in a '%s'", + current_id, name.GetCString(), + context.m_decl_context->getDeclKindName()); } if (const NamespaceDecl *namespace_context = @@ -828,7 +747,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)", current_id, static_cast<void *>(namespace_map.get()), (int)namespace_map->size()); - + for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); i != e; ++i) { @@ -848,7 +767,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl, current_id); } - + ClangASTSource::FindExternalVisibleDecls(context); } @@ -922,9 +841,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( MaybeRegisterFunctionBody(parser_function_decl); } - if (log) - log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id, - name.GetCString()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Found persistent decl %s", current_id, + name.GetCString()); context.AddNamedDecl(parser_named_decl); } while (false); @@ -979,8 +897,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (log) { ASTDumper ast_dumper(class_qual_type); - log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", - current_id, ast_dumper.GetCString()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Adding type for $__lldb_class: %s", + current_id, ast_dumper.GetCString()); } AddThisType(context, class_user_type, current_id); @@ -1024,8 +942,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (pointee_type.IsValid()) { if (log) { ASTDumper ast_dumper(pointee_type); - log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s", - current_id, ast_dumper.GetCString()); + LLDB_LOGF(log, " FEVD[%u] Adding type for $__lldb_class: %s", + current_id, ast_dumper.GetCString()); } AddThisType(context, pointee_type, current_id); @@ -1048,7 +966,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( return; AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()), - current_id); + current_id); m_struct_vars->m_object_pointer_type = TypeFromUser(ctx_obj_ptr->GetCompilerType()); @@ -1096,8 +1014,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (log) { ASTDumper ast_dumper(interface_type); - log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", - current_id, ast_dumper.GetCString()); + LLDB_LOGF(log, " FEVD[%u] Adding type for $__lldb_objc_class: %s", + current_id, ast_dumper.GetCString()); } AddOneType(context, class_user_type, current_id); @@ -1157,8 +1075,9 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (log) { ASTDumper ast_dumper(self_type->GetFullCompilerType()); - log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", - current_id, ast_dumper.GetCString()); + LLDB_LOGF(log, + " FEVD[%u] Adding type for $__lldb_objc_class: %s", + current_id, ast_dumper.GetCString()); } TypeFromUser class_user_type(self_clang_type); @@ -1222,9 +1141,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( reg_name)); if (reg_info) { - if (log) - log->Printf(" CEDM::FEVD[%u] Found register %s", current_id, - reg_info->name); + LLDB_LOGF(log, " CEDM::FEVD[%u] Found register %s", current_id, + reg_info->name); AddOneRegister(context, reg_info, current_id); } @@ -1298,14 +1216,12 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( } const bool include_inlines = false; - const bool append = false; - + sc_list.Clear(); if (namespace_decl && module_sp) { const bool include_symbols = false; module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase, - include_symbols, include_inlines, append, - sc_list); + include_symbols, include_inlines, sc_list); } else if (target && !namespace_decl) { const bool include_symbols = true; @@ -1314,7 +1230,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( target->GetImages().FindFunctions(name, eFunctionNameTypeFull, include_symbols, include_inlines, - append, sc_list); + sc_list); } // If we found more than one function, see if we can use the frame's decl @@ -1511,9 +1427,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) { if (log) { - log->Printf(" CAS::FEVD[%u] Matching function found for " - "\"%s\" in the modules", - current_id, name.GetCString()); + LLDB_LOGF(log, + " CAS::FEVD[%u] Matching function found for " + "\"%s\" in the modules", + current_id, name.GetCString()); } clang::Decl *copied_decl = CopyDecl(decl_from_modules); @@ -1522,10 +1439,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( : nullptr; if (!copied_function_decl) { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a function " - "declaration from the modules", - current_id); + LLDB_LOGF(log, + " CAS::FEVD[%u] - Couldn't export a function " + "declaration from the modules", + current_id); break; } @@ -1538,9 +1455,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( context.m_found.function = true; } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) { if (log) { - log->Printf(" CAS::FEVD[%u] Matching variable found for " - "\"%s\" in the modules", - current_id, name.GetCString()); + LLDB_LOGF(log, + " CAS::FEVD[%u] Matching variable found for " + "\"%s\" in the modules", + current_id, name.GetCString()); } clang::Decl *copied_decl = CopyDecl(decl_from_modules); @@ -1549,10 +1467,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( : nullptr; if (!copied_var_decl) { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a variable " - "declaration from the modules", - current_id); + LLDB_LOGF(log, + " CAS::FEVD[%u] - Couldn't export a variable " + "declaration from the modules", + current_id); break; } @@ -1647,8 +1565,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, const_value_extractor.GetByteSize()); var_location.SetValueType(Value::eValueTypeHostAddress); } else { - if (log) - log->Printf("Error evaluating constant variable: %s", err.AsCString()); + LLDB_LOGF(log, "Error evaluating constant variable: %s", err.AsCString()); return false; } } @@ -1656,9 +1573,8 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, CompilerType type_to_use = GuardedCopyType(var_clang_type); if (!type_to_use) { - if (log) - log->Printf( - "Couldn't copy a variable's type into the parser's AST context"); + LLDB_LOGF(log, + "Couldn't copy a variable's type into the parser's AST context"); return false; } @@ -1751,9 +1667,10 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, if (log) { ASTDumper orig_dumper(ut.GetOpaqueQualType()); ASTDumper ast_dumper(var_decl); - log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)", - current_id, decl_name.c_str(), ast_dumper.GetCString(), - orig_dumper.GetCString()); + LLDB_LOGF(log, + " CEDM::FEVD[%u] Found variable %s, returned %s (original %s)", + current_id, decl_name.c_str(), ast_dumper.GetCString(), + orig_dumper.GetCString()); } } @@ -1768,9 +1685,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, TypeFromParser parser_type(GuardedCopyType(user_type)); if (!parser_type.GetOpaqueQualType()) { - if (log) - log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s", - current_id, pvar_sp->GetName().GetCString()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Couldn't import type for pvar %s", + current_id, pvar_sp->GetName().GetCString()); return; } @@ -1789,8 +1705,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, if (log) { ASTDumper ast_dumper(var_decl); - log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id, - pvar_sp->GetName().GetCString(), ast_dumper.GetCString()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Added pvar %s, returned %s", current_id, + pvar_sp->GetName().GetCString(), ast_dumper.GetCString()); } } @@ -1848,8 +1764,8 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, if (log) { ASTDumper ast_dumper(var_decl); - log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id, - decl_name.c_str(), ast_dumper.GetCString()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Found variable %s, returned %s", + current_id, decl_name.c_str(), ast_dumper.GetCString()); } } @@ -1858,7 +1774,7 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() { Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); ClangASTContextForExpressions *scratch_ast_context = - static_cast<ClangASTContextForExpressions*>( + static_cast<ClangASTContextForExpressions *>( target->GetScratchClangASTContext()); for (size_t index = 0, num_entities = m_found_entities.GetSize(); @@ -1874,15 +1790,14 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() { const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl); if (!var_decl) { - if (log) - log->Printf("Entity of unknown type does not have a VarDecl"); + LLDB_LOGF(log, "Entity of unknown type does not have a VarDecl"); return false; } if (log) { ASTDumper ast_dumper(const_cast<VarDecl *>(var_decl)); - log->Printf("Variable of unknown type now has Decl %s", - ast_dumper.GetCString()); + LLDB_LOGF(log, "Variable of unknown type now has Decl %s", + ast_dumper.GetCString()); } QualType var_type = var_decl->getType(); @@ -1897,18 +1812,17 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() { var_type.getAsOpaquePtr()); } else if (HasMerger()) { copied_type = CopyTypeWithMerger( - var_decl->getASTContext(), - scratch_ast_context->GetMergerUnchecked(), - var_type).getAsOpaquePtr(); + var_decl->getASTContext(), + scratch_ast_context->GetMergerUnchecked(), var_type) + .getAsOpaquePtr(); } else { lldbassert(0 && "No mechanism to copy a resolved unknown type!"); return false; } if (!copied_type) { - if (log) - log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't " - "import the type for a variable"); + LLDB_LOGF(log, "ClangExpressionDeclMap::ResolveUnknownType - Couldn't " + "import the type for a variable"); return (bool)lldb::ExpressionVariableSP(); } @@ -1939,9 +1853,8 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, m_ast_context, reg_info->encoding, reg_info->byte_size * 8); if (!clang_type) { - if (log) - log->Printf(" Tried to add a type for %s, but couldn't get one", - context.m_decl_name.getAsString().c_str()); + LLDB_LOGF(log, " Tried to add a type for %s, but couldn't get one", + context.m_decl_name.getAsString().c_str()); return; } @@ -1969,9 +1882,9 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, if (log) { ASTDumper ast_dumper(var_decl); - log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id, - context.m_decl_name.getAsString().c_str(), - ast_dumper.GetCString()); + LLDB_LOGF(log, " CEDM::FEVD[%d] Added register %s, returned %s", + current_id, context.m_decl_name.getAsString().c_str(), + ast_dumper.GetCString()); } } @@ -2016,24 +1929,24 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, if (copied_function_template) { if (log) { ASTDumper ast_dumper((clang::Decl *)copied_function_template); - + StreamString ss; - + function->DumpSymbolContext(&ss); - + log->Printf(" CEDM::FEVD[%u] Imported decl for function template" " %s (description %s), returned %s", current_id, copied_function_template->getNameAsString().c_str(), ss.GetData(), ast_dumper.GetCString()); } - + context.AddNamedDecl(copied_function_template); } } else if (src_function_decl) { if (clang::FunctionDecl *copied_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>( - CopyDecl(src_function_decl))) { + CopyDecl(src_function_decl))) { if (log) { ASTDumper ast_dumper((clang::Decl *)copied_function_decl); @@ -2041,19 +1954,20 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, function->DumpSymbolContext(&ss); - log->Printf(" CEDM::FEVD[%u] Imported decl for function %s " - "(description %s), returned %s", - current_id, - copied_function_decl->getNameAsString().c_str(), - ss.GetData(), ast_dumper.GetCString()); + LLDB_LOGF(log, + " CEDM::FEVD[%u] Imported decl for function %s " + "(description %s), returned %s", + current_id, + copied_function_decl->getNameAsString().c_str(), + ss.GetData(), ast_dumper.GetCString()); } context.AddNamedDecl(copied_function_decl); return; } else { if (log) { - log->Printf(" Failed to import the function decl for '%s'", - src_function_decl->getName().str().c_str()); + LLDB_LOGF(log, " Failed to import the function decl for '%s'", + src_function_decl->getName().str().c_str()); } } } @@ -2082,7 +1996,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, if (!function_decl) { if (log) { - log->Printf( + LLDB_LOGF( + log, " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}", function_type->GetName().GetCString(), function_type->GetID()); } @@ -2092,10 +2007,11 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, } else { // We failed to copy the type we found if (log) { - log->Printf(" Failed to import the function type '%s' {0x%8.8" PRIx64 - "} into the expression parser AST contenxt", - function_type->GetName().GetCString(), - function_type->GetID()); + LLDB_LOGF(log, + " Failed to import the function type '%s' {0x%8.8" PRIx64 + "} into the expression parser AST contenxt", + function_type->GetName().GetCString(), + function_type->GetID()); } return; @@ -2154,7 +2070,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); - log->Printf( + LLDB_LOGF( + log, " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s", current_id, (function ? "specific" : "generic"), decl_name.c_str(), ss.GetData(), function_str.c_str()); @@ -2170,7 +2087,8 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context, if (!copied_clang_type) { if (log) - log->Printf( + LLDB_LOGF( + log, "ClangExpressionDeclMap::AddThisType - Couldn't import the type"); return; @@ -2203,9 +2121,10 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context, ASTDumper method_ast_dumper((clang::Decl *)method_decl); ASTDumper type_ast_dumper(copied_clang_type); - log->Printf(" CEDM::AddThisType Added function $__lldb_expr " - "(description %s) for this type %s", - method_ast_dumper.GetCString(), type_ast_dumper.GetCString()); + LLDB_LOGF(log, + " CEDM::AddThisType Added function $__lldb_expr " + "(description %s) for this type %s", + method_ast_dumper.GetCString(), type_ast_dumper.GetCString()); } } @@ -2244,8 +2163,8 @@ void ClangExpressionDeclMap::AddOneType(NameSearchContext &context, Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); if (log) - log->Printf( - "ClangExpressionDeclMap::AddOneType - Couldn't import the type"); + LLDB_LOGF( + log, "ClangExpressionDeclMap::AddOneType - Couldn't import the type"); return; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index 03b73e6be391..2711e90726e7 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -356,7 +356,7 @@ private: /// Activate parser-specific variables void EnableParserVars() { if (!m_parser_vars.get()) - m_parser_vars = llvm::make_unique<ParserVars>(); + m_parser_vars = std::make_unique<ParserVars>(); } /// Deallocate parser-specific variables diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 7d13891ded8d..1422911d6546 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -105,16 +105,26 @@ using namespace lldb_private; class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks { ClangModulesDeclVendor &m_decl_vendor; ClangPersistentVariables &m_persistent_vars; + clang::SourceManager &m_source_mgr; StreamString m_error_stream; bool m_has_errors = false; public: LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor, - ClangPersistentVariables &persistent_vars) - : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars) {} + ClangPersistentVariables &persistent_vars, + clang::SourceManager &source_mgr) + : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars), + m_source_mgr(source_mgr) {} void moduleImport(SourceLocation import_location, clang::ModuleIdPath path, const clang::Module * /*null*/) override { + // Ignore modules that are imported in the wrapper code as these are not + // loaded by the user. + llvm::StringRef filename = + m_source_mgr.getPresumedLoc(import_location).getFilename(); + if (filename == ClangExpressionSourceCode::g_prefix_file_name) + return; + SourceModule module; for (const std::pair<IdentifierInfo *, SourceLocation> &component : path) @@ -137,12 +147,14 @@ public: class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer { public: - ClangDiagnosticManagerAdapter() - : m_passthrough(new clang::TextDiagnosticBuffer) {} - - ClangDiagnosticManagerAdapter( - const std::shared_ptr<clang::TextDiagnosticBuffer> &passthrough) - : m_passthrough(passthrough) {} + ClangDiagnosticManagerAdapter(DiagnosticOptions &opts) { + DiagnosticOptions *m_options = new DiagnosticOptions(opts); + m_options->ShowPresumedLoc = true; + m_options->ShowLevel = false; + m_os.reset(new llvm::raw_string_ostream(m_output)); + m_passthrough.reset( + new clang::TextDiagnosticPrinter(*m_os, m_options, false)); + } void ResetManager(DiagnosticManager *manager = nullptr) { m_manager = manager; @@ -150,79 +162,92 @@ public: void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override { - if (m_manager) { - llvm::SmallVector<char, 32> diag_str; - Info.FormatDiagnostic(diag_str); - diag_str.push_back('\0'); - const char *data = diag_str.data(); - - lldb_private::DiagnosticSeverity severity; - bool make_new_diagnostic = true; - - switch (DiagLevel) { - case DiagnosticsEngine::Level::Fatal: - case DiagnosticsEngine::Level::Error: - severity = eDiagnosticSeverityError; - break; - case DiagnosticsEngine::Level::Warning: - severity = eDiagnosticSeverityWarning; - break; - case DiagnosticsEngine::Level::Remark: - case DiagnosticsEngine::Level::Ignored: - severity = eDiagnosticSeverityRemark; - break; - case DiagnosticsEngine::Level::Note: - m_manager->AppendMessageToDiagnostic(data); - make_new_diagnostic = false; - } - if (make_new_diagnostic) { - ClangDiagnostic *new_diagnostic = - new ClangDiagnostic(data, severity, Info.getID()); - m_manager->AddDiagnostic(new_diagnostic); - - // Don't store away warning fixits, since the compiler doesn't have - // enough context in an expression for the warning to be useful. - // FIXME: Should we try to filter out FixIts that apply to our generated - // code, and not the user's expression? - if (severity == eDiagnosticSeverityError) { - size_t num_fixit_hints = Info.getNumFixItHints(); - for (size_t i = 0; i < num_fixit_hints; i++) { - const clang::FixItHint &fixit = Info.getFixItHint(i); - if (!fixit.isNull()) - new_diagnostic->AddFixitHint(fixit); - } - } + if (!m_manager) { + // We have no DiagnosticManager before/after parsing but we still could + // receive diagnostics (e.g., by the ASTImporter failing to copy decls + // when we move the expression result ot the ScratchASTContext). Let's at + // least log these diagnostics until we find a way to properly render + // them and display them to the user. + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + if (log) { + llvm::SmallVector<char, 32> diag_str; + Info.FormatDiagnostic(diag_str); + diag_str.push_back('\0'); + const char *plain_diag = diag_str.data(); + LLDB_LOG(log, "Received diagnostic outside parsing: {0}", plain_diag); } + return; } + // Render diagnostic message to m_output. + m_output.clear(); m_passthrough->HandleDiagnostic(DiagLevel, Info); - } + m_os->flush(); - void FlushDiagnostics(DiagnosticsEngine &Diags) { - m_passthrough->FlushDiagnostics(Diags); - } + lldb_private::DiagnosticSeverity severity; + bool make_new_diagnostic = true; + + switch (DiagLevel) { + case DiagnosticsEngine::Level::Fatal: + case DiagnosticsEngine::Level::Error: + severity = eDiagnosticSeverityError; + break; + case DiagnosticsEngine::Level::Warning: + severity = eDiagnosticSeverityWarning; + break; + case DiagnosticsEngine::Level::Remark: + case DiagnosticsEngine::Level::Ignored: + severity = eDiagnosticSeverityRemark; + break; + case DiagnosticsEngine::Level::Note: + m_manager->AppendMessageToDiagnostic(m_output); + make_new_diagnostic = false; + } + if (make_new_diagnostic) { + // ClangDiagnostic messages are expected to have no whitespace/newlines + // around them. + std::string stripped_output = llvm::StringRef(m_output).trim(); + + auto new_diagnostic = std::make_unique<ClangDiagnostic>( + stripped_output, severity, Info.getID()); + + // Don't store away warning fixits, since the compiler doesn't have + // enough context in an expression for the warning to be useful. + // FIXME: Should we try to filter out FixIts that apply to our generated + // code, and not the user's expression? + if (severity == eDiagnosticSeverityError) { + size_t num_fixit_hints = Info.getNumFixItHints(); + for (size_t i = 0; i < num_fixit_hints; i++) { + const clang::FixItHint &fixit = Info.getFixItHint(i); + if (!fixit.isNull()) + new_diagnostic->AddFixitHint(fixit); + } + } - DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { - return new ClangDiagnosticManagerAdapter(m_passthrough); + m_manager->AddDiagnostic(std::move(new_diagnostic)); + } } - clang::TextDiagnosticBuffer *GetPassthrough() { return m_passthrough.get(); } + clang::TextDiagnosticPrinter *GetPassthrough() { return m_passthrough.get(); } private: DiagnosticManager *m_manager = nullptr; - std::shared_ptr<clang::TextDiagnosticBuffer> m_passthrough; + std::shared_ptr<clang::TextDiagnosticPrinter> m_passthrough; + /// Output stream of m_passthrough. + std::shared_ptr<llvm::raw_string_ostream> m_os; + /// Output string filled by m_os. + std::string m_output; }; -static void -SetupModuleHeaderPaths(CompilerInstance *compiler, - std::vector<ConstString> include_directories, - lldb::TargetSP target_sp) { +static void SetupModuleHeaderPaths(CompilerInstance *compiler, + std::vector<std::string> include_directories, + lldb::TargetSP target_sp) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); HeaderSearchOptions &search_opts = compiler->getHeaderSearchOpts(); - for (ConstString dir : include_directories) { - search_opts.AddPath(dir.AsCString(), frontend::System, false, true); + for (const std::string &dir : include_directories) { + search_opts.AddPath(dir, frontend::System, false, true); LLDB_LOG(log, "Added user include dir: {0}", dir); } @@ -232,27 +257,9 @@ SetupModuleHeaderPaths(CompilerInstance *compiler, search_opts.ModuleCachePath = module_cache.str(); LLDB_LOG(log, "Using module cache path: {0}", module_cache.c_str()); - FileSpec clang_resource_dir = GetClangResourceDir(); - std::string resource_dir = clang_resource_dir.GetPath(); - if (FileSystem::Instance().IsDirectory(resource_dir)) { - search_opts.ResourceDir = resource_dir; - std::string resource_include = resource_dir + "/include"; - search_opts.AddPath(resource_include, frontend::System, false, true); - - LLDB_LOG(log, "Added resource include dir: {0}", resource_include); - } + search_opts.ResourceDir = GetClangResourceDir().GetPath(); search_opts.ImplicitModuleMaps = true; - - std::vector<std::string> system_include_directories = - target_sp->GetPlatform()->GetSystemIncludeDirectories( - lldb::eLanguageTypeC_plus_plus); - - for (const std::string &include_dir : system_include_directories) { - search_opts.AddPath(include_dir, frontend::System, false, true); - - LLDB_LOG(log, "Added system include dir: {0}", include_dir); - } } //===----------------------------------------------------------------------===// @@ -261,10 +268,12 @@ SetupModuleHeaderPaths(CompilerInstance *compiler, ClangExpressionParser::ClangExpressionParser( ExecutionContextScope *exe_scope, Expression &expr, - bool generate_debug_info, std::vector<ConstString> include_directories) + bool generate_debug_info, std::vector<std::string> include_directories, + std::string filename) : ExpressionParser(exe_scope, expr, generate_debug_info), m_compiler(), m_pp_callbacks(nullptr), - m_include_directories(std::move(include_directories)) { + m_include_directories(std::move(include_directories)), + m_filename(std::move(filename)) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // We can't compile expressions without a target. So if the exe_scope is @@ -331,9 +340,8 @@ ClangExpressionParser::ClangExpressionParser( if (process_sp && frame_lang != lldb::eLanguageTypeUnknown) { lang_rt = process_sp->GetLanguageRuntime(frame_lang); - if (log) - log->Printf("Frame has language of type %s", - Language::GetNameForLanguageType(frame_lang)); + LLDB_LOGF(log, "Frame has language of type %s", + Language::GetNameForLanguageType(frame_lang)); } // 2. Configure the compiler with a set of default options that are @@ -341,9 +349,8 @@ ClangExpressionParser::ClangExpressionParser( if (target_arch.IsValid()) { std::string triple = target_arch.GetTriple().str(); m_compiler->getTargetOpts().Triple = triple; - if (log) - log->Printf("Using %s as the target triple", - m_compiler->getTargetOpts().Triple.c_str()); + LLDB_LOGF(log, "Using %s as the target triple", + m_compiler->getTargetOpts().Triple.c_str()); } else { // If we get here we don't have a valid target and just have to guess. // Sometimes this will be ok to just use the host target triple (when we @@ -352,9 +359,8 @@ ClangExpressionParser::ClangExpressionParser( // the host triple. In such a case the language runtime should expose an // overridden options set (3), below. m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple(); - if (log) - log->Printf("Using default target triple of %s", - m_compiler->getTargetOpts().Triple.c_str()); + LLDB_LOGF(log, "Using default target triple of %s", + m_compiler->getTargetOpts().Triple.c_str()); } // Now add some special fixes for known architectures: Any arm32 iOS // environment, but not on arm64 @@ -408,12 +414,13 @@ ClangExpressionParser::ClangExpressionParser( auto target_info = TargetInfo::CreateTargetInfo( m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts); if (log) { - log->Printf("Using SIMD alignment: %d", target_info->getSimdDefaultAlign()); - log->Printf("Target datalayout string: '%s'", - target_info->getDataLayout().getStringRepresentation().c_str()); - log->Printf("Target ABI: '%s'", target_info->getABI().str().c_str()); - log->Printf("Target vector alignment: %d", - target_info->getMaxVectorAlign()); + LLDB_LOGF(log, "Using SIMD alignment: %d", + target_info->getSimdDefaultAlign()); + LLDB_LOGF(log, "Target datalayout string: '%s'", + target_info->getDataLayout().getStringRepresentation().c_str()); + LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str()); + LLDB_LOGF(log, "Target vector alignment: %d", + target_info->getMaxVectorAlign()); } m_compiler->setTarget(target_info); @@ -508,6 +515,9 @@ ClangExpressionParser::ClangExpressionParser( lang_opts.DoubleSquareBracketAttributes = true; lang_opts.CPlusPlus11 = true; + // The Darwin libc expects this macro to be set. + lang_opts.GNUCVersion = 40201; + SetupModuleHeaderPaths(m_compiler.get(), m_include_directories, target_sp); } @@ -537,8 +547,8 @@ ClangExpressionParser::ClangExpressionParser( // Set CodeGen options m_compiler->getCodeGenOpts().EmitDeclMetadata = true; m_compiler->getCodeGenOpts().InstrumentFunctions = false; - m_compiler->getCodeGenOpts().DisableFPElim = true; - m_compiler->getCodeGenOpts().OmitLeafFramePointer = false; + m_compiler->getCodeGenOpts().setFramePointer( + CodeGenOptions::FramePointerKind::All); if (generate_debug_info) m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo); else @@ -560,7 +570,9 @@ ClangExpressionParser::ClangExpressionParser( // 6. Set up the diagnostic buffer for reporting errors - m_compiler->getDiagnostics().setClient(new ClangDiagnosticManagerAdapter); + auto diag_mgr = new ClangDiagnosticManagerAdapter( + m_compiler->getDiagnostics().getDiagnosticOptions()); + m_compiler->getDiagnostics().setClient(diag_mgr); // 7. Set up the source management objects inside the compiler m_compiler->createFileManager(); @@ -574,8 +586,8 @@ ClangExpressionParser::ClangExpressionParser( llvm::cast<ClangPersistentVariables>( target_sp->GetPersistentExpressionStateForLanguage( lldb::eLanguageTypeC)); - std::unique_ptr<PPCallbacks> pp_callbacks( - new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars)); + std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks( + *decl_vendor, *clang_persistent_vars, m_compiler->getSourceManager())); m_pp_callbacks = static_cast<LLDBPreprocessorCallbacks *>(pp_callbacks.get()); m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks)); @@ -592,9 +604,7 @@ ClangExpressionParser::ClangExpressionParser( m_compiler->createASTContext(); clang::ASTContext &ast_context = m_compiler->getASTContext(); - m_ast_context.reset( - new ClangASTContext(m_compiler->getTargetOpts().Triple.c_str())); - m_ast_context->setASTContext(&ast_context); + m_ast_context.reset(new ClangASTContext(ast_context)); std::string module_name("$__lldb_module"); @@ -872,8 +882,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, ClangDiagnosticManagerAdapter *adapter = static_cast<ClangDiagnosticManagerAdapter *>( m_compiler->getDiagnostics().getClient()); - clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough(); - diag_buf->FlushDiagnostics(m_compiler->getDiagnostics()); + auto diag_buf = adapter->GetPassthrough(); adapter->ResetManager(&diagnostic_manager); @@ -904,16 +913,19 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, } if (temp_fd != -1) { - lldb_private::File file(temp_fd, true); + lldb_private::NativeFile file(temp_fd, File::eOpenOptionWrite, true); const size_t expr_text_len = strlen(expr_text); size_t bytes_written = expr_text_len; if (file.Write(expr_text, bytes_written).Success()) { if (bytes_written == expr_text_len) { file.Close(); - source_mgr.setMainFileID(source_mgr.createFileID( - m_compiler->getFileManager().getFile(result_path), - SourceLocation(), SrcMgr::C_User)); - created_main_file = true; + if (auto fileEntry = + m_compiler->getFileManager().getFile(result_path)) { + source_mgr.setMainFileID(source_mgr.createFileID( + *fileEntry, + SourceLocation(), SrcMgr::C_User)); + created_main_file = true; + } } } } @@ -921,7 +933,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, if (!created_main_file) { std::unique_ptr<MemoryBuffer> memory_buffer = - MemoryBuffer::getMemBufferCopy(expr_text, "<lldb-expr>"); + MemoryBuffer::getMemBufferCopy(expr_text, m_filename); source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer))); } @@ -1092,8 +1104,8 @@ bool ClangExpressionParser::RewriteExpression( if (num_diags == 0) return false; - for (const Diagnostic *diag : diagnostic_manager.Diagnostics()) { - const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag); + for (const auto &diag : diagnostic_manager.Diagnostics()) { + const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get()); if (diagnostic && diagnostic->HasFixIts()) { for (const FixItHint &fixit : diagnostic->FixIts()) { // This is cobbed from clang::Rewrite::FixItRewriter. @@ -1181,9 +1193,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( m_expr.FunctionName()); return err; } else { - if (log) - log->Printf("Found function %s for %s", function_name.AsCString(), - m_expr.FunctionName()); + LLDB_LOGF(log, "Found function %s for %s", function_name.AsCString(), + m_expr.FunctionName()); } } @@ -1198,9 +1209,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( LLVMUserExpression::IRPasses custom_passes; { auto lang = m_expr.Language(); - if (log) - log->Printf("%s - Current expression language is %s\n", __FUNCTION__, - Language::GetNameForLanguageType(lang)); + LLDB_LOGF(log, "%s - Current expression language is %s\n", __FUNCTION__, + Language::GetNameForLanguageType(lang)); lldb::ProcessSP process_sp = exe_ctx.GetProcessSP(); if (process_sp && lang != lldb::eLanguageTypeUnknown) { auto runtime = process_sp->GetLanguageRuntime(lang); @@ -1210,10 +1220,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( } if (custom_passes.EarlyPasses) { - if (log) - log->Printf("%s - Running Early IR Passes from LanguageRuntime on " - "expression module '%s'", - __FUNCTION__, m_expr.FunctionName()); + LLDB_LOGF(log, + "%s - Running Early IR Passes from LanguageRuntime on " + "expression module '%s'", + __FUNCTION__, m_expr.FunctionName()); custom_passes.EarlyPasses->run(*llvm_module_up); } @@ -1230,12 +1240,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( type_system_helper->DeclMap(); // result can be NULL if (decl_map) { - Stream *error_stream = nullptr; Target *target = exe_ctx.GetTargetPtr(); - error_stream = target->GetDebugger().GetErrorFile().get(); - + auto &error_stream = target->GetDebugger().GetErrorStream(); IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), - *execution_unit_sp, *error_stream, + *execution_unit_sp, error_stream, function_name.AsCString()); bool ir_can_run = @@ -1298,9 +1306,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( process->SetDynamicCheckers(dynamic_checkers); - if (log) - log->Printf("== [ClangExpressionParser::PrepareForExecution] " - "Finished installing dynamic checkers =="); + LLDB_LOGF(log, "== [ClangExpressionParser::PrepareForExecution] " + "Finished installing dynamic checkers =="); } if (auto *checker_funcs = llvm::dyn_cast<ClangDynamicCheckerFunctions>( @@ -1316,10 +1323,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( } if (custom_passes.LatePasses) { - if (log) - log->Printf("%s - Running Late IR Passes from LanguageRuntime on " - "expression module '%s'", - __FUNCTION__, m_expr.FunctionName()); + LLDB_LOGF(log, + "%s - Running Late IR Passes from LanguageRuntime on " + "expression module '%s'", + __FUNCTION__, m_expr.FunctionName()); custom_passes.LatePasses->run(*module); } diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h index a42c2190ffb8..79ad5728bf74 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h @@ -53,9 +53,14 @@ public: /// @param[in] include_directories /// List of include directories that should be used when parsing the /// expression. + /// + /// @param[in] filename + /// Name of the source file that should be used when rendering + /// diagnostics (i.e. errors, warnings or notes from Clang). ClangExpressionParser(ExecutionContextScope *exe_scope, Expression &expr, bool generate_debug_info, - std::vector<ConstString> include_directories = {}); + std::vector<std::string> include_directories = {}, + std::string filename = "<clang expression>"); /// Destructor ~ClangExpressionParser() override; @@ -177,7 +182,9 @@ private: ///encounters module imports std::unique_ptr<ClangASTContext> m_ast_context; - std::vector<ConstString> m_include_directories; + std::vector<std::string> m_include_directories; + /// File name used for the user expression. + std::string m_filename; }; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp index f513b1eea360..21cb33402e7f 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp @@ -29,7 +29,15 @@ using namespace lldb_private; -const char *ClangExpressionSourceCode::g_expression_prefix = R"( +#define PREFIX_NAME "<lldb wrapper prefix>" + +const llvm::StringRef ClangExpressionSourceCode::g_prefix_file_name = PREFIX_NAME; + +const char *ClangExpressionSourceCode::g_expression_prefix = +"#line 1 \"" PREFIX_NAME R"(" +#ifndef offsetof +#define offsetof(t, d) __builtin_offsetof(t, d) +#endif #ifndef NULL #define NULL (__null) #endif @@ -64,9 +72,6 @@ extern "C" } )"; -static const char *c_start_marker = " /*LLDB_BODY_START*/\n "; -static const char *c_end_marker = ";\n /*LLDB_BODY_END*/\n"; - namespace { class AddMacroState { @@ -166,6 +171,17 @@ static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit, } } +lldb_private::ClangExpressionSourceCode::ClangExpressionSourceCode( + llvm::StringRef filename, llvm::StringRef name, llvm::StringRef prefix, + llvm::StringRef body, Wrapping wrap) + : ExpressionSourceCode(name, prefix, body, wrap) { + // Use #line markers to pretend that we have a single-line source file + // containing only the user expression. This will hide our wrapper code + // from the user when we render diagnostics with Clang. + m_start_marker = "#line 1 \"" + filename.str() + "\"\n"; + m_end_marker = "\n;\n#line 1 \"<lldb wrapper suffix>\"\n"; +} + namespace { /// Allows checking if a token is contained in a given expression. class TokenVerifier { @@ -286,7 +302,8 @@ bool ClangExpressionSourceCode::GetText( Target *target = exe_ctx.GetTargetPtr(); if (target) { - if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64) { + if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64 || + target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_32) { target_specific_defines = "typedef bool BOOL;\n"; } if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64) { @@ -398,9 +415,9 @@ bool ClangExpressionSourceCode::GetText( case lldb::eLanguageTypeC: case lldb::eLanguageTypeC_plus_plus: case lldb::eLanguageTypeObjC: - tagged_body.append(c_start_marker); + tagged_body.append(m_start_marker); tagged_body.append(m_body); - tagged_body.append(c_end_marker); + tagged_body.append(m_end_marker); break; } switch (wrapping_language) { @@ -474,24 +491,19 @@ bool ClangExpressionSourceCode::GetText( bool ClangExpressionSourceCode::GetOriginalBodyBounds( std::string transformed_text, lldb::LanguageType wrapping_language, size_t &start_loc, size_t &end_loc) { - const char *start_marker; - const char *end_marker; - switch (wrapping_language) { default: return false; case lldb::eLanguageTypeC: case lldb::eLanguageTypeC_plus_plus: case lldb::eLanguageTypeObjC: - start_marker = c_start_marker; - end_marker = c_end_marker; break; } - start_loc = transformed_text.find(start_marker); + start_loc = transformed_text.find(m_start_marker); if (start_loc == std::string::npos) return false; - start_loc += strlen(start_marker); - end_loc = transformed_text.find(end_marker); + start_loc += m_start_marker.size(); + end_loc = transformed_text.find(m_end_marker); return end_loc != std::string::npos; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h index 894290295837..1d159670b962 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h @@ -23,15 +23,18 @@ class ExecutionContext; class ClangExpressionSourceCode : public ExpressionSourceCode { public: + /// The file name we use for the wrapper code that we inject before + /// the user expression. + static const llvm::StringRef g_prefix_file_name; static const char *g_expression_prefix; - static ClangExpressionSourceCode *CreateWrapped(const char *prefix, - const char *body) { - return new ClangExpressionSourceCode("$__lldb_expr", prefix, body, true); + static ClangExpressionSourceCode *CreateWrapped(llvm::StringRef filename, + llvm::StringRef prefix, + llvm::StringRef body) { + return new ClangExpressionSourceCode(filename, "$__lldb_expr", prefix, body, + Wrap); } - uint32_t GetNumBodyLines(); - /// Generates the source code that will evaluate the expression. /// /// \param text output parameter containing the source code string. @@ -56,14 +59,20 @@ public: // Given a string returned by GetText, find the beginning and end of the body // passed to CreateWrapped. Return true if the bounds could be found. This // will also work on text with FixItHints applied. - static bool GetOriginalBodyBounds(std::string transformed_text, - lldb::LanguageType wrapping_language, - size_t &start_loc, size_t &end_loc); + bool GetOriginalBodyBounds(std::string transformed_text, + lldb::LanguageType wrapping_language, + size_t &start_loc, size_t &end_loc); protected: - ClangExpressionSourceCode(const char *name, const char *prefix, const char *body, - bool wrap) : - ExpressionSourceCode(name, prefix, body, wrap) {} + ClangExpressionSourceCode(llvm::StringRef filename, llvm::StringRef name, + llvm::StringRef prefix, llvm::StringRef body, + Wrapping wrap); + +private: + /// String marking the start of the user expression. + std::string m_start_marker; + /// String marking the end of the user expression. + std::string m_end_marker; }; } // namespace lldb_private diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp index eabc96aa8e51..8fbfa6e47578 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp @@ -179,8 +179,7 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp, m_wrapper_function_text.append(");\n}\n"); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); + LLDB_LOGF(log, "Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); // Okay, now compile this expression diff --git a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp index 65c547391831..42d3f22014dd 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp @@ -30,10 +30,10 @@ static bool VerifyClangPath(const llvm::Twine &clang_path) { if (FileSystem::Instance().IsDirectory(clang_path)) return true; Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (log) - log->Printf("VerifyClangPath(): " - "failed to stat clang resource directory at \"%s\"", - clang_path.str().c_str()); + LLDB_LOGF(log, + "VerifyClangPath(): " + "failed to stat clang resource directory at \"%s\"", + clang_path.str().c_str()); return false; } @@ -67,10 +67,10 @@ static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec, llvm::sys::path::native(relative_path); llvm::sys::path::append(clang_dir, relative_path); if (!verify || VerifyClangPath(clang_dir)) { - if (log) - log->Printf("DefaultComputeClangResourceDir: Setting ClangResourceDir " - "to \"%s\", verify = %s", - clang_dir.str().str().c_str(), verify ? "true" : "false"); + LLDB_LOGF(log, + "DefaultComputeClangResourceDir: Setting ClangResourceDir " + "to \"%s\", verify = %s", + clang_dir.str().str().c_str(), verify ? "true" : "false"); file_spec.GetDirectory().SetString(clang_dir); FileSystem::Instance().Resolve(file_spec); return true; @@ -160,9 +160,8 @@ FileSpec lldb_private::GetClangResourceDir() { ComputeClangResourceDirectory(lldb_file_spec, g_cached_resource_dir, true); Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (log) - log->Printf("GetClangResourceDir() => '%s'", - g_cached_resource_dir.GetPath().c_str()); + LLDB_LOGF(log, "GetClangResourceDir() => '%s'", + g_cached_resource_dir.GetPath().c_str()); }); return g_cached_resource_dir; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp index 4a220790e50d..f3df589d7311 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -27,6 +27,7 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/SourceModule.h" #include "lldb/Target/Target.h" @@ -110,6 +111,9 @@ private: ImportedModuleMap m_imported_modules; ImportedModuleSet m_user_imported_modules; const clang::ExternalASTMerger::OriginMap m_origin_map; + // We assume that every ASTContext has an ClangASTContext, so we also store + // a custom ClangASTContext for our internal ASTContext. + std::unique_ptr<ClangASTContext> m_ast_context; }; } // anonymous namespace @@ -143,7 +147,8 @@ void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) { } } -ClangModulesDeclVendor::ClangModulesDeclVendor() {} +ClangModulesDeclVendor::ClangModulesDeclVendor() + : ClangDeclVendor(eClangModuleDeclVendor) {} ClangModulesDeclVendor::~ClangModulesDeclVendor() {} @@ -155,7 +160,11 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl( : m_diagnostics_engine(std::move(diagnostics_engine)), m_compiler_invocation(std::move(compiler_invocation)), m_compiler_instance(std::move(compiler_instance)), - m_parser(std::move(parser)), m_origin_map() {} + m_parser(std::move(parser)), m_origin_map() { + + // Initialize our ClangASTContext. + m_ast_context.reset(new ClangASTContext(m_compiler_instance->getASTContext())); +} void ClangModulesDeclVendorImpl::ReportModuleExportsHelper( std::set<ClangModulesDeclVendor::ModuleID> &exports, @@ -237,11 +246,11 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module, bool is_system = true; bool is_framework = false; - auto *dir = + auto dir = HS.getFileMgr().getDirectory(module.search_path.GetStringRef()); if (!dir) return error(); - auto *file = HS.lookupModuleMapFile(dir, is_framework); + auto *file = HS.lookupModuleMapFile(*dir, is_framework); if (!file) return error(); if (!HS.loadModuleMapFile(file, is_system)) @@ -562,8 +571,9 @@ ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path, clang::ExternalASTMerger::ImporterSource ClangModulesDeclVendorImpl::GetImporterSource() { - return {m_compiler_instance->getASTContext(), - m_compiler_instance->getFileManager(), m_origin_map}; + return clang::ExternalASTMerger::ImporterSource( + m_compiler_instance->getASTContext(), + m_compiler_instance->getFileManager(), m_origin_map); } static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer"; diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h index d5c8757bdcd0..e099b59041d8 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h +++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h @@ -10,22 +10,27 @@ #define liblldb_ClangModulesDeclVendor_h #include "lldb/Core/ClangForward.h" -#include "lldb/Symbol/DeclVendor.h" #include "lldb/Symbol/SourceModule.h" #include "lldb/Target/Platform.h" +#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h" + #include <set> #include <vector> namespace lldb_private { -class ClangModulesDeclVendor : public DeclVendor { +class ClangModulesDeclVendor : public ClangDeclVendor { public: // Constructors and Destructors ClangModulesDeclVendor(); ~ClangModulesDeclVendor() override; + static bool classof(const DeclVendor *vendor) { + return vendor->GetKind() == eClangModuleDeclVendor; + } + static ClangModulesDeclVendor *Create(Target &target); typedef std::vector<ConstString> ModulePath; diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp index 742a14992dc9..24dd705e37b1 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp @@ -23,8 +23,7 @@ using namespace lldb; using namespace lldb_private; ClangPersistentVariables::ClangPersistentVariables() - : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang), - m_next_persistent_variable_id(0) {} + : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang) {} ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable( const lldb::ValueObjectSP &valobj_sp) { @@ -43,13 +42,25 @@ void ClangPersistentVariables::RemovePersistentVariable( lldb::ExpressionVariableSP variable) { RemoveVariable(variable); - const char *name = variable->GetName().AsCString(); + // Check if the removed variable was the last one that was created. If yes, + // reuse the variable id for the next variable. - if (*name != '$') + // Nothing to do if we have not assigned a variable id so far. + if (m_next_persistent_variable_id == 0) return; - name++; - if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1) + llvm::StringRef name = variable->GetName().GetStringRef(); + // Remove the prefix from the variable that only the indes is left. + if (!name.consume_front(GetPersistentVariablePrefix(false))) + return; + + // Check if the variable contained a variable id. + uint32_t variable_id; + if (name.getAsInteger(10, variable_id)) + return; + // If it's the most recent variable id that was assigned, make sure that this + // variable id will be used for the next persistent variable. + if (variable_id == m_next_persistent_variable_id - 1) m_next_persistent_variable_id--; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h index b39f89ad7eef..95e6c3ac963d 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h +++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h @@ -45,11 +45,20 @@ public: uint32_t addr_byte_size) override; void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override; - llvm::StringRef - GetPersistentVariablePrefix(bool is_error) const override { + + llvm::StringRef GetPersistentVariablePrefix(bool is_error) const override { return "$"; } + /// Returns the next file name that should be used for user expressions. + std::string GetNextExprFileName() { + std::string name; + name.append("<user expression "); + name.append(std::to_string(m_next_user_file_id++)); + name.append(">"); + return name; + } + llvm::Optional<CompilerType> GetCompilerTypeFromPersistentDecl(ConstString type_name) override; @@ -66,8 +75,10 @@ public: } private: - uint32_t m_next_persistent_variable_id; ///< The counter used by - ///GetNextResultName(). + /// The counter used by GetNextExprFileName. + uint32_t m_next_user_file_id = 0; + // The counter used by GetNextPersistentVariableName + uint32_t m_next_persistent_variable_id = 0; typedef llvm::DenseMap<const char *, clang::NamedDecl *> PersistentDeclMap; PersistentDeclMap diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 2dae5b7022f3..da1ca785635c 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +#include "lldb/Host/Config.h" + #include <stdio.h> #if HAVE_SYS_TYPES_H #include <sys/types.h> @@ -21,9 +23,9 @@ #include "ClangDiagnostic.h" #include "ClangExpressionDeclMap.h" #include "ClangExpressionParser.h" -#include "ClangExpressionSourceCode.h" #include "ClangModulesDeclVendor.h" #include "ClangPersistentVariables.h" +#include "CppModuleConfiguration.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -90,21 +92,18 @@ ClangUserExpression::~ClangUserExpression() {} void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("ClangUserExpression::ScanContext()"); + LLDB_LOGF(log, "ClangUserExpression::ScanContext()"); m_target = exe_ctx.GetTargetPtr(); if (!(m_allow_cxx || m_allow_objc)) { - if (log) - log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C"); + LLDB_LOGF(log, " [CUE::SC] Settings inhibit C++ and Objective-C"); return; } StackFrame *frame = exe_ctx.GetFramePtr(); if (frame == nullptr) { - if (log) - log->Printf(" [CUE::SC] Null stack frame"); + LLDB_LOGF(log, " [CUE::SC] Null stack frame"); return; } @@ -112,8 +111,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { lldb::eSymbolContextBlock); if (!sym_ctx.function) { - if (log) - log->Printf(" [CUE::SC] Null function"); + LLDB_LOGF(log, " [CUE::SC] Null function"); return; } @@ -121,16 +119,14 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { Block *function_block = sym_ctx.GetFunctionBlock(); if (!function_block) { - if (log) - log->Printf(" [CUE::SC] Null function block"); + LLDB_LOGF(log, " [CUE::SC] Null function block"); return; } CompilerDeclContext decl_context = function_block->GetDeclContext(); if (!decl_context) { - if (log) - log->Printf(" [CUE::SC] Null decl context"); + LLDB_LOGF(log, " [CUE::SC] Null decl context"); return; } @@ -317,17 +313,13 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { // count is not available, [myArray count] returns id, which can't be directly // cast to int without causing a clang error. static void ApplyObjcCastHack(std::string &expr) { -#define OBJC_CAST_HACK_FROM "(int)[" -#define OBJC_CAST_HACK_TO "(int)(long long)[" - - size_t from_offset; + const std::string from = "(int)["; + const std::string to = "(int)(long long)["; - while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos) - expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, - OBJC_CAST_HACK_TO); + size_t offset; -#undef OBJC_CAST_HACK_TO -#undef OBJC_CAST_HACK_FROM + while ((offset = expr.find(from)) != expr.npos) + expr.replace(offset, from.size(), to); } bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager, @@ -336,6 +328,7 @@ bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_man if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage( lldb::eLanguageTypeC)) { + m_clang_state = llvm::cast<ClangPersistentVariables>(persistent_state); m_result_delegate.RegisterPersistentState(persistent_state); } else { diagnostic_manager.PutString( @@ -384,30 +377,34 @@ static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) { } } -void ClangUserExpression::UpdateLanguageForExpr( +void ClangUserExpression::UpdateLanguageForExpr() { + m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown; + if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) + return; + if (m_in_cplusplus_method) + m_expr_lang = lldb::eLanguageTypeC_plus_plus; + else if (m_in_objectivec_method) + m_expr_lang = lldb::eLanguageTypeObjC; + else + m_expr_lang = lldb::eLanguageTypeC; +} + +void ClangUserExpression::CreateSourceCode( DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, std::vector<std::string> modules_to_import, bool for_completion) { - m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown; + m_filename = m_clang_state->GetNextExprFileName(); std::string prefix = m_expr_prefix; if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) { m_transformed_text = m_expr_text; } else { - std::unique_ptr<ClangExpressionSourceCode> source_code( - ClangExpressionSourceCode::CreateWrapped(prefix.c_str(), - m_expr_text.c_str())); - - if (m_in_cplusplus_method) - m_expr_lang = lldb::eLanguageTypeC_plus_plus; - else if (m_in_objectivec_method) - m_expr_lang = lldb::eLanguageTypeObjC; - else - m_expr_lang = lldb::eLanguageTypeC; - - if (!source_code->GetText(m_transformed_text, m_expr_lang, - m_in_static_method, exe_ctx, !m_ctx_obj, - for_completion, modules_to_import)) { + m_source_code.reset(ClangExpressionSourceCode::CreateWrapped( + m_filename, prefix.c_str(), m_expr_text.c_str())); + + if (!m_source_code->GetText(m_transformed_text, m_expr_lang, + m_in_static_method, exe_ctx, !m_ctx_obj, + for_completion, modules_to_import)) { diagnostic_manager.PutString(eDiagnosticSeverityError, "couldn't construct expression body"); return; @@ -417,7 +414,7 @@ void ClangUserExpression::UpdateLanguageForExpr( // transformed code. We need this later for the code completion. std::size_t original_start; std::size_t original_end; - bool found_bounds = source_code->GetOriginalBodyBounds( + bool found_bounds = m_source_code->GetOriginalBodyBounds( m_transformed_text, m_expr_lang, original_start, original_end); if (found_bounds) m_user_expression_start_pos = original_start; @@ -437,48 +434,70 @@ static bool SupportsCxxModuleImport(lldb::LanguageType language) { } } -std::vector<std::string> -ClangUserExpression::GetModulesToImport(ExecutionContext &exe_ctx) { +/// Utility method that puts a message into the expression log and +/// returns an invalid module configuration. +static CppModuleConfiguration LogConfigError(const std::string &msg) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + LLDB_LOG(log, "[C++ module config] {0}", msg); + return CppModuleConfiguration(); +} - if (!SupportsCxxModuleImport(Language())) - return {}; +CppModuleConfiguration GetModuleConfig(lldb::LanguageType language, + ExecutionContext &exe_ctx) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + // Don't do anything if this is not a C++ module configuration. + if (!SupportsCxxModuleImport(language)) + return LogConfigError("Language doesn't support C++ modules"); Target *target = exe_ctx.GetTargetPtr(); - if (!target || !target->GetEnableImportStdModule()) - return {}; + if (!target) + return LogConfigError("No target"); + + if (!target->GetEnableImportStdModule()) + return LogConfigError("Importing std module not enabled in settings"); StackFrame *frame = exe_ctx.GetFramePtr(); if (!frame) - return {}; + return LogConfigError("No frame"); Block *block = frame->GetFrameBlock(); if (!block) - return {}; + return LogConfigError("No block"); SymbolContext sc; block->CalculateSymbolContext(&sc); if (!sc.comp_unit) - return {}; - - if (log) { - for (const SourceModule &m : sc.comp_unit->GetImportedModules()) { - LLDB_LOG(log, "Found module in compile unit: {0:$[.]} - include dir: {1}", - llvm::make_range(m.path.begin(), m.path.end()), m.search_path); + return LogConfigError("Couldn't calculate symbol context"); + + // Build a list of files we need to analyze to build the configuration. + FileSpecList files; + for (const FileSpec &f : sc.comp_unit->GetSupportFiles()) + files.AppendIfUnique(f); + // We also need to look at external modules in the case of -gmodules as they + // contain the support files for libc++ and the C library. + sc.comp_unit->ForEachExternalModule([&files](lldb::ModuleSP module) { + for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) { + const FileSpecList &support_files = + module->GetCompileUnitAtIndex(i)->GetSupportFiles(); + for (const FileSpec &f : support_files) { + files.AppendIfUnique(f); + } } + }); + + LLDB_LOG(log, "[C++ module config] Found {0} support files to analyze", + files.GetSize()); + if (log && log->GetVerbose()) { + for (const FileSpec &f : files) + LLDB_LOGV(log, "[C++ module config] Analyzing support file: {0}", + f.GetPath()); } - for (const SourceModule &m : sc.comp_unit->GetImportedModules()) - m_include_directories.push_back(m.search_path); - - // Check if we imported 'std' or any of its submodules. - // We currently don't support importing any other modules in the expression - // parser. - for (const SourceModule &m : sc.comp_unit->GetImportedModules()) - if (!m.path.empty() && m.path.front() == "std") - return {"std"}; - - return {}; + // Try to create a configuration from the files. If there is no valid + // configuration possible with the files, this just returns an invalid + // configuration. + return CppModuleConfiguration(files); } bool ClangUserExpression::PrepareForParsing( @@ -506,14 +525,21 @@ bool ClangUserExpression::PrepareForParsing( SetupDeclVendor(exe_ctx, m_target); - std::vector<std::string> used_modules = GetModulesToImport(exe_ctx); - m_imported_cpp_modules = !used_modules.empty(); + CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx); + llvm::ArrayRef<std::string> imported_modules = + module_config.GetImportedModules(); + m_imported_cpp_modules = !imported_modules.empty(); + m_include_directories = module_config.GetIncludeDirs(); LLDB_LOG(log, "List of imported modules in expression: {0}", - llvm::make_range(used_modules.begin(), used_modules.end())); - - UpdateLanguageForExpr(diagnostic_manager, exe_ctx, used_modules, - for_completion); + llvm::make_range(imported_modules.begin(), imported_modules.end())); + LLDB_LOG(log, "List of include directories gathered for modules: {0}", + llvm::make_range(m_include_directories.begin(), + m_include_directories.end())); + + UpdateLanguageForExpr(); + CreateSourceCode(diagnostic_manager, exe_ctx, imported_modules, + for_completion); return true; } @@ -527,8 +553,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false)) return false; - if (log) - log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); + LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str()); //////////////////////////////////// // Set up the target and compiler @@ -573,7 +598,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, // parser_sp will never be empty. ClangExpressionParser parser(exe_scope, *this, generate_debug_info, - m_include_directories); + m_include_directories, m_filename); unsigned num_errors = parser.Parse(diagnostic_manager); @@ -586,8 +611,11 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, size_t fixed_end; const std::string &fixed_expression = diagnostic_manager.GetFixedExpression(); - if (ClangExpressionSourceCode::GetOriginalBodyBounds( - fixed_expression, m_expr_lang, fixed_start, fixed_end)) + // Retrieve the original expression in case we don't have a top level + // expression (which has no surrounding source code). + if (m_source_code && + m_source_code->GetOriginalBodyBounds(fixed_expression, m_expr_lang, + fixed_start, fixed_end)) m_fixed_text = fixed_expression.substr(fixed_start, fixed_end - fixed_start); } @@ -648,12 +676,10 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, register_execution_unit = true; } - if (register_execution_unit) { - llvm::cast<PersistentExpressionState>( - exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage( - m_language)) + if (register_execution_unit) + exe_ctx.GetTargetPtr() + ->GetPersistentExpressionStateForLanguage(m_language) ->RegisterExecutionUnit(m_execution_unit_sp); - } } if (generate_debug_info) { @@ -726,8 +752,7 @@ bool ClangUserExpression::Complete(ExecutionContext &exe_ctx, if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ true)) return false; - if (log) - log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); + LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str()); ////////////////////////// // Parse the expression diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h index 24c152bdb45d..d94f9cc5e066 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h +++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h @@ -15,6 +15,7 @@ #include "ASTStructExtractor.h" #include "ClangExpressionDeclMap.h" #include "ClangExpressionHelper.h" +#include "ClangExpressionSourceCode.h" #include "ClangExpressionVariable.h" #include "IRForTarget.h" @@ -105,6 +106,9 @@ public: /// If not eResultTypeAny, the type to use for the expression /// result. /// + /// \param[in] options + /// Additional options for the expression. + /// /// \param[in] ctx_obj /// The object (if any) in which context the expression /// must be evaluated. For details see the comment to @@ -175,11 +179,11 @@ private: lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager) override; - std::vector<std::string> GetModulesToImport(ExecutionContext &exe_ctx); - void UpdateLanguageForExpr(DiagnosticManager &diagnostic_manager, - ExecutionContext &exe_ctx, - std::vector<std::string> modules_to_import, - bool for_completion); + void CreateSourceCode(DiagnosticManager &diagnostic_manager, + ExecutionContext &exe_ctx, + std::vector<std::string> modules_to_import, + bool for_completion); + void UpdateLanguageForExpr(); bool SetupPersistentState(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx); bool PrepareForParsing(DiagnosticManager &diagnostic_manager, @@ -205,13 +209,17 @@ private: /// The language type of the current expression. lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown; /// The include directories that should be used when parsing the expression. - std::vector<ConstString> m_include_directories; + std::vector<std::string> m_include_directories; /// The absolute character position in the transformed source code where the /// user code (as typed by the user) starts. If the variable is empty, then we /// were not able to calculate this position. llvm::Optional<size_t> m_user_expression_start_pos; ResultDelegate m_result_delegate; + ClangPersistentVariables *m_clang_state; + std::unique_ptr<ClangExpressionSourceCode> m_source_code; + /// File name used for the expression. + std::string m_filename; /// The object (if any) in which context the expression is evaluated. /// See the comment to `UserExpression::Evaluate` for details. @@ -219,6 +227,23 @@ private: /// True iff this expression explicitly imported C++ modules. bool m_imported_cpp_modules = false; + + /// True if the expression parser should enforce the presence of a valid class + /// pointer in order to generate the expression as a method. + bool m_enforce_valid_object = true; + /// True if the expression is compiled as a C++ member function (true if it + /// was parsed when exe_ctx was in a C++ method). + bool m_in_cplusplus_method = false; + /// True if the expression is compiled as an Objective-C method (true if it + /// was parsed when exe_ctx was in an Objective-C method). + bool m_in_objectivec_method = false; + /// True if the expression is compiled as a static (or class) method + /// (currently true if it was parsed when exe_ctx was in an Objective-C class + /// method). + bool m_in_static_method = false; + /// True if "this" or "self" must be looked up and passed in. False if the + /// expression doesn't really use them and they can be NULL. + bool m_needs_object_ptr = false; }; } // namespace lldb_private diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index 5eec224477fc..564c62c6a2c6 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +#include "lldb/Host/Config.h" + #include "ClangUtilityFunction.h" #include "ClangExpressionDeclMap.h" #include "ClangExpressionParser.h" diff --git a/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp new file mode 100644 index 000000000000..51ae73285b53 --- /dev/null +++ b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp @@ -0,0 +1,82 @@ +//===-- CppModuleConfiguration.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 "CppModuleConfiguration.h" + +#include "ClangHost.h" +#include "lldb/Host/FileSystem.h" + +using namespace lldb_private; + +bool CppModuleConfiguration::SetOncePath::TrySet(llvm::StringRef path) { + // Setting for the first time always works. + if (m_first) { + m_path = path.str(); + m_valid = true; + m_first = false; + return true; + } + // Changing the path to the same value is fine. + if (m_path == path) + return true; + + // Changing the path after it was already set is not allowed. + m_valid = false; + return false; +} + +bool CppModuleConfiguration::analyzeFile(const FileSpec &f) { + using namespace llvm::sys::path; + // Convert to slashes to make following operations simpler. + std::string dir_buffer = convert_to_slash(f.GetDirectory().GetStringRef()); + llvm::StringRef posix_dir(dir_buffer); + + // Check for /c++/vX/ that is used by libc++. + static llvm::Regex libcpp_regex(R"regex(/c[+][+]/v[0-9]/)regex"); + if (libcpp_regex.match(f.GetPath())) { + // Strip away libc++'s /experimental directory if there is one. + posix_dir.consume_back("/experimental"); + return m_std_inc.TrySet(posix_dir); + } + + // Check for /usr/include. On Linux this might be /usr/include/bits, so + // we should remove that '/bits' suffix to get the actual include directory. + if (posix_dir.endswith("/usr/include/bits")) + posix_dir.consume_back("/bits"); + if (posix_dir.endswith("/usr/include")) + return m_c_inc.TrySet(posix_dir); + + // File wasn't interesting, continue analyzing. + return true; +} + +bool CppModuleConfiguration::hasValidConfig() { + // We all these include directories to have a valid usable configuration. + return m_c_inc.Valid() && m_std_inc.Valid(); +} + +CppModuleConfiguration::CppModuleConfiguration( + const FileSpecList &support_files) { + // Analyze all files we were given to build the configuration. + bool error = !llvm::all_of(support_files, + std::bind(&CppModuleConfiguration::analyzeFile, + this, std::placeholders::_1)); + // If we have a valid configuration at this point, set the + // include directories and module list that should be used. + if (!error && hasValidConfig()) { + // Calculate the resource directory for LLDB. + llvm::SmallString<256> resource_dir; + llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(), + "include"); + m_resource_inc = resource_dir.str(); + + // This order matches the way Clang orders these directories. + m_include_dirs = {m_std_inc.Get(), m_resource_inc, m_c_inc.Get()}; + m_imported_modules = {"std"}; + } +} diff --git a/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h new file mode 100644 index 000000000000..8e892e37d0de --- /dev/null +++ b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h @@ -0,0 +1,84 @@ +//===-- CppModuleConfiguration.h --------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CppModuleConfiguration_h_ +#define liblldb_CppModuleConfiguration_h_ + +#include <lldb/Core/FileSpecList.h> +#include <llvm/Support/Regex.h> + +namespace lldb_private { + +/// A Clang configuration when importing C++ modules. +/// +/// Includes a list of include paths that should be used when importing +/// and a list of modules that can be imported. Currently only used when +/// importing the 'std' module and its dependencies. +class CppModuleConfiguration { + /// Utility class for a path that can only be set once. + class SetOncePath { + std::string m_path; + bool m_valid = false; + /// True iff this path hasn't been set yet. + bool m_first = true; + + public: + /// Try setting the path. Returns true if the path was set and false if + /// the path was already set. + LLVM_NODISCARD bool TrySet(llvm::StringRef path); + /// Return the path if there is one. + std::string Get() const { + assert(m_valid && "Called Get() on an invalid SetOncePath?"); + return m_path; + } + /// Returns true iff this path was set exactly once so far. + bool Valid() const { return m_valid; } + }; + + /// If valid, the include path used for the std module. + SetOncePath m_std_inc; + /// If valid, the include path to the C library (e.g. /usr/include). + SetOncePath m_c_inc; + /// The Clang resource include path for this configuration. + std::string m_resource_inc; + + std::vector<std::string> m_include_dirs; + std::vector<std::string> m_imported_modules; + + /// Analyze a given source file to build the current configuration. + /// Returns false iff there was a fatal error that makes analyzing any + /// further files pointless as the configuration is now invalid. + bool analyzeFile(const FileSpec &f); + +public: + /// Creates a configuraiton by analyzing the given list of used source files. + /// + /// Currently only looks at the used paths and doesn't actually access the + /// files on the disk. + explicit CppModuleConfiguration(const FileSpecList &support_files); + /// Creates an empty and invalid configuration. + CppModuleConfiguration() {} + + /// Returns true iff this is a valid configuration that can be used to + /// load and compile modules. + bool hasValidConfig(); + + /// Returns a list of include directories that should be used when using this + /// configuration (e.g. {"/usr/include", "/usr/include/c++/v1"}). + llvm::ArrayRef<std::string> GetIncludeDirs() const { return m_include_dirs; } + + /// Returns a list of (top level) modules that should be imported when using + /// this configuration (e.g. {"std"}). + llvm::ArrayRef<std::string> GetImportedModules() const { + return m_imported_modules; + } +}; + +} // namespace lldb_private + +#endif diff --git a/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp index f8e004fe7d4a..d5ffb9529f36 100644 --- a/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp +++ b/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp @@ -320,9 +320,8 @@ protected: bool InstrumentInstruction(llvm::Instruction *inst) override { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("Instrumenting load/store instruction: %s\n", - PrintValue(inst).c_str()); + LLDB_LOGF(log, "Instrumenting load/store instruction: %s\n", + PrintValue(inst).c_str()); if (!m_valid_pointer_check_func) m_valid_pointer_check_func = @@ -483,9 +482,8 @@ protected: std::string name_str = called_function->getName().str(); const char *name_cstr = name_str.c_str(); - if (log) - log->Printf("Found call to %s: %s\n", name_cstr, - PrintValue(call_inst).c_str()); + LLDB_LOGF(log, "Found call to %s: %s\n", name_cstr, + PrintValue(call_inst).c_str()); if (name_str.find("objc_msgSend") == std::string::npos) return true; @@ -520,10 +518,9 @@ protected: return true; } - if (log) - log->Printf( - "Function name '%s' contains 'objc_msgSend' but is not handled", - name_str.c_str()); + LLDB_LOGF(log, + "Function name '%s' contains 'objc_msgSend' but is not handled", + name_str.c_str()); return true; } @@ -548,8 +545,7 @@ bool IRDynamicChecks::runOnModule(llvm::Module &M) { llvm::Function *function = M.getFunction(StringRef(m_func_name)); if (!function) { - if (log) - log->Printf("Couldn't find %s() in the module", m_func_name.c_str()); + LLDB_LOGF(log, "Couldn't find %s() in the module", m_func_name.c_str()); return false; } @@ -582,7 +578,7 @@ bool IRDynamicChecks::runOnModule(llvm::Module &M) { oss.flush(); - log->Printf("Module after dynamic checks: \n%s", s.c_str()); + LLDB_LOGF(log, "Module after dynamic checks: \n%s", s.c_str()); } return true; diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index 07acb2e1030f..4e871f7d6a44 100644 --- a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -43,6 +43,8 @@ using namespace llvm; static char ID; +typedef SmallVector<Instruction *, 2> InstrList; + IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) : m_maker(maker), m_values() {} @@ -153,6 +155,15 @@ clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) { return DeclForGlobal(global_val, m_module); } +/// Returns true iff the mangled symbol is for a static guard variable. +static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol, + bool check_ms_abi = true) { + bool result = mangled_symbol.startswith("_ZGV"); // Itanium ABI guard variable + if (check_ms_abi) + result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI + return result; +} + bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -164,64 +175,58 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable(); - std::string result_name_str; - const char *result_name = nullptr; + llvm::StringRef result_name; + bool found_result = false; - for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), - ve = value_symbol_table.end(); - vi != ve; ++vi) { - result_name_str = vi->first().str(); - const char *value_name = result_name_str.c_str(); + for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) { + result_name = value_symbol.first(); - if (strstr(value_name, "$__lldb_expr_result_ptr") && - strncmp(value_name, "_ZGV", 4)) { - result_name = value_name; + // Check if this is a guard variable. It seems this causes some hiccups + // on Windows, so let's only check for Itanium guard variables. + bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false); + + if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) { + found_result = true; m_result_is_pointer = true; break; } - if (strstr(value_name, "$__lldb_expr_result") && - strncmp(value_name, "_ZGV", 4)) { - result_name = value_name; + if (result_name.contains("$__lldb_expr_result") && !is_guard_var) { + found_result = true; m_result_is_pointer = false; break; } } - if (!result_name) { - if (log) - log->PutCString("Couldn't find result variable"); + if (!found_result) { + LLDB_LOG(log, "Couldn't find result variable"); return true; } - if (log) - log->Printf("Result name: \"%s\"", result_name); + LLDB_LOG(log, "Result name: \"{0}\"", result_name); Value *result_value = m_module->getNamedValue(result_name); if (!result_value) { - if (log) - log->PutCString("Result variable had no data"); + LLDB_LOG(log, "Result variable had no data"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable's " - "name (%s) exists, but not its definition\n", + m_error_stream.Format("Internal error [IRForTarget]: Result variable's " + "name ({0}) exists, but not its definition\n", result_name); return false; } - if (log) - log->Printf("Found result in the IR: \"%s\"", - PrintValue(result_value, false).c_str()); + LLDB_LOG(log, "Found result in the IR: \"{0}\"", + PrintValue(result_value, false)); GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value); if (!result_global) { - if (log) - log->PutCString("Result variable isn't a GlobalVariable"); + LLDB_LOG(log, "Result variable isn't a GlobalVariable"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) " + m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) " "is defined, but is not a global variable\n", result_name); @@ -230,10 +235,9 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { clang::NamedDecl *result_decl = DeclForGlobal(result_global); if (!result_decl) { - if (log) - log->PutCString("Result variable doesn't have a corresponding Decl"); + LLDB_LOG(log, "Result variable doesn't have a corresponding Decl"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) " + m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) " "does not have a corresponding Clang entity\n", result_name); @@ -246,16 +250,15 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { result_decl->print(decl_desc_stream); decl_desc_stream.flush(); - log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str()); + LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str); } clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl); if (!result_var) { - if (log) - log->PutCString("Result variable Decl isn't a VarDecl"); + LLDB_LOG(log, "Result variable Decl isn't a VarDecl"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable " - "(%s)'s corresponding Clang entity isn't a " + m_error_stream.Format("Internal error [IRForTarget]: Result variable " + "({0})'s corresponding Clang entity isn't a " "variable\n", result_name); @@ -292,10 +295,9 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { lldb_private::ClangASTContext::GetASTContext( &result_decl->getASTContext())); } else { - if (log) - log->PutCString("Expected result to have pointer type, but it did not"); + LLDB_LOG(log, "Expected result to have pointer type, but it did not"); - m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) " + m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) " "is not a pointer variable\n", result_name); @@ -316,8 +318,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { lldb_private::StreamString type_desc_stream; m_result_type.DumpTypeDescription(&type_desc_stream); - if (log) - log->Printf("Result type has unknown size"); + LLDB_LOG(log, "Result type has unknown size"); m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' " "couldn't be determined\n", @@ -329,15 +330,13 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { lldb_private::StreamString type_desc_stream; m_result_type.DumpTypeDescription(&type_desc_stream); - log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData()); + LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData()); } m_result_name = lldb_private::ConstString("$RESULT_NAME"); - if (log) - log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64, - m_result_name.GetCString(), - m_result_type.GetByteSize(nullptr).getValueOr(0)); + LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}", + m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0)); // Construct a new result global and set up its metadata @@ -369,10 +368,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { m_module->getNamedMetadata("clang.global.decl.ptrs"); named_metadata->addOperand(persistent_global_md); - if (log) - log->Printf("Replacing \"%s\" with \"%s\"", - PrintValue(result_global).c_str(), - PrintValue(new_result_global).c_str()); + LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global), + PrintValue(new_result_global)); if (result_global->use_empty()) { // We need to synthesize a store for this variable, because otherwise @@ -385,11 +382,10 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { return false; if (!result_global->hasInitializer()) { - if (log) - log->Printf("Couldn't find initializer for unused variable"); + LLDB_LOG(log, "Couldn't find initializer for unused variable"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable " - "(%s) has no writes and no initializer\n", + m_error_stream.Format("Internal error [IRForTarget]: Result variable " + "({0}) has no writes and no initializer\n", result_name); return false; @@ -400,9 +396,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { StoreInst *synthesized_store = new StoreInst(initializer, new_result_global, first_entry_instruction); - if (log) - log->Printf("Synthesized result store \"%s\"\n", - PrintValue(synthesized_store).c_str()); + LLDB_LOG(log, "Synthesized result store \"{0}\"\n", + PrintValue(synthesized_store)); } else { result_global->replaceAllUsesWith(new_result_global); } @@ -438,7 +433,6 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str, missing_weak); if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) { - if (log) log->PutCString("Couldn't find CFStringCreateWithBytes in the target"); m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C " @@ -448,9 +442,8 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, return false; } - if (log) - log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, - CFStringCreateWithBytes_addr); + LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}", + CFStringCreateWithBytes_addr); // Build the function type: // @@ -543,9 +536,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder, m_error_stream)) { - if (log) - log->PutCString( - "Couldn't replace the NSString with the result of the call"); + LLDB_LOG(log, "Couldn't replace the NSString with the result of the call"); m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an " "Objective-C constant string with a dynamic " @@ -565,21 +556,17 @@ bool IRForTarget::RewriteObjCConstStrings() { ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable(); - for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), - ve = value_symbol_table.end(); - vi != ve; ++vi) { - std::string value_name = vi->first().str(); - const char *value_name_cstr = value_name.c_str(); + for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) { + llvm::StringRef value_name = value_symbol.first(); - if (strstr(value_name_cstr, "_unnamed_cfstring_")) { - Value *nsstring_value = vi->second; + if (value_name.contains("_unnamed_cfstring_")) { + Value *nsstring_value = value_symbol.second; GlobalVariable *nsstring_global = dyn_cast<GlobalVariable>(nsstring_value); if (!nsstring_global) { - if (log) - log->PutCString("NSString variable is not a GlobalVariable"); + LLDB_LOG(log, "NSString variable is not a GlobalVariable"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string is not a global variable\n"); @@ -588,8 +575,7 @@ bool IRForTarget::RewriteObjCConstStrings() { } if (!nsstring_global->hasInitializer()) { - if (log) - log->PutCString("NSString variable does not have an initializer"); + LLDB_LOG(log, "NSString variable does not have an initializer"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string does not have an initializer\n"); @@ -601,9 +587,8 @@ bool IRForTarget::RewriteObjCConstStrings() { dyn_cast<ConstantStruct>(nsstring_global->getInitializer()); if (!nsstring_struct) { - if (log) - log->PutCString( - "NSString variable's initializer is not a ConstantStruct"); + LLDB_LOG(log, + "NSString variable's initializer is not a ConstantStruct"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string is not a structure constant\n"); @@ -621,10 +606,11 @@ bool IRForTarget::RewriteObjCConstStrings() { // }; if (nsstring_struct->getNumOperands() != 4) { - if (log) - log->Printf("NSString variable's initializer structure has an " - "unexpected number of members. Should be 4, is %d", - nsstring_struct->getNumOperands()); + + LLDB_LOG(log, + "NSString variable's initializer structure has an " + "unexpected number of members. Should be 4, is {0}", + nsstring_struct->getNumOperands()); m_error_stream.Printf("Internal error [IRForTarget]: The struct for an " "Objective-C constant string is not as " @@ -636,8 +622,7 @@ bool IRForTarget::RewriteObjCConstStrings() { Constant *nsstring_member = nsstring_struct->getOperand(2); if (!nsstring_member) { - if (log) - log->PutCString("NSString initializer's str element was empty"); + LLDB_LOG(log, "NSString initializer's str element was empty"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string does not have a string " @@ -649,9 +634,8 @@ bool IRForTarget::RewriteObjCConstStrings() { ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member); if (!nsstring_expr) { - if (log) - log->PutCString( - "NSString initializer's str element is not a ConstantExpr"); + LLDB_LOG(log, + "NSString initializer's str element is not a ConstantExpr"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string's string initializer is not " @@ -671,9 +655,8 @@ bool IRForTarget::RewriteObjCConstStrings() { } if (!cstr_global) { - if (log) - log->PutCString( - "NSString initializer's str element is not a GlobalVariable"); + LLDB_LOG(log, + "NSString initializer's str element is not a GlobalVariable"); m_error_stream.Printf("Internal error [IRForTarget]: Unhandled" "constant string initializer\n"); @@ -682,9 +665,8 @@ bool IRForTarget::RewriteObjCConstStrings() { } if (!cstr_global->hasInitializer()) { - if (log) - log->PutCString("NSString initializer's str element does not have an " - "initializer"); + LLDB_LOG(log, "NSString initializer's str element does not have an " + "initializer"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string's string initializer doesn't " @@ -726,21 +708,18 @@ bool IRForTarget::RewriteObjCConstStrings() { ConstantDataArray *cstr_array = dyn_cast<ConstantDataArray>(cstr_global->getInitializer()); - if (log) { - if (cstr_array) - log->Printf("Found NSString constant %s, which contains \"%s\"", - value_name_cstr, cstr_array->getAsString().str().c_str()); - else - log->Printf("Found NSString constant %s, which contains \"\"", - value_name_cstr); - } + if (cstr_array) + LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"", + value_name, cstr_array->getAsString()); + else + LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"", + value_name); if (!cstr_array) cstr_global = nullptr; if (!RewriteObjCConstString(nsstring_global, cstr_global)) { - if (log) - log->PutCString("Error rewriting the constant string"); + LLDB_LOG(log, "Error rewriting the constant string"); // We don't print an error message here because RewriteObjCConstString // has done so for us. @@ -750,19 +729,15 @@ bool IRForTarget::RewriteObjCConstStrings() { } } - for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), - ve = value_symbol_table.end(); - vi != ve; ++vi) { - std::string value_name = vi->first().str(); - const char *value_name_cstr = value_name.c_str(); + for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) { + llvm::StringRef value_name = value_symbol.first(); - if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) { - GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second); + if (value_name == "__CFConstantStringClassReference") { + GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second); if (!gv) { - if (log) - log->PutCString( - "__CFConstantStringClassReference is not a global variable"); + LLDB_LOG(log, + "__CFConstantStringClassReference is not a global variable"); m_error_stream.Printf("Internal error [IRForTarget]: Found a " "CFConstantStringClassReference, but it is not a " @@ -850,9 +825,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { std::string omvn_initializer_string = omvn_initializer_array->getAsString(); - if (log) - log->Printf("Found Objective-C selector reference \"%s\"", - omvn_initializer_string.c_str()); + LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"", + omvn_initializer_string); // Construct a call to sel_registerName @@ -866,9 +840,7 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak) return false; - if (log) - log->Printf("Found sel_registerName at 0x%" PRIx64, - sel_registerName_addr); + LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr); // Build the function type: struct objc_selector // *sel_registerName(uint8_t*) @@ -921,32 +893,21 @@ bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - BasicBlock::iterator ii; - - typedef SmallVector<Instruction *, 2> InstrList; - typedef InstrList::iterator InstrIterator; - InstrList selector_loads; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; - + for (Instruction &inst : basic_block) { if (LoadInst *load = dyn_cast<LoadInst>(&inst)) if (IsObjCSelectorRef(load->getPointerOperand())) selector_loads.push_back(&inst); } - InstrIterator iter; - - for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) { - if (!RewriteObjCSelector(*iter)) { + for (Instruction *inst : selector_loads) { + if (!RewriteObjCSelector(inst)) { m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a " "static reference to an Objective-C selector to a " "dynamic reference\n"); - if (log) - log->PutCString( - "Couldn't rewrite a reference to an Objective-C selector"); + LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector"); return false; } @@ -1022,9 +983,8 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { std::string ocn_initializer_string = ocn_initializer_array->getAsString(); - if (log) - log->Printf("Found Objective-C class reference \"%s\"", - ocn_initializer_string.c_str()); + LLDB_LOG(log, "Found Objective-C class reference \"{0}\"", + ocn_initializer_string); // Construct a call to objc_getClass @@ -1038,9 +998,7 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak) return false; - if (log) - log->Printf("Found objc_getClass at 0x%" PRIx64, - objc_getClass_addr); + LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr); // Build the function type: %struct._objc_class *objc_getClass(i8*) @@ -1086,32 +1044,21 @@ bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - BasicBlock::iterator ii; - - typedef SmallVector<Instruction *, 2> InstrList; - typedef InstrList::iterator InstrIterator; - InstrList class_loads; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; - + for (Instruction &inst : basic_block) { if (LoadInst *load = dyn_cast<LoadInst>(&inst)) if (IsObjCClassReference(load->getPointerOperand())) class_loads.push_back(&inst); } - InstrIterator iter; - - for (iter = class_loads.begin(); iter != class_loads.end(); ++iter) { - if (!RewriteObjCClassReference(*iter)) { + for (Instruction *inst : class_loads) { + if (!RewriteObjCClassReference(inst)) { m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a " "static reference to an Objective-C class to a " "dynamic reference\n"); - if (log) - log->PutCString( - "Couldn't rewrite a reference to an Objective-C class"); + LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class"); return false; } @@ -1180,9 +1127,8 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) { LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc); - if (log) - log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(), - PrintValue(persistent_load).c_str()); + LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc), + PrintValue(persistent_load)); alloc->replaceAllUsesWith(persistent_load); alloc->eraseFromParent(); @@ -1197,23 +1143,16 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - BasicBlock::iterator ii; - - typedef SmallVector<Instruction *, 2> InstrList; - typedef InstrList::iterator InstrIterator; - InstrList pvar_allocs; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; + for (Instruction &inst : basic_block) { if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) { llvm::StringRef alloc_name = alloc->getName(); if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) { if (alloc_name.find_first_of("0123456789") == 1) { - if (log) - log->Printf("Rejecting a numeric persistent variable."); + LLDB_LOG(log, "Rejecting a numeric persistent variable."); m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, " "$1, ... are reserved for use as result " @@ -1227,16 +1166,12 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { } } - InstrIterator iter; - - for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) { - if (!RewritePersistentAlloc(*iter)) { + for (Instruction *inst : pvar_allocs) { + if (!RewritePersistentAlloc(inst)) { m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite " "the creation of a persistent variable\n"); - if (log) - log->PutCString( - "Couldn't rewrite the creation of a persistent variable"); + LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable"); return false; } @@ -1245,79 +1180,12 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { return true; } -bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) { - if (!initializer) - return true; - - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - - if (log && log->GetVerbose()) - log->Printf(" MaterializeInitializer(%p, %s)", (void *)data, - PrintValue(initializer).c_str()); - - Type *initializer_type = initializer->getType(); - - if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) { - size_t constant_size = m_target_data->getTypeStoreSize(initializer_type); - lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc( - llvm::NextPowerOf2(constant_size) * 8); - - lldb_private::Status get_data_error; - return scalar.GetAsMemoryData(data, constant_size, - lldb_private::endian::InlHostByteOrder(), - get_data_error) != 0; - } else if (ConstantDataArray *array_initializer = - dyn_cast<ConstantDataArray>(initializer)) { - if (array_initializer->isString()) { - std::string array_initializer_string = array_initializer->getAsString(); - memcpy(data, array_initializer_string.c_str(), - m_target_data->getTypeStoreSize(initializer_type)); - } else { - ArrayType *array_initializer_type = array_initializer->getType(); - Type *array_element_type = array_initializer_type->getElementType(); - - size_t element_size = m_target_data->getTypeAllocSize(array_element_type); - - for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) { - Value *operand_value = array_initializer->getOperand(i); - Constant *operand_constant = dyn_cast<Constant>(operand_value); - - if (!operand_constant) - return false; - - if (!MaterializeInitializer(data + (i * element_size), - operand_constant)) - return false; - } - } - return true; - } else if (ConstantStruct *struct_initializer = - dyn_cast<ConstantStruct>(initializer)) { - StructType *struct_initializer_type = struct_initializer->getType(); - const StructLayout *struct_layout = - m_target_data->getStructLayout(struct_initializer_type); - - for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) { - if (!MaterializeInitializer(data + struct_layout->getElementOffset(i), - struct_initializer->getOperand(i))) - return false; - } - return true; - } else if (isa<ConstantAggregateZero>(initializer)) { - memset(data, 0, m_target_data->getTypeStoreSize(initializer_type)); - return true; - } - return false; -} - // This function does not report errors; its callers are responsible. bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str()); + LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr)); if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) { switch (constant_expr->getOpcode()) { @@ -1343,25 +1211,26 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { if (!global_variable->hasExternalLinkage()) return true; - if (log) - log->Printf("Found global variable \"%s\" without metadata", - global_variable->getName().str().c_str()); + LLDB_LOG(log, "Found global variable \"{0}\" without metadata", + global_variable->getName()); return false; } - std::string name(named_decl->getName().str()); + llvm::StringRef name(named_decl->getName()); clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl); if (value_decl == nullptr) return false; - lldb_private::CompilerType compiler_type(&value_decl->getASTContext(), - value_decl->getType()); + lldb_private::CompilerType compiler_type( + lldb_private::ClangASTContext::GetASTContext( + &value_decl->getASTContext()), + value_decl->getType().getAsOpaquePtr()); const Type *value_type = nullptr; - if (name[0] == '$') { + if (name.startswith("$")) { // The $__lldb_expr_result name indicates the return value has allocated // as a static variable. Per the comment at // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static @@ -1381,31 +1250,24 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr); if (!value_size) return false; - lldb::offset_t value_alignment = - (compiler_type.GetTypeBitAlign() + 7ull) / 8ull; - - if (log) { - log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 - ", align %" PRIu64 "]", - name.c_str(), - lldb_private::ClangUtil::GetQualType(compiler_type) - .getAsString() - .c_str(), - PrintType(value_type).c_str(), *value_size, value_alignment); - } - - if (named_decl && - !m_decl_map->AddValueToStruct( - named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr, - *value_size, value_alignment)) { - if (!global_variable->hasExternalLinkage()) - return true; - else - return true; - } + llvm::Optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(nullptr); + if (!opt_alignment) + return false; + lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull; + + LLDB_LOG(log, + "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, " + "align {4}]", + name, + lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(), + PrintType(value_type), *value_size, value_alignment); + + if (named_decl) + m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name), + llvm_value_ptr, *value_size, + value_alignment); } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) { - if (log) - log->Printf("Function pointers aren't handled right now"); + LLDB_LOG(log, "Function pointers aren't handled right now"); return false; } @@ -1424,14 +1286,12 @@ bool IRForTarget::HandleSymbol(Value *symbol) { m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny); if (symbol_addr == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf("Symbol \"%s\" had no address", name.GetCString()); + LLDB_LOG(log, "Symbol \"{0}\" had no address", name); return false; } - if (log) - log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr); + LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr); Type *symbol_type = symbol->getType(); @@ -1440,9 +1300,8 @@ bool IRForTarget::HandleSymbol(Value *symbol) { Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type); - if (log) - log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), - PrintValue(symbol_addr_ptr).c_str()); + LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol), + PrintValue(symbol_addr_ptr)); symbol->replaceAllUsesWith(symbol_addr_ptr); @@ -1453,14 +1312,12 @@ bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str()); + LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old)); for (unsigned op_index = 0, num_ops = Old->getNumArgOperands(); op_index < num_ops; ++op_index) - if (!MaybeHandleVariable(Old->getArgOperand( - op_index))) // conservatively believe that this is a store - { + // conservatively believe that this is a store + if (!MaybeHandleVariable(Old->getArgOperand(op_index))) { m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite " "one of the arguments of a function call.\n"); @@ -1493,9 +1350,8 @@ bool IRForTarget::HandleObjCClass(Value *classlist_reference) { lldb::addr_t class_ptr = m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass); - if (log) - log->Printf("Found reference to Objective-C class %s (0x%llx)", - name_cstr.AsCString(), (unsigned long long)class_ptr); + LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name, + (unsigned long long)class_ptr); if (class_ptr == LLDB_INVALID_ADDRESS) return false; @@ -1528,13 +1384,9 @@ bool IRForTarget::HandleObjCClass(Value *classlist_reference) { } bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) { - BasicBlock::iterator ii; - std::vector<CallInst *> calls_to_remove; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; - + for (Instruction &inst : basic_block) { CallInst *call = dyn_cast<CallInst>(&inst); // MaybeHandleCallArguments handles error reporting; we are silent here @@ -1557,25 +1409,16 @@ bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) { calls_to_remove.push_back(call); } - for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(), - ce = calls_to_remove.end(); - ci != ce; ++ci) { - (*ci)->eraseFromParent(); - } + for (CallInst *ci : calls_to_remove) + ci->eraseFromParent(); return true; } bool IRForTarget::ResolveCalls(BasicBlock &basic_block) { - ///////////////////////////////////////////////////////////////////////// // Prepare the current basic block for execution in the remote process - // - - BasicBlock::iterator ii; - - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; + for (Instruction &inst : basic_block) { CallInst *call = dyn_cast<CallInst>(&inst); // MaybeHandleCallArguments handles error reporting; we are silent here @@ -1591,31 +1434,27 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) { lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); for (GlobalVariable &global_var : m_module->globals()) { - std::string global_name = global_var.getName().str(); + llvm::StringRef global_name = global_var.getName(); - if (log) - log->Printf("Examining %s, DeclForGlobalValue returns %p", - global_name.c_str(), - static_cast<void *>(DeclForGlobal(&global_var))); + LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name, + static_cast<void *>(DeclForGlobal(&global_var))); - if (global_name.find("OBJC_IVAR") == 0) { + if (global_name.startswith("OBJC_IVAR")) { if (!HandleSymbol(&global_var)) { - m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C " - "indirect ivar symbol %s\n", - global_name.c_str()); + m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C " + "indirect ivar symbol {0}\n", + global_name); return false; } - } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") != - global_name.npos) { + } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) { if (!HandleObjCClass(&global_var)) { m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class " "for an Objective-C static method call\n"); return false; } - } else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") != - global_name.npos) { + } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) { if (!HandleObjCClass(&global_var)) { m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class " "for an Objective-C static method call\n"); @@ -1624,9 +1463,9 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) { } } else if (DeclForGlobal(&global_var)) { if (!MaybeHandleVariable(&global_var)) { - m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite " - "external variable %s\n", - global_name.c_str()); + m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite " + "external variable {0}\n", + global_name); return false; } @@ -1637,14 +1476,12 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) { } static bool isGuardVariableRef(Value *V) { - Constant *Old = nullptr; + Constant *Old = dyn_cast<Constant>(V); - if (!(Old = dyn_cast<Constant>(V))) + if (!Old) return false; - ConstantExpr *CE = nullptr; - - if ((CE = dyn_cast<ConstantExpr>(V))) { + if (auto CE = dyn_cast<ConstantExpr>(V)) { if (CE->getOpcode() != Instruction::BitCast) return false; @@ -1653,12 +1490,8 @@ static bool isGuardVariableRef(Value *V) { GlobalVariable *GV = dyn_cast<GlobalVariable>(Old); - if (!GV || !GV->hasName() || - (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable - !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable - { + if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName())) return false; - } return true; } @@ -1674,20 +1507,12 @@ static void ExciseGuardStore(Instruction *guard_store) { } bool IRForTarget::RemoveGuards(BasicBlock &basic_block) { - /////////////////////////////////////////////////////// // Eliminate any reference to guard variables found. - // - - BasicBlock::iterator ii; - - typedef SmallVector<Instruction *, 2> InstrList; - typedef InstrList::iterator InstrIterator; InstrList guard_loads; InstrList guard_stores; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; + for (Instruction &inst : basic_block) { if (LoadInst *load = dyn_cast<LoadInst>(&inst)) if (isGuardVariableRef(load->getPointerOperand())) @@ -1698,13 +1523,11 @@ bool IRForTarget::RemoveGuards(BasicBlock &basic_block) { guard_stores.push_back(&inst); } - InstrIterator iter; + for (Instruction *inst : guard_loads) + TurnGuardLoadIntoZero(inst); - for (iter = guard_loads.begin(); iter != guard_loads.end(); ++iter) - TurnGuardLoadIntoZero(*iter); - - for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter) - ExciseGuardStore(*iter); + for (Instruction *inst : guard_stores) + ExciseGuardStore(inst); return true; } @@ -1837,8 +1660,7 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { m_decl_map->DoStructLayout(); - if (log) - log->Printf("Element arrangement:"); + LLDB_LOG(log, "Element arrangement:"); uint32_t num_elements; uint32_t element_index; @@ -1884,9 +1706,9 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { } if (!iter->getName().equals("_cmd")) { - m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' " + m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' " "after 'self' argument (should take '_cmd')", - iter->getName().str().c_str()); + iter->getName()); return false; } @@ -1905,15 +1727,14 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { } if (!argument->getName().equals("$__lldb_arg")) { - m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an " - "argument named '%s' instead of the struct pointer", - argument->getName().str().c_str()); + m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an " + "argument named '{0}' instead of the struct pointer", + argument->getName()); return false; } - if (log) - log->Printf("Arg: \"%s\"", PrintValue(argument).c_str()); + LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument)); BasicBlock &entry_block(llvm_function.getEntryBlock()); Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg()); @@ -1950,13 +1771,11 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { return false; } - if (log) - log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(), - decl->getNameAsString().c_str(), offset); + LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at {2}", name, + decl->getNameAsString(), offset); if (value) { - if (log) - log->Printf(" Replacing [%s]", PrintValue(value).c_str()); + LLDB_LOG(log, " Replacing [{0}]", PrintValue(value)); FunctionValueCache body_result_maker( [this, name, offset_type, offset, argument, @@ -2005,9 +1824,8 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { value->replaceAllUsesWith( body_result_maker.GetValue(instruction->getParent()->getParent())); } else { - if (log) - log->Printf("Unhandled non-constant type: \"%s\"", - PrintValue(value).c_str()); + LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"", + PrintValue(value)); return false; } @@ -2016,35 +1834,12 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { } } - if (log) - log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]", - (int64_t)alignment, (uint64_t)size); + LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment, + (uint64_t)size); return true; } -llvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type, - uint64_t offset) { - llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset); - - llvm::Constant *offset_array[1]; - - offset_array[0] = offset_int; - - llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1); - llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext()); - llvm::Type *char_pointer_type = char_type->getPointerTo(); - - llvm::Constant *reloc_placeholder_bitcast = - ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type); - llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr( - char_type, reloc_placeholder_bitcast, offsets); - llvm::Constant *reloc_bitcast = - ConstantExpr::getBitCast(reloc_getelementptr, type); - - return reloc_bitcast; -} - bool IRForTarget::runOnModule(Module &llvm_module) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -2062,7 +1857,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { oss.flush(); - log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str()); + LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s); } Function *const main_function = @@ -2070,21 +1865,18 @@ bool IRForTarget::runOnModule(Module &llvm_module) { : m_module->getFunction(m_func_name.GetStringRef()); if (!m_func_name.IsEmpty() && !main_function) { - if (log) - log->Printf("Couldn't find \"%s()\" in the module", - m_func_name.AsCString()); + LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name); - m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper " - "'%s' in the module", - m_func_name.AsCString()); + m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper " + "'{0}' in the module", + m_func_name); return false; } if (main_function) { if (!FixFunctionLinkage(*main_function)) { - if (log) - log->Printf("Couldn't fix the linkage for the function"); + LLDB_LOG(log, "Couldn't fix the linkage for the function"); return false; } @@ -2104,8 +1896,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { if (main_function) { if (!CreateResultVariable(*main_function)) { - if (log) - log->Printf("CreateResultVariable() failed"); + LLDB_LOG(log, "CreateResultVariable() failed"); // CreateResultVariable() reports its own errors, so we don't do so here @@ -2121,32 +1912,21 @@ bool IRForTarget::runOnModule(Module &llvm_module) { oss.flush(); - log->Printf("Module after creating the result variable: \n\"%s\"", - s.c_str()); + LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s); } - for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe; - ++fi) { - llvm::Function *function = &*fi; - - if (function->begin() == function->end()) - continue; - - Function::iterator bbi; - - for (bbi = function->begin(); bbi != function->end(); ++bbi) { - if (!RemoveGuards(*bbi)) { - if (log) - log->Printf("RemoveGuards() failed"); + for (llvm::Function &function : *m_module) { + for (BasicBlock &bb : function) { + if (!RemoveGuards(bb)) { + LLDB_LOG(log, "RemoveGuards() failed"); // RemoveGuards() reports its own errors, so we don't do so here return false; } - if (!RewritePersistentAllocs(*bbi)) { - if (log) - log->Printf("RewritePersistentAllocs() failed"); + if (!RewritePersistentAllocs(bb)) { + LLDB_LOG(log, "RewritePersistentAllocs() failed"); // RewritePersistentAllocs() reports its own errors, so we don't do so // here @@ -2154,9 +1934,8 @@ bool IRForTarget::runOnModule(Module &llvm_module) { return false; } - if (!RemoveCXAAtExit(*bbi)) { - if (log) - log->Printf("RemoveCXAAtExit() failed"); + if (!RemoveCXAAtExit(bb)) { + LLDB_LOG(log, "RemoveCXAAtExit() failed"); // RemoveCXAAtExit() reports its own errors, so we don't do so here @@ -2170,24 +1949,17 @@ bool IRForTarget::runOnModule(Module &llvm_module) { // if (!RewriteObjCConstStrings()) { - if (log) - log->Printf("RewriteObjCConstStrings() failed"); + LLDB_LOG(log, "RewriteObjCConstStrings() failed"); // RewriteObjCConstStrings() reports its own errors, so we don't do so here return false; } - for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe; - ++fi) { - llvm::Function *function = &*fi; - - for (llvm::Function::iterator bbi = function->begin(), - bbe = function->end(); - bbi != bbe; ++bbi) { - if (!RewriteObjCSelectors(*bbi)) { - if (log) - log->Printf("RewriteObjCSelectors() failed"); + for (llvm::Function &function : *m_module) { + for (llvm::BasicBlock &bb : function) { + if (!RewriteObjCSelectors(bb)) { + LLDB_LOG(log, "RewriteObjCSelectors() failed"); // RewriteObjCSelectors() reports its own errors, so we don't do so // here @@ -2195,9 +1967,8 @@ bool IRForTarget::runOnModule(Module &llvm_module) { return false; } - if (!RewriteObjCClassReferences(*bbi)) { - if (log) - log->Printf("RewriteObjCClassReferences() failed"); + if (!RewriteObjCClassReferences(bb)) { + LLDB_LOG(log, "RewriteObjCClassReferences() failed"); // RewriteObjCClasses() reports its own errors, so we don't do so here @@ -2206,16 +1977,10 @@ bool IRForTarget::runOnModule(Module &llvm_module) { } } - for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe; - ++fi) { - llvm::Function *function = &*fi; - - for (llvm::Function::iterator bbi = function->begin(), - bbe = function->end(); - bbi != bbe; ++bbi) { - if (!ResolveCalls(*bbi)) { - if (log) - log->Printf("ResolveCalls() failed"); + for (llvm::Function &function : *m_module) { + for (BasicBlock &bb : function) { + if (!ResolveCalls(bb)) { + LLDB_LOG(log, "ResolveCalls() failed"); // ResolveCalls() reports its own errors, so we don't do so here @@ -2230,8 +1995,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { if (main_function) { if (!ResolveExternals(*main_function)) { - if (log) - log->Printf("ResolveExternals() failed"); + LLDB_LOG(log, "ResolveExternals() failed"); // ResolveExternals() reports its own errors, so we don't do so here @@ -2239,8 +2003,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { } if (!ReplaceVariables(*main_function)) { - if (log) - log->Printf("ReplaceVariables() failed"); + LLDB_LOG(log, "ReplaceVariables() failed"); // ReplaceVariables() reports its own errors, so we don't do so here @@ -2256,7 +2019,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { oss.flush(); - log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str()); + LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s); } return true; diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/source/Plugins/ExpressionParser/Clang/IRForTarget.h index f87fd8ac32cb..893620f7f8e0 100644 --- a/source/Plugins/ExpressionParser/Clang/IRForTarget.h +++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.h @@ -10,6 +10,7 @@ #ifndef liblldb_IRForTarget_h_ #define liblldb_IRForTarget_h_ +#include "lldb/Core/ClangForward.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" @@ -331,27 +332,6 @@ private: /// a call to a function pointer whose value is the address of the function /// in the target process. - /// Write an initializer to a memory array of assumed sufficient size. - /// - /// \param[in] data - /// A pointer to the data to write to. - /// - /// \param[in] initializer - /// The initializer itself. - /// - /// \return - /// True on success; false otherwise - bool MaterializeInitializer(uint8_t *data, llvm::Constant *initializer); - - /// Move an internal variable into the static allocation section. - /// - /// \param[in] global_variable - /// The variable. - /// - /// \return - /// True on success; false otherwise - bool MaterializeInternalVariable(llvm::GlobalVariable *global_variable); - /// Handle a single externally-defined variable /// /// \param[in] value @@ -539,20 +519,6 @@ private: FunctionValueCache &entry_instruction_finder, lldb_private::Stream &error_stream); - /// Construct a reference to m_reloc_placeholder with a given type and - /// offset. This typically happens after inserting data into - /// m_data_allocator. - /// - /// \param[in] type - /// The type of the value being loaded. - /// - /// \param[in] offset - /// The offset of the value from the base of m_data_allocator. - /// - /// \return - /// The Constant for the reference, usually a ConstantExpr. - llvm::Constant *BuildRelocation(llvm::Type *type, uint64_t offset); - /// Commit the allocation in m_data_allocator and use its final location to /// replace m_reloc_placeholder. /// diff --git a/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h b/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h index 0e959f86fd2a..7553860f2492 100644 --- a/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h +++ b/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h @@ -9,21 +9,23 @@ #ifndef liblldb_ModuleDependencyCollector_h_ #define liblldb_ModuleDependencyCollector_h_ -#include "lldb/Utility/FileCollector.h" #include "clang/Frontend/Utils.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/FileCollector.h" namespace lldb_private { class ModuleDependencyCollectorAdaptor : public clang::ModuleDependencyCollector { public: - ModuleDependencyCollectorAdaptor(FileCollector &file_collector) + ModuleDependencyCollectorAdaptor( + std::shared_ptr<llvm::FileCollector> file_collector) : clang::ModuleDependencyCollector(""), m_file_collector(file_collector) { } void addFile(llvm::StringRef Filename, llvm::StringRef FileDst = {}) override { - m_file_collector.AddFile(Filename); + if (m_file_collector) + m_file_collector->addFile(Filename); } bool insertSeen(llvm::StringRef Filename) override { return false; } @@ -31,7 +33,7 @@ public: void writeFileMap() override {} private: - FileCollector &m_file_collector; + std::shared_ptr<llvm::FileCollector> m_file_collector; }; } // namespace lldb_private diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index 6323889c2e09..19a987b0f004 100644 --- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -14507,6 +14507,7 @@ bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { unwind_plan.SetSourceName("EmulateInstructionARM"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); unwind_plan.SetReturnAddressRegister(dwarf_lr); return true; } diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp index d7e8e0491342..3e06fca2504c 100644 --- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp +++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp @@ -149,7 +149,8 @@ EmulateInstructionARM64::CreateInstance(const ArchSpec &arch, InstructionType inst_type) { if (EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic( inst_type)) { - if (arch.GetTriple().getArch() == llvm::Triple::aarch64) { + if (arch.GetTriple().getArch() == llvm::Triple::aarch64 || + arch.GetTriple().getArch() == llvm::Triple::aarch64_32) { return new EmulateInstructionARM64(arch); } } @@ -479,6 +480,7 @@ bool EmulateInstructionARM64::CreateFunctionEntryUnwind( unwind_plan.SetSourceName("EmulateInstructionARM64"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); unwind_plan.SetReturnAddressRegister(gpr_lr_arm64); return true; } diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp index cbf3dda7896e..21b6296745bd 100644 --- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -1150,6 +1150,7 @@ bool EmulateInstructionMIPS::CreateFunctionEntryUnwind( unwind_plan.SetSourceName("EmulateInstructionMIPS"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); unwind_plan.SetReturnAddressRegister(dwarf_ra_mips); return true; diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp index 69f0278d1437..5fabbeb756cc 100644 --- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp +++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp @@ -1042,6 +1042,7 @@ bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind( unwind_plan.SetSourceName("EmulateInstructionMIPS64"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64); return true; diff --git a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp index c77fa04fc7d7..4b8d8dd2228c 100644 --- a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp +++ b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp @@ -135,6 +135,7 @@ bool EmulateInstructionPPC64::CreateFunctionEntryUnwind( unwind_plan.SetSourceName("EmulateInstructionPPC64"); unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); unwind_plan.SetReturnAddressRegister(gpr_lr_ppc64le); return true; } diff --git a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp index c8ac04641e68..2e5dd5989e77 100644 --- a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp +++ b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp @@ -264,7 +264,7 @@ bool AddressSanitizerRuntime::NotifyBreakpointHit( *thread_sp, description, report)); StreamFileSP stream_sp( - process_sp->GetTarget().GetDebugger().GetOutputFile()); + process_sp->GetTarget().GetDebugger().GetOutputStreamSP()); if (stream_sp) { stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread " "info -s' to get extended information about the " diff --git a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp index 89f2139db71b..45a3aeeb204e 100644 --- a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp +++ b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp @@ -863,13 +863,11 @@ bool ThreadSanitizerRuntime::NotifyBreakpointHit( CreateStopReasonWithInstrumentationData( *thread_sp, stop_reason_description, report)); - StreamFileSP stream_sp( - process_sp->GetTarget().GetDebugger().GetOutputFile()); - if (stream_sp) { - stream_sp->Printf("ThreadSanitizer report breakpoint hit. Use 'thread " - "info -s' to get extended information about the " - "report.\n"); - } + StreamFile &s = process_sp->GetTarget().GetDebugger().GetOutputStream(); + s.Printf("ThreadSanitizer report breakpoint hit. Use 'thread " + "info -s' to get extended information about the " + "report.\n"); + return true; // Return true to stop the target } else return false; // Let target run diff --git a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp index 367098bb448e..50f1d48d03e0 100644 --- a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp +++ b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp @@ -124,7 +124,7 @@ StructuredData::ObjectSP UndefinedBehaviorSanitizerRuntime::RetrieveReportData( if (!frame_sp) return StructuredData::ObjectSP(); - StreamFileSP Stream(target.GetDebugger().GetOutputFile()); + StreamFileSP Stream = target.GetDebugger().GetOutputStreamSP(); EvaluateExpressionOptions options; options.SetUnwindOnError(true); diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp index 140d09ed43cf..fff44123539f 100644 --- a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp +++ b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// - -#include "llvm/Support/MathExtras.h" - +#include "JITLoaderGDB.h" +#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" @@ -26,8 +25,7 @@ #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" - -#include "JITLoaderGDB.h" +#include "llvm/Support/MathExtras.h" #include <memory> @@ -59,21 +57,33 @@ enum EnableJITLoaderGDB { eEnableJITLoaderGDBOff, }; -static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] = { - {eEnableJITLoaderGDBDefault, "default", "Enable JIT compilation interface " - "for all platforms except macOS"}, - {eEnableJITLoaderGDBOn, "on", "Enable JIT compilation interface"}, - {eEnableJITLoaderGDBOff, "off", "Disable JIT compilation interface"} - }; +static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] = + { + { + eEnableJITLoaderGDBDefault, + "default", + "Enable JIT compilation interface for all platforms except macOS", + }, + { + eEnableJITLoaderGDBOn, + "on", + "Enable JIT compilation interface", + }, + { + eEnableJITLoaderGDBOff, + "off", + "Disable JIT compilation interface", + }, +}; -static constexpr PropertyDefinition g_properties[] = { - {"enable", OptionValue::eTypeEnum, true, - eEnableJITLoaderGDBDefault, nullptr, - OptionEnumValues(g_enable_jit_loader_gdb_enumerators), - "Enable GDB's JIT compilation interface (default: enabled on " - "all platforms except macOS)"}}; +#define LLDB_PROPERTIES_jitloadergdb +#include "JITLoaderGDBProperties.inc" -enum { ePropertyEnable, ePropertyEnableJITBreakpoint }; +enum { +#define LLDB_PROPERTIES_jitloadergdb +#include "JITLoaderGDBPropertiesEnum.inc" + ePropertyEnableJITBreakpoint +}; class PluginProperties : public Properties { public: @@ -83,13 +93,13 @@ public: PluginProperties() { m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName()); - m_collection_sp->Initialize(g_properties); + m_collection_sp->Initialize(g_jitloadergdb_properties); } EnableJITLoaderGDB GetEnable() const { return (EnableJITLoaderGDB)m_collection_sp->GetPropertyAtIndexAsEnumeration( nullptr, ePropertyEnable, - g_properties[ePropertyEnable].default_uint_value); + g_jitloadergdb_properties[ePropertyEnable].default_uint_value); } }; @@ -177,8 +187,8 @@ void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) { return; Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER)); - if (log) - log->Printf("JITLoaderGDB::%s looking for JIT register hook", __FUNCTION__); + LLDB_LOGF(log, "JITLoaderGDB::%s looking for JIT register hook", + __FUNCTION__); addr_t jit_addr = GetSymbolAddress( module_list, ConstString("__jit_debug_register_code"), eSymbolTypeAny); @@ -188,14 +198,12 @@ void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) { m_jit_descriptor_addr = GetSymbolAddress( module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData); if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf("JITLoaderGDB::%s failed to find JIT descriptor address", - __FUNCTION__); + LLDB_LOGF(log, "JITLoaderGDB::%s failed to find JIT descriptor address", + __FUNCTION__); return; } - if (log) - log->Printf("JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__); + LLDB_LOGF(log, "JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__); Breakpoint *bp = m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get(); @@ -211,8 +219,7 @@ bool JITLoaderGDB::JITDebugBreakpointHit(void *baton, user_id_t break_id, user_id_t break_loc_id) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER)); - if (log) - log->Printf("JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__); + LLDB_LOGF(log, "JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__); JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton); return instance->ReadJITDescriptor(false); } @@ -285,9 +292,8 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) { size_t bytes_read = m_process->DoReadMemory(m_jit_descriptor_addr, &jit_desc, jit_desc_size, error); if (bytes_read != jit_desc_size || !error.Success()) { - if (log) - log->Printf("JITLoaderGDB::%s failed to read JIT descriptor", - __FUNCTION__); + LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT descriptor", + __FUNCTION__); return false; } @@ -301,9 +307,8 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) { while (jit_relevant_entry != 0) { jit_code_entry<ptr_t> jit_entry; if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry)) { - if (log) - log->Printf("JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64, - __FUNCTION__, jit_relevant_entry); + LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64, + __FUNCTION__, jit_relevant_entry); return false; } @@ -312,10 +317,10 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) { ModuleSP module_sp; if (jit_action == JIT_REGISTER_FN) { - if (log) - log->Printf("JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64 - " (%" PRIu64 " bytes)", - __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size); + LLDB_LOGF(log, + "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64 + " (%" PRIu64 " bytes)", + __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size); char jit_name[64]; snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr); @@ -331,20 +336,16 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) { module_sp->GetObjectFile()->GetSymtab(); m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp)); - if (module_sp->GetObjectFile()->GetPluginName() == - ConstString("mach-o")) { - ObjectFile *image_object_file = module_sp->GetObjectFile(); - if (image_object_file) { - const SectionList *section_list = - image_object_file->GetSectionList(); - if (section_list) { - uint64_t vmaddrheuristic = 0; - uint64_t lower = (uint64_t)-1; - uint64_t upper = 0; - updateSectionLoadAddress(*section_list, target, symbolfile_addr, - symbolfile_size, vmaddrheuristic, lower, - upper); - } + if (auto image_object_file = + llvm::dyn_cast<ObjectFileMachO>(module_sp->GetObjectFile())) { + const SectionList *section_list = image_object_file->GetSectionList(); + if (section_list) { + uint64_t vmaddrheuristic = 0; + uint64_t lower = (uint64_t)-1; + uint64_t upper = 0; + updateSectionLoadAddress(*section_list, target, symbolfile_addr, + symbolfile_size, vmaddrheuristic, lower, + upper); } } else { bool changed = false; @@ -357,15 +358,14 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) { module_list.Append(module_sp); target.ModulesDidLoad(module_list); } else { - if (log) - log->Printf("JITLoaderGDB::%s failed to load module for " - "JIT entry at 0x%" PRIx64, - __FUNCTION__, symbolfile_addr); + LLDB_LOGF(log, + "JITLoaderGDB::%s failed to load module for " + "JIT entry at 0x%" PRIx64, + __FUNCTION__, symbolfile_addr); } } else if (jit_action == JIT_UNREGISTER_FN) { - if (log) - log->Printf("JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64, - __FUNCTION__, symbolfile_addr); + LLDB_LOGF(log, "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64, + __FUNCTION__, symbolfile_addr); JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr); if (it != m_jit_objects.end()) { @@ -458,8 +458,8 @@ addr_t JITLoaderGDB::GetSymbolAddress(ModuleList &module_list, SymbolContextList target_symbols; Target &target = m_process->GetTarget(); - if (!module_list.FindSymbolsWithNameAndType(name, symbol_type, - target_symbols)) + module_list.FindSymbolsWithNameAndType(name, symbol_type, target_symbols); + if (target_symbols.IsEmpty()) return LLDB_INVALID_ADDRESS; SymbolContext sym_ctx; diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td b/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td new file mode 100644 index 000000000000..0493838bc85d --- /dev/null +++ b/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td @@ -0,0 +1,9 @@ +include "../../../../include/lldb/Core/PropertiesBase.td" + +let Definition = "jitloadergdb" in { + def Enable: Property<"enable", "Enum">, + Global, + DefaultEnumValue<"eEnableJITLoaderGDBDefault">, + EnumValues<"OptionEnumValues(g_enable_jit_loader_gdb_enumerators)">, + Desc<"Enable GDB's JIT compilation interface (default: enabled on all platforms except macOS)">; +} diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp index 87b5b5947f35..5cfd978774fd 100644 --- a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp @@ -17,6 +17,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; @@ -39,16 +40,17 @@ public: return; } - Status err; - TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage( - &err, lldb::eLanguageTypeC_plus_plus); - - if (!err.Success() || !type_system) { + auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage( + lldb::eLanguageTypeC_plus_plus); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR( + lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS), + std::move(err), "Failed to get scratch ClangASTContext"); return; } ClangASTContext *clang_ast_context = - llvm::dyn_cast<ClangASTContext>(type_system); + llvm::dyn_cast<ClangASTContext>(&type_system_or_err.get()); if (!clang_ast_context) { return; diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 44b9e5e24ccd..489fa7d0ad91 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -486,8 +486,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { cpp_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", - ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"), stl_deref_flags, - true); + // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$" + // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$" + ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|" + "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"), + stl_deref_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, @@ -547,8 +550,8 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true); cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( - RegularExpressionSP(new RegularExpression( - llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$"))), + RegularExpression( + llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$")), SyntheticChildrenSP(new ScriptedSyntheticChildren( stl_synth_flags, "lldb.formatters.cpp.libcxx.stddeque_SynthProvider"))); @@ -566,12 +569,6 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { ConstString("^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::LibcxxFunctionSummaryProvider, - "libc++ std::function summary provider", - ConstString("^std::__[[:alnum:]]+::function<.+>$"), stl_summary_flags, - true); - stl_summary_flags.SetDontShowChildren(false); stl_summary_flags.SetSkipPointers(false); AddCXXSummary(cpp_category_sp, @@ -589,11 +586,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "libc++ std::list summary provider", ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"), stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::list summary provider", - ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"), - stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::list summary provider", + // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$" + // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$" + ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|" + "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"), + stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::map summary provider", @@ -750,38 +750,32 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { false); cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( - RegularExpressionSP( - new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))), + RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")), SyntheticChildrenSP(new ScriptedSyntheticChildren( stl_synth_flags, "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider"))); cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( - RegularExpressionSP( - new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))), + RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")), SyntheticChildrenSP(new ScriptedSyntheticChildren( stl_synth_flags, "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider"))); cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( - RegularExpressionSP(new RegularExpression( - llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))), + RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")), SyntheticChildrenSP(new ScriptedSyntheticChildren( stl_synth_flags, "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider"))); stl_summary_flags.SetDontShowChildren(false); stl_summary_flags.SetSkipPointers(true); cpp_category_sp->GetRegexTypeSummariesContainer()->Add( - RegularExpressionSP( - new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))), + RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")), TypeSummaryImplSP( new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); cpp_category_sp->GetRegexTypeSummariesContainer()->Add( - RegularExpressionSP( - new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))), + RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")), TypeSummaryImplSP( new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); cpp_category_sp->GetRegexTypeSummariesContainer()->Add( - RegularExpressionSP(new RegularExpression( - llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))), + RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")), TypeSummaryImplSP( new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); @@ -860,6 +854,14 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { // FIXME because of a bug in the FormattersContainer we need to add a summary // for both X* and const X* (<rdar://problem/12717717>) AddCXXSummary( + cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider, + "char8_t * summary provider", ConstString("char8_t *"), string_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char8StringSummaryProvider, + "char8_t [] summary provider", + ConstString("char8_t \\[[0-9]+\\]"), string_array_flags, true); + + AddCXXSummary( cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t * summary provider", ConstString("char16_t *"), string_flags); AddCXXSummary(cpp_category_sp, @@ -896,6 +898,9 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { .SetHideItemNames(true) .SetShowMembersOneLiner(false); + AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider, + "char8_t summary provider", ConstString("char8_t"), + widechar_flags); AddCXXSummary( cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, "char16_t summary provider", ConstString("char16_t"), widechar_flags); diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index 959079070acc..3ea7589d8e4a 100644 --- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -32,6 +32,31 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +bool lldb_private::formatters::Char8StringSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { + ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return false; + + lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); + if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) + return false; + + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); + options.SetLocation(valobj_addr); + options.SetProcessSP(process_sp); + options.SetStream(&stream); + options.SetPrefixToken("u8"); + + if (!StringPrinter::ReadStringAndDumpToStream< + StringPrinter::StringElementType::UTF8>(options)) { + stream.Printf("Summary Unavailable"); + return true; + } + + return true; +} + bool lldb_private::formatters::Char16StringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { ProcessSP process_sp = valobj.GetProcessSP(); @@ -128,6 +153,32 @@ bool lldb_private::formatters::WCharStringSummaryProvider( return true; } +bool lldb_private::formatters::Char8SummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { + DataExtractor data; + Status error; + valobj.GetData(data, error); + + if (error.Fail()) + return false; + + std::string value; + valobj.GetValueAsCString(lldb::eFormatUnicode8, value); + if (!value.empty()) + stream.Printf("%s ", value.c_str()); + + StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); + options.SetData(data); + options.SetStream(&stream); + options.SetPrefixToken("u8"); + options.SetQuote('\''); + options.SetSourceSize(1); + options.SetBinaryZeroIsTerminator(false); + + return StringPrinter::ReadBufferAndDumpToStream< + StringPrinter::StringElementType::UTF8>(options); +} + bool lldb_private::formatters::Char16SummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { DataExtractor data; diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h index 92bef2382eac..35498b3b568f 100644 --- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h +++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h @@ -16,6 +16,9 @@ namespace lldb_private { namespace formatters { +bool Char8StringSummaryProvider(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // char8_t* + bool Char16StringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // char16_t* and unichar* @@ -27,6 +30,9 @@ bool Char32StringSummaryProvider( bool WCharStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // wchar_t* +bool Char8SummaryProvider(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // char8_t + bool Char16SummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // char16_t and unichar diff --git a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp index 815dafb6c724..78c453cd1b3c 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp @@ -30,8 +30,15 @@ public: ValueObjectSP GetChildAtIndex(size_t idx) override; private: + // The lifetime of a ValueObject and all its derivative ValueObjects + // (children, clones, etc.) is managed by a ClusterManager. These + // objects are only destroyed when every shared pointer to any of them + // is destroyed, so we must not store a shared pointer to any ValueObject + // derived from our backend ValueObject (since we're in the same cluster). + // Value objects created from raw data (i.e. in a different cluster) must + // be referenced via shared pointer to keep them alive, however. std::vector<ValueObjectSP> m_elements; - ValueObjectSP m_first; + ValueObject* m_first = nullptr; CompilerType m_bool_type; ByteOrder m_byte_order = eByteOrderInvalid; uint8_t m_byte_size = 0; @@ -50,7 +57,7 @@ BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj) bool BitsetFrontEnd::Update() { m_elements.clear(); - m_first.reset(); + m_first = nullptr; TargetSP target_sp = m_backend.GetTargetSP(); if (!target_sp) @@ -63,7 +70,7 @@ bool BitsetFrontEnd::Update() { m_elements.assign(size, ValueObjectSP()); - m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true); + m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true).get(); return false; } @@ -86,7 +93,7 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) { chunk = m_first->GetChildAtIndex(idx / *bit_size, true); } else { type = m_first->GetCompilerType(); - chunk = m_first; + chunk = m_first->GetSP(); } if (!type || !chunk) return {}; diff --git a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp index 116021588848..b1ad171d0b0c 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp @@ -31,7 +31,6 @@ public: private: size_t m_size = 0; - ValueObjectSP m_base_sp; }; } // namespace diff --git a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp index 4b72089c6ba2..2f06d684f953 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp @@ -38,16 +38,21 @@ public: } private: - ValueObjectSP m_container_sp; + // The lifetime of a ValueObject and all its derivative ValueObjects + // (children, clones, etc.) is managed by a ClusterManager. These + // objects are only destroyed when every shared pointer to any of them + // is destroyed, so we must not store a shared pointer to any ValueObject + // derived from our backend ValueObject (since we're in the same cluster). + ValueObject* m_container_sp = nullptr; }; } // namespace bool QueueFrontEnd::Update() { - m_container_sp.reset(); + m_container_sp = nullptr; ValueObjectSP c_sp = m_backend.GetChildMemberWithName(ConstString("c"), true); if (!c_sp) return false; - m_container_sp = c_sp->GetSyntheticValue(); + m_container_sp = c_sp->GetSyntheticValue().get(); return false; } diff --git a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp index 8da7460f2275..45294e25f0f5 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp @@ -30,47 +30,58 @@ public: ValueObjectSP GetChildAtIndex(size_t idx) override; private: - std::vector<ValueObjectSP> m_elements; - ValueObjectSP m_base_sp; + // The lifetime of a ValueObject and all its derivative ValueObjects + // (children, clones, etc.) is managed by a ClusterManager. These + // objects are only destroyed when every shared pointer to any of them + // is destroyed, so we must not store a shared pointer to any ValueObject + // derived from our backend ValueObject (since we're in the same cluster). + std::vector<ValueObject*> m_elements; + ValueObject* m_base = nullptr; }; } bool TupleFrontEnd::Update() { m_elements.clear(); - m_base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true); - if (! m_base_sp) { + m_base = nullptr; + + ValueObjectSP base_sp; + base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true); + if (!base_sp) { // Pre r304382 name of the base element. - m_base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true); + base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true); } - if (! m_base_sp) + if (!base_sp) return false; - m_elements.assign(m_base_sp->GetCompilerType().GetNumDirectBaseClasses(), - ValueObjectSP()); + m_base = base_sp.get(); + m_elements.assign(base_sp->GetCompilerType().GetNumDirectBaseClasses(), + nullptr); return false; } ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) { if (idx >= m_elements.size()) return ValueObjectSP(); - if (!m_base_sp) + if (!m_base) return ValueObjectSP(); if (m_elements[idx]) - return m_elements[idx]; + return m_elements[idx]->GetSP(); CompilerType holder_type = - m_base_sp->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr); + m_base->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr); if (!holder_type) return ValueObjectSP(); - ValueObjectSP holder_sp = m_base_sp->GetChildAtIndex(idx, true); + ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx, true); if (!holder_sp) return ValueObjectSP(); ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true); if (elem_sp) m_elements[idx] = - elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())); + elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())).get(); - return m_elements[idx]; + if (m_elements[idx]) + return m_elements[idx]->GetSP(); + return ValueObjectSP(); } SyntheticChildrenFrontEnd * diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp index 491cf048e459..62945bd3ce80 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp @@ -184,7 +184,6 @@ public: private: size_t m_size = 0; - ValueObjectSP m_base_sp; }; } // namespace diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp index 66624e5beb6d..0ac7b8f8e02b 100644 --- a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp +++ b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp @@ -37,7 +37,12 @@ public: size_t GetIndexOfChildWithName(ConstString name) override; private: - std::vector<ValueObjectSP> m_members; + // The lifetime of a ValueObject and all its derivative ValueObjects + // (children, clones, etc.) is managed by a ClusterManager. These + // objects are only destroyed when every shared pointer to any of them + // is destroyed, so we must not store a shared pointer to any ValueObject + // derived from our backend ValueObject (since we're in the same cluster). + std::vector<ValueObject*> m_members; }; } // end of anonymous namespace @@ -72,7 +77,7 @@ bool LibStdcppTupleSyntheticFrontEnd::Update() { if (value_sp) { StreamString name; name.Printf("[%zd]", m_members.size()); - m_members.push_back(value_sp->Clone(ConstString(name.GetString()))); + m_members.push_back(value_sp->Clone(ConstString(name.GetString())).get()); } } } @@ -85,8 +90,8 @@ bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; } lldb::ValueObjectSP LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(size_t idx) { - if (idx < m_members.size()) - return m_members[idx]; + if (idx < m_members.size() && m_members[idx]) + return m_members[idx]->GetSP(); return lldb::ValueObjectSP(); } diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp index 3860f960cb3d..cceb511cdc46 100644 --- a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp +++ b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -39,9 +39,14 @@ public: bool GetSummary(Stream &stream, const TypeSummaryOptions &options); private: - ValueObjectSP m_ptr_obj; - ValueObjectSP m_obj_obj; - ValueObjectSP m_del_obj; + // The lifetime of a ValueObject and all its derivative ValueObjects + // (children, clones, etc.) is managed by a ClusterManager. These + // objects are only destroyed when every shared pointer to any of them + // is destroyed, so we must not store a shared pointer to any ValueObject + // derived from our backend ValueObject (since we're in the same cluster). + ValueObject* m_ptr_obj = nullptr; + ValueObject* m_obj_obj = nullptr; + ValueObject* m_del_obj = nullptr; ValueObjectSP GetTuple(); }; @@ -92,17 +97,17 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::Update() { ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0); if (ptr_obj) - m_ptr_obj = ptr_obj->Clone(ConstString("pointer")); + m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get(); ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1); if (del_obj) - m_del_obj = del_obj->Clone(ConstString("deleter")); + m_del_obj = del_obj->Clone(ConstString("deleter")).get(); if (m_ptr_obj) { Status error; ValueObjectSP obj_obj = m_ptr_obj->Dereference(error); if (error.Success()) { - m_obj_obj = obj_obj->Clone(ConstString("object")); + m_obj_obj = obj_obj->Clone(ConstString("object")).get(); } } @@ -113,12 +118,12 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; } lldb::ValueObjectSP LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) { - if (idx == 0) - return m_ptr_obj; - if (idx == 1) - return m_del_obj; - if (idx == 2) - return m_obj_obj; + if (idx == 0 && m_ptr_obj) + return m_ptr_obj->GetSP(); + if (idx == 1 && m_del_obj) + return m_del_obj->GetSP(); + if (idx == 2 && m_obj_obj) + return m_obj_obj->GetSP(); return lldb::ValueObjectSP(); } diff --git a/source/Plugins/Language/ObjC/CoreMedia.cpp b/source/Plugins/Language/ObjC/CoreMedia.cpp index d19290ec56fb..247429da1b06 100644 --- a/source/Plugins/Language/ObjC/CoreMedia.cpp +++ b/source/Plugins/Language/ObjC/CoreMedia.cpp @@ -10,6 +10,7 @@ #include "CoreMedia.h" #include "lldb/Utility/Flags.h" +#include "lldb/Utility/Log.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Target.h" @@ -25,18 +26,21 @@ bool lldb_private::formatters::CMTimeSummaryProvider( if (!type.IsValid()) return false; - TypeSystem *type_system = + auto type_system_or_err = valobj.GetExecutionContextRef() .GetTargetSP() - ->GetScratchTypeSystemForLanguage(nullptr, lldb::eLanguageTypeC); - if (!type_system) + ->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR( + lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS), + std::move(err), "Failed to get scratch type system"); return false; - + } // fetch children by offset to compensate for potential lack of debug info - auto int64_ty = - type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64); - auto int32_ty = - type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32); + auto int64_ty = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize( + eEncodingSint, 64); + auto int32_ty = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize( + eEncodingSint, 32); auto value_sp(valobj.GetSyntheticChildAtOffset(0, int64_ty, true)); auto timescale_sp(valobj.GetSyntheticChildAtOffset(8, int32_ty, true)); diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp index 404dabf2870c..7219c016dfd1 100644 --- a/source/Plugins/Language/ObjC/NSArray.cpp +++ b/source/Plugins/Language/ObjC/NSArray.cpp @@ -461,12 +461,13 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontE : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), m_id_type() { if (valobj_sp) { - clang::ASTContext *ast = valobj_sp->GetExecutionContextRef() - .GetTargetSP() - ->GetScratchClangASTContext() - ->getASTContext(); - if (ast) - m_id_type = CompilerType(ast, ast->ObjCBuiltinIdTy); + auto *clang_ast_context = valobj_sp->GetExecutionContextRef() + .GetTargetSP() + ->GetScratchClangASTContext(); + if (clang_ast_context) + m_id_type = CompilerType( + clang_ast_context, + clang_ast_context->getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr()); if (valobj_sp->GetProcessSP()) m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize(); } @@ -609,12 +610,13 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: if (valobj_sp) { CompilerType type = valobj_sp->GetCompilerType(); if (type) { - ClangASTContext *ast = valobj_sp->GetExecutionContextRef() - .GetTargetSP() - ->GetScratchClangASTContext(); - if (ast) - m_id_type = CompilerType(ast->getASTContext(), - ast->getASTContext()->ObjCBuiltinIdTy); + auto *clang_ast_context = valobj_sp->GetExecutionContextRef() + .GetTargetSP() + ->GetScratchClangASTContext(); + if (clang_ast_context) + m_id_type = CompilerType(clang_ast_context, + clang_ast_context->getASTContext() + ->ObjCBuiltinIdTy.getAsOpaquePtr()); } } } diff --git a/source/Plugins/Language/ObjC/NSDictionary.h b/source/Plugins/Language/ObjC/NSDictionary.h index ecb3fccdf877..44d56f9c2c68 100644 --- a/source/Plugins/Language/ObjC/NSDictionary.h +++ b/source/Plugins/Language/ObjC/NSDictionary.h @@ -68,10 +68,10 @@ public: }; typedef Matcher::UP MatcherUP; - MatcherUP GetFullMatch(ConstString n) { return llvm::make_unique<Full>(n); } + MatcherUP GetFullMatch(ConstString n) { return std::make_unique<Full>(n); } MatcherUP GetPrefixMatch(ConstString p) { - return llvm::make_unique<Prefix>(p); + return std::make_unique<Prefix>(p); } }; diff --git a/source/Plugins/Language/ObjC/NSString.cpp b/source/Plugins/Language/ObjC/NSString.cpp index 4800c955e5f5..55e129b098dc 100644 --- a/source/Plugins/Language/ObjC/NSString.cpp +++ b/source/Plugins/Language/ObjC/NSString.cpp @@ -78,12 +78,12 @@ bool lldb_private::formatters::NSStringSummaryProvider( return false; ConstString class_name_cs = descriptor->GetClassName(); - const char *class_name = class_name_cs.GetCString(); + llvm::StringRef class_name = class_name_cs.GetStringRef(); - if (!class_name || !*class_name) + if (class_name.empty()) return false; - bool is_tagged_ptr = (0 == strcmp(class_name, "NSTaggedPointerString")) && + bool is_tagged_ptr = class_name == "NSTaggedPointerString" && descriptor->GetTaggedPointerInfo(); // for a tagged pointer, the descriptor has everything we need if (is_tagged_ptr) @@ -111,7 +111,7 @@ bool lldb_private::formatters::NSStringSummaryProvider( bool is_inline = (info_bits & 0x60) == 0; bool has_explicit_length = (info_bits & (1 | 4)) != 4; bool is_unicode = (info_bits & 0x10) == 0x10; - bool is_path_store = strcmp(class_name, "NSPathStore2") == 0; + bool is_path_store = class_name == "NSPathStore2"; bool has_null = (info_bits & 8) == 8; size_t explicit_length = 0; @@ -135,14 +135,14 @@ bool lldb_private::formatters::NSStringSummaryProvider( } } - if (strcmp(class_name, "NSString") && strcmp(class_name, "CFStringRef") && - strcmp(class_name, "CFMutableStringRef") && - strcmp(class_name, "__NSCFConstantString") && - strcmp(class_name, "__NSCFString") && - strcmp(class_name, "NSCFConstantString") && - strcmp(class_name, "NSCFString") && strcmp(class_name, "NSPathStore2")) { + const llvm::StringSet<> supported_string_classes = { + "NSString", "CFMutableStringRef", + "CFStringRef", "__NSCFConstantString", + "__NSCFString", "NSCFConstantString", + "NSCFString", "NSPathStore2"}; + if (supported_string_classes.count(class_name) == 0) { // not one of us - but tell me class name - stream.Printf("class name = %s", class_name); + stream.Printf("class name = %s", class_name_cs.GetCString()); return true; } diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/source/Plugins/Language/ObjC/ObjCLanguage.cpp index f9ab18688de7..c5bfb5747c13 100644 --- a/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -22,6 +22,7 @@ #include "llvm/Support/Threading.h" +#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" #include "CF.h" diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index b392282c3eb1..f38014505a8b 100644 --- a/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -231,7 +231,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( SymbolContextList scl; target.GetImages().FindSymbolsMatchingRegExAndType( - RegularExpression{R"(^)" + func_to_match}, eSymbolTypeAny, scl, true); + RegularExpression{R"(^)" + func_to_match}, eSymbolTypeAny, scl); // Case 1,2 or 3 if (scl.GetSize() >= 1) { diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 41f38a4e3dcd..02e62a263286 100644 --- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -79,11 +79,10 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( if (name && strstr(name, vtable_demangled_prefix) == name) { Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); - if (log) - log->Printf("0x%16.16" PRIx64 - ": static-type = '%s' has vtable symbol '%s'\n", - original_ptr, in_value.GetTypeName().GetCString(), - name); + LLDB_LOGF(log, + "0x%16.16" PRIx64 + ": static-type = '%s' has vtable symbol '%s'\n", + original_ptr, in_value.GetTypeName().GetCString(), name); // We are a C++ class, that's good. Get the class name and look it // up: const char *class_name = name + strlen(vtable_demangled_prefix); @@ -96,87 +95,81 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( const bool exact_match = true; TypeList class_types; - uint32_t num_matches = 0; // First look in the module that the vtable symbol came from and // look for a single exact match. llvm::DenseSet<SymbolFile *> searched_symbol_files; - if (sc.module_sp) { - num_matches = sc.module_sp->FindTypes( - ConstString(lookup_name), exact_match, 1, - searched_symbol_files, class_types); - } + if (sc.module_sp) + sc.module_sp->FindTypes(ConstString(lookup_name), exact_match, 1, + searched_symbol_files, class_types); // If we didn't find a symbol, then move on to the entire module // list in the target and get as many unique matches as possible - if (num_matches == 0) { - num_matches = target.GetImages().FindTypes( - nullptr, ConstString(lookup_name), exact_match, UINT32_MAX, - searched_symbol_files, class_types); - } + if (class_types.Empty()) + target.GetImages().FindTypes(nullptr, ConstString(lookup_name), + exact_match, UINT32_MAX, + searched_symbol_files, class_types); lldb::TypeSP type_sp; - if (num_matches == 0) { - if (log) - log->Printf("0x%16.16" PRIx64 ": is not dynamic\n", - original_ptr); + if (class_types.Empty()) { + LLDB_LOGF(log, "0x%16.16" PRIx64 ": is not dynamic\n", + original_ptr); return TypeAndOrName(); } - if (num_matches == 1) { + if (class_types.GetSize() == 1) { type_sp = class_types.GetTypeAtIndex(0); if (type_sp) { if (ClangASTContext::IsCXXClassType( type_sp->GetForwardCompilerType())) { - if (log) - log->Printf( - "0x%16.16" PRIx64 - ": static-type = '%s' has dynamic type: uid={0x%" PRIx64 - "}, type-name='%s'\n", - original_ptr, in_value.GetTypeName().AsCString(), - type_sp->GetID(), type_sp->GetName().GetCString()); + LLDB_LOGF( + log, + "0x%16.16" PRIx64 + ": static-type = '%s' has dynamic type: uid={0x%" PRIx64 + "}, type-name='%s'\n", + original_ptr, in_value.GetTypeName().AsCString(), + type_sp->GetID(), type_sp->GetName().GetCString()); type_info.SetTypeSP(type_sp); } } - } else if (num_matches > 1) { + } else { size_t i; if (log) { - for (i = 0; i < num_matches; i++) { + for (i = 0; i < class_types.GetSize(); i++) { type_sp = class_types.GetTypeAtIndex(i); if (type_sp) { - if (log) - log->Printf( - "0x%16.16" PRIx64 - ": static-type = '%s' has multiple matching dynamic " - "types: uid={0x%" PRIx64 "}, type-name='%s'\n", - original_ptr, in_value.GetTypeName().AsCString(), - type_sp->GetID(), type_sp->GetName().GetCString()); + LLDB_LOGF( + log, + "0x%16.16" PRIx64 + ": static-type = '%s' has multiple matching dynamic " + "types: uid={0x%" PRIx64 "}, type-name='%s'\n", + original_ptr, in_value.GetTypeName().AsCString(), + type_sp->GetID(), type_sp->GetName().GetCString()); } } } - for (i = 0; i < num_matches; i++) { + for (i = 0; i < class_types.GetSize(); i++) { type_sp = class_types.GetTypeAtIndex(i); if (type_sp) { if (ClangASTContext::IsCXXClassType( type_sp->GetForwardCompilerType())) { - if (log) - log->Printf( - "0x%16.16" PRIx64 ": static-type = '%s' has multiple " - "matching dynamic types, picking " - "this one: uid={0x%" PRIx64 - "}, type-name='%s'\n", - original_ptr, in_value.GetTypeName().AsCString(), - type_sp->GetID(), type_sp->GetName().GetCString()); + LLDB_LOGF( + log, + "0x%16.16" PRIx64 ": static-type = '%s' has multiple " + "matching dynamic types, picking " + "this one: uid={0x%" PRIx64 "}, type-name='%s'\n", + original_ptr, in_value.GetTypeName().AsCString(), + type_sp->GetID(), type_sp->GetName().GetCString()); type_info.SetTypeSP(type_sp); } } } - if (log && i == num_matches) { - log->Printf( - "0x%16.16" PRIx64 - ": static-type = '%s' has multiple matching dynamic " - "types, didn't find a C++ match\n", - original_ptr, in_value.GetTypeName().AsCString()); + if (log) { + LLDB_LOGF(log, + "0x%16.16" PRIx64 + ": static-type = '%s' has multiple matching dynamic " + "types, didn't find a C++ match\n", + original_ptr, in_value.GetTypeName().AsCString()); } } if (type_info) @@ -351,7 +344,7 @@ protected: bool demangled_any = false; bool error_any = false; for (auto &entry : command.entries()) { - if (entry.ref.empty()) + if (entry.ref().empty()) continue; // the actual Mangled class should be strict about this, but on the @@ -359,21 +352,21 @@ protected: // they will come out with an extra underscore - be willing to strip this // on behalf of the user. This is the moral equivalent of the -_/-n // options to c++filt - auto name = entry.ref; + auto name = entry.ref(); if (name.startswith("__Z")) name = name.drop_front(); - Mangled mangled(name, true); + Mangled mangled(name); if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) { ConstString demangled( mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus)); demangled_any = true; - result.AppendMessageWithFormat("%s ---> %s\n", entry.ref.str().c_str(), + result.AppendMessageWithFormat("%s ---> %s\n", entry.c_str(), demangled.GetCString()); } else { error_any = true; result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n", - entry.ref.str().c_str()); + entry.ref().str().c_str()); } } @@ -471,8 +464,8 @@ lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() { if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) { // Limit the number of modules that are searched for these breakpoints for // Apple binaries. - filter_modules.Append(FileSpec("libc++abi.dylib")); - filter_modules.Append(FileSpec("libSystem.B.dylib")); + filter_modules.EmplaceBack("libc++abi.dylib"); + filter_modules.EmplaceBack("libSystem.B.dylib"); } return target.GetSearchFilterForModuleList(&filter_modules); } diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp index 18f2a1829a41..1f27a4f0b3ed 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp @@ -38,12 +38,13 @@ public: LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? if (log) { - log->Printf("AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%" - "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p", - current_id, - static_cast<void *>(&decl_ctx->getParentASTContext()), - name.getAsString().c_str(), decl_ctx->getDeclKindName(), - static_cast<const void *>(decl_ctx)); + LLDB_LOGF(log, + "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%" + "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p", + current_id, + static_cast<void *>(&decl_ctx->getParentASTContext()), + name.getAsString().c_str(), decl_ctx->getDeclKindName(), + static_cast<const void *>(decl_ctx)); } do { @@ -77,19 +78,20 @@ public: LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? if (log) { - log->Printf("AppleObjCExternalASTSource::CompleteType[%u] on " - "(ASTContext*)%p Completing (TagDecl*)%p named %s", - current_id, static_cast<void *>(&tag_decl->getASTContext()), - static_cast<void *>(tag_decl), - tag_decl->getName().str().c_str()); - - log->Printf(" AOEAS::CT[%u] Before:", current_id); + LLDB_LOGF(log, + "AppleObjCExternalASTSource::CompleteType[%u] on " + "(ASTContext*)%p Completing (TagDecl*)%p named %s", + current_id, static_cast<void *>(&tag_decl->getASTContext()), + static_cast<void *>(tag_decl), + tag_decl->getName().str().c_str()); + + LLDB_LOGF(log, " AOEAS::CT[%u] Before:", current_id); ASTDumper dumper((clang::Decl *)tag_decl); dumper.ToLog(log, " [CT] "); } if (log) { - log->Printf(" AOEAS::CT[%u] After:", current_id); + LLDB_LOGF(log, " AOEAS::CT[%u] After:", current_id); ASTDumper dumper((clang::Decl *)tag_decl); dumper.ToLog(log, " [CT] "); } @@ -104,14 +106,15 @@ public: LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? if (log) { - log->Printf("AppleObjCExternalASTSource::CompleteType[%u] on " - "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s", - current_id, - static_cast<void *>(&interface_decl->getASTContext()), - static_cast<void *>(interface_decl), - interface_decl->getName().str().c_str()); - - log->Printf(" AOEAS::CT[%u] Before:", current_id); + LLDB_LOGF(log, + "AppleObjCExternalASTSource::CompleteType[%u] on " + "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s", + current_id, + static_cast<void *>(&interface_decl->getASTContext()), + static_cast<void *>(interface_decl), + interface_decl->getName().str().c_str()); + + LLDB_LOGF(log, " AOEAS::CT[%u] Before:", current_id); ASTDumper dumper((clang::Decl *)interface_decl); dumper.ToLog(log, " [CT] "); } @@ -119,7 +122,7 @@ public: m_decl_vendor.FinishDecl(interface_decl); if (log) { - log->Printf(" [CT] After:"); + LLDB_LOGF(log, " [CT] After:"); ASTDumper dumper((clang::Decl *)interface_decl); dumper.ToLog(log, " [CT] "); } @@ -148,12 +151,13 @@ private: }; AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime) - : DeclVendor(), m_runtime(runtime), m_ast_ctx(runtime.GetProcess() - ->GetTarget() - .GetArchitecture() - .GetTriple() - .getTriple() - .c_str()), + : ClangDeclVendor(eAppleObjCDeclVendor), m_runtime(runtime), + m_ast_ctx(runtime.GetProcess() + ->GetTarget() + .GetArchitecture() + .GetTriple() + .getTriple() + .c_str()), m_type_realizer_sp(m_runtime.GetEncodingToType()) { m_external_source = new AppleObjCExternalASTSource(*this); llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr( @@ -462,8 +466,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) { clang::ObjCMethodDecl *method_decl = method_type.BuildMethod(interface_decl, name, true, m_type_realizer_sp); - if (log) - log->Printf("[ AOTV::FD] Instance method [%s] [%s]", name, types); + LLDB_LOGF(log, "[ AOTV::FD] Instance method [%s] [%s]", name, types); if (method_decl) interface_decl->addDecl(method_decl); @@ -481,8 +484,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) { clang::ObjCMethodDecl *method_decl = method_type.BuildMethod( interface_decl, name, false, m_type_realizer_sp); - if (log) - log->Printf("[ AOTV::FD] Class method [%s] [%s]", name, types); + LLDB_LOGF(log, "[ AOTV::FD] Class method [%s] [%s]", name, types); if (method_decl) interface_decl->addDecl(method_decl); @@ -498,10 +500,9 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) { const bool for_expression = false; - if (log) - log->Printf( - "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64, name, - type, offset_ptr); + LLDB_LOGF(log, + "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64, + name, type, offset_ptr); CompilerType ivar_type = m_runtime.GetEncodingToType()->RealizeType( m_ast_ctx, type, for_expression); @@ -527,9 +528,10 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) { if (log) { ASTDumper method_dumper((clang::Decl *)interface_decl); - log->Printf("[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C " - "interface for %s", - descriptor->GetClassName().AsCString()); + LLDB_LOGF(log, + "[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C " + "interface for %s", + descriptor->GetClassName().AsCString()); } if (!descriptor->Describe(superclass_func, instance_method_func, @@ -539,7 +541,8 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) { if (log) { ASTDumper method_dumper((clang::Decl *)interface_decl); - log->Printf( + LLDB_LOGF( + log, "[AppleObjCDeclVendor::FinishDecl] Finished Objective-C interface"); method_dumper.ToLog(log, " [AOTV::FD] "); @@ -558,10 +561,9 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append, Log *log(GetLogIfAllCategoriesSet( LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? - if (log) - log->Printf("AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )", - current_id, (const char *)name.AsCString(), - append ? "true" : "false", max_matches); + LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )", + current_id, (const char *)name.AsCString(), + append ? "true" : "false", max_matches); if (!append) decls.clear(); @@ -595,24 +597,25 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append, if (metadata) isa_value = metadata->GetISAPtr(); - log->Printf("AOCTV::FT [%u] Found %s (isa 0x%" PRIx64 - ") in the ASTContext", - current_id, dumper.GetCString(), isa_value); + LLDB_LOGF(log, + "AOCTV::FT [%u] Found %s (isa 0x%" PRIx64 + ") in the ASTContext", + current_id, dumper.GetCString(), isa_value); } decls.push_back(result_iface_decl); ret++; break; } else { - if (log) - log->Printf("AOCTV::FT [%u] There's something in the ASTContext, but " - "it's not something we know about", - current_id); + LLDB_LOGF(log, + "AOCTV::FT [%u] There's something in the ASTContext, but " + "it's not something we know about", + current_id); break; } } else if (log) { - log->Printf("AOCTV::FT [%u] Couldn't find %s in the ASTContext", - current_id, name.AsCString()); + LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find %s in the ASTContext", + current_id, name.AsCString()); } // It's not. If it exists, we have to put it into our ASTContext. @@ -620,8 +623,7 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append, ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name); if (!isa) { - if (log) - log->Printf("AOCTV::FT [%u] Couldn't find the isa", current_id); + LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find the isa", current_id); break; } @@ -629,10 +631,10 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append, clang::ObjCInterfaceDecl *iface_decl = GetDeclForISA(isa); if (!iface_decl) { - if (log) - log->Printf("AOCTV::FT [%u] Couldn't get the Objective-C interface for " - "isa 0x%" PRIx64, - current_id, (uint64_t)isa); + LLDB_LOGF(log, + "AOCTV::FT [%u] Couldn't get the Objective-C interface for " + "isa 0x%" PRIx64, + current_id, (uint64_t)isa); break; } @@ -641,8 +643,8 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append, clang::QualType new_iface_type = ast_ctx->getObjCInterfaceType(iface_decl); ASTDumper dumper(new_iface_type); - log->Printf("AOCTV::FT [%u] Created %s (isa 0x%" PRIx64 ")", current_id, - dumper.GetCString(), (uint64_t)isa); + LLDB_LOGF(log, "AOCTV::FT [%u] Created %s (isa 0x%" PRIx64 ")", + current_id, dumper.GetCString(), (uint64_t)isa); } decls.push_back(iface_decl); @@ -655,8 +657,7 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append, clang::ExternalASTMerger::ImporterSource AppleObjCDeclVendor::GetImporterSource() { - return {*m_ast_ctx.getASTContext(), - *m_ast_ctx.getFileManager(), - m_ast_ctx.GetOriginMap() - }; + return clang::ExternalASTMerger::ImporterSource(*m_ast_ctx.getASTContext(), + *m_ast_ctx.getFileManager(), + m_ast_ctx.GetOriginMap()); } diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h index 77b30b7fde79..99ca4b748709 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h @@ -10,19 +10,23 @@ #define liblldb_AppleObjCDeclVendor_h_ #include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/DeclVendor.h" #include "lldb/lldb-private.h" +#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" namespace lldb_private { class AppleObjCExternalASTSource; -class AppleObjCDeclVendor : public DeclVendor { +class AppleObjCDeclVendor : public ClangDeclVendor { public: AppleObjCDeclVendor(ObjCLanguageRuntime &runtime); + static bool classof(const DeclVendor *vendor) { + return vendor->GetKind() == eAppleObjCDeclVendor; + } + uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches, std::vector<clang::NamedDecl *> &decls) override; diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index 52ed3628520f..8ca9ad7b843a 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -223,11 +223,14 @@ Address *AppleObjCRuntime::GetPrintForDebuggerAddr() { SymbolContextList contexts; SymbolContext context; - if ((!modules.FindSymbolsWithNameAndType(ConstString("_NSPrintForDebugger"), - eSymbolTypeCode, contexts)) && - (!modules.FindSymbolsWithNameAndType(ConstString("_CFPrintForDebugger"), - eSymbolTypeCode, contexts))) - return nullptr; + modules.FindSymbolsWithNameAndType(ConstString("_NSPrintForDebugger"), + eSymbolTypeCode, contexts); + if (contexts.IsEmpty()) { + modules.FindSymbolsWithNameAndType(ConstString("_CFPrintForDebugger"), + eSymbolTypeCode, contexts); + if (contexts.IsEmpty()) + return nullptr; + } contexts.GetContextAtIndex(0, context); @@ -444,10 +447,12 @@ bool AppleObjCRuntime::CalculateHasNewLiteralsAndIndexing() { SymbolContextList sc_list; - return target.GetImages().FindSymbolsWithNameAndType( - s_method_signature, eSymbolTypeCode, sc_list) || - target.GetImages().FindSymbolsWithNameAndType( - s_arclite_method_signature, eSymbolTypeCode, sc_list); + target.GetImages().FindSymbolsWithNameAndType(s_method_signature, + eSymbolTypeCode, sc_list); + if (sc_list.IsEmpty()) + target.GetImages().FindSymbolsWithNameAndType(s_arclite_method_signature, + eSymbolTypeCode, sc_list); + return !sc_list.IsEmpty(); } lldb::SearchFilterSP AppleObjCRuntime::CreateExceptionSearchFilter() { diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index c8884fd5c9b9..88bfe2ce0203 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -395,10 +395,11 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() { new ClassDescriptorV1(isa, process_sp)); if (log && log->GetVerbose()) - log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 - " from _objc_debug_class_hash to " - "isa->descriptor cache", - isa); + LLDB_LOGF(log, + "AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 + " from _objc_debug_class_hash to " + "isa->descriptor cache", + isa); AddClass(isa, descriptor_sp); } @@ -417,7 +418,8 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() { new ClassDescriptorV1(isa, process_sp)); if (log && log->GetVerbose()) - log->Printf( + LLDB_LOGF( + log, "AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor " "cache", diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 635eaff637bc..9bdbef393e39 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -582,9 +582,9 @@ protected: case 0: break; case 1: { - regex_up.reset(new RegularExpression()); - if (!regex_up->Compile(llvm::StringRef::withNullAsEmpty( - command.GetArgumentAtIndex(0)))) { + regex_up.reset(new RegularExpression( + llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0)))); + if (!regex_up->IsValid()) { result.AppendError( "invalid argument - please provide a valid regular expression"); result.SetStatus(lldb::eReturnStatusFailed); @@ -1209,11 +1209,11 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) { objc_class_sp = GetClassDescriptorFromISA(isa); if (isa && !objc_class_sp) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("0x%" PRIx64 - ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was " - "not in class descriptor cache 0x%" PRIx64, - isa_pointer, isa); + LLDB_LOGF(log, + "0x%" PRIx64 + ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was " + "not in class descriptor cache 0x%" PRIx64, + isa_pointer, isa); } } } @@ -1317,8 +1317,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( // Read the total number of classes from the hash table const uint32_t num_classes = hash_table.GetCount(); if (num_classes == 0) { - if (log) - log->Printf("No dynamic classes found in gdb_objc_realized_classes."); + LLDB_LOGF(log, "No dynamic classes found in gdb_objc_realized_classes."); return DescriptorMapUpdateResult::Success(0); } @@ -1337,17 +1336,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( g_get_dynamic_class_info_body, eLanguageTypeObjC, g_get_dynamic_class_info_name, error)); if (error.Fail()) { - if (log) - log->Printf( - "Failed to get Utility Function for implementation lookup: %s", - error.AsCString()); + LLDB_LOGF(log, + "Failed to get Utility Function for implementation lookup: %s", + error.AsCString()); m_get_class_info_code.reset(); } else { diagnostics.Clear(); if (!m_get_class_info_code->Install(diagnostics, exe_ctx)) { if (log) { - log->Printf("Failed to install implementation lookup"); + LLDB_LOGF(log, "Failed to install implementation lookup"); diagnostics.Dump(log); } m_get_class_info_code.reset(); @@ -1372,17 +1370,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( clang_uint32_t_type, arguments, thread_sp, error); if (error.Fail()) { - if (log) - log->Printf( - "Failed to make function caller for implementation lookup: %s.", - error.AsCString()); + LLDB_LOGF(log, + "Failed to make function caller for implementation lookup: %s.", + error.AsCString()); return DescriptorMapUpdateResult::Fail(); } } else { get_class_info_function = m_get_class_info_code->GetFunctionCaller(); if (!get_class_info_function) { if (log) { - log->Printf("Failed to get implementation lookup function caller."); + LLDB_LOGF(log, "Failed to get implementation lookup function caller."); diagnostics.Dump(log); } @@ -1399,10 +1396,10 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err); if (class_infos_addr == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf("unable to allocate %" PRIu32 - " bytes in process for shared cache read", - class_infos_byte_size); + LLDB_LOGF(log, + "unable to allocate %" PRIu32 + " bytes in process for shared cache read", + class_infos_byte_size); return DescriptorMapUpdateResult::Fail(); } @@ -1451,8 +1448,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( if (results == eExpressionCompleted) { // The result is the number of ClassInfo structures that were filled in num_class_infos = return_value.GetScalar().ULong(); - if (log) - log->Printf("Discovered %u ObjC classes\n", num_class_infos); + LLDB_LOGF(log, "Discovered %u ObjC classes\n", num_class_infos); if (num_class_infos > 0) { // Read the ClassInfo structures DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0); @@ -1468,13 +1464,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( success = true; } else { if (log) { - log->Printf("Error evaluating our find class name function."); + LLDB_LOGF(log, "Error evaluating our find class name function."); diagnostics.Dump(log); } } } else { if (log) { - log->Printf("Error writing function arguments."); + LLDB_LOGF(log, "Error writing function arguments."); diagnostics.Dump(log); } } @@ -1507,17 +1503,18 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data, if (isa == 0) { if (should_log) - log->Printf( - "AppleObjCRuntimeV2 found NULL isa, ignoring this class info"); + LLDB_LOGF( + log, "AppleObjCRuntimeV2 found NULL isa, ignoring this class info"); continue; } // Check if we already know about this ISA, if we do, the info will never // change, so we can just skip it. if (ISAIsCached(isa)) { if (should_log) - log->Printf("AppleObjCRuntimeV2 found cached isa=0x%" PRIx64 - ", ignoring this class info", - isa); + LLDB_LOGF(log, + "AppleObjCRuntimeV2 found cached isa=0x%" PRIx64 + ", ignoring this class info", + isa); offset += 4; } else { // Read the 32 bit hash for the class name @@ -1536,15 +1533,16 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data, AddClass(isa, descriptor_sp, descriptor_sp->GetClassName().AsCString(nullptr)); num_parsed++; if (should_log) - log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64 - ", hash=0x%8.8x, name=%s", - isa, name_hash, - descriptor_sp->GetClassName().AsCString("<unknown>")); + LLDB_LOGF(log, + "AppleObjCRuntimeV2 added isa=0x%" PRIx64 + ", hash=0x%8.8x, name=%s", + isa, name_hash, + descriptor_sp->GetClassName().AsCString("<unknown>")); } } if (should_log) - log->Printf("AppleObjCRuntimeV2 parsed %" PRIu32 " class infos", - num_parsed); + LLDB_LOGF(log, "AppleObjCRuntimeV2 parsed %" PRIu32 " class infos", + num_parsed); return num_parsed; } @@ -1603,7 +1601,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { // use that in our jitted expression. Else fall back to the old // class_getName. static ConstString g_class_getName_symbol_name("class_getName"); - static ConstString g_class_getNameRaw_symbol_name("class_getNameRaw"); + static ConstString g_class_getNameRaw_symbol_name("objc_debug_class_getNameRaw"); ConstString class_name_getter_function_name = g_class_getName_symbol_name; ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process); @@ -1646,17 +1644,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { shared_class_expression.c_str(), eLanguageTypeObjC, g_get_shared_cache_class_info_name, error)); if (error.Fail()) { - if (log) - log->Printf( - "Failed to get Utility function for implementation lookup: %s.", - error.AsCString()); + LLDB_LOGF(log, + "Failed to get Utility function for implementation lookup: %s.", + error.AsCString()); m_get_shared_cache_class_info_code.reset(); } else { diagnostics.Clear(); if (!m_get_shared_cache_class_info_code->Install(diagnostics, exe_ctx)) { if (log) { - log->Printf("Failed to install implementation lookup."); + LLDB_LOGF(log, "Failed to install implementation lookup."); diagnostics.Dump(log); } m_get_shared_cache_class_info_code.reset(); @@ -1703,10 +1700,10 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err); if (class_infos_addr == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf("unable to allocate %" PRIu32 - " bytes in process for shared cache read", - class_infos_byte_size); + LLDB_LOGF(log, + "unable to allocate %" PRIu32 + " bytes in process for shared cache read", + class_infos_byte_size); return DescriptorMapUpdateResult::Fail(); } @@ -1757,9 +1754,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { if (results == eExpressionCompleted) { // The result is the number of ClassInfo structures that were filled in num_class_infos = return_value.GetScalar().ULong(); - if (log) - log->Printf("Discovered %u ObjC classes in shared cache\n", - num_class_infos); + LLDB_LOGF(log, "Discovered %u ObjC classes in shared cache\n", + num_class_infos); assert(num_class_infos <= num_classes); if (num_class_infos > 0) { if (num_class_infos > num_classes) { @@ -1786,13 +1782,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { } } else { if (log) { - log->Printf("Error evaluating our find class name function."); + LLDB_LOGF(log, "Error evaluating our find class name function."); diagnostics.Dump(log); } } } else { if (log) { - log->Printf("Error writing function arguments."); + LLDB_LOGF(log, "Error writing function arguments."); diagnostics.Dump(log); } } @@ -1827,9 +1823,10 @@ bool AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory( new ClassDescriptorV2(*this, elt.second, elt.first.AsCString())); if (log && log->GetVerbose()) - log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 - " (%s) from dynamic table to isa->descriptor cache", - elt.second, elt.first.AsCString()); + LLDB_LOGF(log, + "AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 + " (%s) from dynamic table to isa->descriptor cache", + elt.second, elt.first.AsCString()); AddClass(elt.second, descriptor_sp, elt.first.AsCString()); } @@ -1912,14 +1909,14 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { DescriptorMapUpdateResult shared_cache_update_result = UpdateISAToDescriptorMapSharedCache(); - if (log) - log->Printf("attempted to read objc class data - results: " - "[dynamic_update]: ran: %s, count: %" PRIu32 - " [shared_cache_update]: ran: %s, count: %" PRIu32, - dynamic_update_result.m_update_ran ? "yes" : "no", - dynamic_update_result.m_num_found, - shared_cache_update_result.m_update_ran ? "yes" : "no", - shared_cache_update_result.m_num_found); + LLDB_LOGF(log, + "attempted to read objc class data - results: " + "[dynamic_update]: ran: %s, count: %" PRIu32 + " [shared_cache_update]: ran: %s, count: %" PRIu32, + dynamic_update_result.m_update_ran ? "yes" : "no", + dynamic_update_result.m_num_found, + shared_cache_update_result.m_update_ran ? "yes" : "no", + shared_cache_update_result.m_num_found); // warn if: // - we could not run either expression @@ -2032,8 +2029,8 @@ lldb::addr_t AppleObjCRuntimeV2::LookupRuntimeSymbol(ConstString name) { if (name_cstr) { llvm::StringRef name_strref(name_cstr); - static const llvm::StringRef ivar_prefix("OBJC_IVAR_$_"); - static const llvm::StringRef class_prefix("OBJC_CLASS_$_"); + llvm::StringRef ivar_prefix("OBJC_IVAR_$_"); + llvm::StringRef class_prefix("OBJC_CLASS_$_"); if (name_strref.startswith(ivar_prefix)) { llvm::StringRef ivar_skipped_prefix = @@ -2516,8 +2513,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( ObjCISA isa, ObjCISA &ret_isa) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); - if (log) - log->Printf("AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa); + LLDB_LOGF(log, "AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa); if ((isa & ~m_objc_debug_isa_class_mask) == 0) return false; @@ -2543,10 +2539,10 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( // read the count again, and update the cache if the count has been // updated. if (index > m_indexed_isa_cache.size()) { - if (log) - log->Printf("AOCRT::NPI (index = %" PRIu64 - ") exceeds cache (size = %" PRIu64 ")", - (uint64_t)index, (uint64_t)m_indexed_isa_cache.size()); + LLDB_LOGF(log, + "AOCRT::NPI (index = %" PRIu64 + ") exceeds cache (size = %" PRIu64 ")", + (uint64_t)index, (uint64_t)m_indexed_isa_cache.size()); Process *process(m_runtime.GetProcess()); @@ -2561,9 +2557,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( if (error.Fail()) return false; - if (log) - log->Printf("AOCRT::NPI (new class count = %" PRIu64 ")", - (uint64_t)objc_indexed_classes_count); + LLDB_LOGF(log, "AOCRT::NPI (new class count = %" PRIu64 ")", + (uint64_t)objc_indexed_classes_count); if (objc_indexed_classes_count > m_indexed_isa_cache.size()) { // Read the class entries we don't have. We should just read all of @@ -2581,9 +2576,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( if (error.Fail() || bytes_read != buffer.GetByteSize()) return false; - if (log) - log->Printf("AOCRT::NPI (read new classes count = %" PRIu64 ")", - (uint64_t)num_new_classes); + LLDB_LOGF(log, "AOCRT::NPI (read new classes count = %" PRIu64 ")", + (uint64_t)num_new_classes); // Append the new entries to the existing cache. DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(), @@ -2600,9 +2594,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( if (index > m_indexed_isa_cache.size()) return false; - if (log) - log->Printf("AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")", - (uint64_t)m_indexed_isa_cache[index]); + LLDB_LOGF(log, "AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")", + (uint64_t)m_indexed_isa_cache[index]); ret_isa = m_indexed_isa_cache[index]; return (ret_isa != 0); // this is a pointer so 0 is not a valid value @@ -2647,8 +2640,9 @@ bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() { std::function<lldb::addr_t(ConstString)> get_symbol = [this](ConstString sym) -> lldb::addr_t { SymbolContextList sc_list; - if (GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType( - sym, lldb::eSymbolTypeData, sc_list) == 1) { + GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType( + sym, lldb::eSymbolTypeData, sc_list); + if (sc_list.GetSize() == 1) { SymbolContext sc; sc_list.GetContextAtIndex(0, sc); if (sc.symbol) diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index b3eb09caa86d..379ef3dca86c 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -543,7 +543,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines( Status error; DataExtractor data; error = argument_values.GetValueAtIndex(0)->GetValueAsData(&exe_ctx, data, - 0, nullptr); + nullptr); lldb::offset_t offset = 0; lldb::addr_t region_addr = data.GetPointer(&offset); @@ -593,7 +593,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions( if (log) { StreamString s; m_regions.back().Dump(s); - log->Printf("Read vtable region: \n%s", s.GetData()); + LLDB_LOGF(log, "Read vtable region: \n%s", s.GetData()); } next_region = m_regions.back().GetNextRegionAddr(); @@ -704,7 +704,7 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler( // step through any method dispatches. Warn to that effect and get out of // here. if (process_sp->CanJIT()) { - process_sp->GetTarget().GetDebugger().GetErrorFile()->Printf( + process_sp->GetTarget().GetDebugger().GetErrorStream().Printf( "Could not find implementation lookup function \"%s\"" " step in through ObjC method dispatch will not work.\n", get_impl_name.AsCString()); @@ -779,25 +779,24 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, m_lookup_implementation_function_code, eLanguageTypeObjC, g_lookup_implementation_function_name, error)); if (error.Fail()) { - if (log) - log->Printf( - "Failed to get Utility Function for implementation lookup: %s.", - error.AsCString()); + LLDB_LOGF( + log, + "Failed to get Utility Function for implementation lookup: %s.", + error.AsCString()); m_impl_code.reset(); return args_addr; } if (!m_impl_code->Install(diagnostics, exe_ctx)) { if (log) { - log->Printf("Failed to install implementation lookup."); + LLDB_LOGF(log, "Failed to install implementation lookup."); diagnostics.Dump(log); } m_impl_code.reset(); return args_addr; } } else { - if (log) - log->Printf("No method lookup implementation code."); + LLDB_LOGF(log, "No method lookup implementation code."); return LLDB_INVALID_ADDRESS; } @@ -811,10 +810,9 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, impl_function_caller = m_impl_code->MakeFunctionCaller( clang_void_ptr_type, dispatch_values, thread_sp, error); if (error.Fail()) { - if (log) - log->Printf( - "Error getting function caller for dispatch lookup: \"%s\".", - error.AsCString()); + LLDB_LOGF(log, + "Error getting function caller for dispatch lookup: \"%s\".", + error.AsCString()); return args_addr; } } else { @@ -833,7 +831,7 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, if (!impl_function_caller->WriteFunctionArguments( exe_ctx, args_addr, dispatch_values, diagnostics)) { if (log) { - log->Printf("Error writing function arguments."); + LLDB_LOGF(log, "Error writing function arguments."); diagnostics.Dump(log); } return args_addr; @@ -934,9 +932,9 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, lldb::addr_t obj_addr = argument_values.GetValueAtIndex(obj_index)->GetScalar().ULongLong(); if (obj_addr == 0x0) { - if (log) - log->Printf( - "Asked to step to dispatch to nil object, returning empty plan."); + LLDB_LOGF( + log, + "Asked to step to dispatch to nil object, returning empty plan."); return ret_plan_sp; } @@ -976,13 +974,11 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, if (super_value.GetScalar().IsValid()) isa_addr = super_value.GetScalar().ULongLong(); else { - if (log) - log->Printf("Failed to extract the super class value from the " - "class in objc_super."); + LLDB_LOGF(log, "Failed to extract the super class value from the " + "class in objc_super."); } } else { - if (log) - log->Printf("Failed to extract the class value from objc_super."); + LLDB_LOGF(log, "Failed to extract the class value from objc_super."); } } else { // In the objc_msgSendSuper case, we don't get the object @@ -998,8 +994,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, if (super_value.GetScalar().IsValid()) { isa_addr = super_value.GetScalar().ULongLong(); } else { - if (log) - log->Printf("Failed to extract the class value from objc_super."); + LLDB_LOGF(log, "Failed to extract the class value from objc_super."); } } } else { @@ -1022,8 +1017,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, if (isa_value.GetScalar().IsValid()) { isa_addr = isa_value.GetScalar().ULongLong(); } else { - if (log) - log->Printf("Failed to extract the isa value from object."); + LLDB_LOGF(log, "Failed to extract the isa value from object."); } } @@ -1033,9 +1027,10 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, if (isa_addr != LLDB_INVALID_ADDRESS) { if (log) { - log->Printf("Resolving call for class - 0x%" PRIx64 - " and selector - 0x%" PRIx64, - isa_addr, sel_addr); + LLDB_LOGF(log, + "Resolving call for class - 0x%" PRIx64 + " and selector - 0x%" PRIx64, + isa_addr, sel_addr); } ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*thread.GetProcess()); @@ -1047,9 +1042,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, if (impl_addr != LLDB_INVALID_ADDRESS) { // Yup, it was in the cache, so we can run to that address directly. - if (log) - log->Printf("Found implementation address in cache: 0x%" PRIx64, - impl_addr); + LLDB_LOGF(log, "Found implementation address in cache: 0x%" PRIx64, + impl_addr); ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(thread, impl_addr, stop_others); @@ -1137,7 +1131,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, if (log) { StreamString s; ret_plan_sp->GetDescription(&s, eDescriptionLevelFull); - log->Printf("Using ObjC step plan: %s.\n", s.GetData()); + LLDB_LOGF(log, "Using ObjC step plan: %s.\n", s.GetData()); } } } diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp index 26654e9212b9..6402e80d6f98 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp @@ -18,7 +18,6 @@ #include <vector> using namespace lldb_private; -using namespace lldb_utility; AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser( ObjCLanguageRuntime &runtime) @@ -32,16 +31,14 @@ AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser( .c_str())); } -std::string -AppleObjCTypeEncodingParser::ReadStructName(lldb_utility::StringLexer &type) { +std::string AppleObjCTypeEncodingParser::ReadStructName(StringLexer &type) { StreamString buffer; while (type.HasAtLeast(1) && type.Peek() != '=') buffer.Printf("%c", type.Next()); return buffer.GetString(); } -std::string -AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer &type) { +std::string AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) { StreamString buffer; while (type.HasAtLeast(1) && type.Peek() != '"') buffer.Printf("%c", type.Next()); @@ -51,8 +48,7 @@ AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer &type) { return buffer.GetString(); } -uint32_t -AppleObjCTypeEncodingParser::ReadNumber(lldb_utility::StringLexer &type) { +uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) { uint32_t total = 0; while (type.HasAtLeast(1) && isdigit(type.Peek())) total = 10 * total + (type.Next() - '0'); @@ -68,7 +64,7 @@ AppleObjCTypeEncodingParser::StructElement::StructElement() AppleObjCTypeEncodingParser::StructElement AppleObjCTypeEncodingParser::ReadStructElement(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, + StringLexer &type, bool for_expression) { StructElement retval; if (type.NextIf('"')) @@ -81,25 +77,21 @@ AppleObjCTypeEncodingParser::ReadStructElement(clang::ASTContext &ast_ctx, return retval; } -clang::QualType -AppleObjCTypeEncodingParser::BuildStruct(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, - bool for_expression) { +clang::QualType AppleObjCTypeEncodingParser::BuildStruct( + clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) { return BuildAggregate(ast_ctx, type, for_expression, '{', '}', clang::TTK_Struct); } -clang::QualType -AppleObjCTypeEncodingParser::BuildUnion(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, - bool for_expression) { +clang::QualType AppleObjCTypeEncodingParser::BuildUnion( + clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) { return BuildAggregate(ast_ctx, type, for_expression, '(', ')', clang::TTK_Union); } clang::QualType AppleObjCTypeEncodingParser::BuildAggregate( - clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type, - bool for_expression, char opener, char closer, uint32_t kind) { + clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression, + char opener, char closer, uint32_t kind) { if (!type.NextIf(opener)) return clang::QualType(); std::string name(ReadStructName(type)); @@ -149,8 +141,9 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate( } ClangASTContext::AddFieldToRecordType( union_type, element.name.c_str(), - CompilerType(&ast_ctx, element.type), lldb::eAccessPublic, - element.bitfield); + CompilerType(ClangASTContext::GetASTContext(&ast_ctx), + element.type.getAsOpaquePtr()), + lldb::eAccessPublic, element.bitfield); ++count; } ClangASTContext::CompleteTagDeclarationDefinition(union_type); @@ -158,10 +151,8 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate( return ClangUtil::GetQualType(union_type); } -clang::QualType -AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, - bool for_expression) { +clang::QualType AppleObjCTypeEncodingParser::BuildArray( + clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) { if (!type.NextIf('[')) return clang::QualType(); uint32_t size = ReadNumber(type); @@ -172,7 +163,9 @@ AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx, if (!lldb_ctx) return clang::QualType(); CompilerType array_type(lldb_ctx->CreateArrayType( - CompilerType(&ast_ctx, element_type), size, false)); + CompilerType(ClangASTContext::GetASTContext(&ast_ctx), + element_type.getAsOpaquePtr()), + size, false)); return ClangUtil::GetQualType(array_type); } @@ -182,8 +175,7 @@ AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx, // consume but ignore the type info and always return an 'id'; if anything, // dynamic typing will resolve things for us anyway clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType( - clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type, - bool for_expression) { + clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) { if (!type.NextIf('@')) return clang::QualType(); @@ -375,7 +367,8 @@ CompilerType AppleObjCTypeEncodingParser::RealizeType( if (name && name[0]) { StringLexer lexer(name); clang::QualType qual_type = BuildType(ast_ctx, lexer, for_expression); - return CompilerType(&ast_ctx, qual_type); + return CompilerType(ClangASTContext::GetASTContext(&ast_ctx), + qual_type.getAsOpaquePtr()); } return CompilerType(); } diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h index e576e8f283f2..590bc4ba9eae 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h @@ -15,12 +15,8 @@ #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" -namespace lldb_utility { -class StringLexer; -} - namespace lldb_private { - +class StringLexer; class AppleObjCTypeEncodingParser : public ObjCLanguageRuntime::EncodingToType { public: AppleObjCTypeEncodingParser(ObjCLanguageRuntime &runtime); @@ -39,41 +35,35 @@ private: ~StructElement() = default; }; - clang::QualType BuildType(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, + clang::QualType BuildType(clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression, uint32_t *bitfield_bit_size = nullptr); - clang::QualType BuildStruct(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, + clang::QualType BuildStruct(clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression); - clang::QualType BuildAggregate(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, + clang::QualType BuildAggregate(clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression, char opener, char closer, uint32_t kind); - clang::QualType BuildUnion(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, + clang::QualType BuildUnion(clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression); - clang::QualType BuildArray(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, + clang::QualType BuildArray(clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression); - std::string ReadStructName(lldb_utility::StringLexer &type); + std::string ReadStructName(StringLexer &type); - StructElement ReadStructElement(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, + StructElement ReadStructElement(clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression); clang::QualType BuildObjCObjectPointerType(clang::ASTContext &ast_ctx, - lldb_utility::StringLexer &type, + StringLexer &type, bool for_expression); - uint32_t ReadNumber(lldb_utility::StringLexer &type); + uint32_t ReadNumber(StringLexer &type); - std::string ReadQuotedString(lldb_utility::StringLexer &type); + std::string ReadQuotedString(StringLexer &type); ObjCLanguageRuntime &m_runtime; }; diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp index d18435c9c6db..af630eee7265 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -141,17 +141,15 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr()); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (target_addr == 0) { - if (log) - log->Printf("Got target implementation of 0x0, stopping."); + LLDB_LOGF(log, "Got target implementation of 0x0, stopping."); SetPlanComplete(); return true; } if (m_trampoline_handler->AddrIsMsgForward(target_addr)) { - if (log) - log->Printf( - "Implementation lookup returned msgForward function: 0x%" PRIx64 - ", stopping.", - target_addr); + LLDB_LOGF(log, + "Implementation lookup returned msgForward function: 0x%" PRIx64 + ", stopping.", + target_addr); SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext( eSymbolContextEverything); @@ -167,18 +165,17 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { return false; } - if (log) - log->Printf("Running to ObjC method implementation: 0x%" PRIx64, - target_addr); + LLDB_LOGF(log, "Running to ObjC method implementation: 0x%" PRIx64, + target_addr); ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*GetThread().GetProcess()); assert(objc_runtime != nullptr); objc_runtime->AddToMethodCache(m_isa_addr, m_sel_addr, target_addr); - if (log) - log->Printf("Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64 - "} = addr=0x%" PRIx64 " to cache.", - m_isa_addr, m_sel_addr, target_addr); + LLDB_LOGF(log, + "Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64 + "} = addr=0x%" PRIx64 " to cache.", + m_isa_addr, m_sel_addr, target_addr); // Extract the target address from the value: diff --git a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp index 631c15c46ce8..87ae4c2c6c48 100644 --- a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp @@ -64,9 +64,10 @@ void ObjCLanguageRuntime::AddToMethodCache(lldb::addr_t class_addr, lldb::addr_t impl_addr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log) { - log->Printf("Caching: class 0x%" PRIx64 " selector 0x%" PRIx64 - " implementation 0x%" PRIx64 ".", - class_addr, selector, impl_addr); + LLDB_LOGF(log, + "Caching: class 0x%" PRIx64 " selector 0x%" PRIx64 + " implementation 0x%" PRIx64 ".", + class_addr, selector, impl_addr); } m_impl_cache.insert(std::pair<ClassAndSel, lldb::addr_t>( ClassAndSel(class_addr, selector), impl_addr)); @@ -102,8 +103,8 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) { const ModuleList &modules = m_process->GetTarget().GetImages(); SymbolContextList sc_list; - const size_t matching_symbols = - modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list); + modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list); + const size_t matching_symbols = sc_list.GetSize(); if (matching_symbols) { SymbolContext sc; @@ -120,20 +121,17 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) { TypeList types; llvm::DenseSet<SymbolFile *> searched_symbol_files; - const uint32_t num_types = module_sp->FindTypes( - name, exact_match, max_matches, searched_symbol_files, types); - - if (num_types) { - uint32_t i; - for (i = 0; i < num_types; ++i) { - TypeSP type_sp(types.GetTypeAtIndex(i)); - - if (ClangASTContext::IsObjCObjectOrInterfaceType( - type_sp->GetForwardCompilerType())) { - if (type_sp->IsCompleteObjCClass()) { - m_complete_class_cache[name] = type_sp; - return type_sp; - } + module_sp->FindTypes(name, exact_match, max_matches, searched_symbol_files, + types); + + for (uint32_t i = 0; i < types.GetSize(); ++i) { + TypeSP type_sp(types.GetTypeAtIndex(i)); + + if (ClangASTContext::IsObjCObjectOrInterfaceType( + type_sp->GetForwardCompilerType())) { + if (type_sp->IsCompleteObjCClass()) { + m_complete_class_cache[name] = type_sp; + return type_sp; } } } diff --git a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h index 1925c78ed342..39acd6e9f268 100644 --- a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h +++ b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h @@ -17,6 +17,7 @@ #include "llvm/Support/Casting.h" #include "lldb/Breakpoint/BreakpointPrecondition.h" +#include "lldb/Core/ClangForward.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Symbol/CompilerType.h" diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp index 60549663db66..b396781e6726 100644 --- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp +++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp @@ -140,10 +140,10 @@ bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) { // We've been using a triple and datalayout of some ARM variant all along, // so we need to let the backend know that this is no longer the case. if (log) { - log->Printf("%s - Changing RS target triple to '%s'", __FUNCTION__, - real_triple.str().c_str()); - log->Printf( - "%s - Changing RS datalayout to '%s'", __FUNCTION__, + LLDB_LOGF(log, "%s - Changing RS target triple to '%s'", __FUNCTION__, + real_triple.str().c_str()); + LLDB_LOGF( + log, "%s - Changing RS datalayout to '%s'", __FUNCTION__, target_machine->createDataLayout().getStringRepresentation().c_str()); } module.setTargetTriple(real_triple); diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp index c9cd34cf379d..5200749d759f 100644 --- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp @@ -138,9 +138,8 @@ bool GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { size_t read = ctx.process->ReadMemory(sp, &arg.value, sizeof(uint32_t), err); if (read != arg_size || !err.Success()) { - if (log) - log->Printf("%s - error reading argument: %" PRIu64 " '%s'", - __FUNCTION__, uint64_t(i), err.AsCString()); + LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 " '%s'", + __FUNCTION__, uint64_t(i), err.AsCString()); return false; } } @@ -173,8 +172,7 @@ bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { // check the stack alignment was correct (16 byte aligned) if ((sp & 0xf) != 0x0) { - if (log) - log->Printf("%s - stack misaligned", __FUNCTION__); + LLDB_LOGF(log, "%s - stack misaligned", __FUNCTION__); return false; } @@ -213,9 +211,8 @@ bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { } // fail if we couldn't read this argument if (!success) { - if (log) - log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s", - __FUNCTION__, uint64_t(i), err.AsCString("n/a")); + LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s", + __FUNCTION__, uint64_t(i), err.AsCString("n/a")); return false; } } @@ -258,9 +255,8 @@ bool GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { } // fail if we couldn't read this argument if (!success) { - if (log) - log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s", - __FUNCTION__, uint64_t(i), err.AsCString("n/a")); + LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s", + __FUNCTION__, uint64_t(i), err.AsCString("n/a")); return false; } } @@ -285,15 +281,13 @@ bool GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { } // arguments passed on the stack else { - if (log) - log->Printf("%s - reading arguments spilled to stack not implemented", - __FUNCTION__); + LLDB_LOGF(log, "%s - reading arguments spilled to stack not implemented", + __FUNCTION__); } // fail if we couldn't read this argument if (!success) { - if (log) - log->Printf("%s - error reading argument: %" PRIu64, __FUNCTION__, - uint64_t(i)); + LLDB_LOGF(log, "%s - error reading argument: %" PRIu64, __FUNCTION__, + uint64_t(i)); return false; } } @@ -337,9 +331,8 @@ bool GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { } // fail if we couldn't read this argument if (!success) { - if (log) - log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s", - __FUNCTION__, uint64_t(i), err.AsCString("n/a")); + LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s", + __FUNCTION__, uint64_t(i), err.AsCString("n/a")); return false; } } @@ -385,9 +378,8 @@ bool GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { } // fail if we couldn't read this argument if (!success) { - if (log) - log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s", - __FUNCTION__, uint64_t(i), err.AsCString("n/a")); + LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s", + __FUNCTION__, uint64_t(i), err.AsCString("n/a")); return false; } } @@ -399,8 +391,7 @@ bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) { // verify that we have a target if (!exe_ctx.GetTargetPtr()) { - if (log) - log->Printf("%s - invalid target", __FUNCTION__); + LLDB_LOGF(log, "%s - invalid target", __FUNCTION__); return false; } @@ -430,9 +421,8 @@ bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) { default: // unsupported architecture if (log) { - log->Printf( - "%s - architecture not supported: '%s'", __FUNCTION__, - exe_ctx.GetTargetRef().GetArchitecture().GetArchitectureName()); + LLDB_LOGF(log, "%s - architecture not supported: '%s'", __FUNCTION__, + exe_ctx.GetTargetRef().GetArchitecture().GetArchitectureName()); } return false; } @@ -452,28 +442,20 @@ bool ParseCoordinate(llvm::StringRef coord_s, RSCoordinate &coord) { // elements fails the contents of &coord are undefined and `false` is // returned, `true` otherwise - RegularExpression regex; - RegularExpression::Match regex_match(3); - - bool matched = false; - if (regex.Compile(llvm::StringRef("^([0-9]+),([0-9]+),([0-9]+)$")) && - regex.Execute(coord_s, ®ex_match)) - matched = true; - else if (regex.Compile(llvm::StringRef("^([0-9]+),([0-9]+)$")) && - regex.Execute(coord_s, ®ex_match)) - matched = true; - else if (regex.Compile(llvm::StringRef("^([0-9]+)$")) && - regex.Execute(coord_s, ®ex_match)) - matched = true; - - if (!matched) + llvm::SmallVector<llvm::StringRef, 4> matches; + + if (!RegularExpression("^([0-9]+),([0-9]+),([0-9]+)$") + .Execute(coord_s, &matches) && + !RegularExpression("^([0-9]+),([0-9]+)$").Execute(coord_s, &matches) && + !RegularExpression("^([0-9]+)$").Execute(coord_s, &matches)) return false; - auto get_index = [&](int idx, uint32_t &i) -> bool { + auto get_index = [&](size_t idx, uint32_t &i) -> bool { std::string group; errno = 0; - if (regex_match.GetMatchAtIndex(coord_s.str().c_str(), idx + 1, group)) - return !llvm::StringRef(group).getAsInteger<uint32_t>(10, i); + if (idx + 1 < matches.size()) { + return !llvm::StringRef(matches[idx + 1]).getAsInteger<uint32_t>(10, i); + } return true; }; @@ -492,9 +474,8 @@ bool SkipPrologue(lldb::ModuleSP &module, Address &addr) { ConstString name = sc.GetFunctionName(); if (offset) addr.Slide(offset); - if (log) - log->Printf("%s: Prologue offset for %s is %" PRIu32, __FUNCTION__, - name.AsCString(), offset); + LLDB_LOGF(log, "%s: Prologue offset for %s is %" PRIu32, __FUNCTION__, + name.AsCString(), offset); } return true; } else @@ -809,7 +790,7 @@ RenderScriptRuntime::CreateInstance(Process *process, // symbol. Searcher::CallbackReturn RSBreakpointResolver::SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *, bool) { + SymbolContext &context, Address *) { ModuleSP module = context.module_sp; if (!module || !IsRenderScriptScriptModule(module)) @@ -839,7 +820,7 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter, Searcher::CallbackReturn RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, lldb_private::SymbolContext &context, - Address *, bool) { + Address *) { // We need to have access to the list of reductions currently parsed, as // reduce names don't actually exist as symbols in a module. They are only // identifiable by parsing the .rs.info packet, or finding the expand symbol. @@ -884,14 +865,13 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, if (filter.AddressPasses(address)) { bool new_bp; if (!SkipPrologue(module, address)) { - if (log) - log->Printf("%s: Error trying to skip prologue", __FUNCTION__); + LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__); } m_breakpoint->AddLocation(address, &new_bp); - if (log) - log->Printf("%s: %s reduction breakpoint on %s in %s", __FUNCTION__, - new_bp ? "new" : "existing", kernel_name.GetCString(), - address.GetModule()->GetFileSpec().GetCString()); + LLDB_LOGF(log, "%s: %s reduction breakpoint on %s in %s", + __FUNCTION__, new_bp ? "new" : "existing", + kernel_name.GetCString(), + address.GetModule()->GetFileSpec().GetCString()); } } } @@ -900,8 +880,7 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, } Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( - SearchFilter &filter, SymbolContext &context, Address *addr, - bool containing) { + SearchFilter &filter, SymbolContext &context, Address *addr) { if (!m_breakpoint) return eCallbackReturnContinue; @@ -920,48 +899,43 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( for (auto &name : names) { const RSScriptGroupDescriptorSP sg = FindScriptGroup(ConstString(name)); if (!sg) { - if (log) - log->Printf("%s: could not find script group for %s", __FUNCTION__, - name.c_str()); + LLDB_LOGF(log, "%s: could not find script group for %s", __FUNCTION__, + name.c_str()); continue; } - if (log) - log->Printf("%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str()); + LLDB_LOGF(log, "%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str()); for (const RSScriptGroupDescriptor::Kernel &k : sg->m_kernels) { if (log) { - log->Printf("%s: Adding breakpoint for %s", __FUNCTION__, - k.m_name.AsCString()); - log->Printf("%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr); + LLDB_LOGF(log, "%s: Adding breakpoint for %s", __FUNCTION__, + k.m_name.AsCString()); + LLDB_LOGF(log, "%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr); } const lldb_private::Symbol *sym = module->FindFirstSymbolWithNameAndType(k.m_name, eSymbolTypeCode); if (!sym) { - if (log) - log->Printf("%s: Unable to find symbol for %s", __FUNCTION__, - k.m_name.AsCString()); + LLDB_LOGF(log, "%s: Unable to find symbol for %s", __FUNCTION__, + k.m_name.AsCString()); continue; } if (log) { - log->Printf("%s: Found symbol name is %s", __FUNCTION__, - sym->GetName().AsCString()); + LLDB_LOGF(log, "%s: Found symbol name is %s", __FUNCTION__, + sym->GetName().AsCString()); } auto address = sym->GetAddress(); if (!SkipPrologue(module, address)) { - if (log) - log->Printf("%s: Error trying to skip prologue", __FUNCTION__); + LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__); } bool new_bp; m_breakpoint->AddLocation(address, &new_bp); - if (log) - log->Printf("%s: Placed %sbreakpoint on %s", __FUNCTION__, - new_bp ? "new " : "", k.m_name.AsCString()); + LLDB_LOGF(log, "%s: Placed %sbreakpoint on %s", __FUNCTION__, + new_bp ? "new " : "", k.m_name.AsCString()); // exit after placing the first breakpoint if we do not intend to stop on // all kernels making up this script group @@ -1136,8 +1110,7 @@ void RenderScriptRuntime::HookCallback(RuntimeHook *hook, ExecutionContext &exe_ctx) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); - if (log) - log->Printf("%s - '%s'", __FUNCTION__, hook->defn->name); + LLDB_LOGF(log, "%s - '%s'", __FUNCTION__, hook->defn->name); if (hook->defn->grabber) { (this->*(hook->defn->grabber))(hook, exe_ctx); @@ -1163,19 +1136,18 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2( }}; if (!GetArgs(context, args.data(), args.size())) { - if (log) - log->Printf("%s - Error while reading the function parameters", - __FUNCTION__); + LLDB_LOGF(log, "%s - Error while reading the function parameters", + __FUNCTION__); return; } else if (log) { - log->Printf("%s - groupName : 0x%" PRIx64, __FUNCTION__, - addr_t(args[eGroupName])); - log->Printf("%s - groupNameSize: %" PRIu64, __FUNCTION__, - uint64_t(args[eGroupNameSize])); - log->Printf("%s - kernel : 0x%" PRIx64, __FUNCTION__, - addr_t(args[eKernel])); - log->Printf("%s - kernelCount : %" PRIu64, __FUNCTION__, - uint64_t(args[eKernelCount])); + LLDB_LOGF(log, "%s - groupName : 0x%" PRIx64, __FUNCTION__, + addr_t(args[eGroupName])); + LLDB_LOGF(log, "%s - groupNameSize: %" PRIu64, __FUNCTION__, + uint64_t(args[eGroupNameSize])); + LLDB_LOGF(log, "%s - kernel : 0x%" PRIx64, __FUNCTION__, + addr_t(args[eKernel])); + LLDB_LOGF(log, "%s - kernelCount : %" PRIu64, __FUNCTION__, + uint64_t(args[eKernelCount])); } // parse script group name @@ -1187,12 +1159,10 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2( m_process->ReadMemory(addr_t(args[eGroupName]), buffer.get(), len, err); buffer.get()[len] = '\0'; if (!err.Success()) { - if (log) - log->Printf("Error reading scriptgroup name from target"); + LLDB_LOGF(log, "Error reading scriptgroup name from target"); return; } else { - if (log) - log->Printf("Extracted scriptgroup name %s", buffer.get()); + LLDB_LOGF(log, "Extracted scriptgroup name %s", buffer.get()); } // write back the script group name group_name.SetCString(buffer.get()); @@ -1214,9 +1184,8 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2( m_scriptGroups.push_back(group); } else { // already have this script group - if (log) - log->Printf("Attempt to add duplicate script group %s", - group_name.AsCString()); + LLDB_LOGF(log, "Attempt to add duplicate script group %s", + group_name.AsCString()); return; } } @@ -1234,21 +1203,18 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2( size_t read = m_process->ReadMemory(ptr_addr, &kernel_addr, target_ptr_size, err); if (!err.Success() || read != target_ptr_size) { - if (log) - log->Printf("Error parsing kernel address %" PRIu64 " in script group", - i); + LLDB_LOGF(log, "Error parsing kernel address %" PRIu64 " in script group", + i); return; } - if (log) - log->Printf("Extracted scriptgroup kernel address - 0x%" PRIx64, - kernel_addr); + LLDB_LOGF(log, "Extracted scriptgroup kernel address - 0x%" PRIx64, + kernel_addr); kernel.m_addr = kernel_addr; // try to resolve the associated kernel name if (!ResolveKernelName(kernel.m_addr, kernel.m_name)) { - if (log) - log->Printf("Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i, - kernel_addr); + LLDB_LOGF(log, "Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i, + kernel_addr); return; } @@ -1261,9 +1227,8 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2( // verify this function is a valid kernel if (IsKnownKernel(base_kernel)) { kernel.m_name = base_kernel; - if (log) - log->Printf("%s - found non expand version '%s'", __FUNCTION__, - base_kernel.GetCString()); + LLDB_LOGF(log, "%s - found non expand version '%s'", __FUNCTION__, + base_kernel.GetCString()); } } } @@ -1276,15 +1241,13 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2( Target &target = m_process->GetTarget(); const BreakpointList &list = target.GetBreakpointList(); const size_t num_breakpoints = list.GetSize(); - if (log) - log->Printf("Resolving %zu breakpoints", num_breakpoints); + LLDB_LOGF(log, "Resolving %zu breakpoints", num_breakpoints); for (size_t i = 0; i < num_breakpoints; ++i) { const BreakpointSP bp = list.GetBreakpointAtIndex(i); if (bp) { if (bp->MatchesName(group_name.AsCString())) { - if (log) - log->Printf("Found breakpoint with name %s", - group_name.AsCString()); + LLDB_LOGF(log, "Found breakpoint with name %s", + group_name.AsCString()); bp->ResolveBreakpoint(); } } @@ -1322,9 +1285,8 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti( bool success = GetArgs(exe_ctx, &args[0], args.size()); if (!success) { - if (log) - log->Printf("%s - Error while reading the function parameters", - __FUNCTION__); + LLDB_LOGF(log, "%s - Error while reading the function parameters", + __FUNCTION__); return; } @@ -1342,10 +1304,9 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti( uint64_t result = 0; size_t read = m_process->ReadMemory(addr, &result, target_ptr_size, err); if (read != target_ptr_size || !err.Success()) { - if (log) - log->Printf( - "%s - Error while reading allocation list argument %" PRIu64, - __FUNCTION__, i); + LLDB_LOGF(log, + "%s - Error while reading allocation list argument %" PRIu64, + __FUNCTION__, i); } else { allocs.push_back(result); } @@ -1375,8 +1336,8 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti( if (log) { if (alloc->context.isValid() && *alloc->context.get() != addr_t(args[eRsContext])) - log->Printf("%s - Allocation used by multiple contexts", - __FUNCTION__); + LLDB_LOGF(log, "%s - Allocation used by multiple contexts", + __FUNCTION__); } alloc->context = addr_t(args[eRsContext]); } @@ -1388,7 +1349,7 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti( if (log) { if (script->context.isValid() && *script->context.get() != addr_t(args[eRsContext])) - log->Printf("%s - Script used by multiple contexts", __FUNCTION__); + LLDB_LOGF(log, "%s - Script used by multiple contexts", __FUNCTION__); } script->context = addr_t(args[eRsContext]); } @@ -1416,26 +1377,26 @@ void RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook, bool success = GetArgs(context, &args[0], args.size()); if (!success) { - if (log) - log->Printf("%s - error reading the function parameters.", __FUNCTION__); + LLDB_LOGF(log, "%s - error reading the function parameters.", __FUNCTION__); return; } if (log) { - log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 - ":%" PRIu64 "bytes.", - __FUNCTION__, uint64_t(args[eRsContext]), - uint64_t(args[eRsScript]), uint64_t(args[eRsId]), - uint64_t(args[eRsData]), uint64_t(args[eRsLength])); + LLDB_LOGF(log, + "%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 + ":%" PRIu64 "bytes.", + __FUNCTION__, uint64_t(args[eRsContext]), + uint64_t(args[eRsScript]), uint64_t(args[eRsId]), + uint64_t(args[eRsData]), uint64_t(args[eRsLength])); addr_t script_addr = addr_t(args[eRsScript]); if (m_scriptMappings.find(script_addr) != m_scriptMappings.end()) { auto rsm = m_scriptMappings[script_addr]; if (uint64_t(args[eRsId]) < rsm->m_globals.size()) { auto rsg = rsm->m_globals[uint64_t(args[eRsId])]; - log->Printf("%s - Setting of '%s' within '%s' inferred", __FUNCTION__, - rsg.m_name.AsCString(), - rsm->m_module->GetFileSpec().GetFilename().AsCString()); + LLDB_LOGF(log, "%s - Setting of '%s' within '%s' inferred", + __FUNCTION__, rsg.m_name.AsCString(), + rsm->m_module->GetFileSpec().GetFilename().AsCString()); } } } @@ -1455,16 +1416,14 @@ void RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook, bool success = GetArgs(exe_ctx, &args[0], args.size()); if (!success) { - if (log) - log->Printf("%s - error while reading the function parameters", - __FUNCTION__); + LLDB_LOGF(log, "%s - error while reading the function parameters", + __FUNCTION__); return; } - if (log) - log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", - __FUNCTION__, uint64_t(args[eRsContext]), - uint64_t(args[eRsAlloc]), uint64_t(args[eRsForceZero])); + LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", + __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]), + uint64_t(args[eRsForceZero])); AllocationDetails *alloc = CreateAllocation(uint64_t(args[eRsAlloc])); if (alloc) @@ -1487,29 +1446,25 @@ void RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook, bool success = GetArgs(exe_ctx, &args[0], args.size()); if (!success) { - if (log) - log->Printf("%s - error while reading the function parameters.", - __FUNCTION__); + LLDB_LOGF(log, "%s - error while reading the function parameters.", + __FUNCTION__); return; } - if (log) - log->Printf("%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__, - uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc])); + LLDB_LOGF(log, "%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__, + uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc])); for (auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter) { auto &allocation_up = *iter; // get the unique pointer if (allocation_up->address.isValid() && *allocation_up->address.get() == addr_t(args[eRsAlloc])) { m_allocations.erase(iter); - if (log) - log->Printf("%s - deleted allocation entry.", __FUNCTION__); + LLDB_LOGF(log, "%s - deleted allocation entry.", __FUNCTION__); return; } } - if (log) - log->Printf("%s - couldn't find destroyed allocation.", __FUNCTION__); + LLDB_LOGF(log, "%s - couldn't find destroyed allocation.", __FUNCTION__); } void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook, @@ -1526,32 +1481,28 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook, ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}}; bool success = GetArgs(exe_ctx, &args[0], args.size()); if (!success) { - if (log) - log->Printf("%s - error while reading the function parameters.", - __FUNCTION__); + LLDB_LOGF(log, "%s - error while reading the function parameters.", + __FUNCTION__); return; } std::string res_name; process->ReadCStringFromMemory(addr_t(args[eRsResNamePtr]), res_name, err); if (err.Fail()) { - if (log) - log->Printf("%s - error reading res_name: %s.", __FUNCTION__, - err.AsCString()); + LLDB_LOGF(log, "%s - error reading res_name: %s.", __FUNCTION__, + err.AsCString()); } std::string cache_dir; process->ReadCStringFromMemory(addr_t(args[eRsCachedDirPtr]), cache_dir, err); if (err.Fail()) { - if (log) - log->Printf("%s - error reading cache_dir: %s.", __FUNCTION__, - err.AsCString()); + LLDB_LOGF(log, "%s - error reading cache_dir: %s.", __FUNCTION__, + err.AsCString()); } - if (log) - log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", - __FUNCTION__, uint64_t(args[eRsContext]), - uint64_t(args[eRsScript]), res_name.c_str(), cache_dir.c_str()); + LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", + __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsScript]), + res_name.c_str(), cache_dir.c_str()); if (res_name.size() > 0) { StreamString strm; @@ -1566,13 +1517,14 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook, script->context = addr_t(args[eRsContext]); } - if (log) - log->Printf("%s - '%s' tagged with context 0x%" PRIx64 - " and script 0x%" PRIx64 ".", - __FUNCTION__, strm.GetData(), uint64_t(args[eRsContext]), - uint64_t(args[eRsScript])); + LLDB_LOGF(log, + "%s - '%s' tagged with context 0x%" PRIx64 + " and script 0x%" PRIx64 ".", + __FUNCTION__, strm.GetData(), uint64_t(args[eRsContext]), + uint64_t(args[eRsScript])); } else if (log) { - log->Printf("%s - resource name invalid, Script not tagged.", __FUNCTION__); + LLDB_LOGF(log, "%s - resource name invalid, Script not tagged.", + __FUNCTION__); } } @@ -1593,8 +1545,7 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, machine != llvm::Triple::ArchType::mipsel && machine != llvm::Triple::ArchType::mips64el && machine != llvm::Triple::ArchType::x86_64) { - if (log) - log->Printf("%s - unable to hook runtime functions.", __FUNCTION__); + LLDB_LOGF(log, "%s - unable to hook runtime functions.", __FUNCTION__); return; } @@ -1618,23 +1569,22 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ConstString(symbol_name), eSymbolTypeCode); if (!sym) { if (log) { - log->Printf("%s - symbol '%s' related to the function %s not found", - __FUNCTION__, symbol_name, hook_defn->name); + LLDB_LOGF(log, "%s - symbol '%s' related to the function %s not found", + __FUNCTION__, symbol_name, hook_defn->name); } continue; } addr_t addr = sym->GetLoadAddress(&target); if (addr == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf("%s - unable to resolve the address of hook function '%s' " - "with symbol '%s'.", - __FUNCTION__, hook_defn->name, symbol_name); + LLDB_LOGF(log, + "%s - unable to resolve the address of hook function '%s' " + "with symbol '%s'.", + __FUNCTION__, hook_defn->name, symbol_name); continue; } else { - if (log) - log->Printf("%s - function %s, address resolved at 0x%" PRIx64, - __FUNCTION__, hook_defn->name, addr); + LLDB_LOGF(log, "%s - function %s, address resolved at 0x%" PRIx64, + __FUNCTION__, hook_defn->name, addr); } RuntimeHookSP hook(new RuntimeHook()); @@ -1644,11 +1594,12 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, hook->bp_sp->SetCallback(HookCallback, hook.get(), true); m_runtimeHooks[addr] = hook; if (log) { - log->Printf("%s - successfully hooked '%s' in '%s' version %" PRIu64 - " at 0x%" PRIx64 ".", - __FUNCTION__, hook_defn->name, - module->GetFileSpec().GetFilename().AsCString(), - (uint64_t)hook_defn->version, (uint64_t)addr); + LLDB_LOGF(log, + "%s - successfully hooked '%s' in '%s' version %" PRIu64 + " at 0x%" PRIx64 ".", + __FUNCTION__, hook_defn->name, + module->GetFileSpec().GetFilename().AsCString(), + (uint64_t)hook_defn->version, (uint64_t)addr); } hook_placed[idx] = true; } @@ -1661,8 +1612,8 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, const HookDefn &hook_defn = s_runtimeHookDefns[i]; if (hook_defn.kind != kind) continue; - log->Printf("%s - function %s was not hooked", __FUNCTION__, - hook_defn.name); + LLDB_LOGF(log, "%s - function %s was not hooked", __FUNCTION__, + hook_defn.name); } } } @@ -1697,11 +1648,11 @@ void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) { if (m_scriptMappings.find(script) != m_scriptMappings.end()) { // if the module we have stored is different to the one we just received. if (m_scriptMappings[script] != rsmodule_sp) { - if (log) - log->Printf( - "%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.", - __FUNCTION__, (uint64_t)script, - rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); + LLDB_LOGF( + log, + "%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.", + __FUNCTION__, (uint64_t)script, + rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); } } // We don't have a script mapping for the current script. @@ -1713,11 +1664,9 @@ void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) { rsmodule_sp->m_resname = res_name; // Add Script/Module pair to map. m_scriptMappings[script] = rsmodule_sp; - if (log) - log->Printf( - "%s - script %" PRIx64 " associated with rsmodule '%s'.", - __FUNCTION__, (uint64_t)script, - rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); + LLDB_LOGF(log, "%s - script %" PRIx64 " associated with rsmodule '%s'.", + __FUNCTION__, (uint64_t)script, + rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); } } } @@ -1730,8 +1679,7 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr, StackFrame *frame_ptr, uint64_t *result) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); - if (log) - log->Printf("%s(%s)", __FUNCTION__, expr); + LLDB_LOGF(log, "%s(%s)", __FUNCTION__, expr); ValueObjectSP expr_result; EvaluateExpressionOptions options; @@ -1741,8 +1689,7 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr, target.EvaluateExpression(expr, frame_ptr, expr_result, options); if (!expr_result) { - if (log) - log->Printf("%s: couldn't evaluate expression.", __FUNCTION__); + LLDB_LOGF(log, "%s: couldn't evaluate expression.", __FUNCTION__); return false; } @@ -1751,16 +1698,14 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr, Status err = expr_result->GetError(); // Expression returned is void, so this is actually a success if (err.GetError() == UserExpression::kNoResult) { - if (log) - log->Printf("%s - expression returned void.", __FUNCTION__); + LLDB_LOGF(log, "%s - expression returned void.", __FUNCTION__); result = nullptr; return true; } - if (log) - log->Printf("%s - error evaluating expression result: %s", __FUNCTION__, - err.AsCString()); + LLDB_LOGF(log, "%s - error evaluating expression result: %s", __FUNCTION__, + err.AsCString()); return false; } @@ -1769,9 +1714,8 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr, *result = expr_result->GetValueAsUnsigned(0, &success); if (!success) { - if (log) - log->Printf("%s - couldn't convert expression result to uint32_t", - __FUNCTION__); + LLDB_LOGF(log, "%s - couldn't convert expression result to uint32_t", + __FUNCTION__); return false; } @@ -1884,8 +1828,7 @@ bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc, Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); if (!alloc->address.isValid()) { - if (log) - log->Printf("%s - failed to find allocation details.", __FUNCTION__); + LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); return false; } @@ -1895,12 +1838,10 @@ bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc, int written = snprintf(expr_buf, jit_max_expr_size, fmt_str, *alloc->address.get(), x, y, z); if (written < 0) { - if (log) - log->Printf("%s - encoding error in snprintf().", __FUNCTION__); + LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); return false; } else if (written >= jit_max_expr_size) { - if (log) - log->Printf("%s - expression too long.", __FUNCTION__); + LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); return false; } @@ -1922,8 +1863,7 @@ bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc, Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); if (!alloc->address.isValid() || !alloc->context.isValid()) { - if (log) - log->Printf("%s - failed to find allocation details.", __FUNCTION__); + LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); return false; } @@ -1933,12 +1873,10 @@ bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc, int written = snprintf(expr_buf, jit_max_expr_size, fmt_str, *alloc->context.get(), *alloc->address.get()); if (written < 0) { - if (log) - log->Printf("%s - encoding error in snprintf().", __FUNCTION__); + LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); return false; } else if (written >= jit_max_expr_size) { - if (log) - log->Printf("%s - expression too long.", __FUNCTION__); + LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); return false; } @@ -1960,8 +1898,7 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc, Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); if (!alloc->type_ptr.isValid() || !alloc->context.isValid()) { - if (log) - log->Printf("%s - Failed to find allocation details.", __FUNCTION__); + LLDB_LOGF(log, "%s - Failed to find allocation details.", __FUNCTION__); return false; } @@ -1983,12 +1920,10 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc, int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, *alloc->context.get(), bits, *alloc->type_ptr.get()); if (written < 0) { - if (log) - log->Printf("%s - encoding error in snprintf().", __FUNCTION__); + LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); return false; } else if (written >= jit_max_expr_size) { - if (log) - log->Printf("%s - expression too long.", __FUNCTION__); + LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); return false; } @@ -2007,10 +1942,10 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc, addr_t element_ptr = static_cast<lldb::addr_t>(results[3]); alloc->element.element_ptr = element_ptr; - if (log) - log->Printf("%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32 - ") Element*: 0x%" PRIx64 ".", - __FUNCTION__, dims.dim_1, dims.dim_2, dims.dim_3, element_ptr); + LLDB_LOGF(log, + "%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32 + ") Element*: 0x%" PRIx64 ".", + __FUNCTION__, dims.dim_1, dims.dim_2, dims.dim_3, element_ptr); return true; } @@ -2024,8 +1959,7 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem, Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); if (!elem.element_ptr.isValid()) { - if (log) - log->Printf("%s - failed to find allocation details.", __FUNCTION__); + LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); return false; } @@ -2042,12 +1976,10 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem, int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, context, *elem.element_ptr.get()); if (written < 0) { - if (log) - log->Printf("%s - encoding error in snprintf().", __FUNCTION__); + LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); return false; } else if (written >= jit_max_expr_size) { - if (log) - log->Printf("%s - expression too long.", __FUNCTION__); + LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); return false; } @@ -2063,11 +1995,11 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem, elem.type_vec_size = static_cast<uint32_t>(results[2]); elem.field_count = static_cast<uint32_t>(results[3]); - if (log) - log->Printf("%s - data type %" PRIu32 ", pixel type %" PRIu32 - ", vector size %" PRIu32 ", field count %" PRIu32, - __FUNCTION__, *elem.type.get(), *elem.type_kind.get(), - *elem.type_vec_size.get(), *elem.field_count.get()); + LLDB_LOGF(log, + "%s - data type %" PRIu32 ", pixel type %" PRIu32 + ", vector size %" PRIu32 ", field count %" PRIu32, + __FUNCTION__, *elem.type.get(), *elem.type_kind.get(), + *elem.type_vec_size.get(), *elem.field_count.get()); // If this Element has subelements then JIT rsaElementGetSubElements() for // details about its fields @@ -2084,8 +2016,7 @@ bool RenderScriptRuntime::JITSubelements(Element &elem, Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); if (!elem.element_ptr.isValid() || !elem.field_count.isValid()) { - if (log) - log->Printf("%s - failed to find allocation details.", __FUNCTION__); + LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); return false; } @@ -2107,12 +2038,10 @@ bool RenderScriptRuntime::JITSubelements(Element &elem, context, field_count, field_count, field_count, *elem.element_ptr.get(), field_count, field_index); if (written < 0) { - if (log) - log->Printf("%s - encoding error in snprintf().", __FUNCTION__); + LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); return false; } else if (written >= jit_max_expr_size) { - if (log) - log->Printf("%s - expression too long.", __FUNCTION__); + LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); return false; } @@ -2120,8 +2049,7 @@ bool RenderScriptRuntime::JITSubelements(Element &elem, if (!EvalRSExpression(expr_buffer, frame_ptr, &results)) return false; - if (log) - log->Printf("%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results); + LLDB_LOGF(log, "%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results); switch (expr_index) { case 0: // Element* of child @@ -2136,9 +2064,8 @@ bool RenderScriptRuntime::JITSubelements(Element &elem, if (!err.Fail()) child.type_name = ConstString(name); else { - if (log) - log->Printf("%s - warning: Couldn't read field name.", - __FUNCTION__); + LLDB_LOGF(log, "%s - warning: Couldn't read field name.", + __FUNCTION__); } break; } @@ -2173,8 +2100,7 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc, if (!alloc->address.isValid() || !alloc->dimension.isValid() || !alloc->data_ptr.isValid() || !alloc->element.datum_size.isValid()) { - if (log) - log->Printf("%s - failed to find allocation details.", __FUNCTION__); + LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); return false; } @@ -2196,9 +2122,8 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc, alloc->size = dim_x * dim_y * dim_z * *alloc->element.datum_size.get(); - if (log) - log->Printf("%s - inferred size of struct allocation %" PRIu32 ".", - __FUNCTION__, *alloc->size.get()); + LLDB_LOGF(log, "%s - inferred size of struct allocation %" PRIu32 ".", + __FUNCTION__, *alloc->size.get()); return true; } @@ -2213,12 +2138,10 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc, int written = snprintf(expr_buf, jit_max_expr_size, fmt_str, *alloc->address.get(), dim_x, dim_y, dim_z); if (written < 0) { - if (log) - log->Printf("%s - encoding error in snprintf().", __FUNCTION__); + LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); return false; } else if (written >= jit_max_expr_size) { - if (log) - log->Printf("%s - expression too long.", __FUNCTION__); + LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); return false; } @@ -2242,8 +2165,7 @@ bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc, Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); if (!alloc->address.isValid() || !alloc->data_ptr.isValid()) { - if (log) - log->Printf("%s - failed to find allocation details.", __FUNCTION__); + LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); return false; } @@ -2253,12 +2175,10 @@ bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc, int written = snprintf(expr_buf, jit_max_expr_size, fmt_str, *alloc->address.get(), 0, 1, 0); if (written < 0) { - if (log) - log->Printf("%s - encoding error in snprintf().", __FUNCTION__); + LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); return false; } else if (written >= jit_max_expr_size) { - if (log) - log->Printf("%s - expression too long.", __FUNCTION__); + LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); return false; } @@ -2354,9 +2274,8 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem, // '#rs_padding_[0-9]+' if (found && num_children < elem.children.size()) { const uint32_t size_diff = elem.children.size() - num_children; - if (log) - log->Printf("%s - %" PRIu32 " padding struct entries", __FUNCTION__, - size_diff); + LLDB_LOGF(log, "%s - %" PRIu32 " padding struct entries", __FUNCTION__, + size_diff); for (uint32_t i = 0; i < size_diff; ++i) { ConstString name = elem.children[num_children + i].type_name; @@ -2377,9 +2296,8 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem, // Save name of variable in Element. elem.type_name = valobj_sp->GetTypeName(); - if (log) - log->Printf("%s - element name set to %s", __FUNCTION__, - elem.type_name.AsCString()); + LLDB_LOGF(log, "%s - element name set to %s", __FUNCTION__, + elem.type_name.AsCString()); return; } @@ -2424,9 +2342,8 @@ void RenderScriptRuntime::SetElementSize(Element &elem) { elem.padding = padding; elem.datum_size = data_size + padding; - if (log) - log->Printf("%s - element size set to %" PRIu32, __FUNCTION__, - data_size + padding); + LLDB_LOGF(log, "%s - element size set to %" PRIu32, __FUNCTION__, + data_size + padding); } // Given an allocation, this function copies the allocation contents from @@ -2439,13 +2356,11 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc, // JIT all the allocation details if (alloc->ShouldRefresh()) { - if (log) - log->Printf("%s - allocation details not calculated yet, jitting info", - __FUNCTION__); + LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info", + __FUNCTION__); if (!RefreshAllocation(alloc, frame_ptr)) { - if (log) - log->Printf("%s - couldn't JIT allocation details", __FUNCTION__); + LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__); return nullptr; } } @@ -2458,9 +2373,8 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc, const uint32_t size = *alloc->size.get(); std::shared_ptr<uint8_t> buffer(new uint8_t[size]); if (!buffer) { - if (log) - log->Printf("%s - couldn't allocate a %" PRIu32 " byte buffer", - __FUNCTION__, size); + LLDB_LOGF(log, "%s - couldn't allocate a %" PRIu32 " byte buffer", + __FUNCTION__, size); return nullptr; } @@ -2469,10 +2383,10 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc, lldb::addr_t data_ptr = *alloc->data_ptr.get(); GetProcess()->ReadMemory(data_ptr, buffer.get(), size, err); if (err.Fail()) { - if (log) - log->Printf("%s - '%s' Couldn't read %" PRIu32 - " bytes of allocation data from 0x%" PRIx64, - __FUNCTION__, err.AsCString(), size, data_ptr); + LLDB_LOGF(log, + "%s - '%s' Couldn't read %" PRIu32 + " bytes of allocation data from 0x%" PRIx64, + __FUNCTION__, err.AsCString(), size, data_ptr); return nullptr; } @@ -2493,19 +2407,16 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, if (!alloc) return false; - if (log) - log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__, - *alloc->address.get()); + LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__, + *alloc->address.get()); // JIT all the allocation details if (alloc->ShouldRefresh()) { - if (log) - log->Printf("%s - allocation details not calculated yet, jitting info.", - __FUNCTION__); + LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.", + __FUNCTION__); if (!RefreshAllocation(alloc, frame_ptr)) { - if (log) - log->Printf("%s - couldn't JIT allocation details", __FUNCTION__); + LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__); return false; } } @@ -2559,9 +2470,8 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, sizeof(AllocationDetails::FileHeader), sizeof(AllocationDetails::ElementHeader)); - if (log) - log->Printf("%s - header type %" PRIu32 ", element size %" PRIu32, - __FUNCTION__, root_el_hdr.type, root_el_hdr.element_size); + LLDB_LOGF(log, "%s - header type %" PRIu32 ", element size %" PRIu32, + __FUNCTION__, root_el_hdr.type, root_el_hdr.element_size); // Check if the target allocation and file both have the same number of bytes // for an Element @@ -2717,19 +2627,16 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, if (!alloc) return false; - if (log) - log->Printf("%s - found allocation 0x%" PRIx64 ".", __FUNCTION__, - *alloc->address.get()); + LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64 ".", __FUNCTION__, + *alloc->address.get()); // JIT all the allocation details if (alloc->ShouldRefresh()) { - if (log) - log->Printf("%s - allocation details not calculated yet, jitting info.", - __FUNCTION__); + LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.", + __FUNCTION__); if (!RefreshAllocation(alloc, frame_ptr)) { - if (log) - log->Printf("%s - couldn't JIT allocation details.", __FUNCTION__); + LLDB_LOGF(log, "%s - couldn't JIT allocation details.", __FUNCTION__); return false; } } @@ -2743,14 +2650,14 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, // Check we can create writable file FileSpec file_spec(path); FileSystem::Instance().Resolve(file_spec); - File file; - FileSystem::Instance().Open(file, file_spec, - File::eOpenOptionWrite | - File::eOpenOptionCanCreate | - File::eOpenOptionTruncate); + auto file = FileSystem::Instance().Open( + file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | + File::eOpenOptionTruncate); if (!file) { - strm.Printf("Error: Failed to open '%s' for writing", path); + std::string error = llvm::toString(file.takeError()); + strm.Printf("Error: Failed to open '%s' for writing: %s", path, + error.c_str()); strm.EOL(); return false; } @@ -2779,11 +2686,10 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, // Write the file header size_t num_bytes = sizeof(AllocationDetails::FileHeader); - if (log) - log->Printf("%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__, - (uint64_t)num_bytes); + LLDB_LOGF(log, "%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__, + (uint64_t)num_bytes); - Status err = file.Write(&head, num_bytes); + Status err = file.get()->Write(&head, num_bytes); if (!err.Success()) { strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path); strm.EOL(); @@ -2805,11 +2711,10 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, // Write headers for allocation element type to file num_bytes = element_header_size; - if (log) - log->Printf("%s - writing element headers, 0x%" PRIx64 " bytes.", - __FUNCTION__, (uint64_t)num_bytes); + LLDB_LOGF(log, "%s - writing element headers, 0x%" PRIx64 " bytes.", + __FUNCTION__, (uint64_t)num_bytes); - err = file.Write(element_header_buffer.get(), num_bytes); + err = file.get()->Write(element_header_buffer.get(), num_bytes); if (!err.Success()) { strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path); strm.EOL(); @@ -2818,11 +2723,10 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, // Write allocation data to file num_bytes = static_cast<size_t>(*alloc->size.get()); - if (log) - log->Printf("%s - writing 0x%" PRIx64 " bytes", __FUNCTION__, - (uint64_t)num_bytes); + LLDB_LOGF(log, "%s - writing 0x%" PRIx64 " bytes", __FUNCTION__, + (uint64_t)num_bytes); - err = file.Write(buffer.get(), num_bytes); + err = file.get()->Write(buffer.get(), num_bytes); if (!err.Success()) { strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path); strm.EOL(); @@ -2894,17 +2798,17 @@ bool RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) { addr_t addr = debug_present->GetLoadAddress(&target); GetProcess()->WriteMemory(addr, &flag, sizeof(flag), err); if (err.Success()) { - if (log) - log->Printf("%s - debugger present flag set on debugee.", - __FUNCTION__); + LLDB_LOGF(log, "%s - debugger present flag set on debugee.", + __FUNCTION__); m_debuggerPresentFlagged = true; } else if (log) { - log->Printf("%s - error writing debugger present flags '%s' ", - __FUNCTION__, err.AsCString()); + LLDB_LOGF(log, "%s - error writing debugger present flags '%s' ", + __FUNCTION__, err.AsCString()); } } else if (log) { - log->Printf( + LLDB_LOGF( + log, "%s - error writing debugger present flags - symbol not found", __FUNCTION__); } @@ -3004,8 +2908,7 @@ bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines, return false; } - if (log) - log->Printf("Found RenderScript reduction '%s'", spec[2].str().c_str()); + LLDB_LOGF(log, "Found RenderScript reduction '%s'", spec[2].str().c_str()); m_reductions.push_back(RSReductionDescriptor(this, sig, accum_data_size, spec[2], spec[3], spec[4], @@ -3082,10 +2985,8 @@ bool RSModuleDescriptor::ParseRSInfo() { { const llvm::StringRef raw_rs_info((const char *)buffer->GetBytes()); raw_rs_info.split(info_lines, '\n'); - if (log) - log->Printf("'.rs.info symbol for '%s':\n%s", - m_module->GetFileSpec().GetCString(), - raw_rs_info.str().c_str()); + LLDB_LOGF(log, "'.rs.info symbol for '%s':\n%s", + m_module->GetFileSpec().GetCString(), raw_rs_info.str().c_str()); } enum { @@ -3153,9 +3054,8 @@ bool RSModuleDescriptor::ParseRSInfo() { success = ParseVersionInfo(line, n_lines); break; default: { - if (log) - log->Printf("%s - skipping .rs.info field '%s'", __FUNCTION__, - line->str().c_str()); + LLDB_LOGF(log, "%s - skipping .rs.info field '%s'", __FUNCTION__, + line->str().c_str()); continue; } } @@ -3276,15 +3176,13 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr, if (!alloc) return false; // FindAllocByID() will print error message for us here - if (log) - log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__, - *alloc->address.get()); + LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__, + *alloc->address.get()); // Check we have information about the allocation, if not calculate it if (alloc->ShouldRefresh()) { - if (log) - log->Printf("%s - allocation details not calculated yet, jitting info.", - __FUNCTION__); + LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.", + __FUNCTION__); // JIT all the allocation information if (!RefreshAllocation(alloc, frame_ptr)) { @@ -3313,9 +3211,8 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t data_size = *alloc->element.datum_size.get(); - if (log) - log->Printf("%s - element size %" PRIu32 " bytes, including padding", - __FUNCTION__, data_size); + LLDB_LOGF(log, "%s - element size %" PRIu32 " bytes, including padding", + __FUNCTION__, data_size); // Allocate a buffer to copy data into std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr); @@ -3340,10 +3237,10 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t size = *alloc->size.get(); // Size of whole allocation const uint32_t padding = alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0; - if (log) - log->Printf("%s - stride %" PRIu32 " bytes, size %" PRIu32 - " bytes, padding %" PRIu32, - __FUNCTION__, stride, size, padding); + LLDB_LOGF(log, + "%s - stride %" PRIu32 " bytes, size %" PRIu32 + " bytes, padding %" PRIu32, + __FUNCTION__, stride, size, padding); // Find dimensions used to index loops, so need to be non-zero uint32_t dim_x = alloc->dimension.get()->dim_1; @@ -3395,8 +3292,7 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr, *alloc->data_ptr.get() + offset); if (written < 0 || written >= jit_max_expr_size) { - if (log) - log->Printf("%s - error in snprintf().", __FUNCTION__); + LLDB_LOGF(log, "%s - error in snprintf().", __FUNCTION__); continue; } @@ -3573,17 +3469,16 @@ void RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) { for (const auto &module : m_rsmodules) BreakOnModuleKernels(module); - if (log) - log->Printf("%s(True) - breakpoints set on all currently loaded kernels.", - __FUNCTION__); + LLDB_LOGF(log, + "%s(True) - breakpoints set on all currently loaded kernels.", + __FUNCTION__); } else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels. { m_breakAllKernels = false; - if (log) - log->Printf("%s(False) - breakpoints no longer automatically set.", - __FUNCTION__); + LLDB_LOGF(log, "%s(False) - breakpoints no longer automatically set.", + __FUNCTION__); } } @@ -3595,8 +3490,8 @@ RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) { GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); if (!m_filtersp) { - if (log) - log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__); + LLDB_LOGF(log, "%s - error, no breakpoint search filter set.", + __FUNCTION__); return nullptr; } @@ -3610,9 +3505,8 @@ RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) { Status err; target.AddNameToBreakpoint(bp, "RenderScriptKernel", err); if (err.Fail() && log) - if (log) - log->Printf("%s - error setting break name, '%s'.", __FUNCTION__, - err.AsCString()); + LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__, + err.AsCString()); return bp; } @@ -3624,8 +3518,8 @@ RenderScriptRuntime::CreateReductionBreakpoint(ConstString name, GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); if (!m_filtersp) { - if (log) - log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__); + LLDB_LOGF(log, "%s - error, no breakpoint search filter set.", + __FUNCTION__); return nullptr; } @@ -3640,8 +3534,8 @@ RenderScriptRuntime::CreateReductionBreakpoint(ConstString name, Status err; target.AddNameToBreakpoint(bp, "RenderScriptReduction", err); if (err.Fail() && log) - log->Printf("%s - error setting break name, '%s'.", __FUNCTION__, - err.AsCString()); + LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__, + err.AsCString()); return bp; } @@ -3663,9 +3557,8 @@ bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, var_sp, err)); if (!err.Success()) { - if (log) - log->Printf("%s - error, couldn't find '%s' in frame", __FUNCTION__, - var_name); + LLDB_LOGF(log, "%s - error, couldn't find '%s' in frame", __FUNCTION__, + var_name); return false; } @@ -3673,9 +3566,8 @@ bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, bool success = false; val = value_sp->GetValueAsUnsigned(0, &success); if (!success) { - if (log) - log->Printf("%s - error, couldn't parse '%s' as an uint32_t.", - __FUNCTION__, var_name); + LLDB_LOGF(log, "%s - error, couldn't parse '%s' as an uint32_t.", + __FUNCTION__, var_name); return false; } @@ -3695,8 +3587,7 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE)); if (!thread_ptr) { - if (log) - log->Printf("%s - Error, No thread pointer", __FUNCTION__); + LLDB_LOGF(log, "%s - Error, No thread pointer", __FUNCTION__); return false; } @@ -3718,17 +3609,15 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, if (!func_name) continue; - if (log) - log->Printf("%s - Inspecting function '%s'", __FUNCTION__, - func_name.GetCString()); + LLDB_LOGF(log, "%s - Inspecting function '%s'", __FUNCTION__, + func_name.GetCString()); // Check if function name has .expand suffix if (!func_name.GetStringRef().endswith(".expand")) continue; - if (log) - log->Printf("%s - Found .expand function '%s'", __FUNCTION__, - func_name.GetCString()); + LLDB_LOGF(log, "%s - Found .expand function '%s'", __FUNCTION__, + func_name.GetCString()); // Get values for variables in .expand frame that tell us the current // kernel invocation @@ -3770,9 +3659,8 @@ bool RenderScriptRuntime::KernelBreakpointHit(void *baton, // Coordinate we want to stop on RSCoordinate target_coord = *static_cast<RSCoordinate *>(baton); - if (log) - log->Printf("%s - Break ID %" PRIu64 ", " FMT_COORD, __FUNCTION__, break_id, - target_coord.x, target_coord.y, target_coord.z); + LLDB_LOGF(log, "%s - Break ID %" PRIu64 ", " FMT_COORD, __FUNCTION__, + break_id, target_coord.x, target_coord.y, target_coord.z); // Select current thread ExecutionContext context(ctx->exe_ctx_ref); @@ -3782,22 +3670,19 @@ bool RenderScriptRuntime::KernelBreakpointHit(void *baton, // Find current kernel invocation from .expand frame variables RSCoordinate current_coord{}; if (!GetKernelCoordinate(current_coord, thread_ptr)) { - if (log) - log->Printf("%s - Error, couldn't select .expand stack frame", - __FUNCTION__); + LLDB_LOGF(log, "%s - Error, couldn't select .expand stack frame", + __FUNCTION__); return false; } - if (log) - log->Printf("%s - " FMT_COORD, __FUNCTION__, current_coord.x, - current_coord.y, current_coord.z); + LLDB_LOGF(log, "%s - " FMT_COORD, __FUNCTION__, current_coord.x, + current_coord.y, current_coord.z); // Check if the current kernel invocation coordinate matches our target // coordinate if (target_coord == current_coord) { - if (log) - log->Printf("%s, BREAKING " FMT_COORD, __FUNCTION__, current_coord.x, - current_coord.y, current_coord.z); + LLDB_LOGF(log, "%s, BREAKING " FMT_COORD, __FUNCTION__, current_coord.x, + current_coord.y, current_coord.z); BreakpointSP breakpoint_sp = context.GetTargetPtr()->GetBreakpointByID(break_id); @@ -3865,8 +3750,8 @@ RenderScriptRuntime::CreateScriptGroupBreakpoint(ConstString name, GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); if (!m_filtersp) { - if (log) - log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__); + LLDB_LOGF(log, "%s - error, no breakpoint search filter set.", + __FUNCTION__); return nullptr; } @@ -3880,8 +3765,8 @@ RenderScriptRuntime::CreateScriptGroupBreakpoint(ConstString name, Status err; target.AddNameToBreakpoint(bp, name.GetCString(), err); if (err.Fail() && log) - log->Printf("%s - error setting break name, '%s'.", __FUNCTION__, - err.AsCString()); + LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__, + err.AsCString()); // ask the breakpoint to resolve itself bp->ResolveBreakpoint(); return bp; @@ -3964,9 +3849,8 @@ RenderScriptRuntime::CreateAllocation(addr_t address) { auto it = m_allocations.begin(); while (it != m_allocations.end()) { if (*((*it)->address) == address) { - if (log) - log->Printf("%s - Removing allocation id: %d, address: 0x%" PRIx64, - __FUNCTION__, (*it)->id, address); + LLDB_LOGF(log, "%s - Removing allocation id: %d, address: 0x%" PRIx64, + __FUNCTION__, (*it)->id, address); it = m_allocations.erase(it); } else { @@ -3988,9 +3872,8 @@ bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr, Address resolved; // RenderScript module if (!target.GetSectionLoadList().ResolveLoadAddress(kernel_addr, resolved)) { - if (log) - log->Printf("%s: unable to resolve 0x%" PRIx64 " to a loaded symbol", - __FUNCTION__, kernel_addr); + LLDB_LOGF(log, "%s: unable to resolve 0x%" PRIx64 " to a loaded symbol", + __FUNCTION__, kernel_addr); return false; } @@ -4000,9 +3883,8 @@ bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr, name = sym->GetName(); assert(IsRenderScriptModule(resolved.CalculateSymbolContextModule())); - if (log) - log->Printf("%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__, - kernel_addr, name.GetCString()); + LLDB_LOGF(log, "%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__, + kernel_addr, name.GetCString()); return true; } @@ -4256,13 +4138,12 @@ public: // Matching a comma separated list of known words is fairly // straightforward with PCRE, but we're using ERE, so we end up with a // little ugliness... - RegularExpression::Match match(/* max_matches */ 5); RegularExpression match_type_list( llvm::StringRef("^([[:alpha:]]+)(,[[:alpha:]]+){0,4}$")); assert(match_type_list.IsValid()); - if (!match_type_list.Execute(option_val, &match)) { + if (!match_type_list.Execute(option_val)) { err_str.PutCString( "a comma-separated list of kernel types is required"); return false; @@ -4696,32 +4577,36 @@ public: return false; } - Stream *output_strm = nullptr; - StreamFile outfile_stream; + Stream *output_stream_p = nullptr; + std::unique_ptr<Stream> output_stream_storage; + const FileSpec &outfile_spec = m_options.m_outfile; // Dump allocation to file instead if (outfile_spec) { // Open output file std::string path = outfile_spec.GetPath(); - auto error = FileSystem::Instance().Open( - outfile_stream.GetFile(), outfile_spec, - File::eOpenOptionWrite | File::eOpenOptionCanCreate); - if (error.Success()) { - output_strm = &outfile_stream; + auto file = FileSystem::Instance().Open( + outfile_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate); + if (file) { + output_stream_storage = + std::make_unique<StreamFile>(std::move(file.get())); + output_stream_p = output_stream_storage.get(); result.GetOutputStream().Printf("Results written to '%s'", path.c_str()); result.GetOutputStream().EOL(); } else { - result.AppendErrorWithFormat("Couldn't open file '%s'", path.c_str()); + std::string error = llvm::toString(file.takeError()); + result.AppendErrorWithFormat("Couldn't open file '%s': %s", + path.c_str(), error.c_str()); result.SetStatus(eReturnStatusFailed); return false; } } else - output_strm = &result.GetOutputStream(); + output_stream_p = &result.GetOutputStream(); - assert(output_strm != nullptr); + assert(output_stream_p != nullptr); bool dumped = - runtime->DumpAllocation(*output_strm, m_exe_ctx.GetFramePtr(), id); + runtime->DumpAllocation(*output_stream_p, m_exe_ctx.GetFramePtr(), id); if (dumped) result.SetStatus(eReturnStatusSuccessFinishResult); diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h index 3923221d4302..c3740ba55a11 100644 --- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h +++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h @@ -67,8 +67,8 @@ public: void Dump(Stream *s) const override {} Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } @@ -117,8 +117,8 @@ public: void Dump(Stream *s) const override {} Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } @@ -262,8 +262,8 @@ public: void Dump(Stream *s) const override {} Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp index 4725e8c5b0eb..a6d225d2fbd8 100644 --- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp +++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp @@ -93,9 +93,8 @@ llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) { assert(orig && "CallInst has no called function"); llvm::FunctionType *orig_type = orig->getFunctionType(); auto name = orig->getName(); - if (log) - log->Printf("%s - cloning to StructRet function for '%s'", __FUNCTION__, - name.str().c_str()); + LLDB_LOGF(log, "%s - cloning to StructRet function for '%s'", __FUNCTION__, + name.str().c_str()); unsigned num_params = orig_type->getNumParams(); std::vector<llvm::Type *> new_params{num_params + 1, nullptr}; @@ -113,9 +112,9 @@ llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) { if (!return_type_ptr_type) return nullptr; - if (log) - log->Printf("%s - return type pointer type for StructRet clone @ '0x%p':\n", - __FUNCTION__, (void *)return_type_ptr_type); + LLDB_LOGF(log, + "%s - return type pointer type for StructRet clone @ '0x%p':\n", + __FUNCTION__, (void *)return_type_ptr_type); // put the sret pointer argument in place at the beginning of the // argument list. params.emplace(params.begin(), return_type_ptr_type); diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp index d489eaf11115..de17d986a860 100644 --- a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp +++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp @@ -16,7 +16,19 @@ using namespace lldb_private; using namespace lldb_private::breakpad; namespace { -enum class Token { Unknown, Module, Info, CodeID, File, Func, Public, Stack, CFI, Init }; +enum class Token { + Unknown, + Module, + Info, + CodeID, + File, + Func, + Public, + Stack, + CFI, + Init, + Win, +}; } template<typename T> @@ -33,6 +45,7 @@ template <> Token stringTo<Token>(llvm::StringRef Str) { .Case("STACK", Token::Stack) .Case("CFI", Token::CFI) .Case("INIT", Token::Init) + .Case("WIN", Token::Win) .Default(Token::Unknown); } @@ -127,6 +140,8 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) { switch (Tok) { case Token::CFI: return Record::StackCFI; + case Token::Win: + return Record::StackWin; default: return llvm::None; } @@ -134,13 +149,13 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) { case Token::Unknown: // Optimistically assume that any unrecognised token means this is a line // record, those don't have a special keyword and start directly with a - // hex number. CODE_ID should never be at the start of a line, but if it - // is, it can be treated the same way as a garbled line record. + // hex number. return Record::Line; case Token::CodeID: case Token::CFI: case Token::Init: + case Token::Win: // These should never appear at the start of a valid record. return llvm::None; } @@ -390,6 +405,81 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, return OS << " " << R.UnwindRules; } +llvm::Optional<StackWinRecord> StackWinRecord::parse(llvm::StringRef Line) { + // STACK WIN type rva code_size prologue_size epilogue_size parameter_size + // saved_register_size local_size max_stack_size has_program_string + // program_string_OR_allocates_base_pointer + + if (consume<Token>(Line) != Token::Stack) + return llvm::None; + if (consume<Token>(Line) != Token::Win) + return llvm::None; + + llvm::StringRef Str; + uint8_t Type; + std::tie(Str, Line) = getToken(Line); + // Right now we only support the "FrameData" frame type. + if (!to_integer(Str, Type) || FrameType(Type) != FrameType::FrameData) + return llvm::None; + + lldb::addr_t RVA; + std::tie(Str, Line) = getToken(Line); + if (!to_integer(Str, RVA, 16)) + return llvm::None; + + lldb::addr_t CodeSize; + std::tie(Str, Line) = getToken(Line); + if (!to_integer(Str, CodeSize, 16)) + return llvm::None; + + // Skip fields which we aren't using right now. + std::tie(Str, Line) = getToken(Line); // prologue_size + std::tie(Str, Line) = getToken(Line); // epilogue_size + + lldb::addr_t ParameterSize; + std::tie(Str, Line) = getToken(Line); + if (!to_integer(Str, ParameterSize, 16)) + return llvm::None; + + lldb::addr_t SavedRegisterSize; + std::tie(Str, Line) = getToken(Line); + if (!to_integer(Str, SavedRegisterSize, 16)) + return llvm::None; + + lldb::addr_t LocalSize; + std::tie(Str, Line) = getToken(Line); + if (!to_integer(Str, LocalSize, 16)) + return llvm::None; + + std::tie(Str, Line) = getToken(Line); // max_stack_size + + uint8_t HasProgramString; + std::tie(Str, Line) = getToken(Line); + if (!to_integer(Str, HasProgramString)) + return llvm::None; + // FrameData records should always have a program string. + if (!HasProgramString) + return llvm::None; + + return StackWinRecord(RVA, CodeSize, ParameterSize, SavedRegisterSize, + LocalSize, Line.trim()); +} + +bool breakpad::operator==(const StackWinRecord &L, const StackWinRecord &R) { + return L.RVA == R.RVA && L.CodeSize == R.CodeSize && + L.ParameterSize == R.ParameterSize && + L.SavedRegisterSize == R.SavedRegisterSize && + L.LocalSize == R.LocalSize && L.ProgramString == R.ProgramString; +} + +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, + const StackWinRecord &R) { + return OS << llvm::formatv( + "STACK WIN 4 {0:x-} {1:x-} ? ? {2} {3} {4} ? 1 {5}", R.RVA, + R.CodeSize, R.ParameterSize, R.SavedRegisterSize, R.LocalSize, + R.ProgramString); +} + llvm::StringRef breakpad::toString(Record::Kind K) { switch (K) { case Record::Module: @@ -406,6 +496,8 @@ llvm::StringRef breakpad::toString(Record::Kind K) { return "PUBLIC"; case Record::StackCFI: return "STACK CFI"; + case Record::StackWin: + return "STACK WIN"; } llvm_unreachable("Unknown record kind!"); } diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h index 5d5cdb319c10..27bef975125d 100644 --- a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h +++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h @@ -20,7 +20,7 @@ namespace breakpad { class Record { public: - enum Kind { Module, Info, File, Func, Line, Public, StackCFI }; + enum Kind { Module, Info, File, Func, Line, Public, StackCFI, StackWin }; /// Attempt to guess the kind of the record present in the argument without /// doing a full parse. The returned kind will always be correct for valid @@ -157,6 +157,29 @@ public: bool operator==(const StackCFIRecord &L, const StackCFIRecord &R); llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackCFIRecord &R); +class StackWinRecord : public Record { +public: + static llvm::Optional<StackWinRecord> parse(llvm::StringRef Line); + + StackWinRecord(lldb::addr_t RVA, lldb::addr_t CodeSize, + lldb::addr_t ParameterSize, lldb::addr_t SavedRegisterSize, + lldb::addr_t LocalSize, llvm::StringRef ProgramString) + : Record(StackWin), RVA(RVA), CodeSize(CodeSize), + ParameterSize(ParameterSize), SavedRegisterSize(SavedRegisterSize), + LocalSize(LocalSize), ProgramString(ProgramString) {} + + enum class FrameType : uint8_t { FPO = 0, FrameData = 4 }; + lldb::addr_t RVA; + lldb::addr_t CodeSize; + lldb::addr_t ParameterSize; + lldb::addr_t SavedRegisterSize; + lldb::addr_t LocalSize; + llvm::StringRef ProgramString; +}; + +bool operator==(const StackWinRecord &L, const StackWinRecord &R); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackWinRecord &R); + } // namespace breakpad } // namespace lldb_private diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp index 60dd9f9cecf0..3b9e0e2092a9 100644 --- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp +++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp @@ -42,6 +42,8 @@ llvm::Optional<Header> Header::parse(llvm::StringRef text) { return Header{ArchSpec(triple), std::move(uuid)}; } +char ObjectFileBreakpad::ID; + void ObjectFileBreakpad::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, @@ -125,7 +127,7 @@ Symtab *ObjectFileBreakpad::GetSymtab() { void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) { if (m_sections_up) return; - m_sections_up = llvm::make_unique<SectionList>(); + m_sections_up = std::make_unique<SectionList>(); llvm::Optional<Record::Kind> current_section; offset_t section_start; diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h index e8885e0cc898..cb4bba01fb71 100644 --- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h +++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h @@ -48,6 +48,13 @@ public: uint32_t GetPluginVersion() override { return 1; } + // LLVM RTTI support + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || ObjectFile::isA(ClassID); + } + static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } + // ObjectFile Protocol. bool ParseHeader() override; @@ -78,8 +85,6 @@ public: UUID GetUUID() override { return m_uuid; } - FileSpecList GetDebugSymbolFilePaths() override { return FileSpecList(); } - uint32_t GetDependentModules(FileSpecList &files) override { return 0; } Type CalculateType() override { return eTypeDebugInfo; } diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index d62afa34bbe8..3f8502548fc2 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -18,6 +18,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" #include "lldb/Host/FileSystem.h" +#include "lldb/Host/LZMA.h" #include "lldb/Symbol/DWARFCallFrameInfo.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/SectionLoadList.h" @@ -29,12 +30,13 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" - #include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Object/Decompressor.h" #include "llvm/Support/ARMBuildAttributes.h" +#include "llvm/Support/CRC.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MipsABIFlags.h" @@ -80,41 +82,6 @@ const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01; const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; -// LLDB_NT_OWNER_CORE and LLDB_NT_OWNER_LINUX note contants -#define NT_PRSTATUS 1 -#define NT_PRFPREG 2 -#define NT_PRPSINFO 3 -#define NT_TASKSTRUCT 4 -#define NT_AUXV 6 -#define NT_SIGINFO 0x53494749 -#define NT_FILE 0x46494c45 -#define NT_PRXFPREG 0x46e62b7f -#define NT_PPC_VMX 0x100 -#define NT_PPC_SPE 0x101 -#define NT_PPC_VSX 0x102 -#define NT_386_TLS 0x200 -#define NT_386_IOPERM 0x201 -#define NT_X86_XSTATE 0x202 -#define NT_S390_HIGH_GPRS 0x300 -#define NT_S390_TIMER 0x301 -#define NT_S390_TODCMP 0x302 -#define NT_S390_TODPREG 0x303 -#define NT_S390_CTRS 0x304 -#define NT_S390_PREFIX 0x305 -#define NT_S390_LAST_BREAK 0x306 -#define NT_S390_SYSTEM_CALL 0x307 -#define NT_S390_TDB 0x308 -#define NT_S390_VXRS_LOW 0x309 -#define NT_S390_VXRS_HIGH 0x30a -#define NT_ARM_VFP 0x400 -#define NT_ARM_TLS 0x401 -#define NT_ARM_HW_BREAK 0x402 -#define NT_ARM_HW_WATCH 0x403 -#define NT_ARM_SYSTEM_CALL 0x404 -#define NT_METAG_CBUF 0x500 -#define NT_METAG_RPIPE 0x501 -#define NT_METAG_TLS 0x502 - //===----------------------------------------------------------------------===// /// \class ELFRelocation /// Generic wrapper for ELFRel and ELFRela. @@ -264,8 +231,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4)); if (cstr == nullptr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); - if (log) - log->Printf("Failed to parse note name lacking nul terminator"); + LLDB_LOGF(log, "Failed to parse note name lacking nul terminator"); return false; } @@ -333,6 +299,8 @@ static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { return LLDB_INVALID_CPUTYPE; } +char ObjectFileELF::ID; + // Arbitrary constant used as UUID prefix for core files. const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C); @@ -429,67 +397,9 @@ bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp, return false; } -/* - * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c - * - * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or - * code or tables extracted from it, as desired without restriction. - */ -static uint32_t calc_crc32(uint32_t crc, const void *buf, size_t size) { - static const uint32_t g_crc32_tab[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; - const uint8_t *p = (const uint8_t *)buf; - - crc = crc ^ ~0U; - while (size--) - crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); - return crc ^ ~0U; -} - -static uint32_t calc_gnu_debuglink_crc32(const void *buf, size_t size) { - return calc_crc32(0U, buf, size); +static uint32_t calc_crc32(uint32_t init, const DataExtractor &data) { + return llvm::crc32( + init, llvm::makeArrayRef(data.GetDataStart(), data.GetByteSize())); } uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32( @@ -509,8 +419,7 @@ uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32( break; } - core_notes_crc = calc_crc32(core_notes_crc, segment_data.GetDataStart(), - segment_data.GetByteSize()); + core_notes_crc = calc_crc32(core_notes_crc, segment_data); } } @@ -608,10 +517,9 @@ size_t ObjectFileELF::GetModuleSpecifications( llvm::Triple::OSType spec_ostype = spec.GetArchitecture().GetTriple().getOS(); - if (log) - log->Printf("ObjectFileELF::%s file '%s' module OSABI: %s", - __FUNCTION__, file.GetPath().c_str(), - OSABIAsCString(header.e_ident[EI_OSABI])); + LLDB_LOGF(log, "ObjectFileELF::%s file '%s' module OSABI: %s", + __FUNCTION__, file.GetPath().c_str(), + OSABIAsCString(header.e_ident[EI_OSABI])); // SetArchitecture should have set the vendor to unknown vendor = spec.GetArchitecture().GetTriple().getVendor(); @@ -623,10 +531,10 @@ size_t ObjectFileELF::GetModuleSpecifications( GetOsFromOSABI(header.e_ident[EI_OSABI], ostype); assert(spec_ostype == ostype); if (spec_ostype != llvm::Triple::OSType::UnknownOS) { - if (log) - log->Printf("ObjectFileELF::%s file '%s' set ELF module OS type " - "from ELF header OSABI.", - __FUNCTION__, file.GetPath().c_str()); + LLDB_LOGF(log, + "ObjectFileELF::%s file '%s' set ELF module OS type " + "from ELF header OSABI.", + __FUNCTION__, file.GetPath().c_str()); } data_sp = MapFileData(file, -1, file_offset); @@ -652,12 +560,12 @@ size_t ObjectFileELF::GetModuleSpecifications( llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple(); - if (log) - log->Printf("ObjectFileELF::%s file '%s' module set to triple: %s " - "(architecture %s)", - __FUNCTION__, file.GetPath().c_str(), - spec_triple.getTriple().c_str(), - spec.GetArchitecture().GetArchitectureName()); + LLDB_LOGF(log, + "ObjectFileELF::%s file '%s' module set to triple: %s " + "(architecture %s)", + __FUNCTION__, file.GetPath().c_str(), + spec_triple.getTriple().c_str(), + spec.GetArchitecture().GetArchitectureName()); if (!uuid.IsValid()) { uint32_t core_notes_crc = 0; @@ -682,8 +590,7 @@ size_t ObjectFileELF::GetModuleSpecifications( core_notes_crc = CalculateELFNotesSegmentsCRC32(program_headers, data); } else { - gnu_debuglink_crc = calc_gnu_debuglink_crc32( - data.GetDataStart(), data.GetByteSize()); + gnu_debuglink_crc = calc_crc32(0, data); } } using u32le = llvm::support::ulittle32_t; @@ -721,27 +628,16 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length) - : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), - m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0), - m_program_headers(), m_section_headers(), m_dynamic_symbols(), - m_filespec_up(), m_entry_point_address(), m_arch_spec() { + : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) { if (file) m_file = *file; - ::memset(&m_header, 0, sizeof(m_header)); } ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, DataBufferSP &header_data_sp, const lldb::ProcessSP &process_sp, addr_t header_addr) - : ObjectFile(module_sp, process_sp, header_addr, header_data_sp), - m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0), - m_program_headers(), m_section_headers(), m_dynamic_symbols(), - m_filespec_up(), m_entry_point_address(), m_arch_spec() { - ::memset(&m_header, 0, sizeof(m_header)); -} - -ObjectFileELF::~ObjectFileELF() {} + : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {} bool ObjectFileELF::IsExecutable() const { return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0); @@ -872,8 +768,7 @@ UUID ObjectFileELF::GetUUID() { } } else { if (!m_gnu_debuglink_crc) - m_gnu_debuglink_crc = calc_gnu_debuglink_crc32(m_data.GetDataStart(), - m_data.GetByteSize()); + m_gnu_debuglink_crc = calc_crc32(0, m_data); if (m_gnu_debuglink_crc) { // Use 4 bytes of crc from the .gnu_debuglink section. u32le data(m_gnu_debuglink_crc); @@ -885,14 +780,10 @@ UUID ObjectFileELF::GetUUID() { return m_uuid; } -lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() { - FileSpecList file_spec_list; - - if (!m_gnu_debuglink_file.empty()) { - FileSpec file_spec(m_gnu_debuglink_file); - file_spec_list.Append(file_spec); - } - return file_spec_list; +llvm::Optional<FileSpec> ObjectFileELF::GetDebugLink() { + if (m_gnu_debuglink_file.empty()) + return llvm::None; + return FileSpec(m_gnu_debuglink_file); } uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) { @@ -1120,9 +1011,8 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, return error; } - if (log) - log->Printf("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32, - __FUNCTION__, note.n_name.c_str(), note.n_type); + LLDB_LOGF(log, "ObjectFileELF::%s parsing note name='%s', type=%" PRIu32, + __FUNCTION__, note.n_name.c_str(), note.n_type); // Process FreeBSD ELF notes. if ((note.n_name == LLDB_NT_OWNER_FREEBSD) && @@ -1147,11 +1037,11 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, arch_spec.GetTriple().setOSName(os_name); arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); - if (log) - log->Printf("ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32 - ".%" PRIu32, - __FUNCTION__, version_major, version_minor, - static_cast<uint32_t>(version_info % 1000)); + LLDB_LOGF(log, + "ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32 + ".%" PRIu32, + __FUNCTION__, version_major, version_minor, + static_cast<uint32_t>(version_info % 1000)); } // Process GNU ELF notes. else if (note.n_name == LLDB_NT_OWNER_GNU) { @@ -1172,12 +1062,11 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); arch_spec.GetTriple().setVendor( llvm::Triple::VendorType::UnknownVendor); - if (log) - log->Printf( - "ObjectFileELF::%s detected Linux, min version %" PRIu32 - ".%" PRIu32 ".%" PRIu32, - __FUNCTION__, version_info[1], version_info[2], - version_info[3]); + LLDB_LOGF(log, + "ObjectFileELF::%s detected Linux, min version %" PRIu32 + ".%" PRIu32 ".%" PRIu32, + __FUNCTION__, version_info[1], version_info[2], + version_info[3]); // FIXME we have the minimal version number, we could be propagating // that. version_info[1] = OS Major, version_info[2] = OS Minor, // version_info[3] = Revision. @@ -1186,30 +1075,28 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS); arch_spec.GetTriple().setVendor( llvm::Triple::VendorType::UnknownVendor); - if (log) - log->Printf("ObjectFileELF::%s detected Hurd (unsupported), min " - "version %" PRIu32 ".%" PRIu32 ".%" PRIu32, - __FUNCTION__, version_info[1], version_info[2], - version_info[3]); + LLDB_LOGF(log, + "ObjectFileELF::%s detected Hurd (unsupported), min " + "version %" PRIu32 ".%" PRIu32 ".%" PRIu32, + __FUNCTION__, version_info[1], version_info[2], + version_info[3]); break; case LLDB_NT_GNU_ABI_OS_SOLARIS: arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris); arch_spec.GetTriple().setVendor( llvm::Triple::VendorType::UnknownVendor); - if (log) - log->Printf( - "ObjectFileELF::%s detected Solaris, min version %" PRIu32 - ".%" PRIu32 ".%" PRIu32, - __FUNCTION__, version_info[1], version_info[2], - version_info[3]); + LLDB_LOGF(log, + "ObjectFileELF::%s detected Solaris, min version %" PRIu32 + ".%" PRIu32 ".%" PRIu32, + __FUNCTION__, version_info[1], version_info[2], + version_info[3]); break; default: - if (log) - log->Printf( - "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32 - ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, - __FUNCTION__, version_info[0], version_info[1], - version_info[2], version_info[3]); + LLDB_LOGF(log, + "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32 + ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, + __FUNCTION__, version_info[0], version_info[1], + version_info[2], version_info[3]); break; } } @@ -1618,9 +1505,8 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, section_size) == section_size)) { Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid); if (error.Fail()) { - if (log) - log->Printf("ObjectFileELF::%s ELF note processing failed: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, "ObjectFileELF::%s ELF note processing failed: %s", + __FUNCTION__, error.AsCString()); } } } @@ -1790,6 +1676,8 @@ class VMAddressProvider { VMMap Segments = VMMap(Alloc); VMMap Sections = VMMap(Alloc); lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); + size_t SegmentCount = 0; + std::string SegmentName; VMRange GetVMRange(const ELFSectionHeader &H) { addr_t Address = H.sh_addr; @@ -1804,18 +1692,23 @@ class VMAddressProvider { } public: - VMAddressProvider(ObjectFile::Type Type) : ObjectType(Type) {} + VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName) + : ObjectType(Type), SegmentName(SegmentName) {} + + std::string GetNextSegmentName() const { + return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str(); + } llvm::Optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) { if (H.p_memsz == 0) { - LLDB_LOG(Log, - "Ignoring zero-sized PT_LOAD segment. Corrupt object file?"); + LLDB_LOG(Log, "Ignoring zero-sized {0} segment. Corrupt object file?", + SegmentName); return llvm::None; } if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) { - LLDB_LOG(Log, - "Ignoring overlapping PT_LOAD segment. Corrupt object file?"); + LLDB_LOG(Log, "Ignoring overlapping {0} segment. Corrupt object file?", + SegmentName); return llvm::None; } return VMRange(H.p_vaddr, H.p_memsz); @@ -1850,6 +1743,7 @@ public: void AddSegment(const VMRange &Range, SectionSP Seg) { Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg)); + ++SegmentCount; } void AddSection(SectionAddressInfo Info, SectionSP Sect) { @@ -1867,29 +1761,32 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) { if (m_sections_up) return; - m_sections_up = llvm::make_unique<SectionList>(); - VMAddressProvider address_provider(GetType()); + m_sections_up = std::make_unique<SectionList>(); + VMAddressProvider regular_provider(GetType(), "PT_LOAD"); + VMAddressProvider tls_provider(GetType(), "PT_TLS"); - size_t LoadID = 0; for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) { const ELFProgramHeader &PHdr = EnumPHdr.value(); - if (PHdr.p_type != PT_LOAD) + if (PHdr.p_type != PT_LOAD && PHdr.p_type != PT_TLS) continue; - auto InfoOr = address_provider.GetAddressInfo(PHdr); + VMAddressProvider &provider = + PHdr.p_type == PT_TLS ? tls_provider : regular_provider; + auto InfoOr = provider.GetAddressInfo(PHdr); if (!InfoOr) continue; - ConstString Name(("PT_LOAD[" + llvm::Twine(LoadID++) + "]").str()); uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1)); SectionSP Segment = std::make_shared<Section>( - GetModule(), this, SegmentID(EnumPHdr.index()), Name, - eSectionTypeContainer, InfoOr->GetRangeBase(), InfoOr->GetByteSize(), - PHdr.p_offset, PHdr.p_filesz, Log2Align, /*flags*/ 0); + GetModule(), this, SegmentID(EnumPHdr.index()), + ConstString(provider.GetNextSegmentName()), eSectionTypeContainer, + InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.p_offset, + PHdr.p_filesz, Log2Align, /*flags*/ 0); Segment->SetPermissions(GetPermissions(PHdr)); + Segment->SetIsThreadSpecific(PHdr.p_type == PT_TLS); m_sections_up->AddSection(Segment); - address_provider.AddSegment(*InfoOr, std::move(Segment)); + provider.AddSegment(*InfoOr, std::move(Segment)); } ParseSectionHeaders(); @@ -1904,7 +1801,9 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) { const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size; - auto InfoOr = address_provider.GetAddressInfo(header); + VMAddressProvider &provider = + header.sh_flags & SHF_TLS ? tls_provider : regular_provider; + auto InfoOr = provider.GetAddressInfo(header); if (!InfoOr) continue; @@ -1935,13 +1834,77 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) { section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS); (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up) .AddSection(section_sp); - address_provider.AddSection(std::move(*InfoOr), std::move(section_sp)); + provider.AddSection(std::move(*InfoOr), std::move(section_sp)); } // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the // unified section list. if (GetType() != eTypeDebugInfo) unified_section_list = *m_sections_up; + + // If there's a .gnu_debugdata section, we'll try to read the .symtab that's + // embedded in there and replace the one in the original object file (if any). + // If there's none in the orignal object file, we add it to it. + if (auto gdd_obj_file = GetGnuDebugDataObjectFile()) { + if (auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) { + if (SectionSP symtab_section_sp = + gdd_objfile_section_list->FindSectionByType( + eSectionTypeELFSymbolTable, true)) { + SectionSP module_section_sp = unified_section_list.FindSectionByType( + eSectionTypeELFSymbolTable, true); + if (module_section_sp) + unified_section_list.ReplaceSection(module_section_sp->GetID(), + symtab_section_sp); + else + unified_section_list.AddSection(symtab_section_sp); + } + } + } +} + +std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() { + if (m_gnu_debug_data_object_file != nullptr) + return m_gnu_debug_data_object_file; + + SectionSP section = + GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata")); + if (!section) + return nullptr; + + if (!lldb_private::lzma::isAvailable()) { + GetModule()->ReportWarning( + "No LZMA support found for reading .gnu_debugdata section"); + return nullptr; + } + + // Uncompress the data + DataExtractor data; + section->GetSectionData(data); + llvm::SmallVector<uint8_t, 0> uncompressedData; + auto err = lldb_private::lzma::uncompress(data.GetData(), uncompressedData); + if (err) { + GetModule()->ReportWarning( + "An error occurred while decompression the section %s: %s", + section->GetName().AsCString(), llvm::toString(std::move(err)).c_str()); + return nullptr; + } + + // Construct ObjectFileELF object from decompressed buffer + DataBufferSP gdd_data_buf( + new DataBufferHeap(uncompressedData.data(), uncompressedData.size())); + auto fspec = GetFileSpec().CopyByAppendingPathComponent( + llvm::StringRef("gnu_debugdata")); + m_gnu_debug_data_object_file.reset(new ObjectFileELF( + GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize())); + + // This line is essential; otherwise a breakpoint can be set but not hit. + m_gnu_debug_data_object_file->SetType(ObjectFile::eTypeDebugInfo); + + ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture(); + if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec)) + return m_gnu_debug_data_object_file; + + return nullptr; } // Find the arm/aarch64 mapping symbol character in the given symbol name. @@ -2246,8 +2209,6 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, bool is_global = symbol.getBinding() == STB_GLOBAL; uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags; - bool is_mangled = (symbol_name[0] == '_' && symbol_name[1] == 'Z'); - llvm::StringRef symbol_ref(symbol_name); // Symbol names may contain @VERSION suffixes. Find those and strip them @@ -2255,7 +2216,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, size_t version_pos = symbol_ref.find('@'); bool has_suffix = version_pos != llvm::StringRef::npos; llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos); - Mangled mangled(ConstString(symbol_bare), is_mangled); + Mangled mangled(symbol_bare); // Now append the suffix back to mangled and unmangled names. Only do it if // the demangling was successful (string is not empty). @@ -2486,14 +2447,11 @@ static unsigned ParsePLTRelocations( break; const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); - bool is_mangled = - symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false; uint64_t plt_index = plt_offset + i * plt_entsize; Symbol jump_symbol( i + start_id, // Symbol table index symbol_name, // symbol name. - is_mangled, // is the symbol name mangled? eSymbolTypeTrampoline, // Type of this symbol false, // Is this globally visible? false, // Is this symbol debug info? @@ -2654,7 +2612,7 @@ unsigned ObjectFileELF::ApplyRelocations( ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) { Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); - log->Printf("Failed to apply debug info relocations"); + LLDB_LOGF(log, "Failed to apply debug info relocations"); break; } uint32_t truncated_addr = (value & 0xFFFFFFFF); @@ -2749,19 +2707,29 @@ Symtab *ObjectFileELF::GetSymtab() { // while the reverse is not necessarily true. Section *symtab = section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get(); - if (!symtab) { - // The symtab section is non-allocable and can be stripped, so if it - // doesn't exist then use the dynsym section which should always be - // there. - symtab = - section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true) - .get(); - } if (symtab) { m_symtab_up.reset(new Symtab(symtab->GetObjectFile())); symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab); } + // The symtab section is non-allocable and can be stripped, while the + // .dynsym section which should always be always be there. To support the + // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo + // section, nomatter if .symtab was already parsed or not. This is because + // minidebuginfo normally removes the .symtab symbols which have their + // matching .dynsym counterparts. + if (!symtab || + GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) { + Section *dynsym = + section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true) + .get(); + if (dynsym) { + if (!m_symtab_up) + m_symtab_up.reset(new Symtab(dynsym->GetObjectFile())); + symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym); + } + } + // DT_JMPREL // If present, this entry's d_ptr member holds the address of // relocation @@ -2803,6 +2771,50 @@ Symtab *ObjectFileELF::GetSymtab() { if (m_symtab_up == nullptr) m_symtab_up.reset(new Symtab(this)); + // In the event that there's no symbol entry for the entry point we'll + // artifically create one. We delegate to the symtab object the figuring + // out of the proper size, this will usually make it span til the next + // symbol it finds in the section. This means that if there are missing + // symbols the entry point might span beyond its function definition. + // We're fine with this as it doesn't make it worse than not having a + // symbol entry at all. + if (CalculateType() == eTypeExecutable) { + ArchSpec arch = GetArchitecture(); + auto entry_point_addr = GetEntryPointAddress(); + bool is_valid_entry_point = + entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset(); + addr_t entry_point_file_addr = entry_point_addr.GetFileAddress(); + if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress( + entry_point_file_addr)) { + uint64_t symbol_id = m_symtab_up->GetNumSymbols(); + Symbol symbol(symbol_id, + GetNextSyntheticSymbolName().GetCString(), // Symbol name. + eSymbolTypeCode, // Type of this symbol. + true, // Is this globally visible? + false, // Is this symbol debug info? + false, // Is this symbol a trampoline? + true, // Is this symbol artificial? + entry_point_addr.GetSection(), // Section where this + // symbol is defined. + 0, // Offset in section or symbol value. + 0, // Size. + false, // Size is valid. + false, // Contains linker annotations? + 0); // Symbol flags. + m_symtab_up->AddSymbol(symbol); + // When the entry point is arm thumb we need to explicitly set its + // class address to reflect that. This is important because expression + // evaluation relies on correctly setting a breakpoint at this + // address. + if (arch.GetMachine() == llvm::Triple::arm && + (entry_point_file_addr & 1)) + m_address_class_map[entry_point_file_addr ^ 1] = + AddressClass::eCodeAlternateISA; + else + m_address_class_map[entry_point_file_addr] = AddressClass::eCode; + } + } + m_symtab_up->CalculateSymbolSizes(); } @@ -2881,7 +2893,6 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, Symbol eh_symbol( symbol_id, // Symbol table index. symbol_name, // Symbol name. - false, // Is the symbol name mangled? eSymbolTypeCode, // Type of this symbol. true, // Is this globally visible? false, // Is this symbol debug info? diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index b63a5d14d4f5..3b273896cb59 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -56,8 +56,6 @@ struct ELFNote { /// the ObjectFile protocol. class ObjectFileELF : public lldb_private::ObjectFile { public: - ~ObjectFileELF() override; - // Static Functions static void Initialize(); @@ -91,6 +89,13 @@ public: uint32_t GetPluginVersion() override; + // LLVM RTTI support + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || ObjectFile::isA(ClassID); + } + static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } + // ObjectFile Protocol. bool ParseHeader() override; @@ -117,7 +122,9 @@ public: lldb_private::UUID GetUUID() override; - lldb_private::FileSpecList GetDebugSymbolFilePaths() override; + /// Return the contents of the .gnu_debuglink section, if the object file + /// contains it. + llvm::Optional<lldb_private::FileSpec> GetDebugLink(); uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; @@ -190,7 +197,7 @@ private: /// ELF .gnu_debuglink file and crc data if available. std::string m_gnu_debuglink_file; - uint32_t m_gnu_debuglink_crc; + uint32_t m_gnu_debuglink_crc = 0; /// Collection of program headers. ProgramHeaderColl m_program_headers; @@ -201,6 +208,10 @@ private: /// Collection of symbols from the dynamic table. DynamicSymbolColl m_dynamic_symbols; + /// Object file parsed from .gnu_debugdata section (\sa + /// GetGnuDebugDataObjectFile()) + std::shared_ptr<ObjectFileELF> m_gnu_debug_data_object_file; + /// List of file specifications corresponding to the modules (shared /// libraries) on which this object file depends. mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_up; @@ -376,6 +387,14 @@ private: lldb_private::UUID &uuid); bool AnySegmentHasPhysicalAddress(); + + /// Takes the .gnu_debugdata and returns the decompressed object file that is + /// stored within that section. + /// + /// \returns either the decompressed object file stored within the + /// .gnu_debugdata section or \c nullptr if an error occured or if there's no + /// section with that name. + std::shared_ptr<ObjectFileELF> GetGnuDebugDataObjectFile(); }; #endif // liblldb_ObjectFileELF_h_ diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp index eaf973da3835..c55b96d9110b 100644 --- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -39,6 +39,8 @@ using namespace lldb; using namespace lldb_private; +char ObjectFileJIT::ID; + void ObjectFileJIT::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h index 99241126cd1a..c992683cfc3c 100644 --- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -46,6 +46,13 @@ public: lldb::offset_t length, lldb_private::ModuleSpecList &specs); + // LLVM RTTI support + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || ObjectFile::isA(ClassID); + } + static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } + // Member Functions bool ParseHeader() override; diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index c1fe0cc8ddda..b777a5319104 100644 --- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -120,10 +120,10 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() { return nullptr; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); - if (log) - log->Printf("OperatingSystemPython::GetDynamicRegisterInfo() fetching " - "thread register definitions from python for pid %" PRIu64, - m_process->GetID()); + LLDB_LOGF(log, + "OperatingSystemPython::GetDynamicRegisterInfo() fetching " + "thread register definitions from python for pid %" PRIu64, + m_process->GetID()); StructuredData::DictionarySP dictionary = m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp); @@ -169,12 +169,12 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list, api_lock.try_lock(); auto interpreter_lock = m_interpreter->AcquireInterpreterLock(); - if (log) - log->Printf("OperatingSystemPython::UpdateThreadList() fetching thread " - "data from python for pid %" PRIu64, - m_process->GetID()); + LLDB_LOGF(log, + "OperatingSystemPython::UpdateThreadList() fetching thread " + "data from python for pid %" PRIu64, + m_process->GetID()); - // The threads that are in "new_thread_list" upon entry are the threads from + // The threads that are in "core_thread_list" upon entry are the threads from // the lldb_private::Process subclass, no memory threads will be in this // list. StructuredData::ArraySP threads_list = @@ -190,7 +190,7 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list, if (log) { StreamString strm; threads_list->Dump(strm); - log->Printf("threads_list = %s", strm.GetData()); + LLDB_LOGF(log, "threads_list = %s", strm.GetData()); } const uint32_t num_threads = threads_list->GetSize(); @@ -316,21 +316,21 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread, if (reg_data_addr != LLDB_INVALID_ADDRESS) { // The registers data is in contiguous memory, just create the register // context using the address provided - if (log) - log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid " - "= 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 - ") creating memory register context", - thread->GetID(), thread->GetProtocolID(), reg_data_addr); + LLDB_LOGF(log, + "OperatingSystemPython::CreateRegisterContextForThread (tid " + "= 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 + ") creating memory register context", + thread->GetID(), thread->GetProtocolID(), reg_data_addr); reg_ctx_sp = std::make_shared<RegisterContextMemory>( *thread, 0, *GetDynamicRegisterInfo(), reg_data_addr); } else { // No register data address is provided, query the python plug-in to let it // make up the data as it sees fit - if (log) - log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid " - "= 0x%" PRIx64 ", 0x%" PRIx64 - ") fetching register data from python", - thread->GetID(), thread->GetProtocolID()); + LLDB_LOGF(log, + "OperatingSystemPython::CreateRegisterContextForThread (tid " + "= 0x%" PRIx64 ", 0x%" PRIx64 + ") fetching register data from python", + thread->GetID(), thread->GetProtocolID()); StructuredData::StringSP reg_context_data = m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp, @@ -351,10 +351,10 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread, // if we still have no register data, fallback on a dummy context to avoid // crashing if (!reg_ctx_sp) { - if (log) - log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid " - "= 0x%" PRIx64 ") forcing a dummy register context", - thread->GetID()); + LLDB_LOGF(log, + "OperatingSystemPython::CreateRegisterContextForThread (tid " + "= 0x%" PRIx64 ") forcing a dummy register context", + thread->GetID()); reg_ctx_sp = std::make_shared<RegisterContextDummy>( *thread, 0, target.GetArchitecture().GetAddressByteSize()); } @@ -375,10 +375,10 @@ lldb::ThreadSP OperatingSystemPython::CreateThread(lldb::tid_t tid, addr_t context) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); - if (log) - log->Printf("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 - ", context = 0x%" PRIx64 ") fetching register data from python", - tid, context); + LLDB_LOGF(log, + "OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 + ", context = 0x%" PRIx64 ") fetching register data from python", + tid, context); if (m_interpreter && m_python_object_sp) { // First thing we have to do is to try to get the API lock, and the diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index d10557596ff8..b12e21deb459 100644 --- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -27,11 +27,11 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" -#include "lldb/Utility/CleanUp.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" +#include "llvm/ADT/ScopeExit.h" using namespace lldb; using namespace lldb_private; @@ -276,8 +276,7 @@ PlatformPOSIX::PutFile(const lldb_private::FileSpec &source, } else command.Printf("rsync %s %s %s:%s", GetRSyncOpts(), src_path.c_str(), GetHostname(), dst_path.c_str()); - if (log) - log->Printf("[PutFile] Running command: %s\n", command.GetData()); + LLDB_LOGF(log, "[PutFile] Running command: %s\n", command.GetData()); int retcode; Host::RunShellCommand(command.GetData(), nullptr, &retcode, nullptr, nullptr, std::chrono::minutes(1)); @@ -334,8 +333,7 @@ lldb_private::Status PlatformPOSIX::GetFile( command.Printf("rsync %s %s:%s %s", GetRSyncOpts(), m_remote_platform_sp->GetHostname(), src_path.c_str(), dst_path.c_str()); - if (log) - log->Printf("[GetFile] Running command: %s\n", command.GetData()); + LLDB_LOGF(log, "[GetFile] Running command: %s\n", command.GetData()); int retcode; Host::RunShellCommand(command.GetData(), nullptr, &retcode, nullptr, nullptr, std::chrono::minutes(1)); @@ -348,8 +346,7 @@ lldb_private::Status PlatformPOSIX::GetFile( // read/write, read/write, read/write, ... // close src // close dst - if (log) - log->Printf("[GetFile] Using block by block transfer....\n"); + LLDB_LOGF(log, "[GetFile] Using block by block transfer....\n"); Status error; user_id_t fd_src = OpenFile(source, File::eOpenOptionRead, lldb::eFilePermissionsFileDefault, error); @@ -515,24 +512,21 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info, error = debugger.GetTargetList().CreateTarget( debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp); target = new_target_sp.get(); - if (log) - log->Printf("PlatformPOSIX::%s created new target", __FUNCTION__); + LLDB_LOGF(log, "PlatformPOSIX::%s created new target", __FUNCTION__); } else { error.Clear(); - if (log) - log->Printf("PlatformPOSIX::%s target already existed, setting target", - __FUNCTION__); + LLDB_LOGF(log, "PlatformPOSIX::%s target already existed, setting target", + __FUNCTION__); } if (target && error.Success()) { debugger.GetTargetList().SetSelectedTarget(target); if (log) { ModuleSP exe_module_sp = target->GetExecutableModule(); - log->Printf("PlatformPOSIX::%s set selected target to %p %s", - __FUNCTION__, (void *)target, - exe_module_sp - ? exe_module_sp->GetFileSpec().GetPath().c_str() - : "<null>"); + LLDB_LOGF(log, "PlatformPOSIX::%s set selected target to %p %s", + __FUNCTION__, (void *)target, + exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str() + : "<null>"); } process_sp = @@ -804,12 +798,13 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, "for path: %s", utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } - + // Make sure we deallocate the input string memory: - CleanUp path_cleanup([process, path_addr] { - process->DeallocateMemory(path_addr); + auto path_cleanup = llvm::make_scope_exit([process, path_addr] { + // Deallocate the buffer. + process->DeallocateMemory(path_addr); }); - + process->WriteMemory(path_addr, path.c_str(), path_len, utility_error); if (utility_error.Fail()) { error.SetErrorStringWithFormat("dlopen error: could not write path string:" @@ -830,21 +825,24 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, } // Make sure we deallocate the result structure memory - CleanUp return_cleanup([process, return_addr] { - process->DeallocateMemory(return_addr); + auto return_cleanup = llvm::make_scope_exit([process, return_addr] { + // Deallocate the buffer + process->DeallocateMemory(return_addr); }); - + // This will be the address of the storage for paths, if we are using them, // or nullptr to signal we aren't. lldb::addr_t path_array_addr = 0x0; - llvm::Optional<CleanUp> path_array_cleanup; + llvm::Optional<llvm::detail::scope_exit<std::function<void()>>> + path_array_cleanup; // This is the address to a buffer large enough to hold the largest path // conjoined with the library name we're passing in. This is a convenience // to avoid having to call malloc in the dlopen function. lldb::addr_t buffer_addr = 0x0; - llvm::Optional<CleanUp> buffer_cleanup; - + llvm::Optional<llvm::detail::scope_exit<std::function<void()>>> + buffer_cleanup; + // Set the values into our args and write them to the target: if (paths != nullptr) { // First insert the paths into the target. This is expected to be a @@ -877,8 +875,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, } // Make sure we deallocate the paths array. - path_array_cleanup.emplace([process, path_array_addr] { - process->DeallocateMemory(path_array_addr); + path_array_cleanup.emplace([process, path_array_addr]() { + // Deallocate the path array. + process->DeallocateMemory(path_array_addr); }); process->WriteMemory(path_array_addr, path_array.data(), @@ -904,8 +903,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, } // Make sure we deallocate the buffer memory: - buffer_cleanup.emplace([process, buffer_addr] { - process->DeallocateMemory(buffer_addr); + buffer_cleanup.emplace([process, buffer_addr]() { + // Deallocate the buffer. + process->DeallocateMemory(buffer_addr); }); } @@ -930,10 +930,11 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, // Make sure we clean up the args structure. We can't reuse it because the // Platform lives longer than the process and the Platforms don't get a // signal to clean up cached data when a process goes away. - CleanUp args_cleanup([do_dlopen_function, &exe_ctx, func_args_addr] { - do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr); - }); - + auto args_cleanup = + llvm::make_scope_exit([do_dlopen_function, &exe_ctx, func_args_addr] { + do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr); + }); + // Now run the caller: EvaluateExpressionOptions options; options.SetExecutionPolicy(eExecutionPolicyAlways); diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index 9c52b59e2b06..1e62ddfe94fd 100644 --- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -169,21 +169,21 @@ bool PlatformRemoteGDBServer::GetModuleSpec(const FileSpec &module_file_spec, const auto module_path = module_file_spec.GetPath(false); if (!m_gdb_client.GetModuleInfo(module_file_spec, arch, module_spec)) { - if (log) - log->Printf( - "PlatformRemoteGDBServer::%s - failed to get module info for %s:%s", - __FUNCTION__, module_path.c_str(), - arch.GetTriple().getTriple().c_str()); + LLDB_LOGF( + log, + "PlatformRemoteGDBServer::%s - failed to get module info for %s:%s", + __FUNCTION__, module_path.c_str(), + arch.GetTriple().getTriple().c_str()); return false; } if (log) { StreamString stream; module_spec.Dump(stream); - log->Printf( - "PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s", - __FUNCTION__, module_path.c_str(), arch.GetTriple().getTriple().c_str(), - stream.GetData()); + LLDB_LOGF(log, + "PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s", + __FUNCTION__, module_path.c_str(), + arch.GetTriple().getTriple().c_str(), stream.GetData()); } return true; @@ -253,9 +253,9 @@ FileSpec PlatformRemoteGDBServer::GetRemoteWorkingDirectory() { Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); FileSpec working_dir; if (m_gdb_client.GetWorkingDir(working_dir) && log) - log->Printf( - "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'", - working_dir.GetCString()); + LLDB_LOGF(log, + "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'", + working_dir.GetCString()); return working_dir; } else { return Platform::GetRemoteWorkingDirectory(); @@ -268,9 +268,8 @@ bool PlatformRemoteGDBServer::SetRemoteWorkingDirectory( // Clear the working directory it case it doesn't get set correctly. This // will for use to re-read it Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); - if (log) - log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')", - working_dir.GetCString()); + LLDB_LOGF(log, "PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')", + working_dir.GetCString()); return m_gdb_client.SetWorkingDir(working_dir) == 0; } else return Platform::SetRemoteWorkingDirectory(working_dir); @@ -370,8 +369,7 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); Status error; - if (log) - log->Printf("PlatformRemoteGDBServer::%s() called", __FUNCTION__); + LLDB_LOGF(log, "PlatformRemoteGDBServer::%s() called", __FUNCTION__); auto num_file_actions = launch_info.GetNumFileActions(); for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) { @@ -408,10 +406,10 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) { const char *arch_triple = arch_spec.GetTriple().str().c_str(); m_gdb_client.SendLaunchArchPacket(arch_triple); - if (log) - log->Printf( - "PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'", - __FUNCTION__, arch_triple ? arch_triple : "<NULL>"); + LLDB_LOGF( + log, + "PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'", + __FUNCTION__, arch_triple ? arch_triple : "<NULL>"); int arg_packet_err; { @@ -427,22 +425,21 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) { const auto pid = m_gdb_client.GetCurrentProcessID(false); if (pid != LLDB_INVALID_PROCESS_ID) { launch_info.SetProcessID(pid); - if (log) - log->Printf("PlatformRemoteGDBServer::%s() pid %" PRIu64 - " launched successfully", - __FUNCTION__, pid); + LLDB_LOGF(log, + "PlatformRemoteGDBServer::%s() pid %" PRIu64 + " launched successfully", + __FUNCTION__, pid); } else { - if (log) - log->Printf("PlatformRemoteGDBServer::%s() launch succeeded but we " - "didn't get a valid process id back!", - __FUNCTION__); + LLDB_LOGF(log, + "PlatformRemoteGDBServer::%s() launch succeeded but we " + "didn't get a valid process id back!", + __FUNCTION__); error.SetErrorString("failed to get PID"); } } else { error.SetErrorString(error_str.c_str()); - if (log) - log->Printf("PlatformRemoteGDBServer::%s() launch failed: %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, "PlatformRemoteGDBServer::%s() launch failed: %s", + __FUNCTION__, error.AsCString()); } } else { error.SetErrorStringWithFormat("'A' packet returned an error: %i", @@ -600,11 +597,10 @@ Status PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec, uint32_t mode) { Status error = m_gdb_client.MakeDirectory(file_spec, mode); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); - if (log) - log->Printf("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) " - "error = %u (%s)", - file_spec.GetCString(), mode, error.GetError(), - error.AsCString()); + LLDB_LOGF(log, + "PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) " + "error = %u (%s)", + file_spec.GetCString(), mode, error.GetError(), error.AsCString()); return error; } @@ -612,11 +608,11 @@ Status PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) { Status error = m_gdb_client.GetFilePermissions(file_spec, file_permissions); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); - if (log) - log->Printf("PlatformRemoteGDBServer::GetFilePermissions(path='%s', " - "file_permissions=%o) error = %u (%s)", - file_spec.GetCString(), file_permissions, error.GetError(), - error.AsCString()); + LLDB_LOGF(log, + "PlatformRemoteGDBServer::GetFilePermissions(path='%s', " + "file_permissions=%o) error = %u (%s)", + file_spec.GetCString(), file_permissions, error.GetError(), + error.AsCString()); return error; } @@ -624,16 +620,17 @@ Status PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions) { Status error = m_gdb_client.SetFilePermissions(file_spec, file_permissions); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); - if (log) - log->Printf("PlatformRemoteGDBServer::SetFilePermissions(path='%s', " - "file_permissions=%o) error = %u (%s)", - file_spec.GetCString(), file_permissions, error.GetError(), - error.AsCString()); + LLDB_LOGF(log, + "PlatformRemoteGDBServer::SetFilePermissions(path='%s', " + "file_permissions=%o) error = %u (%s)", + file_spec.GetCString(), file_permissions, error.GetError(), + error.AsCString()); return error; } lldb::user_id_t PlatformRemoteGDBServer::OpenFile(const FileSpec &file_spec, - uint32_t flags, uint32_t mode, + File::OpenOptions flags, + uint32_t mode, Status &error) { return m_gdb_client.OpenFile(file_spec, flags, mode, error); } @@ -671,20 +668,19 @@ Status PlatformRemoteGDBServer::CreateSymlink( { Status error = m_gdb_client.CreateSymlink(src, dst); Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); - if (log) - log->Printf("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') " - "error = %u (%s)", - src.GetCString(), dst.GetCString(), error.GetError(), - error.AsCString()); + LLDB_LOGF(log, + "PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') " + "error = %u (%s)", + src.GetCString(), dst.GetCString(), error.GetError(), + error.AsCString()); return error; } Status PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) { |