You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							108 lines
						
					
					
						
							3.7 KiB
						
					
					
				
			
		
		
	
	
							108 lines
						
					
					
						
							3.7 KiB
						
					
					
				#include "common.h" | 
						|
 | 
						|
#include "dwarf.c" | 
						|
#include "eh_frame.c" | 
						|
#include "util.c" | 
						|
#include "command.c" | 
						|
 | 
						|
int | 
						|
main(int argc, char *argv[]) | 
						|
{ | 
						|
    if (argc != 2) { | 
						|
        printf("Usage: %s executable\n", argv[0]); | 
						|
        return(1); | 
						|
    } | 
						|
     | 
						|
    struct mi_process process = process_create(argv[1]); | 
						|
    printf("pid of child = %d\n", process.pid); | 
						|
     | 
						|
    size_t max_command_length = 1023; | 
						|
    int command_length = 0; | 
						|
    char *command = malloc(max_command_length + 1); | 
						|
    char *last_command = malloc(max_command_length + 1); | 
						|
     | 
						|
    parse_debug_info(process.elf, &process.debug); | 
						|
    parse_eh_frame(process); | 
						|
     | 
						|
    process.base_address = 0x555555554000UL; // get_executable_base_address(file, proc.pid); | 
						|
    process.main_address = get_address_of_subroutine(process, "main"); | 
						|
     | 
						|
    printf("Base address: %#lx\n", process.base_address); | 
						|
    printf("Main address: %#lx\n", process.main_address); | 
						|
     | 
						|
    printf("> "); | 
						|
    fflush(stdout); | 
						|
     | 
						|
    parse_debug_line(process.elf, &process.debug); | 
						|
     | 
						|
    while ((command_length = getline(&command, &max_command_length, stdin))) { | 
						|
        if (command_length == 1) { | 
						|
            memset(command, 0, max_command_length); | 
						|
            memcpy(command, last_command, command_length); | 
						|
        } | 
						|
         | 
						|
        int wait = 0; | 
						|
         | 
						|
        if (0 == strncmp(command, "exit\n", command_length) || 0 == strncmp(command, "q\n", command_length)) { | 
						|
            break; | 
						|
        } else if (0 == strncmp(command, "regs\n", command_length)) { | 
						|
            command_regs(process); | 
						|
        } else if (0 == strncmp(command, "step\n", command_length)) { | 
						|
            command_step(process); | 
						|
        } else if (0 == strncmp(command, "start\n", command_length)) { | 
						|
            command_start(process); | 
						|
        } else if (0 == strncmp(command, "print ", 6)) { | 
						|
            command_print(process, command + 6, command_length - 7); | 
						|
        } else if (0 == strncmp(command, "next\n", command_length)) { | 
						|
            command_next(process); | 
						|
        } else if (0 == strncmp(command, "line\n", command_length)) { | 
						|
            command_list(process); | 
						|
        } else if (0 == strncmp(command, "bt\n", command_length)) { | 
						|
            command_backtrace(process); | 
						|
        } else if (0 == strncmp(command, "cont\n", command_length)) { | 
						|
            command_cont(process); | 
						|
            wait = 1; | 
						|
        } else if (0 == strncmp(command, "kill\n", command_length)) { | 
						|
            command_kill(process); | 
						|
            wait = 1; | 
						|
        } else { | 
						|
            printf("Unknown command: %.*s", command_length, command); | 
						|
        } | 
						|
         | 
						|
        if (wait) { | 
						|
            int wstatus; | 
						|
            int cpid = waitpid(process.pid, &wstatus, 0); | 
						|
             | 
						|
            if (cpid != 0) { | 
						|
                if (WIFEXITED(wstatus)) { | 
						|
                    int status = WEXITSTATUS(wstatus); | 
						|
                    printf("Child terminated normally with status %d\n", status); | 
						|
                    break; | 
						|
                } | 
						|
                 | 
						|
                if (WIFSIGNALED(wstatus)) { | 
						|
                    int signal = WTERMSIG(wstatus); | 
						|
                    printf("Child terminated by signal %d (%s)\n", signal, strsignal(signal)); | 
						|
                    break; | 
						|
                } | 
						|
                 | 
						|
                if (WIFSTOPPED(wstatus)) { | 
						|
                    int signal = WSTOPSIG(wstatus); | 
						|
                    printf("Child stopped by signal %d (%s)\n", signal, strsignal(signal)); | 
						|
                    break; | 
						|
                } | 
						|
                 | 
						|
                if (WIFCONTINUED(wstatus)) { | 
						|
                    printf("Child continued by SIGCONT\n"); | 
						|
                } | 
						|
            } | 
						|
        } | 
						|
         | 
						|
        memset(last_command, 0, max_command_length); | 
						|
        memcpy(last_command, command, command_length); | 
						|
         | 
						|
        printf("> "); | 
						|
    } | 
						|
     | 
						|
    return(0); | 
						|
} |