135 lines
3.6 KiB
C
135 lines
3.6 KiB
C
/*
|
|
* 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 <option(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;
|
|
}
|
|
|