#include "sdb.h" #include "vector.h" #include "logger.h" #include #include #include #include #include #include static inline enum instruction prompt(void) { static char *input; static size_t input_len; OUTPUT("(sdb) "); getline(&input, &input_len, stdin); char *op = strtok(input, " \t\n"); if (op == NULL) return INST_NOP; if (strcmp(op, "exit") == 0) return INST_EXIT; if (strcmp(op, "load") == 0) return INST_LOAD; if (strcmp(op, "show") == 0) return INST_SHOW; if (strcmp(op, "info") == 0) return INST_INFO; if (strcmp(op, "break") == 0) return INST_BREAK; if (strcmp(op, "delete") == 0) return INST_DELETE; if (strcmp(op, "patch") == 0) return INST_PATCH; if (strcmp(op, "si") == 0) return INST_SI; if (strcmp(op, "cont") == 0) return INST_CONT; if (strcmp(op, "syscall") == 0) return INST_SYSCALL; return INST_INVALID; } int main(int argc, char *argv[]) { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); char *filename = ""; if (argc > 1) { filename = malloc(strlen(argv[1]) + 1); strcpy(filename, argv[1]); if (access(filename, F_OK) != 0) { perror("main file open"); exit(1); } } if (access(filename, F_OK) != 0) { load_retry: enum instruction op = prompt(); switch (op) { case INST_NOP: goto load_retry; case INST_EXIT: goto exit; case INST_LOAD: inst_load(&filename); if (access(filename, F_OK) == 0) break; else { INFO("file invalid\n"); goto load_retry; } default: INFO("please load a program first.\n"); goto load_retry; } } DEBUG("filename = %s\n", filename); run(filename); sync_regs(); disassemble_addr = regs.rip; disassemble(); for (;;) { enum instruction op = prompt(); DEBUG("op = 0x%x\n", (int)op); switch (op) { case INST_NOP: break; case INST_EXIT: goto exit; case INST_SHOW: disassemble(); break; case INST_INFO: inst_info(); break; case INST_BREAK: inst_break(); break; case INST_DELETE: inst_delete(); break; case INST_PATCH: inst_patch(); break; case INST_SI: inst_si(); disassemble(); break; case INST_CONT: inst_cont(); disassemble(); break; case INST_SYSCALL: inst_syscall(); disassemble(); break; default: INFO("invalid command\n"); } DEBUG("disassemble_addr = %p\n", (void *)disassemble_addr); if (disassemble_addr == 0x00) goto exit; } exit: free(filename); free(bps); return 0; }