Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions lldb/include/lldb/Core/Disassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down
4 changes: 4 additions & 0 deletions lldb/include/lldb/Target/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/lldb-enumerations.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,8 @@ enum CommandArgumentType {
eArgTypeRemotePath,
eArgTypeRemoteFilename,
eArgTypeModule,
eArgTypeCPUName,
eArgTypeCPUFeatures,
eArgTypeLastArg // Always keep this entry as the last entry in this
// enumeration!!
};
Expand Down
5 changes: 3 additions & 2 deletions lldb/include/lldb/lldb-private-interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/API/SBFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ 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,
target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(),
*target_sp, m_opaque_ptr->GetAddressRange(), force_live_memory));
}
}
return sb_instructions;
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/API/SBSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, *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));
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions lldb/source/API/SBTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2013,7 +2013,8 @@ 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,
target_sp->GetArchitecture(), nullptr, target_sp->GetDisassemblyCPU(),
target_sp->GetDisassemblyFeatures(), flavor_string, *addr_ptr,
data.GetBytes(), bytes_read, count, data_from_file));
}
}
Expand All @@ -2038,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, *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;
Expand Down Expand Up @@ -2071,8 +2073,9 @@ 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,
target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(),
addr, buf, size, UINT32_MAX, data_from_file));
}

return sb_instructions;
Expand Down
38 changes: 28 additions & 10 deletions lldb/source/Commands/CommandObjectDisassemble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down
14 changes: 14 additions & 0 deletions lldb/source/Commands/CommandObjectDisassemble.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
4 changes: 4 additions & 0 deletions lldb/source/Commands/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">,
Expand Down
42 changes: 25 additions & 17 deletions lldb/source/Core/Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -67,34 +68,38 @@ 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 {
for (uint32_t idx = 0;
(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,
if (arch.GetTriple().getArch() == llvm::Triple::x86 ||
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) {
Expand All @@ -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 {};
Expand All @@ -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 {};
Expand All @@ -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,
Expand All @@ -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;

Expand Down Expand Up @@ -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)
Expand Down
Loading
Loading