mirror of
https://github.com/FEX-Emu/vixl.git
synced 2024-11-23 14:40:17 +00:00
Add a skip
command to the AArch64 debugger.
Here is an example of user interaction: Hit breakpoint at pc=0xb3cc50. Next: 0x0000000000b3cc50 d4200000 brk #0x0 vixl> disasm 0x0000000000b3cc50 d4200000 brk #0x0 0x0000000000b3cc54 d2800000 mov x0, #0x0 0x0000000000b3cc58 d2800021 mov x1, #0x1 0x0000000000b3cc5c d2800042 mov x2, #0x2 0x0000000000b3cc60 d2800063 mov x3, #0x3 0x0000000000b3cc64 d2800084 mov x4, #0x4 0x0000000000b3cc68 d28000a5 mov x5, #0x5 0x0000000000b3cc6c f100001f cmp x0, #0x0 (0) 0x0000000000b3cc70 da805400 cneg x0, x0, mi 0x0000000000b3cc74 d65f03c0 ret vixl> stepi Next: 0x0000000000b3cc58 d2800021 mov x1, #0x1 vixl> skip 3 Skipping over 3 instructions: Skip: 0x0000000000b3cc58 d2800021 mov x1, #0x1 Skip: 0x0000000000b3cc5c d2800042 mov x2, #0x2 Skip: 0x0000000000b3cc60 d2800063 mov x3, #0x3 Next: 0x0000000000b3cc64 d2800084 mov x4, #0x4 vixl> Change-Id: I833cf6381edf94423f1e54dae636d206a93fed9f
This commit is contained in:
parent
384fe09960
commit
80497ed4c9
@ -36,6 +36,7 @@ namespace aarch64 {
|
||||
C(HelpCommand) \
|
||||
C(ContinueCommand) \
|
||||
C(StepCommand) \
|
||||
C(SkipCommand) \
|
||||
C(DisasmCommand) \
|
||||
C(PrintCommand) \
|
||||
C(ExamineCommand)
|
||||
@ -329,6 +330,26 @@ class StepCommand : public DebugCommand {
|
||||
IntegerToken* count_;
|
||||
};
|
||||
|
||||
class SkipCommand : public DebugCommand {
|
||||
public:
|
||||
SkipCommand(Token* name, IntegerToken* count)
|
||||
: DebugCommand(name), count_(count) {}
|
||||
virtual ~SkipCommand() { delete count_; }
|
||||
|
||||
int64_t count() { return count_->value(); }
|
||||
virtual bool Run(Debugger* debugger);
|
||||
virtual void Print(FILE* out = stdout);
|
||||
|
||||
static DebugCommand* Build(std::vector<Token*> args);
|
||||
|
||||
static const char* kHelp;
|
||||
static const char* kAliases[];
|
||||
static const char* kArguments;
|
||||
|
||||
private:
|
||||
IntegerToken* count_;
|
||||
};
|
||||
|
||||
class DisasmCommand : public DebugCommand {
|
||||
public:
|
||||
static DebugCommand* Build(std::vector<Token*> args);
|
||||
@ -434,6 +455,10 @@ const char* StepCommand::kAliases[] = {"stepi", "si", NULL};
|
||||
const char* StepCommand::kArguments = "[n = 1]";
|
||||
const char* StepCommand::kHelp = " Execute n next instruction(s).";
|
||||
|
||||
const char* SkipCommand::kAliases[] = {"skip", NULL};
|
||||
const char* SkipCommand::kArguments = "[n = 1]";
|
||||
const char* SkipCommand::kHelp = " Skip the next n instruction(s).";
|
||||
|
||||
const char* DisasmCommand::kAliases[] = {"disasm", "di", NULL};
|
||||
const char* DisasmCommand::kArguments = "[n = 10]";
|
||||
const char* DisasmCommand::kHelp =
|
||||
@ -563,7 +588,9 @@ void Debugger::Run() {
|
||||
}
|
||||
|
||||
|
||||
void Debugger::PrintInstructions(const void* address, int64_t count) {
|
||||
void Debugger::PrintInstructions(const void* address,
|
||||
int64_t count,
|
||||
const char* prefix) {
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
@ -577,6 +604,7 @@ void Debugger::PrintInstructions(const void* address, int64_t count) {
|
||||
|
||||
for (const Instruction* current = from; current < to;
|
||||
current = current->GetNextInstruction()) {
|
||||
printf("%s", prefix);
|
||||
printer_->Decode(current);
|
||||
}
|
||||
}
|
||||
@ -713,8 +741,7 @@ void Debugger::RunDebuggerShell() {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Next: ");
|
||||
PrintInstructions(ReadPc());
|
||||
PrintNextInstruction();
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
char buffer[kMaxDebugShellLine];
|
||||
@ -1273,6 +1300,51 @@ DebugCommand* StepCommand::Build(std::vector<Token*> args) {
|
||||
}
|
||||
|
||||
|
||||
bool SkipCommand::Run(Debugger* debugger) {
|
||||
VIXL_ASSERT(debugger->IsDebuggerRunning());
|
||||
|
||||
int64_t steps = count();
|
||||
if (steps < 0) {
|
||||
printf(" ** invalid value for steps: %" PRId64 " (<0) **\n", steps);
|
||||
} else {
|
||||
printf("Skipping over %" PRId64 " instructions:\n", steps);
|
||||
debugger->PrintInstructions(debugger->ReadPc(), steps, "Skip: ");
|
||||
debugger->WritePc(debugger->ReadPc() + steps * kInstructionSize);
|
||||
debugger->PrintNextInstruction();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SkipCommand::Print(FILE* out) {
|
||||
fprintf(out, "%s %" PRId64 "", name(), count());
|
||||
}
|
||||
|
||||
|
||||
DebugCommand* SkipCommand::Build(std::vector<Token*> args) {
|
||||
IntegerToken* count = NULL;
|
||||
switch (args.size()) {
|
||||
case 1: { // step [1]
|
||||
count = new IntegerToken(1);
|
||||
break;
|
||||
}
|
||||
case 2: { // step n
|
||||
Token* first = args[1];
|
||||
if (!first->IsInteger()) {
|
||||
return new InvalidCommand(args, 1, "expects int");
|
||||
}
|
||||
count = IntegerToken::Cast(first);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return new InvalidCommand(args, -1, "too many arguments");
|
||||
}
|
||||
|
||||
return new SkipCommand(args[0], count);
|
||||
}
|
||||
|
||||
|
||||
DebugCommand* DisasmCommand::Build(std::vector<Token*> args) {
|
||||
IntegerToken* count = NULL;
|
||||
switch (args.size()) {
|
||||
|
@ -106,7 +106,12 @@ class Debugger : public Simulator {
|
||||
UpdatePendingRequestStatus();
|
||||
}
|
||||
|
||||
void PrintInstructions(const void* address, int64_t count = 1);
|
||||
void PrintInstructions(const void* address,
|
||||
int64_t count = 1,
|
||||
const char* prefix = "");
|
||||
void PrintNextInstruction() {
|
||||
PrintInstructions(ReadPc(), 1, "Next: ");
|
||||
}
|
||||
void PrintMemory(const uint8_t* address,
|
||||
const FormatToken* format,
|
||||
int64_t count = 1);
|
||||
|
Loading…
Reference in New Issue
Block a user