Skip to content

Instantly share code, notes, and snippets.

@nuta
Created March 7, 2020 12:21
Show Gist options
  • Select an option

  • Save nuta/e36850d81da0bad2416be18d48278ec4 to your computer and use it in GitHub Desktop.

Select an option

Save nuta/e36850d81da0bad2416be18d48278ec4 to your computer and use it in GitHub Desktop.
lldb stub
//
// LLDB Stub.
//
enum lldb_input_state {
LLDB_INPUT_BEGIN,
LLDB_INPUT_DATA,
LLDB_INPUT_CHECKSUM1,
LLDB_INPUT_CHECKSUM2,
};
static void lldb_process(const char *cmd) {
DBG("lldb: < %s", cmd);
}
static bool lldb_input(char ch) {
static char cmd[128];
static char checksum[2];
static int i = 0;
static bool escaped = false;
static char repeat = 0;
static enum lldb_input_state state = LLDB_INPUT_BEGIN;
// FIXME: overflow checks for `i`
switch (state) {
case LLDB_INPUT_BEGIN:
i = 0;
state = LLDB_INPUT_DATA;
/* fallthrough */
case LLDB_INPUT_DATA:
if (escaped) {
cmd[i] = ch ^ 0x20;
i++;
escaped = false;
} else if (repeat) {
for (int j = ch - 29; j > 0; j--) {
cmd[i] = repeat;
i++;
}
repeat = 0;
} else {
switch (ch) {
// Repetition of the previous character.
case '*':
if (i > 0) {
repeat = cmd[i - 1];
}
break;
// Escaping character.
case '}':
escaped = true;
break;
default:
if (ch == '#') {
state = LLDB_INPUT_CHECKSUM1;
} else {
cmd[i] = ch;
i++;
}
}
}
return true;
case LLDB_INPUT_CHECKSUM1:
checksum[0] = ch;
state = LLDB_INPUT_CHECKSUM2;
return true;
case LLDB_INPUT_CHECKSUM2:
checksum[1] = ch;
state = LLDB_INPUT_BEGIN;
break;
}
lldb_process(cmd);
return false;
}
void kdebug_handle_interrupt(void) {
static bool gdb_pkt = false;
int ch;
while ((ch = kdebug_readchar()) > 0) {
if (gdb_pkt) {
gdb_pkt = lldb_input(ch);
} else if (ch == '$') {
gdb_pkt = true;
} else {
input(ch);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment