2024-11-14 10:39:45 +08:00

80 lines
2.3 KiB
C

/************************************************************************/
/* File Name : lc4_loader.c */
/* Purpose : This file implements the loader (ld) from PennSim */
/* It will be called by main() */
/* */
/* Author(s) : tjf and you */
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "lc4_memory.h"
/* declarations of functions that must defined in lc4_loader.c */
FILE *open_file(char *file_name) {
FILE *file = fopen(file_name, "rb");
if (file == NULL) {
perror("Error opening file");
}
return file;
}
/* Helper function to read a 16-bit word from the file */
unsigned short read_half_word(FILE *file) {
unsigned char bytes[2];
if (fread(bytes, 1, 2, file) != 2) {
return 0;
}
return (bytes[0] << 8) | bytes[1];
}
int parse_file(FILE *my_obj_file, row_of_memory **memory) {
while (!feof(my_obj_file)) {
unsigned short header = read_half_word(my_obj_file);
if (feof(my_obj_file)) {
break;
}
unsigned short address = read_half_word(my_obj_file);
unsigned short n = read_half_word(my_obj_file);
if (header == 0xCADE || header == 0xDADA) {
/* Code or Data section */
for (int i = 0; i < n; i++) {
unsigned short contents = read_half_word(my_obj_file);
add_to_list(memory, address + i, contents);
}
} else if (header == 0xC3B7) {
/* Symbol section */
char *label = (char *)malloc(n + 1);
if (label == NULL) {
return -1;
}
if (fread(label, 1, n, my_obj_file) != n) {
free(label);
return -1;
}
label[n] = '\0'; // Null-terminate the string
row_of_memory *node = search_address(*memory, address);
if (node != NULL) {
free(node->label);
node->label = label;
} else {
/* Create a new node with only label and address */
if (add_to_list(memory, address, 0) != 0) {
/* If adding the node fails, free label to avoid a memory leak */
free(label);
return -1;
}
node = search_address(*memory, address);
node->label = label;
}
} else {
/* Unknown header, skip n words */
fseek(my_obj_file, n * 2, SEEK_CUR);
}
}
return 0;
}