Compare commits

..

No commits in common. "0eec2bf24de9f6dd1af82afe0544539c0962958a" and "fff0444f6c9f666e5956dd9a7f7f2443d6d3d58f" have entirely different histories.

16 changed files with 32 additions and 145 deletions

View file

@ -1,31 +0,0 @@
include config.mk
.PHONY: build clean install uninstall masm mld msim
build: masm mld msim
./bin/masm/masm -o ./bin/runtime.o ./lib/runtime.asm
clean:
rm -fr ./bin
install:
install -m 755 -D -t $(PREFIX)/bin ./bin/masm/masm
install -m 755 -D -t $(PREFIX)/bin ./bin/mld/mld
install -m 755 -D -t $(PREFIX)/bin ./bin/msim/msim
install -m 444 -D -t $(PREFIX)/lib/mips ./bin/runtime.o
uninstall:
rm $(PREFIX)/bin/masm
rm $(PREFIX)/bin/mld
rm $(PREFIX)/bin/msim
rm $(PREFIX)/lib/mips/runtime.o
rmdir $(PREFIX)/lib/mips
masm:
make -C ./masm build
mld:
make -C ./mld build
msim:
make -C ./msim build

View file

@ -6,17 +6,6 @@ a full mips r2000 toolchain with a assembler and linker
outputs MIPS32r6 ELF32 Big Endian executables
##### installing
```bash
$ make build
$ sudo make install
```
##### uninstalling
```bash
$ sudo make uninstall
```
#### masm
the assembler

View file

@ -5,4 +5,3 @@
-pedantic
-Wno-gnu-binary-literal
-Iinclude
-DPREFIX=/usr/local

View file

@ -8,8 +8,6 @@ CFLAGS += -Wall -Wextra -pedantic
CFLAGS += -Wno-initializer-overrides
CFLAGS += -O0 -g
PREFIX=/usr/local
# ======================== CONFIG OPTIONS ==
#
# MAX LEX LENGTH

View file

@ -1,29 +0,0 @@
#
# MIPS32r6 ASSEMBLY RUNTIME
# - sets up the stack
# - calls main
# - exits
#
.extern main
.stack
.align 2
.space 4096
__mips_stack:
.text
.align 2
_start:
# setup stack
la $sp, __mips_stack
# call main
jal main
# exit
move $a0, $v0
li $v0, 1
syscall

View file

@ -4,6 +4,4 @@ SRC=.
BIN=../bin/mld
OUT=mld
CFLAGS += -DPREFIX=$(PREFIX)
include ../makefile.mk

View file

@ -16,11 +16,8 @@
static int load_objects(struct linker *linker)
{
int max_entries = linker->args->in_count + 1;
// 1 needed for the runtime
linker->objects = malloc(sizeof(struct object) *
max_entries);
linker->args->in_count);
linker->obj_len = 0;
if (linker->objects == NULL) {
@ -49,19 +46,6 @@ static int load_objects(struct linker *linker)
skip_obj:
}
if (linker->args->freestanding == false) {
#define _STR(x) _STR2(x)
#define _STR2(x) #x
char *path = _STR(PREFIX) "/lib/mips/runtime.o";
struct object *obj = &linker->objects[linker->obj_len++];
if (object_load(obj, path))
return M_ERROR;
#undef _STR
#undef _STR2
}
return M_SUCCESS;
}
@ -177,7 +161,7 @@ static int relocate_symbol(struct linker *linker, struct object *obj,
struct segment *sec = NULL;
for (size_t i = 0; i < obj->phdr_len; i++) {
Elf32_Phdr *temp = &obj->phdr[i];
if (PHDR_SHDR_MATCH(temp, shdr)) {
if (shdr->sh_offset == temp->p_offset) {
sec = &obj->segments[i];
break;
}
@ -402,22 +386,30 @@ static int relocate_instruction_rela(struct linker *linker,
return M_ERROR;
}
Elf32_Sym *sym = &symtab->syms[idx];
const char *symname = symtab->strtab->data + B32(sym->st_name);
char const *sym_name = symtab->strtab->data + B32(sym->st_name);
if (B32(sym->st_name) >= symtab->strtab->len) {
ERROR("relocation symbol name out of bounds");
return M_ERROR;
}
// get the new sym for the new vaddr
Elf32_Sym *new_sym = NULL;
if (symtab_get(&linker->symtab, &new_sym, sym_name)) {
ERROR("relocation symbol not found");
/// get the section header that the symbol is related to
Elf32_Shdr *shdr = NULL;
if (B16(sym->st_shndx) >= seg->obj->shdr_len) {
ERROR("shndx index [%d] out of bounds", B16(sym->st_shndx));
return M_ERROR;
}
shdr = &seg->obj->shdr[B16(sym->st_shndx)];
/// get the segment that the symbol is in
uint32_t sym_vaddr = B32(new_sym->st_value);
struct segment_table_entry *ent;
const char *segname = seg->obj->shstrtab->data + B32(shdr->sh_name);
if (B32(shdr->sh_name) >= seg->obj->shstrtab->len) {
ERROR("relocation segment name out of bounds");
return M_ERROR;
}
if (segtab_get(&linker->segments, &ent, segname)) {
ERROR("could not locate segment for relocation");
return M_ERROR;
}
uint32_t sym_vaddr = B32(sym->st_value) + ent->vaddr;
uint32_t *ins_raw = (uint32_t *) &seg->bytes[off];
union mips_instruction_data ins;
@ -470,7 +462,7 @@ static int relocate_instruction_rela(struct linker *linker,
*ins_raw = B32(ins.raw);
if (warn)
WARNING("truncating relocation for symbol '%s'", sym_name);
WARNING("truncating relocation for symbol '%s'", symname);
return M_SUCCESS;
@ -655,15 +647,6 @@ static int link_executable(struct linker *linker)
ehdr->e_shnum = B16(linker->shdr_len);
ehdr->e_shstrndx = B16(linker->shstrtab_shidx);
Elf32_Sym *entry = NULL;
if (symtab_get(&linker->symtab, &entry, "_start")) {
ERROR("undefined symbol _start");
return M_ERROR;
}
// BE to BE, no endiness conversion needed
ehdr->e_entry = entry->st_value;
update_offsets(linker);
if (write_file(linker))

View file

@ -26,11 +26,6 @@
#define ADDR_CHK(lnk_f, seg_f, max) \
((lnk_f) > max - (seg_f) || (lnk_f) + (seg_f) > max)
// checks if a phdr and shdr are matches
#define PHDR_SHDR_MATCH(phdr, shdr) ( \
((phdr)->p_offset == (shdr)->sh_offset) && \
((phdr)->p_filesz == (shdr)->sh_size)) \
// start addresses for each tyoe of segment
#define TEXT_VADDR_MIN 0x00400000
#define DATA_VADDR_MIN 0x10000000
@ -124,8 +119,6 @@ struct segment {
// object im related to
struct object *obj;
// segment table entry im related to
struct segment_table_entry *ent;
// relocation table
struct relocation_table reltab;
@ -259,7 +252,6 @@ struct linker_arguments {
char **in_files;
int in_count;
char *out_file;
bool freestanding;
};
/* link object files */

View file

@ -10,7 +10,6 @@ void help(void) {
printf("options:\n");
printf("\t-h\t\tprints this help message\n");
printf("\t-o <output>\tselect a output file destination\n");
printf("\t-f\t\tmake this binary freestanding (no runtime)\n");
}
int main(int argc, char **argv) {
@ -19,12 +18,11 @@ int main(int argc, char **argv) {
.in_files = NULL,
.in_count = 0,
.out_file = "a.out",
.freestanding = false,
};
int c;
while ((c = getopt(argc, argv, "ho:f")) != 1) {
while ((c = getopt(argc, argv, "ho:")) != 1) {
switch(c) {
case 'h':
help();
@ -32,9 +30,6 @@ int main(int argc, char **argv) {
case 'o':
args.out_file = optarg;
break;
case 'f':
args.freestanding = true;
break;
case '?':
return M_ERROR;
default:

View file

@ -31,9 +31,10 @@ static int load_shdr(struct object *obj, struct segment *seg, size_t index)
Elf32_Shdr *hdr = &obj->shdr[i];
// find shdr that matches the offset in phdr
if (!PHDR_SHDR_MATCH(seg->phdr, hdr))
if (seg->phdr->p_offset != hdr->sh_offset)
continue;
// get name
uint32_t name = B32(hdr->sh_name);
if (name >= obj->shstrtab->len) {
@ -42,6 +43,11 @@ static int load_shdr(struct object *obj, struct segment *seg, size_t index)
}
seg->name = &obj->shstrtab->data[name];
if (seg->phdr->p_filesz != hdr->sh_size) {
ERROR("segment phdr and shdr file sizes to not match");
return M_ERROR;
}
// map bytes
uint32_t len = B32(hdr->sh_size);
uint32_t off = B32(hdr->sh_offset);
@ -148,7 +154,6 @@ int segment_load(struct object *obj, struct segment *seg, size_t index)
seg->align = B32(seg->phdr->p_align);
seg->obj = obj;
seg->ent = NULL;
return M_SUCCESS;
}

View file

@ -136,8 +136,6 @@ int segtab_ent_push(struct segment_table_entry *ent, struct segment *seg)
}
ent->parts[ent->len++] = seg;
seg->ent = ent;
return M_SUCCESS;
}

View file

@ -1,7 +0,0 @@
include ../config.mk
SRC=.
BIN=../bin/msim
OUT=msim
include ../makefile.mk

View file

@ -1,5 +0,0 @@
int main(void) {
// NOT YET IMPLEMENTED
return 1;
}

View file

@ -18,6 +18,7 @@ null:
.text
.align 2
.globl main
.globl _start
# init the heap
heap_init:
@ -203,6 +204,7 @@ realloc_free:
jr $ra
_start:
main:
# push return address
addi $sp, $sp, -4

Binary file not shown.

Binary file not shown.