-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb] Support overriding the disassembly CPU & features #115382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[lldb] Support overriding the disassembly CPU & features #115382
Conversation
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.
@llvm/pr-subscribers-lldb Author: Jonas Devlieghere (JDevlieghere) ChangesAdd the ability to override the disassembly CPU and CPU features through a target setting ( 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. Patch is 49.22 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/115382.diff 30 Files Affected:
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::Disassemb...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, but I do wonder if we should get the target settings at least in the ReadInstruction/GetInstruction SB API methods when creating the disassembler, otherwise a UI which shows disassembly to the user won't reflect the settings the user has made. What do you think?
@@ -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.">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe -mcpu clang flag
? If another compiler has a -mcpu, it's unlikely the names would be the same as llvm/clang's.
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.">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably fine as-is, but these are llvm's ISA feature names, which are specific to llvm's naming. But I don't see them exposed to user through any well-known command line options (clang, tool) so it's probably better to leave this as-is, and not get into the details of what a CPU feature is. For instance a RISCV specification like RV32IMAF would be a riscv32 triple with +i,+m,+a,+f
, a unique llvm way of expressing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I were a risc-v clang user I'd probably reference this:
$ ./bin/clang -target riscv64-linux-gnu --print-supported-extensions
clang version 20.0.0git (https://github.com/llvm/llvm-project.git 5f342816efe1854333f2be41a03fdd25fa0db433)
Target: riscv64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/david.spickett/build-llvm-aarch64/bin
Build config: +assertions
All available -march extensions for RISC-V
Name Version Description
i 2.1 'I' (Base Integer Instruction Set)
e 2.0 Implements RV{32,64}E (provides 16 rather than 32 GPRs)
Assuming I knew to add the +
on. This works for AArch64 as well.
For AArch64 I know some of the MC names are slightly different (because we made mistakes, e.g. memtag
and mte
) so that could be interesting for a user here.
If the CPU option takes -mcpu
I'd expect this to take -march
names. I see +all
though so I assume this actually takes llvm-mc -mattr=
names.
It would be nice to use the frontend names but doing so is probably more hassle than it's worth given that the users of this setting probably know how to figure it out anyway for the few cases where the name is different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's helpful, yes I was talking to Jonas about how you have to read the RISCVFeatures.td table in the llvm sources to get the names that llvm uses for the ISA extensions there, but we didn't want to document that. I didn't realize there was a commandline way of dumping them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW my thought was that most e.g. RISC-V users will be specifying a CPU (a collection of ISA extensions) -- they already had to specify that cpu string when compiling with clang, so they would know the cpu name that clang recognizes. It seemed less common that someone would want/need to specify a set of ISA extensions manually for a target, but an important capability to have available.
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. (cherry picked from commit f109517)
[lldb] Support overriding the disassembly CPU & features (llvm#115382)
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.
Add the ability to override the disassembly CPU and CPU features through a target setting (
target.disassembly-cpu
andtarget.disassembly-features
) and adisassemble
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.