summaryrefslogtreecommitdiff
path: root/qdme.c
diff options
context:
space:
mode:
authorJacob McDonnell <jacob@jacobmcdonnell.com>2024-05-28 00:33:52 -0400
committerJacob McDonnell <jacob@jacobmcdonnell.com>2024-05-28 00:33:52 -0400
commit83b0b878db0bcb29f7fb70a9fbcab30d793f7b1e (patch)
tree618d8206836a6d29d3dc473380167ddf79d7a403 /qdme.c
parent0f1f3a13ac3c3b23510e142f042d25ca17de2b2f (diff)
Initial Implementation of ELF
Diffstat (limited to 'qdme.c')
-rwxr-xr-xqdme.c66
1 files changed, 54 insertions, 12 deletions
diff --git a/qdme.c b/qdme.c
index 7ddd1ce..0198e66 100755
--- a/qdme.c
+++ b/qdme.c
@@ -3,11 +3,15 @@
#include <string.h>
#include <arpa/inet.h>
#include "qdme.h"
+#include "elf.h"
-uint8_t memory[MEM_SIZE * WORD_SIZE] = {0};
+uint8_t *memory = NULL;
+size_t memsize;
uint32_t pc = 0, hi = 0, lo = 0;
uint32_t regFile[32] = {0};
+int LoadProgramHeader(ProgramHeader_t p, FILE *fp);
+
/* InstFetch: Fetch the next instruction from memory into the given
* instruction */
void InstFetch(inst_t *inst) {
@@ -241,7 +245,7 @@ void CycleCpu(void) {
inst_t instFetch, instExec;
memset(&instFetch, 0, sizeof(inst_t));
memset(&instExec, 0, sizeof(inst_t));
- while (pc < MEM_SIZE) {
+ while (pc < memsize) {
InstFetch(&instFetch);
InstExec(instExec);
instExec = instFetch;
@@ -255,31 +259,69 @@ int LoadBinary(const char * const path) {
return -1;
}
- uint8_t *freeMem = memory;
- size_t i = 0, offset = 0;
- while ((i = fread(freeMem + offset, sizeof(memory[0]), (MEM_SIZE * WORD_SIZE) - offset, fp)) != 0) {
- offset += i;
+ ElfHeader_t e = ReadElf(fp);
+ if (!ValidateElf(e)) {
+ return -1;
+ }
+
+ pc = e.e_entry;
+
+ const size_t n = e.e_phnum;
+ ProgramHeader_t *p = (ProgramHeader_t *)calloc(n, e.e_phentsize);
+ if (p == NULL) {
+ perror("calloc");
+ return -1;
}
+ ReadProgramHeader(n, p, fp);
- for (size_t i = 0; i < offset; i += 4) {
- uint32_t x;
- memcpy(&x, memory + i, sizeof(x));
- printf("%02lu: 0x%08x\n", i, x);
+ for (size_t i = 0; i < n; i++) {
+ memsize += p[i].memsz;
}
- if (ferror(fp) || !feof(fp)) {
- perror("fread");
+ if ((memory = (uint8_t *)calloc(memsize, sizeof(uint8_t))) == NULL) {
+ perror("calloc");
+ free((void *)p);
+ fclose(fp);
return -1;
}
+ for (size_t i = 0; i < n; i++) {
+ if (LoadProgramHeader(p[i], fp) == -1) {
+ free((void *)p);
+ fclose(fp);
+ return -1;
+ }
+ }
+
+ free((void *)p);
fclose(fp);
return 0;
}
+/* LoadProgramHeader: Load the program segment described by the given program
+ * header from file fp. Returns 0 on success and -1 on failure. */
+int LoadProgramHeader(ProgramHeader_t p, FILE *fp) {
+ uint8_t *memloc = memory + p.vaddr;
+ size_t s = p.filesz;
+ if (fseek(fp, p.offset, SEEK_SET) != 0) {
+ perror("fseek");
+ return -1;
+ }
+ fread(memloc, sizeof(uint8_t), s, fp);
+ if (ferror(fp)) {
+ return -1;
+ }
+ for (size_t j = p.vaddr; j < p.filesz; j++) {
+ printf("%lu: %08x\n", j, memory[j]);
+ }
+ return 0;
+}
+
int main(int argc, char *argv[]) {
if (LoadBinary(*++argv) == -1) {
return -1;
}
CycleCpu();
+ free((void *)memory);
}