|
|
|
#include "../src/common.h"
|
|
|
|
|
|
|
|
#include "../src/dwarf.c"
|
|
|
|
#include "../src/eh_frame.c"
|
|
|
|
#include "../src/util.c"
|
|
|
|
#include "../src/command.c"
|
|
|
|
|
|
|
|
#define DO_TEST(title, call) do { \
|
|
|
|
int rt = call; \
|
|
|
|
if (rt == 0) { \
|
|
|
|
fprintf(stderr, "Test '%s' \033[1m\033[32msuccess\033[0m...\n", title); \
|
|
|
|
} else { \
|
|
|
|
fprintf(stderr, "Test '%s' \033[1m\033[31mfail\033[0m\n", title); \
|
|
|
|
exit(1); \
|
|
|
|
} \
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
static int
|
|
|
|
test_start(char *path)
|
|
|
|
{
|
|
|
|
struct mi_process proc = process_create(path);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
parse_debug_info(proc.elf, &proc.debug);
|
|
|
|
proc.main_address = get_address_of_subroutine(proc, "main");
|
|
|
|
command_start(proc);
|
|
|
|
struct mi_registers regs = get_process_registers(proc);
|
|
|
|
|
|
|
|
int result = 1;
|
|
|
|
|
|
|
|
if (proc.main_address == regs.rip - proc.base_address) {
|
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
command_kill(proc);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
test_regs(char *path)
|
|
|
|
{
|
|
|
|
struct mi_process proc = process_create(path);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
parse_debug_info(proc.elf, &proc.debug);
|
|
|
|
proc.main_address = get_address_of_subroutine(proc, "main");
|
|
|
|
command_start(proc);
|
|
|
|
struct mi_registers regs = get_process_registers(proc);
|
|
|
|
|
|
|
|
int result = 1;
|
|
|
|
if (regs.rbp > 0 && regs.rsp > 0 && regs.rip > 0) {
|
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
command_kill(proc);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
test_step(char *path, int steps, u64 pc)
|
|
|
|
{
|
|
|
|
struct mi_process proc = process_create(path);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
parse_debug_info(proc.elf, &proc.debug);
|
|
|
|
parse_debug_line(proc.elf, &proc.debug);
|
|
|
|
proc.main_address = get_address_of_subroutine(proc, "main");
|
|
|
|
command_start(proc);
|
|
|
|
for (int i = 0; i < steps; ++i) {
|
|
|
|
command_step(proc);
|
|
|
|
}
|
|
|
|
struct mi_registers regs = get_process_registers(proc);
|
|
|
|
int result = 1;
|
|
|
|
if ((regs.rip - proc.base_address) == pc) {
|
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
command_kill(proc);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
test_next(char *path, int nexts, u64 pc)
|
|
|
|
{
|
|
|
|
struct mi_process proc = process_create(path);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
parse_debug_info(proc.elf, &proc.debug);
|
|
|
|
parse_debug_line(proc.elf, &proc.debug);
|
|
|
|
proc.main_address = get_address_of_subroutine(proc, "main");
|
|
|
|
command_start(proc);
|
|
|
|
for (int i = 0; i < nexts; ++i) {
|
|
|
|
command_next(proc);
|
|
|
|
}
|
|
|
|
struct mi_registers regs = get_process_registers(proc);
|
|
|
|
int result = 1;
|
|
|
|
if ((regs.rip - proc.base_address) == pc) {
|
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
command_kill(proc);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
test_list(char *path, int steps, int line, int column)
|
|
|
|
{
|
|
|
|
struct mi_process proc = process_create(path);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
parse_debug_info(proc.elf, &proc.debug);
|
|
|
|
parse_debug_line(proc.elf, &proc.debug);
|
|
|
|
proc.main_address = get_address_of_subroutine(proc, "main");
|
|
|
|
command_start(proc);
|
|
|
|
for (int i = 0; i < steps; ++i) {
|
|
|
|
command_step(proc);
|
|
|
|
}
|
|
|
|
|
|
|
|
int comp_unit;
|
|
|
|
struct mi_registers regs = get_process_registers(proc);
|
|
|
|
struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address, &comp_unit);
|
|
|
|
|
|
|
|
int result = 1;
|
|
|
|
if (sp->line == line && sp->column == column) {
|
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
command_kill(proc);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
test_print(char *path, int steps, char *name, char *type, int location)
|
|
|
|
{
|
|
|
|
struct mi_process proc = process_create(path);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
parse_debug_info(proc.elf, &proc.debug);
|
|
|
|
parse_debug_line(proc.elf, &proc.debug);
|
|
|
|
proc.main_address = get_address_of_subroutine(proc, "main");
|
|
|
|
command_start(proc);
|
|
|
|
for (int i = 0; i < steps; ++i) {
|
|
|
|
command_step(proc);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct mi_registers regs = get_process_registers(proc);
|
|
|
|
u64 pc = regs.rip - proc.base_address;
|
|
|
|
u64 cfa = get_cfa_at_pc(proc, pc);
|
|
|
|
|
|
|
|
struct mi_variable *variable = get_variable(proc, name, strlen(name), pc);
|
|
|
|
struct mi_type real_type = proc.debug.types[variable->type];
|
|
|
|
|
|
|
|
int result = 1;
|
|
|
|
int type_length = strlen(type);
|
|
|
|
if (0 == strncmp(type, real_type.name, type_length) && variable->location == location) {
|
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
command_kill(proc);
|
|
|
|
waitpid(proc.pid, 0, 0);
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(void)
|
|
|
|
{
|
|
|
|
freopen("/dev/null", "wb", stdout);
|
|
|
|
|
|
|
|
DO_TEST("start 001-simple", test_start("res/001-simple"));
|
|
|
|
DO_TEST("start 002-compilation-units", test_start("res/002-compilation-units"));
|
|
|
|
DO_TEST("start 003-recursion", test_start("res/003-recursion"));
|
|
|
|
DO_TEST("start 004-scoped-variables", test_start("res/004-scoped-variables"));
|
|
|
|
DO_TEST("start 005-base-types", test_start("res/005-base-types"));
|
|
|
|
DO_TEST("start 006-composite-types", test_start("res/006-composite-types"));
|
|
|
|
|
|
|
|
DO_TEST("regs 001-simple", test_regs("res/001-simple"));
|
|
|
|
DO_TEST("regs 002-compilation-units", test_regs("res/002-compilation-units"));
|
|
|
|
DO_TEST("regs 003-recursion", test_regs("res/003-recursion"));
|
|
|
|
DO_TEST("regs 004-scoped-variables", test_regs("res/004-scoped-variables"));
|
|
|
|
DO_TEST("regs 005-base-types", test_regs("res/005-base-types"));
|
|
|
|
DO_TEST("regs 006-composite-types", test_regs("res/006-composite-types"));
|
|
|
|
|
|
|
|
DO_TEST("step 001-simple", test_step("res/001-simple", 4, 0x1166));
|
|
|
|
DO_TEST("step 002-compilation-units", test_step("res/002-compilation-units", 4, 0x114f));
|
|
|
|
DO_TEST("step 003-recursion", test_step("res/003-recursion", 9, 0x1130));
|
|
|
|
DO_TEST("step 004-scoped-variables", test_step("res/004-scoped-variables", 7, 0x1145));
|
|
|
|
DO_TEST("step 005-base-types", test_step("res/005-base-types", 3, 0x113e));
|
|
|
|
DO_TEST("step 006-composite-types", test_step("res/006-composite-types", 5, 0x114c));
|
|
|
|
|
|
|
|
DO_TEST("next 001-simple", test_next("res/001-simple", 4, 0x1166));
|
|
|
|
DO_TEST("next 002-compilation-units", test_next("res/002-compilation-units", 4, 0x1146));
|
|
|
|
DO_TEST("next 003-recursion", test_next("res/003-recursion", 2, 0x116b));
|
|
|
|
DO_TEST("next 004-scoped-variables", test_next("res/004-scoped-variables", 4, 0x11a3));
|
|
|
|
DO_TEST("next 005-base-types", test_next("res/005-base-types", 3, 0x113e));
|
|
|
|
DO_TEST("next 006-composite-types", test_next("res/006-composite-types", 5, 0x114c));
|
|
|
|
|
|
|
|
DO_TEST("list 001-simple", test_list("res/001-simple", 4, 12, 20));
|
|
|
|
DO_TEST("list 002-compilation-units", test_list("res/002-compilation-units", 4, 5, 6));
|
|
|
|
DO_TEST("list 003-recursion", test_list("res/003-recursion", 9, 4, 5));
|
|
|
|
DO_TEST("list 004-scoped-variables", test_list("res/004-scoped-variables", 7, 15, 6));
|
|
|
|
DO_TEST("list 005-base-types", test_list("res/005-base-types", 3, 6, 7));
|
|
|
|
DO_TEST("list 006-composite-types", test_list("res/006-composite-types", 5, 18, 14));
|
|
|
|
|
|
|
|
DO_TEST("print 001-simple", test_print("res/001-simple", 4, "i", "int", -28));
|
|
|
|
DO_TEST("print 002-compilation-units", test_print("res/002-compilation-units", 5, "sq", "int", -20));
|
|
|
|
DO_TEST("print 003-recursion", test_print("res/003-recursion", 28, "result", "int", -20));
|
|
|
|
DO_TEST("print 004-scoped-variables", test_print("res/004-scoped-variables", 9, "b_f2", "int", -24));
|
|
|
|
DO_TEST("print 005-base-types long", test_print("res/005-base-types", 5, "var_unsigned_long", "long unsigned int", -40));
|
|
|
|
DO_TEST("print 005-base-types char", test_print("res/005-base-types", 4, "var_char", "char", -41));
|
|
|
|
DO_TEST("print 005-base-types float", test_print("res/005-base-types", 8, "var_float", "float", -48));
|
|
|
|
DO_TEST("print 005-base-types double", test_print("res/005-base-types", 9, "var_double", "double", -56));
|
|
|
|
|
|
|
|
fprintf(stderr, "\033[1m\033[32mAll tests succeeded!\033[0m\n");
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|