/* * CS 261: Main driver * * Name: Nicholas Tamassia * This code was developed in compliance with the JMU Honor Code. */ #include "p1-check.h" #include "p2-load.h" /* Helper function for printing help text */ void usage (char **argv) { printf("Usage: %s mini-elf-file\n", argv[0]); printf(" Options are:\n"); printf(" -h Display usage\n"); printf(" -H Show the Mini-ELF header\n"); printf(" -a Show all with brief memory\n"); printf(" -f Show all with full memory\n"); printf(" -s Show the program headers\n"); printf(" -m Show the memory contents (brief)\n"); printf(" -M Show the memory contents (full)\n"); } void exit_file_error(FILE* file) { if (file) { fclose(file); } printf("Failed to read file\n"); exit(EXIT_FAILURE); } int main (int argc, char **argv) { int c; bool show_elf_header = false; bool show_program_header = false; bool show_memory_brief = false; bool show_memory_full = false; while ((c = getopt(argc, argv, "hHafsmM")) != -1) { switch (c) { case 'h': usage(argv); return EXIT_SUCCESS; case 'H': show_elf_header = true; break; case 'a': show_elf_header = true; show_program_header = true; show_memory_brief = true; break; case 'f': show_elf_header = true; show_program_header = true; show_memory_full = true; break; case 's': show_program_header = true; break; case 'm': show_memory_brief = true; break; case 'M': show_memory_full = true; break; default: usage(argv); return EXIT_FAILURE; } } bool invalid_arguments = optind != argc - 1; /* File path was not the last argument */ bool memory_flag_conflict = show_memory_brief && show_memory_full; /* Attempted to ask for brief and full memory at same time */ if (invalid_arguments || memory_flag_conflict) { usage(argv); return EXIT_FAILURE; } elf_hdr_t header = { 0 }; FILE *header_file = fopen(argv[optind], "r"); /* Read contents of header_file into header */ if (!read_header(header_file, &header)) { exit_file_error(header_file); } if (show_elf_header) { dump_header(&header); } elf_phdr_t phdrs[header.e_num_phdr]; memset(phdrs, 0, sizeof(phdrs)); /* Read program headers into phdrs array */ for (int i = 0; i < header.e_num_phdr; i++) { if (!read_phdr(header_file, header.e_phdr_start + i * sizeof(elf_phdr_t), &phdrs[i])) { exit_file_error(header_file); } } if (show_program_header) { dump_phdrs(header.e_num_phdr, phdrs); } byte_t memory[MEMSIZE]; memset(memory, 0, MEMSIZE); /* Read memory segments into memory array */ for (int i = 0; i < header.e_num_phdr; i++) { if (!load_segment(header_file, memory, &phdrs[i])) { exit_file_error(header_file); } } if (show_memory_brief) { for (int i = 0; i < header.e_num_phdr; i++) { uint32_t start = phdrs[i].p_vaddr; uint32_t end = start + phdrs[i].p_size; dump_memory(memory, start, end); } } else if (show_memory_full) { dump_memory(memory, 0, MEMSIZE); } fclose(header_file); return EXIT_SUCCESS; }