https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/115382
>From b5947cfe8fd7702f801c91f48ca050a5c839a707 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Thu, 7 Nov 2024 14:08:50 -0800 Subject: [PATCH 1/4] [lldb] Support overriding the disassembly CPU & features Add the ability to override the disassembly CPU and CPU features through a target setting (`target.disassembly-cpu` and `target.disassembly-features`) and a `disassemble` command option (`--cpu` and `--features`). This is especially relevant for architectures like RISC-V which relies heavily on CPU extensions. The majority of this patch is plumbing the options through. I recommend looking at DisassemblerLLVMC and the test for the observable change in behavior. --- lldb/include/lldb/Core/Disassembler.h | 32 +-- .../Interpreter/CommandOptionArgumentTable.h | 2 + lldb/include/lldb/Target/Target.h | 4 + lldb/include/lldb/lldb-enumerations.h | 2 + lldb/include/lldb/lldb-private-interfaces.h | 5 +- lldb/source/API/SBFunction.cpp | 4 +- lldb/source/API/SBSymbol.cpp | 4 +- lldb/source/API/SBTarget.cpp | 13 +- .../Commands/CommandObjectDisassemble.cpp | 38 ++- .../Commands/CommandObjectDisassemble.h | 14 ++ lldb/source/Commands/Options.td | 4 + lldb/source/Core/Disassembler.cpp | 42 ++-- lldb/source/Core/DumpDataExtractor.cpp | 7 +- lldb/source/Expression/IRExecutionUnit.cpp | 6 +- .../Architecture/Mips/ArchitectureMips.cpp | 2 +- .../Disassembler/LLVMC/DisassemblerLLVMC.cpp | 120 ++++----- .../Disassembler/LLVMC/DisassemblerLLVMC.h | 8 +- .../Windows-DYLD/DynamicLoaderWindowsDYLD.cpp | 2 +- .../Process/Utility/StopInfoMachException.cpp | 7 +- .../UnwindAssemblyInstEmulation.cpp | 4 +- lldb/source/Symbol/Function.cpp | 6 +- lldb/source/Symbol/Symbol.cpp | 6 +- lldb/source/Target/Process.cpp | 5 +- lldb/source/Target/StackFrame.cpp | 17 +- lldb/source/Target/Target.cpp | 14 ++ lldb/source/Target/TargetProperties.td | 6 + lldb/source/Target/ThreadPlanStepRange.cpp | 6 +- lldb/source/Target/ThreadPlanTracer.cpp | 5 +- lldb/source/Target/TraceDumper.cpp | 6 +- .../command-disassemble-cpu-features.yaml | 230 ++++++++++++++++++ 30 files changed, 478 insertions(+), 143 deletions(-) create mode 100644 lldb/test/Shell/Commands/command-disassemble-cpu-features.yaml diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h index 21969aed03c209..e0ad4316e02497 100644 --- a/lldb/include/lldb/Core/Disassembler.h +++ b/lldb/include/lldb/Core/Disassembler.h @@ -409,35 +409,37 @@ class Disassembler : public std::enable_shared_from_this<Disassembler>, // flavor string gets set wrong. Instead, if you get a flavor string you // don't understand, use the default. Folks who care to check can use the // FlavorValidForArchSpec method on the disassembler they got back. - static lldb::DisassemblerSP - FindPlugin(const ArchSpec &arch, const char *flavor, const char *plugin_name); + static lldb::DisassemblerSP FindPlugin(const ArchSpec &arch, + const char *flavor, const char *cpu, + const char *features, + const char *plugin_name); // This version will use the value in the Target settings if flavor is NULL; - static lldb::DisassemblerSP FindPluginForTarget(const Target &target, - const ArchSpec &arch, - const char *flavor, - const char *plugin_name); + static lldb::DisassemblerSP + FindPluginForTarget(const Target &target, const ArchSpec &arch, + const char *flavor, const char *cpu, const char *features, + const char *plugin_name); struct Limit { enum { Bytes, Instructions } kind; lldb::addr_t value; }; - static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, - const char *plugin_name, - const char *flavor, - Target &target, - const AddressRange &disasm_range, - bool force_live_memory = false); + static lldb::DisassemblerSP + DisassembleRange(const ArchSpec &arch, const char *plugin_name, + const char *flavor, const char *cpu, const char *features, + Target &target, const AddressRange &disasm_range, + bool force_live_memory = false); static lldb::DisassemblerSP DisassembleBytes(const ArchSpec &arch, const char *plugin_name, - const char *flavor, const Address &start, const void *bytes, - size_t length, uint32_t max_num_instructions, - bool data_from_file); + const char *flavor, const char *cpu, const char *features, + const Address &start, const void *bytes, size_t length, + uint32_t max_num_instructions, bool data_from_file); static bool Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, + const char *cpu, const char *features, const ExecutionContext &exe_ctx, const Address &start, Limit limit, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, diff --git a/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h b/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h index b5e989633ea3fc..1875ff6a048d4c 100644 --- a/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h +++ b/lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h @@ -312,6 +312,8 @@ static constexpr CommandObject::ArgumentTableEntry g_argument_table[] = { { lldb::eArgTypeRemotePath, "remote-path", lldb::CompletionType::eRemoteDiskFileCompletion, {}, { nullptr, false }, "A path on the system managed by the current platform." }, { lldb::eArgTypeRemoteFilename, "remote-filename", lldb::CompletionType::eRemoteDiskFileCompletion, {}, { nullptr, false }, "A file on the system managed by the current platform." }, { lldb::eArgTypeModule, "module", lldb::CompletionType::eModuleCompletion, {}, { nullptr, false }, "The name of a module loaded into the current target." }, + { lldb::eArgTypeCPUName, "cpu-name", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The name of a CPU." }, + { lldb::eArgTypeCPUFeatures, "cpu-features", lldb::CompletionType::eNoCompletion, {}, { nullptr, false }, "The CPU feature string." }, // clang-format on }; diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index cab21c29a7486f..f4ca5df44b7878 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -119,6 +119,10 @@ class TargetProperties : public Properties { const char *GetDisassemblyFlavor() const; + const char *GetDisassemblyCPU() const; + + const char *GetDisassemblyFeatures() const; + InlineStrategy GetInlineStrategy() const; RealpathPrefixes GetSourceRealpathPrefixes() const; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 938f6e3abe8f2a..a9a66ea2662f39 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -655,6 +655,8 @@ enum CommandArgumentType { eArgTypeRemotePath, eArgTypeRemoteFilename, eArgTypeModule, + eArgTypeCPUName, + eArgTypeCPUFeatures, eArgTypeLastArg // Always keep this entry as the last entry in this // enumeration!! }; diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index 5bac5cd3e86b59..d366dbd1d78329 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -29,8 +29,9 @@ typedef lldb::ABISP (*ABICreateInstance)(lldb::ProcessSP process_sp, const ArchSpec &arch); typedef std::unique_ptr<Architecture> (*ArchitectureCreateInstance)( const ArchSpec &arch); -typedef lldb::DisassemblerSP (*DisassemblerCreateInstance)(const ArchSpec &arch, - const char *flavor); +typedef lldb::DisassemblerSP (*DisassemblerCreateInstance)( + const ArchSpec &arch, const char *flavor, const char *cpu, + const char *features); typedef DynamicLoader *(*DynamicLoaderCreateInstance)(Process *process, bool force); typedef lldb::JITLoaderSP (*JITLoaderCreateInstance)(Process *process, diff --git a/lldb/source/API/SBFunction.cpp b/lldb/source/API/SBFunction.cpp index 6a97352fc2c2fd..c07d48fe5b499d 100644 --- a/lldb/source/API/SBFunction.cpp +++ b/lldb/source/API/SBFunction.cpp @@ -125,8 +125,8 @@ SBInstructionList SBFunction::GetInstructions(SBTarget target, lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); const bool force_live_memory = true; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( - module_sp->GetArchitecture(), nullptr, flavor, *target_sp, - m_opaque_ptr->GetAddressRange(), force_live_memory)); + module_sp->GetArchitecture(), nullptr, flavor, nullptr, nullptr, + *target_sp, m_opaque_ptr->GetAddressRange(), force_live_memory)); } } return sb_instructions; diff --git a/lldb/source/API/SBSymbol.cpp b/lldb/source/API/SBSymbol.cpp index 3f940538d1240a..90920060594143 100644 --- a/lldb/source/API/SBSymbol.cpp +++ b/lldb/source/API/SBSymbol.cpp @@ -126,8 +126,8 @@ SBInstructionList SBSymbol::GetInstructions(SBTarget target, AddressRange symbol_range(symbol_addr, m_opaque_ptr->GetByteSize()); const bool force_live_memory = true; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( - module_sp->GetArchitecture(), nullptr, flavor_string, *target_sp, - symbol_range, force_live_memory)); + module_sp->GetArchitecture(), nullptr, flavor_string, nullptr, + nullptr, *target_sp, symbol_range, force_live_memory)); } } } diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 28bdf47a34137a..ff752a519d951e 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -2013,8 +2013,9 @@ lldb::SBInstructionList SBTarget::ReadInstructions(lldb::SBAddress base_addr, error, force_live_memory, &load_addr); const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; sb_instructions.SetDisassembler(Disassembler::DisassembleBytes( - target_sp->GetArchitecture(), nullptr, flavor_string, *addr_ptr, - data.GetBytes(), bytes_read, count, data_from_file)); + target_sp->GetArchitecture(), nullptr, nullptr, nullptr, + flavor_string, *addr_ptr, data.GetBytes(), bytes_read, count, + data_from_file)); } } @@ -2038,8 +2039,8 @@ lldb::SBInstructionList SBTarget::ReadInstructions(lldb::SBAddress start_addr, AddressRange range(start_load_addr, size); const bool force_live_memory = true; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( - target_sp->GetArchitecture(), nullptr, flavor_string, *target_sp, - range, force_live_memory)); + target_sp->GetArchitecture(), nullptr, flavor_string, nullptr, + nullptr, *target_sp, range, force_live_memory)); } } return sb_instructions; @@ -2071,8 +2072,8 @@ SBTarget::GetInstructionsWithFlavor(lldb::SBAddress base_addr, const bool data_from_file = true; sb_instructions.SetDisassembler(Disassembler::DisassembleBytes( - target_sp->GetArchitecture(), nullptr, flavor_string, addr, buf, size, - UINT32_MAX, data_from_file)); + target_sp->GetArchitecture(), nullptr, flavor_string, nullptr, nullptr, + addr, buf, size, UINT32_MAX, data_from_file)); } return sb_instructions; diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp index 250f849ac04c55..6db4b2665bd84a 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -120,6 +120,14 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( break; } + case 'X': + cpu_string = std::string(option_arg); + break; + + case 'Y': + features_string = std::string(option_arg); + break; + case 'r': raw = true; break; @@ -176,20 +184,27 @@ void CommandObjectDisassemble::CommandOptions::OptionParsingStarting( Target *target = execution_context ? execution_context->GetTargetPtr() : nullptr; - // This is a hack till we get the ability to specify features based on - // architecture. For now GetDisassemblyFlavor is really only valid for x86 - // (and for the llvm assembler plugin, but I'm papering over that since that - // is the only disassembler plugin we have... if (target) { + // This is a hack till we get the ability to specify features based on + // architecture. For now GetDisassemblyFlavor is really only valid for x86 + // (and for the llvm assembler plugin, but I'm papering over that since that + // is the only disassembler plugin we have... if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86 || target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64) { flavor_string.assign(target->GetDisassemblyFlavor()); - } else + } else { flavor_string.assign("default"); - - } else + } + if (const char *cpu = target->GetDisassemblyCPU()) + cpu_string.assign(cpu); + if (const char *features = target->GetDisassemblyFeatures()) + features_string.assign(features); + } else { flavor_string.assign("default"); + cpu_string.assign("default"); + features_string.assign("default"); + } arch.Clear(); some_location_specified = false; @@ -453,9 +468,11 @@ void CommandObjectDisassemble::DoExecute(Args &command, const char *plugin_name = m_options.GetPluginName(); const char *flavor_string = m_options.GetFlavorString(); + const char *cpu_string = m_options.GetCPUString(); + const char *features_string = m_options.GetFeaturesString(); - DisassemblerSP disassembler = - Disassembler::FindPlugin(m_options.arch, flavor_string, plugin_name); + DisassemblerSP disassembler = Disassembler::FindPlugin( + m_options.arch, flavor_string, cpu_string, features_string, plugin_name); if (!disassembler) { if (plugin_name) { @@ -524,7 +541,8 @@ void CommandObjectDisassemble::DoExecute(Args &command, } if (Disassembler::Disassemble( GetDebugger(), m_options.arch, plugin_name, flavor_string, - m_exe_ctx, cur_range.GetBaseAddress(), limit, m_options.show_mixed, + cpu_string, features_string, m_exe_ctx, cur_range.GetBaseAddress(), + limit, m_options.show_mixed, m_options.show_mixed ? m_options.num_lines_context : 0, options, result.GetOutputStream())) { result.SetStatus(eReturnStatusSuccessFinishResult); diff --git a/lldb/source/Commands/CommandObjectDisassemble.h b/lldb/source/Commands/CommandObjectDisassemble.h index 2e4d46dd0ec586..f9cba1e5ae9cb6 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.h +++ b/lldb/source/Commands/CommandObjectDisassemble.h @@ -42,6 +42,18 @@ class CommandObjectDisassemble : public CommandObjectParsed { return flavor_string.c_str(); } + const char *GetCPUString() { + if (cpu_string.empty() || cpu_string == "default") + return nullptr; + return cpu_string.c_str(); + } + + const char *GetFeaturesString() { + if (features_string.empty() || features_string == "default") + return nullptr; + return features_string.c_str(); + } + Status OptionParsingFinished(ExecutionContext *execution_context) override; bool show_mixed; // Show mixed source/assembly @@ -58,6 +70,8 @@ class CommandObjectDisassemble : public CommandObjectParsed { bool frame_line = false; std::string plugin_name; std::string flavor_string; + std::string cpu_string; + std::string features_string; ArchSpec arch; bool some_location_specified = false; // If no location was specified, we'll // select "at_pc". This should be set diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9d8d45d083eca4..777f8c36c4916c 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -324,6 +324,10 @@ let Command = "disassemble" in { Arg<"DisassemblyFlavor">, Desc<"Name of the disassembly flavor you want to " "use. Currently the only valid options are default, and for Intel " "architectures, att and intel.">; + def disassemble_options_cpu : Option<"cpu", "X">, Arg<"CPUName">, + Desc<"Override the CPU for disassembling.">; + def disassemble_options_features : Option<"features", "Y">, Arg<"CPUFeatures">, + Desc<"Specify additional CPU features for disassembling.">; def disassemble_options_arch : Option<"arch", "A">, Arg<"Architecture">, Desc<"Specify the architecture to use from cross disassembly.">; def disassemble_options_start_address : Option<"start-address", "s">, diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index d071e3bfe4f77d..522a3ef2efc334 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -56,7 +56,8 @@ using namespace lldb; using namespace lldb_private; DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch, - const char *flavor, + const char *flavor, const char *cpu, + const char *features, const char *plugin_name) { LLDB_SCOPED_TIMERF("Disassembler::FindPlugin (arch = %s, plugin_name = %s)", arch.GetArchitectureName(), plugin_name); @@ -67,7 +68,7 @@ DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch, create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName(plugin_name); if (create_callback) { - if (auto disasm_sp = create_callback(arch, flavor)) + if (auto disasm_sp = create_callback(arch, flavor, cpu, features)) return disasm_sp; } } else { @@ -75,18 +76,17 @@ DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch, (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex( idx)) != nullptr; ++idx) { - if (auto disasm_sp = create_callback(arch, flavor)) + if (auto disasm_sp = create_callback(arch, flavor, cpu, features)) return disasm_sp; } } return DisassemblerSP(); } -DisassemblerSP Disassembler::FindPluginForTarget(const Target &target, - const ArchSpec &arch, - const char *flavor, - const char *plugin_name) { - if (flavor == nullptr) { +DisassemblerSP Disassembler::FindPluginForTarget( + const Target &target, const ArchSpec &arch, const char *flavor, + const char *cpu, const char *features, const char *plugin_name) { + if (!flavor) { // FIXME - we don't have the mechanism in place to do per-architecture // settings. But since we know that for now we only support flavors on x86 // & x86_64, @@ -94,7 +94,12 @@ DisassemblerSP Disassembler::FindPluginForTarget(const Target &target, arch.GetTriple().getArch() == llvm::Triple::x86_64) flavor = target.GetDisassemblyFlavor(); } - return FindPlugin(arch, flavor, plugin_name); + if (!cpu) + cpu = target.GetDisassemblyCPU(); + if (!features) + features = target.GetDisassemblyFeatures(); + + return FindPlugin(arch, flavor, cpu, features, plugin_name); } static Address ResolveAddress(Target &target, const Address &addr) { @@ -117,15 +122,16 @@ static Address ResolveAddress(Target &target, const Address &addr) { lldb::DisassemblerSP Disassembler::DisassembleRange( const ArchSpec &arch, const char *plugin_name, const char *flavor, - Target &target, const AddressRange &range, bool force_live_memory) { + const char *cpu, const char *features, Target &target, + const AddressRange &range, bool force_live_memory) { if (range.GetByteSize() <= 0) return {}; if (!range.GetBaseAddress().IsValid()) return {}; - lldb::DisassemblerSP disasm_sp = - Disassembler::FindPluginForTarget(target, arch, flavor, plugin_name); + lldb::DisassemblerSP disasm_sp = Disassembler::FindPluginForTarget( + target, arch, flavor, cpu, features, plugin_name); if (!disasm_sp) return {}; @@ -141,14 +147,15 @@ lldb::DisassemblerSP Disassembler::DisassembleRange( lldb::DisassemblerSP Disassembler::DisassembleBytes(const ArchSpec &arch, const char *plugin_name, - const char *flavor, const Address &start, + const char *flavor, const char *cpu, + const char *features, const Address &start, const void *src, size_t src_len, uint32_t num_instructions, bool data_from_file) { if (!src) return {}; lldb::DisassemblerSP disasm_sp = - Disassembler::FindPlugin(arch, flavor, plugin_name); + Disassembler::FindPlugin(arch, flavor, cpu, features, plugin_name); if (!disasm_sp) return {}; @@ -163,6 +170,7 @@ Disassembler::DisassembleBytes(const ArchSpec &arch, const char *plugin_name, bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, + const char *cpu, const char *features, const ExecutionContext &exe_ctx, const Address &address, Limit limit, bool mixed_source_and_assembly, @@ -172,7 +180,7 @@ bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, return false; lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget( - exe_ctx.GetTargetRef(), arch, flavor, plugin_name)); + exe_ctx.GetTargetRef(), arch, flavor, cpu, features, plugin_name)); if (!disasm_sp) return false; @@ -559,8 +567,8 @@ bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, if (limit.value == 0) limit.value = DEFAULT_DISASM_BYTE_SIZE; - return Disassemble(debugger, arch, nullptr, nullptr, frame, - range.GetBaseAddress(), limit, false, 0, 0, strm); + return Disassemble(debugger, arch, nullptr, nullptr, nullptr, nullptr, + frame, range.GetBaseAddress(), limit, false, 0, 0, strm); } Instruction::Instruction(const Address &address, AddressClass addr_class) diff --git a/lldb/source/Core/DumpDataExtractor.cpp b/lldb/source/Core/DumpDataExtractor.cpp index 826edd7bab046e..565ee3a0ae40a4 100644 --- a/lldb/source/Core/DumpDataExtractor.cpp +++ b/lldb/source/Core/DumpDataExtractor.cpp @@ -128,9 +128,10 @@ static lldb::offset_t DumpInstructions(const DataExtractor &DE, Stream *s, if (exe_scope) target_sp = exe_scope->CalculateTarget(); if (target_sp) { - DisassemblerSP disassembler_sp( - Disassembler::FindPlugin(target_sp->GetArchitecture(), - target_sp->GetDisassemblyFlavor(), nullptr)); + DisassemblerSP disassembler_sp(Disassembler::FindPlugin( + target_sp->GetArchitecture(), target_sp->GetDisassemblyFlavor(), + target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(), + nullptr)); if (disassembler_sp) { lldb::addr_t addr = base_addr + start_offset; lldb_private::Address so_addr; diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index 7bee183d2ff227..9158b43b1c5c0d 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -167,8 +167,10 @@ Status IRExecutionUnit::DisassembleFunction(Stream &stream, const char *plugin_name = nullptr; const char *flavor_string = nullptr; - lldb::DisassemblerSP disassembler_sp = - Disassembler::FindPlugin(arch, flavor_string, plugin_name); + const char *cpu_string = nullptr; + const char *features_string = nullptr; + lldb::DisassemblerSP disassembler_sp = Disassembler::FindPlugin( + arch, flavor_string, cpu_string, features_string, plugin_name); if (!disassembler_sp) { ret = Status::FromErrorStringWithFormat( diff --git a/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp index a9f2e7af601db9..27ba10524141ed 100644 --- a/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp +++ b/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp @@ -150,7 +150,7 @@ Instruction *ArchitectureMips::GetInstructionAtAddress( // Create Disassembler Instance lldb::DisassemblerSP disasm_sp( - Disassembler::FindPlugin(m_arch, nullptr, nullptr)); + Disassembler::FindPlugin(m_arch, nullptr, nullptr, nullptr, nullptr)); InstructionList instruction_list; InstructionSP prev_insn; diff --git a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp index 31edd8d46c444e..e108e92fcca4ce 100644 --- a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp +++ b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp @@ -1439,7 +1439,9 @@ bool DisassemblerLLVMC::MCDisasmInstance::IsAuthenticated( } DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, - const char *flavor_string) + const char *flavor_string, + const char *cpu_string, + const char *features_string) : Disassembler(arch, flavor_string), m_exe_ctx(nullptr), m_inst(nullptr), m_data_from_file(false), m_adrp_address(LLDB_INVALID_ADDRESS), m_adrp_insn() { @@ -1447,6 +1449,7 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, m_flavor.assign("default"); } + const bool cpu_or_features_overriden = cpu_string || features_string; unsigned flavor = ~0U; llvm::Triple triple = arch.GetTriple(); @@ -1483,64 +1486,68 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, triple.getSubArch() == llvm::Triple::NoSubArch) triple.setArchName("armv9.3a"); - std::string features_str; + std::string features_str = + features_string ? std::string(features_string) : ""; const char *triple_str = triple.getTriple().c_str(); // ARM Cortex M0-M7 devices only execute thumb instructions if (arch.IsAlwaysThumbInstructions()) { triple_str = thumb_arch.GetTriple().getTriple().c_str(); - features_str += "+fp-armv8,"; + if (!features_string) + features_str += "+fp-armv8,"; } - const char *cpu = ""; + const char *cpu = cpu_string; - switch (arch.GetCore()) { - case ArchSpec::eCore_mips32: - case ArchSpec::eCore_mips32el: - cpu = "mips32"; - break; - case ArchSpec::eCore_mips32r2: - case ArchSpec::eCore_mips32r2el: - cpu = "mips32r2"; - break; - case ArchSpec::eCore_mips32r3: - case ArchSpec::eCore_mips32r3el: - cpu = "mips32r3"; - break; - case ArchSpec::eCore_mips32r5: - case ArchSpec::eCore_mips32r5el: - cpu = "mips32r5"; - break; - case ArchSpec::eCore_mips32r6: - case ArchSpec::eCore_mips32r6el: - cpu = "mips32r6"; - break; - case ArchSpec::eCore_mips64: - case ArchSpec::eCore_mips64el: - cpu = "mips64"; - break; - case ArchSpec::eCore_mips64r2: - case ArchSpec::eCore_mips64r2el: - cpu = "mips64r2"; - break; - case ArchSpec::eCore_mips64r3: - case ArchSpec::eCore_mips64r3el: - cpu = "mips64r3"; - break; - case ArchSpec::eCore_mips64r5: - case ArchSpec::eCore_mips64r5el: - cpu = "mips64r5"; - break; - case ArchSpec::eCore_mips64r6: - case ArchSpec::eCore_mips64r6el: - cpu = "mips64r6"; - break; - default: - cpu = ""; - break; + if (!cpu_or_features_overriden) { + switch (arch.GetCore()) { + case ArchSpec::eCore_mips32: + case ArchSpec::eCore_mips32el: + cpu = "mips32"; + break; + case ArchSpec::eCore_mips32r2: + case ArchSpec::eCore_mips32r2el: + cpu = "mips32r2"; + break; + case ArchSpec::eCore_mips32r3: + case ArchSpec::eCore_mips32r3el: + cpu = "mips32r3"; + break; + case ArchSpec::eCore_mips32r5: + case ArchSpec::eCore_mips32r5el: + cpu = "mips32r5"; + break; + case ArchSpec::eCore_mips32r6: + case ArchSpec::eCore_mips32r6el: + cpu = "mips32r6"; + break; + case ArchSpec::eCore_mips64: + case ArchSpec::eCore_mips64el: + cpu = "mips64"; + break; + case ArchSpec::eCore_mips64r2: + case ArchSpec::eCore_mips64r2el: + cpu = "mips64r2"; + break; + case ArchSpec::eCore_mips64r3: + case ArchSpec::eCore_mips64r3el: + cpu = "mips64r3"; + break; + case ArchSpec::eCore_mips64r5: + case ArchSpec::eCore_mips64r5el: + cpu = "mips64r5"; + break; + case ArchSpec::eCore_mips64r6: + case ArchSpec::eCore_mips64r6el: + cpu = "mips64r6"; + break; + default: + cpu = ""; + break; + } } - if (arch.IsMIPS()) { + if (arch.IsMIPS() && !cpu_or_features_overriden) { uint32_t arch_flags = arch.GetFlags(); if (arch_flags & ArchSpec::eMIPSAse_msa) features_str += "+msa,"; @@ -1550,15 +1557,15 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, features_str += "+dspr2,"; } - // If any AArch64 variant, enable latest ISA with all extensions. - if (triple.isAArch64()) { + // If any AArch64 variant, enable latest ISA with all extensions unless the + // CPU or features were overridden. + if (triple.isAArch64() && !cpu_or_features_overriden) { features_str += "+all,"; - if (triple.getVendor() == llvm::Triple::Apple) cpu = "apple-latest"; } - if (triple.isRISCV()) { + if (triple.isRISCV() && !cpu_or_features_overriden) { uint32_t arch_flags = arch.GetFlags(); if (arch_flags & ArchSpec::eRISCV_rvc) features_str += "+c,"; @@ -1614,9 +1621,12 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, DisassemblerLLVMC::~DisassemblerLLVMC() = default; lldb::DisassemblerSP DisassemblerLLVMC::CreateInstance(const ArchSpec &arch, - const char *flavor) { + const char *flavor, + const char *cpu, + const char *features) { if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch) { - auto disasm_sp = std::make_shared<DisassemblerLLVMC>(arch, flavor); + auto disasm_sp = + std::make_shared<DisassemblerLLVMC>(arch, flavor, cpu, features); if (disasm_sp && disasm_sp->IsValid()) return disasm_sp; } diff --git a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h index 30c69de81dfc83..d6b3d70934989b 100644 --- a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h +++ b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h @@ -22,8 +22,8 @@ class InstructionLLVMC; class DisassemblerLLVMC : public lldb_private::Disassembler { public: - DisassemblerLLVMC(const lldb_private::ArchSpec &arch, - const char *flavor /* = NULL */); + DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor, + const char *cpu, const char *features); ~DisassemblerLLVMC() override; @@ -35,7 +35,9 @@ class DisassemblerLLVMC : public lldb_private::Disassembler { static llvm::StringRef GetPluginNameStatic() { return "llvm-mc"; } static lldb::DisassemblerSP CreateInstance(const lldb_private::ArchSpec &arch, - const char *flavor); + const char *flavor, + const char *cpu, + const char *features); size_t DecodeInstructions(const lldb_private::Address &base_addr, const lldb_private::DataExtractor &data, diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp index f044aa786806fc..348cf58d69243d 100644 --- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp @@ -183,7 +183,7 @@ DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, AddressRange range(pc, 2 * 15); DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( - arch, nullptr, nullptr, m_process->GetTarget(), range); + arch, nullptr, nullptr, nullptr, nullptr, m_process->GetTarget(), range); if (!disassembler_sp) { return ThreadPlanSP(); } diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 25cee369d7ee3d..d08e99f4844de3 100644 --- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -48,10 +48,13 @@ GetPtrauthInstructionInfo(Target &target, const ArchSpec &arch, const Address &at_addr) { const char *plugin_name = nullptr; const char *flavor = nullptr; + const char *cpu = nullptr; + const char *features = nullptr; AddressRange range_bounds(at_addr, 4); const bool prefer_file_cache = true; - DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( - arch, plugin_name, flavor, target, range_bounds, prefer_file_cache); + DisassemblerSP disassembler_sp = + Disassembler::DisassembleRange(arch, plugin_name, flavor, cpu, features, + target, range_bounds, prefer_file_cache); if (!disassembler_sp) return std::nullopt; diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp index 1a680d80a9d3d7..8a26d76b65d1b4 100644 --- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -70,8 +70,8 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly( const bool prefer_file_cache = true; DisassemblerSP disasm_sp(Disassembler::DisassembleBytes( - m_arch, nullptr, nullptr, range.GetBaseAddress(), opcode_data, - opcode_size, 99999, prefer_file_cache)); + m_arch, nullptr, nullptr, nullptr, nullptr, range.GetBaseAddress(), + opcode_data, opcode_size, 99999, prefer_file_cache)); Log *log = GetLog(LLDBLog::Unwind); diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index 96d8322b43d843..04766e26674c8c 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -459,9 +459,9 @@ lldb::DisassemblerSP Function::GetInstructions(const ExecutionContext &exe_ctx, bool prefer_file_cache) { ModuleSP module_sp(GetAddressRange().GetBaseAddress().GetModule()); if (module_sp && exe_ctx.HasTargetScope()) { - return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr, - flavor, exe_ctx.GetTargetRef(), - GetAddressRange(), !prefer_file_cache); + return Disassembler::DisassembleRange( + module_sp->GetArchitecture(), nullptr, nullptr, nullptr, flavor, + exe_ctx.GetTargetRef(), GetAddressRange(), !prefer_file_cache); } return lldb::DisassemblerSP(); } diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 9b0042ffdb4bfe..4828de4fdfa377 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -591,9 +591,9 @@ lldb::DisassemblerSP Symbol::GetInstructions(const ExecutionContext &exe_ctx, bool prefer_file_cache) { ModuleSP module_sp(m_addr_range.GetBaseAddress().GetModule()); if (module_sp && exe_ctx.HasTargetScope()) { - return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr, - flavor, exe_ctx.GetTargetRef(), - m_addr_range, !prefer_file_cache); + return Disassembler::DisassembleRange( + module_sp->GetArchitecture(), nullptr, flavor, nullptr, nullptr, + exe_ctx.GetTargetRef(), m_addr_range, !prefer_file_cache); } return lldb::DisassemblerSP(); } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index c009d17d3ba507..b99692b8a0bfd9 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -6144,8 +6144,11 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr, const char *plugin_name = nullptr; const char *flavor = nullptr; + const char *cpu = nullptr; + const char *features = nullptr; disassembler_sp = Disassembler::DisassembleRange( - target.GetArchitecture(), plugin_name, flavor, GetTarget(), range_bounds); + target.GetArchitecture(), plugin_name, flavor, cpu, features, GetTarget(), + range_bounds); if (disassembler_sp) insn_list = &disassembler_sp->GetInstructionList(); diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 3761b867452c99..ef71fc6acb1703 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -1316,11 +1316,13 @@ lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) { const char *plugin_name = nullptr; const char *flavor = nullptr; + const char *cpu = nullptr; + const char *features = nullptr; const bool force_live_memory = true; - DisassemblerSP disassembler_sp = - Disassembler::DisassembleRange(target_arch, plugin_name, flavor, - *target_sp, pc_range, force_live_memory); + DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( + target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range, + force_live_memory); if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) { return ValueObjectSP(); @@ -1697,10 +1699,12 @@ lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg, const char *plugin_name = nullptr; const char *flavor = nullptr; + const char *cpu = nullptr; + const char *features = nullptr; const bool force_live_memory = true; - DisassemblerSP disassembler_sp = - Disassembler::DisassembleRange(target_arch, plugin_name, flavor, - *target_sp, pc_range, force_live_memory); + DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( + target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range, + force_live_memory); if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) { return ValueObjectSP(); @@ -1966,6 +1970,7 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source, const bool mixed_source_and_assembly = false; Disassembler::Disassemble( target->GetDebugger(), target_arch, plugin_name, flavor, + target->GetDisassemblyCPU(), target->GetDisassemblyFeatures(), exe_ctx, GetFrameCodeAddress(), {Disassembler::Limit::Instructions, disasm_lines}, mixed_source_and_assembly, 0, diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 242d2eaec2a15a..a788bad88b2977 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -4490,6 +4490,20 @@ const char *TargetProperties::GetDisassemblyFlavor() const { return return_value; } +const char *TargetProperties::GetDisassemblyCPU() const { + const uint32_t idx = ePropertyDisassemblyCPU; + llvm::StringRef str = GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_target_properties[idx].default_cstr_value); + return str.empty() ? nullptr : str.data(); +} + +const char *TargetProperties::GetDisassemblyFeatures() const { + const uint32_t idx = ePropertyDisassemblyFeatures; + llvm::StringRef str = GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_target_properties[idx].default_cstr_value); + return str.empty() ? nullptr : str.data(); +} + InlineStrategy TargetProperties::GetInlineStrategy() const { const uint32_t idx = ePropertyInlineStrategy; return GetPropertyAtIndexAs<InlineStrategy>( diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td index 00ad8dd2a9f7f9..d8d7e6353aad43 100644 --- a/lldb/source/Target/TargetProperties.td +++ b/lldb/source/Target/TargetProperties.td @@ -157,6 +157,12 @@ let Definition = "target" in { DefaultEnumValue<"eX86DisFlavorDefault">, EnumValues<"OptionEnumValues(g_x86_dis_flavor_value_types)">, Desc<"The default disassembly flavor to use for x86 or x86-64 targets.">; + def DisassemblyCPU: Property<"disassembly-cpu", "String">, + DefaultStringValue<"">, + Desc<"Override the CPU for disassembling. Takes the same values as the -mcpu compiler flag.">; + def DisassemblyFeatures: Property<"disassembly-features", "String">, + DefaultStringValue<"">, + Desc<"Specify additional CPU features for disassembling.">; def UseHexImmediates: Property<"use-hex-immediates", "Boolean">, DefaultTrue, Desc<"Show immediates in disassembly as hexadecimal.">; diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp index b64ce6f0dc9c28..de4cd5995f6953 100644 --- a/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp @@ -266,9 +266,11 @@ InstructionList *ThreadPlanStepRange::GetInstructionsForAddress( // Disassemble the address range given: const char *plugin_name = nullptr; const char *flavor = nullptr; + const char *cpu = nullptr; + const char *features = nullptr; m_instruction_ranges[i] = Disassembler::DisassembleRange( - GetTarget().GetArchitecture(), plugin_name, flavor, GetTarget(), - m_address_ranges[i]); + GetTarget().GetArchitecture(), plugin_name, flavor, cpu, features, + GetTarget(), m_address_ranges[i]); } if (!m_instruction_ranges[i]) return nullptr; diff --git a/lldb/source/Target/ThreadPlanTracer.cpp b/lldb/source/Target/ThreadPlanTracer.cpp index acadda8f582f9d..ff9f49c6d4bb68 100644 --- a/lldb/source/Target/ThreadPlanTracer.cpp +++ b/lldb/source/Target/ThreadPlanTracer.cpp @@ -95,8 +95,9 @@ ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer(Thread &thread) Disassembler *ThreadPlanAssemblyTracer::GetDisassembler() { if (!m_disassembler_sp) - m_disassembler_sp = Disassembler::FindPlugin( - m_process.GetTarget().GetArchitecture(), nullptr, nullptr); + m_disassembler_sp = + Disassembler::FindPlugin(m_process.GetTarget().GetArchitecture(), + nullptr, nullptr, nullptr, nullptr); return m_disassembler_sp.get(); } diff --git a/lldb/source/Target/TraceDumper.cpp b/lldb/source/Target/TraceDumper.cpp index 4ef8efc1a67689..fa732fa87c5290 100644 --- a/lldb/source/Target/TraceDumper.cpp +++ b/lldb/source/Target/TraceDumper.cpp @@ -510,9 +510,9 @@ CalculateDisass(const TraceDumper::SymbolInfo &symbol_info, const ArchSpec arch = target.GetArchitecture(); lldb_private::AddressRange range(symbol_info.address, arch.GetMaximumOpcodeByteSize()); - DisassemblerSP disassembler = - Disassembler::DisassembleRange(arch, /*plugin_name*/ nullptr, - /*flavor*/ nullptr, target, range); + DisassemblerSP disassembler = Disassembler::DisassembleRange( + arch, /*plugin_name=*/nullptr, + /*flavor=*/nullptr, /*cpu=*/nullptr, /*features=*/nullptr, target, range); return std::make_tuple( disassembler, disassembler ? disassembler->GetInstructionList().GetInstructionAtAddress( diff --git a/lldb/test/Shell/Commands/command-disassemble-cpu-features.yaml b/lldb/test/Shell/Commands/command-disassemble-cpu-features.yaml new file mode 100644 index 00000000000000..199e78f4474ca6 --- /dev/null +++ b/lldb/test/Shell/Commands/command-disassemble-cpu-features.yaml @@ -0,0 +1,230 @@ +# REQUIRES: aarch64 + +# RUN: yaml2obj %s -o %t.out + +# RUN: %lldb %t.out -b -o "disassemble -c 1 --cpu 'apple-a16' -n main" | FileCheck %s --check-prefix SUPPORTED +# RUN: %lldb %t.out -b -o "disassemble -c 1 --cpu 'apple-a11' -n main" | FileCheck %s --check-prefix UNSUPPORTED +# RUN: %lldb %t.out -b -o "disassemble -c 1 --cpu 'apple-a11' --features '+all' -n main" | FileCheck %s --check-prefix SUPPORTED + +# RUN: %lldb %t.out -b -o "settings set target.disassembly-cpu 'apple-a16'" -o "disassemble -c 1 -n main" | FileCheck %s --check-prefix SUPPORTED +# RUN: %lldb %t.out -b -o "settings set target.disassembly-cpu 'apple-a11'" -o "disassemble -c 1 -n main" | FileCheck %s --check-prefix UNSUPPORTED +# RUN: %lldb %t.out -b -o "settings set target.disassembly-cpu 'apple-a11'" -o "settings set target.disassembly-features '+all'" -o "disassemble -c 1 -n main" | FileCheck %s --check-prefix SUPPORTED + +# SUPPORTED: <+0>: pacibsp +# UNSUPPORTED-NOT: <+0>: pacibsp + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x80000002 + filetype: 0x2 + ncmds: 17 + sizeofcmds: 1056 + flags: 0x200085 + reserved: 0x0 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 4294967296 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x100000460 + size: 36 + offset: 0x460 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 7F2303D5FD7BBFA9FD03009100000090005012910400009400008052FD7BC1A8FF0F5FD6 + - sectname: __cstring + segname: __TEXT + addr: 0x100000494 + size: 3 + offset: 0x494 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '484900' + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 4294983680 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4295000064 + vmsize: 16384 + fileoff: 32768 + filesize: 664 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 32920 + nsyms: 3 + stroff: 32976 + strsize: 40 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 2 + iundefsym: 2 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 32968 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_LOAD_DYLINKER + cmdsize: 32 + name: 12 + Content: '/usr/lib/dyld' + ZeroPadBytes: 7 + - cmd: LC_UUID + cmdsize: 24 + uuid: CF3EBEFA-8D83-3C25-931A-5AF74AFE0B3A + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983808 + ntools: 1 + Tools: + - tool: 3 + version: 76153600 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_MAIN + cmdsize: 24 + entryoff: 1120 + stacksize: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 32912 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 32920 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 33024 + datasize: 408 +LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 0 + NodeOffset: 18 + Name: _ + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 2 + NodeOffset: 9 + Name: _mh_execute_header + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 13 + Name: main + Flags: 0x0 + Address: 0x460 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 22 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 4294968416 + - n_strx: 28 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - __mh_execute_header + - _main + - _puts + - '' + - '' + - '' + - '' + - '' + - '' + IndirectSymbols: [ 0x2, 0x2 ] + FunctionStarts: [ 0x460 ] +... >From 584eba125a8263d3739a28739a8ca27a39a3107c Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Thu, 7 Nov 2024 16:29:10 -0800 Subject: [PATCH 2/4] Address Jason's feedback --- lldb/source/Target/TargetProperties.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td index d8d7e6353aad43..4faf4c26b57011 100644 --- a/lldb/source/Target/TargetProperties.td +++ b/lldb/source/Target/TargetProperties.td @@ -159,7 +159,7 @@ let Definition = "target" in { Desc<"The default disassembly flavor to use for x86 or x86-64 targets.">; def DisassemblyCPU: Property<"disassembly-cpu", "String">, DefaultStringValue<"">, - Desc<"Override the CPU for disassembling. Takes the same values as the -mcpu compiler flag.">; + Desc<"Override the CPU for disassembling. Takes the same values as the -mcpu clang flag.">; def DisassemblyFeatures: Property<"disassembly-features", "String">, DefaultStringValue<"">, Desc<"Specify additional CPU features for disassembling.">; >From 390624d7f63ac85f616e568dd7f8c38424b1cb6f Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Thu, 7 Nov 2024 16:29:56 -0800 Subject: [PATCH 3/4] Update unit test --- lldb/unittests/Disassembler/ARM/TestArm64Disassembly.cpp | 5 +++-- lldb/unittests/Disassembler/ARM/TestArmv7Disassembly.cpp | 5 +++-- .../Disassembler/RISCV/TestMCDisasmInstanceRISCV.cpp | 6 +++--- .../Disassembler/x86/TestGetControlFlowKindx86.cpp | 6 +++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lldb/unittests/Disassembler/ARM/TestArm64Disassembly.cpp b/lldb/unittests/Disassembler/ARM/TestArm64Disassembly.cpp index f89a918e3e54fa..dcca1a7ae959b3 100644 --- a/lldb/unittests/Disassembler/ARM/TestArm64Disassembly.cpp +++ b/lldb/unittests/Disassembler/ARM/TestArm64Disassembly.cpp @@ -56,8 +56,9 @@ TEST_F(TestArm64Disassembly, TestArmv81Instruction) { DisassemblerSP disass_sp; Address start_addr(0x100); - disass_sp = Disassembler::DisassembleBytes(arch, nullptr, nullptr, start_addr, - &data, sizeof (data), num_of_instructions, false); + disass_sp = Disassembler::DisassembleBytes( + arch, nullptr, nullptr, nullptr, nullptr, start_addr, &data, sizeof(data), + num_of_instructions, false); // If we failed to get a disassembler, we can assume it is because // the llvm we linked against was not built with the ARM target, diff --git a/lldb/unittests/Disassembler/ARM/TestArmv7Disassembly.cpp b/lldb/unittests/Disassembler/ARM/TestArmv7Disassembly.cpp index 047cba1db40821..00632cc57f005b 100644 --- a/lldb/unittests/Disassembler/ARM/TestArmv7Disassembly.cpp +++ b/lldb/unittests/Disassembler/ARM/TestArmv7Disassembly.cpp @@ -64,8 +64,9 @@ TEST_F(TestArmv7Disassembly, TestCortexFPDisass) { DisassemblerSP disass_sp; Address start_addr(0x100); - disass_sp = Disassembler::DisassembleBytes(arch, nullptr, nullptr, start_addr, - &data, sizeof (data), num_of_instructions, false); + disass_sp = Disassembler::DisassembleBytes( + arch, nullptr, nullptr, nullptr, nullptr, start_addr, &data, sizeof(data), + num_of_instructions, false); // If we failed to get a disassembler, we can assume it is because // the llvm we linked against was not built with the ARM target, diff --git a/lldb/unittests/Disassembler/RISCV/TestMCDisasmInstanceRISCV.cpp b/lldb/unittests/Disassembler/RISCV/TestMCDisasmInstanceRISCV.cpp index 2f2585a23d7624..8ec5d62a99ac57 100644 --- a/lldb/unittests/Disassembler/RISCV/TestMCDisasmInstanceRISCV.cpp +++ b/lldb/unittests/Disassembler/RISCV/TestMCDisasmInstanceRISCV.cpp @@ -56,9 +56,9 @@ TEST_F(TestMCDisasmInstanceRISCV, TestRISCV32Instruction) { DisassemblerSP disass_sp; Address start_addr(0x100); - disass_sp = - Disassembler::DisassembleBytes(arch, nullptr, nullptr, start_addr, &data, - sizeof (data), num_of_instructions, false); + disass_sp = Disassembler::DisassembleBytes( + arch, nullptr, nullptr, nullptr, nullptr, start_addr, &data, sizeof(data), + num_of_instructions, false); // If we failed to get a disassembler, we can assume it is because // the llvm we linked against was not built with the riscv target, diff --git a/lldb/unittests/Disassembler/x86/TestGetControlFlowKindx86.cpp b/lldb/unittests/Disassembler/x86/TestGetControlFlowKindx86.cpp index e9d5ae3f7b3cdb..4b62e5f747529c 100644 --- a/lldb/unittests/Disassembler/x86/TestGetControlFlowKindx86.cpp +++ b/lldb/unittests/Disassembler/x86/TestGetControlFlowKindx86.cpp @@ -124,9 +124,9 @@ TEST_F(TestGetControlFlowKindx86, TestX86_64Instruction) { DisassemblerSP disass_sp; Address start_addr(0x100); - disass_sp = - Disassembler::DisassembleBytes(arch, nullptr, nullptr, start_addr, &data, - sizeof (data), num_of_instructions, false); + disass_sp = Disassembler::DisassembleBytes( + arch, nullptr, nullptr, nullptr, nullptr, start_addr, &data, sizeof(data), + num_of_instructions, false); // If we failed to get a disassembler, we can assume it is because // the llvm we linked against was not built with the i386 target, >From 3e3b00b96489ee0975c1b88fe3775642570ee123 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Fri, 8 Nov 2024 09:32:46 -0800 Subject: [PATCH 4/4] Honor the setting in the SBAPI --- lldb/source/API/SBFunction.cpp | 3 ++- lldb/source/API/SBSymbol.cpp | 5 +++-- lldb/source/API/SBTarget.cpp | 14 ++++++++------ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lldb/source/API/SBFunction.cpp b/lldb/source/API/SBFunction.cpp index c07d48fe5b499d..ac61220ec8736a 100644 --- a/lldb/source/API/SBFunction.cpp +++ b/lldb/source/API/SBFunction.cpp @@ -125,7 +125,8 @@ SBInstructionList SBFunction::GetInstructions(SBTarget target, lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); const bool force_live_memory = true; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( - module_sp->GetArchitecture(), nullptr, flavor, nullptr, nullptr, + module_sp->GetArchitecture(), nullptr, flavor, + target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(), *target_sp, m_opaque_ptr->GetAddressRange(), force_live_memory)); } } diff --git a/lldb/source/API/SBSymbol.cpp b/lldb/source/API/SBSymbol.cpp index 90920060594143..79477dd3a70fc6 100644 --- a/lldb/source/API/SBSymbol.cpp +++ b/lldb/source/API/SBSymbol.cpp @@ -126,8 +126,9 @@ SBInstructionList SBSymbol::GetInstructions(SBTarget target, AddressRange symbol_range(symbol_addr, m_opaque_ptr->GetByteSize()); const bool force_live_memory = true; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( - module_sp->GetArchitecture(), nullptr, flavor_string, nullptr, - nullptr, *target_sp, symbol_range, force_live_memory)); + module_sp->GetArchitecture(), nullptr, flavor_string, + target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(), + *target_sp, symbol_range, force_live_memory)); } } } diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index ff752a519d951e..3c4c3d8d85292e 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -2013,9 +2013,9 @@ lldb::SBInstructionList SBTarget::ReadInstructions(lldb::SBAddress base_addr, error, force_live_memory, &load_addr); const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; sb_instructions.SetDisassembler(Disassembler::DisassembleBytes( - target_sp->GetArchitecture(), nullptr, nullptr, nullptr, - flavor_string, *addr_ptr, data.GetBytes(), bytes_read, count, - data_from_file)); + target_sp->GetArchitecture(), nullptr, target_sp->GetDisassemblyCPU(), + target_sp->GetDisassemblyFeatures(), flavor_string, *addr_ptr, + data.GetBytes(), bytes_read, count, data_from_file)); } } @@ -2039,8 +2039,9 @@ lldb::SBInstructionList SBTarget::ReadInstructions(lldb::SBAddress start_addr, AddressRange range(start_load_addr, size); const bool force_live_memory = true; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( - target_sp->GetArchitecture(), nullptr, flavor_string, nullptr, - nullptr, *target_sp, range, force_live_memory)); + target_sp->GetArchitecture(), nullptr, flavor_string, + target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(), + *target_sp, range, force_live_memory)); } } return sb_instructions; @@ -2072,7 +2073,8 @@ SBTarget::GetInstructionsWithFlavor(lldb::SBAddress base_addr, const bool data_from_file = true; sb_instructions.SetDisassembler(Disassembler::DisassembleBytes( - target_sp->GetArchitecture(), nullptr, flavor_string, nullptr, nullptr, + target_sp->GetArchitecture(), nullptr, flavor_string, + target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(), addr, buf, size, UINT32_MAX, data_from_file)); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits