97 lines
2.5 KiB
C
97 lines
2.5 KiB
C
/*
|
|
* CS 261 PA2: Mini-ELF loader
|
|
*
|
|
* Name: Nicholas Tamassia
|
|
* This code was developed in compliance with the JMU Honor Code.
|
|
*/
|
|
|
|
#include "p2-load.h"
|
|
|
|
/**********************************************************************
|
|
* REQUIRED FUNCTIONS
|
|
*********************************************************************/
|
|
|
|
bool read_phdr (FILE *file, uint16_t offset, elf_phdr_t *phdr)
|
|
{
|
|
if (!file || !phdr || fseek(file, offset, SEEK_SET) != 0) {
|
|
return false;
|
|
}
|
|
|
|
return ((fread(phdr, sizeof(elf_phdr_t), 1, file) == 1) && phdr->magic == 0xDEADBEEF);
|
|
}
|
|
|
|
bool load_segment (FILE *file, byte_t *memory, elf_phdr_t *phdr)
|
|
{
|
|
if (!file || !memory || !phdr) {
|
|
return false;
|
|
}
|
|
|
|
if (phdr->p_vaddr + phdr->p_size > MEMSIZE || fseek(file, phdr->p_offset, SEEK_SET) != 0) {
|
|
return false;
|
|
}
|
|
|
|
if ((fread(memory + phdr->p_vaddr, phdr->p_size, 1, file) != 1) && phdr->p_size != 0) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* OPTIONAL FUNCTIONS
|
|
*********************************************************************/
|
|
|
|
void dump_phdrs (uint16_t numphdrs, elf_phdr_t *phdrs)
|
|
{
|
|
printf(" Segment Offset Size VirtAddr Type Flags\n");
|
|
|
|
for (int i = 0; i < numphdrs; i++) {
|
|
elf_phdr_t phdr = phdrs[i];
|
|
char flags[4] = "RWX";
|
|
|
|
for (int j = 2; j >= 0; j--) {
|
|
if ((phdr.p_flags & (1 << (2 - j))) == 0) {
|
|
flags[j] = ' ';
|
|
}
|
|
}
|
|
|
|
printf(" %02d 0x%04x 0x%04x 0x%04x %-10s%s\n", i, phdr.p_offset, phdr.p_size, phdr.p_vaddr, p_type_mapper(phdr.p_type), flags);
|
|
}
|
|
}
|
|
|
|
char* p_type_mapper(uint16_t type) {
|
|
switch (type) {
|
|
case 0: return "DATA"; break;
|
|
case 1: return "CODE"; break;
|
|
case 2: return "STACK"; break;
|
|
case 3: return "HEAP"; break;
|
|
default: return "UNKNOWN"; break;
|
|
}
|
|
}
|
|
|
|
void dump_memory (byte_t *memory, uint16_t start, uint16_t end)
|
|
{
|
|
printf("Contents of memory from %04x to %04x:\n", start, end);
|
|
|
|
int aligned_start = start - (start % 16);
|
|
|
|
for (int i = aligned_start; i < end; i++) {
|
|
if (i % 16 == 0) {
|
|
printf(" %04x ", i);
|
|
}
|
|
|
|
if (i >= start) {
|
|
printf(" %02x", memory[i]);
|
|
} else {
|
|
printf(" ");
|
|
}
|
|
|
|
if (i % 16 == 15 || i == end - 1) {
|
|
printf("\n");
|
|
} else if (i % 16 == 7) {
|
|
printf(" ");
|
|
}
|
|
}
|
|
}
|
|
|