summaryrefslogtreecommitdiff
path: root/masm/asm.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-09-12 08:37:46 -0400
committerFreya Murphy <freya@freyacat.org>2024-09-12 08:37:46 -0400
commit0c8ad22d45ea74b1687cc3b6f452c5a0939873a5 (patch)
tree8ab44b1048e73f52ee9e597f85fff38e277801b9 /masm/asm.c
parentadd ascii and asciiz directives, fix symtab bug (diff)
downloadmips-0c8ad22d45ea74b1687cc3b6f452c5a0939873a5.tar.gz
mips-0c8ad22d45ea74b1687cc3b6f452c5a0939873a5.tar.bz2
mips-0c8ad22d45ea74b1687cc3b6f452c5a0939873a5.zip
big endian
Diffstat (limited to 'masm/asm.c')
-rw-r--r--masm/asm.c161
1 files changed, 88 insertions, 73 deletions
diff --git a/masm/asm.c b/masm/asm.c
index a9cee99..1050b18 100644
--- a/masm/asm.c
+++ b/masm/asm.c
@@ -1,10 +1,12 @@
#include <merror.h>
#include <mips.h>
+#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <elf.h>
#include <string.h>
#include <stddef.h>
+#include <arpa/inet.h>
#include "asm.h"
#include "mlimits.h"
@@ -26,12 +28,12 @@ static int create_symbol(struct assembler *assembler,
return M_ERROR;
Elf32_Sym symbol = {
- .st_name = str_off,
- .st_value = section_offset,
+ .st_name = htonl(str_off),
+ .st_value = htonl(section_offset),
.st_size = 0,
.st_info = ELF32_ST_INFO(bind, STT_NOTYPE),
.st_other = ELF32_ST_VISIBILITY(STV_DEFAULT),
- .st_shndx = section_idx,
+ .st_shndx = htons(section_idx),
};
// dont put magic flag values inside symbol, only real indexes
@@ -105,6 +107,7 @@ static int handle_directive(struct assembler *assembler,
struct section_entry entry;
entry.type = ENT_WORD;
entry.word = directive->words[i];
+ entry.size = sizeof(uint32_t);
if (sec_push(assembler->sectab.current,
entry))
return M_ERROR;
@@ -117,6 +120,7 @@ static int handle_directive(struct assembler *assembler,
struct section_entry entry;
entry.type = ENT_HALF;
entry.half = directive->halfs[i];
+ entry.size = sizeof(uint16_t);
if (sec_push(assembler->sectab.current,
entry))
return M_ERROR;
@@ -129,6 +133,7 @@ static int handle_directive(struct assembler *assembler,
struct section_entry entry;
entry.type = ENT_BYTE;
entry.byte = directive->bytes[i];
+ entry.size = sizeof(uint8_t);
if (sec_push(assembler->sectab.current,
entry))
return M_ERROR;
@@ -205,7 +210,7 @@ static int handle_label(struct assembler *assembler,
// we need to update it
if (*sec == SYMSEC_STUB) {
*sec = cur->index;
- ref->st_value = sec_size(cur);
+ ref->st_value = htonl(sec_size(cur));
return M_SUCCESS;
}
@@ -227,15 +232,15 @@ static int handle_ins(struct assembler *assembler,
size_t secidx = sec->len;
for (size_t i = 0; i < expr->ins_len; i++) {
- struct mips_instruction *ins =
- &expr->ins[i];
+ union mips_instruction_data *ins =
+ &expr->ins[i].data;
struct reference *ref =
&expr->ref[i];
struct section_entry entry;
entry.type = ENT_INS;
- entry.size = sizeof(struct mips_instruction);
- entry.ins = *ins;
+ entry.size = sizeof(union mips_instruction_data);
+ entry.ins = htonl(ins->raw);
if (sec_push(sec, entry))
return M_ERROR;
@@ -257,9 +262,9 @@ static int handle_ins(struct assembler *assembler,
return M_ERROR;
Elf32_Rela rel = {
- .r_info = ELF32_R_INFO(symidx, type),
- .r_addend = ref->addend,
- .r_offset = sec_index(sec, secidx + i),
+ .r_info = htonl(ELF32_R_INFO(symidx, type)),
+ .r_addend = htonl(ref->addend),
+ .r_offset = htonl(sec_index(sec, secidx + i)),
};
if (reltab_push(&sec->reltab, rel))
@@ -323,16 +328,17 @@ static int assemble_phdr(struct assembler *assembler, Elf32_Phdr **res,
Elf32_Phdr *hdr = &phdr[i];
struct section *sec = &assembler->sectab.sections[i];
size_t size = sec_size(sec);
- hdr->p_type = PT_LOAD;
- hdr->p_flags = (sec->execute << 0) |
+ hdr->p_type = htonl(PT_LOAD);
+ hdr->p_flags = htonl(
+ (sec->execute << 0) |
(sec->write << 1) |
- (sec->read << 2);
+ (sec->read << 2));
hdr->p_offset = 0;
hdr->p_vaddr = 0;
hdr->p_paddr = 0;
- hdr->p_filesz = size;
- hdr->p_memsz = size;
- hdr->p_align = sec->alignment;
+ hdr->p_filesz = htonl(size);
+ hdr->p_memsz = htonl(size);
+ hdr->p_align = htonl(0x1000);
}
*res = phdr;
@@ -343,7 +349,11 @@ static int assemble_phdr(struct assembler *assembler, Elf32_Phdr **res,
static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
uint32_t *res2)
{
- uint32_t max_entries = 4; // symtab, strtab, shstrtab
+ uint32_t max_entries = 0;
+ max_entries += 1; // null
+ max_entries += 1; // symtab
+ max_entries += 1; // strtab
+ max_entries += 1; // shtrtab
max_entries += assembler->sectab.len; // sections
max_entries += assembler->sectab.len; // reltabs per section
@@ -352,7 +362,10 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
size_t str_off;
uint32_t count = 0;
- // eeltables
+ // null
+ shdr[count++] = (Elf32_Shdr) {0};
+
+ // reltables
for (uint32_t i = 0; i < assembler->sectab.len; i++) {
struct section *sec = &assembler->sectab.sections[i];
const char *prefix = ".reltab.";
@@ -372,16 +385,16 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
sec->reltab_shidx = count;
shdr[count++] = (Elf32_Shdr) {
- .sh_name = str_off,
- .sh_type = SHT_RELA,
+ .sh_name = htonl(str_off),
+ .sh_type = htonl(SHT_RELA),
.sh_flags = 0,
.sh_addr = 0,
.sh_offset = 0,
.sh_size = 0,
.sh_link = 0,
.sh_info = 0,
- .sh_addralign = 1,
- .sh_entsize = sizeof(Elf32_Rela),
+ .sh_addralign = htonl(1),
+ .sh_entsize = htonl(sizeof(Elf32_Rela)),
};
}
@@ -398,20 +411,22 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
sec->shdr_idx = count;
if (sec->reltab.len != 0)
- shdr[sec->reltab_shidx].sh_info = count;
+ shdr[sec->reltab_shidx].sh_info = htonl(count);
shdr[count++] = (Elf32_Shdr){
- .sh_name = str_off,
- .sh_type = SHT_PROGBITS,
- .sh_flags = (sec->write << 0) | (sec->execute << 2) |
- SHF_ALLOC,
+ .sh_name = htonl(str_off),
+ .sh_type = htonl(SHT_PROGBITS),
+ .sh_flags = htonl(
+ (sec->write << 0) |
+ (sec->execute << 2) |
+ SHF_ALLOC),
.sh_addr = 0,
.sh_offset = 0,
.sh_size = 0,
.sh_link = 0,
.sh_info = 0,
- .sh_addralign = sec->alignment,
- .sh_entsize = sizeof(struct mips_instruction),
+ .sh_addralign = htonl(sec->alignment),
+ .sh_entsize = 0,
};
}
@@ -423,16 +438,16 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
assembler->symtab_shidx = count;
shdr[count++] = (Elf32_Shdr) {
- .sh_name = str_off,
- .sh_type = SHT_SYMTAB,
+ .sh_name = htonl(str_off),
+ .sh_type = htonl(SHT_SYMTAB),
.sh_flags = 0,
.sh_addr = 0,
.sh_offset = 0,
.sh_size = 0,
.sh_link = 1,
.sh_info = 0,
- .sh_addralign = 1,
- .sh_entsize = sizeof(Elf32_Sym),
+ .sh_addralign = htonl(1),
+ .sh_entsize = htonl(sizeof(Elf32_Sym)),
};
// string table
@@ -443,15 +458,15 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
assembler->strtab_shidx = count;
shdr[count++] = (Elf32_Shdr) {
- .sh_name = str_off,
- .sh_type = SHT_STRTAB,
- .sh_flags = SHF_STRINGS,
+ .sh_name = htonl(str_off),
+ .sh_type = htonl(SHT_STRTAB),
+ .sh_flags = htonl(SHF_STRINGS),
.sh_addr = 0,
.sh_offset = 0,
.sh_size = 0,
.sh_link = 0,
.sh_info = 0,
- .sh_addralign = 1,
+ .sh_addralign = htonl(1),
.sh_entsize = 0,
};
@@ -463,15 +478,15 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
assembler->shstrtab_shidx = count;
shdr[count++] = (Elf32_Shdr) {
- .sh_name = str_off,
- .sh_type = SHT_STRTAB,
- .sh_flags = SHF_STRINGS,
+ .sh_name = htonl(str_off),
+ .sh_type = htonl(SHT_STRTAB),
+ .sh_flags = htonl(SHF_STRINGS),
.sh_addr = 0,
.sh_offset = 0,
.sh_size = 0,
.sh_link = 0,
.sh_info = 0,
- .sh_addralign = 1,
+ .sh_addralign = htonl(1),
.sh_entsize = 0,
};
@@ -480,7 +495,7 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
if (sec->reltab.len == 0)
continue;
shdr[sec->reltab_shidx].sh_link =
- assembler->symtab_shidx;
+ htonl(assembler->symtab_shidx);
}
*res = shdr;
@@ -500,7 +515,7 @@ static void update_offsets(struct assembler *assembler, Elf32_Ehdr *ehdr)
ptr += sizeof(Elf32_Ehdr);
// phdr
- ehdr->e_phoff = ptr;
+ ehdr->e_phoff = htonl(ptr);
ptr += assembler->phdr_len * sizeof(Elf32_Phdr);
// reltbls
@@ -510,8 +525,8 @@ static void update_offsets(struct assembler *assembler, Elf32_Ehdr *ehdr)
continue;
int idx = sec->reltab_shidx;
int len = sec->reltab.len;
- shdr[idx].sh_offset = ptr;
- shdr[idx].sh_size = len * sizeof(Elf32_Rela);
+ shdr[idx].sh_offset = htonl(ptr);
+ shdr[idx].sh_size = htonl(len * sizeof(Elf32_Rela));
ptr += len * sizeof(Elf32_Rela);
}
@@ -519,35 +534,35 @@ static void update_offsets(struct assembler *assembler, Elf32_Ehdr *ehdr)
for (uint32_t i = 0; i < assembler->sectab.len; i++) {
struct section *sec = &assembler->sectab.sections[i];
int idx = sec->shdr_idx;
- phdr[i].p_offset = ptr;
- phdr[i].p_vaddr = ptr;
- phdr[i].p_paddr = ptr;
- shdr[idx].sh_offset = ptr;
+ phdr[i].p_offset = htonl(ptr);
+ phdr[i].p_vaddr = htonl(ptr);
+ phdr[i].p_paddr = htonl(ptr);
+ shdr[idx].sh_offset = htonl(ptr);
shdr[idx].sh_size = phdr[i].p_filesz;
shdr[idx].sh_addr = phdr[i].p_vaddr;
- shdr[idx].sh_addralign = phdr[i].p_align;
- ptr += phdr[i].p_filesz;
+ ptr += ntohl(phdr[i].p_filesz);
}
// symtab
- shdr[assembler->symtab_shidx].sh_offset = ptr;
- shdr[assembler->symtab_shidx].sh_link = assembler->strtab_shidx;
+ shdr[assembler->symtab_shidx].sh_offset = htonl(ptr);
+ shdr[assembler->symtab_shidx].sh_link = htonl(assembler->strtab_shidx);
shdr[assembler->symtab_shidx].sh_size =
- assembler->symtab.len * sizeof(Elf32_Sym);
+ htonl(assembler->symtab.len * sizeof(Elf32_Sym));
ptr += assembler->symtab.len * sizeof(Elf32_Sym);
// strtab
- shdr[assembler->strtab_shidx].sh_offset = ptr;
- shdr[assembler->strtab_shidx].sh_size = assembler->strtab.size;
+ shdr[assembler->strtab_shidx].sh_offset = htonl(ptr);
+ shdr[assembler->strtab_shidx].sh_size = htonl(assembler->strtab.size);
ptr += assembler->strtab.size;
// shstrtab
- shdr[assembler->shstrtab_shidx].sh_offset = ptr;
- shdr[assembler->shstrtab_shidx].sh_size = assembler->shstrtab.size;
+ shdr[assembler->shstrtab_shidx].sh_offset = htonl(ptr);
+ shdr[assembler->shstrtab_shidx].sh_size =
+ htonl(assembler->shstrtab.size);
ptr += assembler->shstrtab.size;
// shdr
- ehdr->e_shoff = ptr;
+ ehdr->e_shoff = htonl(ptr);
}
static void update_sym_shindx(struct assembler *assembler)
@@ -558,8 +573,8 @@ static void update_sym_shindx(struct assembler *assembler)
ssize_t sec = assembler->symtab.sections[i];
if (sec >= 0) {
- sym->st_shndx = assembler->
- sectab.sections[sec].shdr_idx;
+ sym->st_shndx = htons(assembler->
+ sectab.sections[sec].shdr_idx);
}
}
}
@@ -642,25 +657,25 @@ static int assemble_elf(struct assembler *assembler, const char *out)
[EI_MAG2] = ELFMAG2,
[EI_MAG3] = ELFMAG3,
[EI_CLASS] = ELFCLASS32,
- [EI_DATA] = ELFDATA2LSB,
+ [EI_DATA] = ELFDATA2MSB,
[EI_VERSION] = EV_CURRENT,
[EI_OSABI] = ELFOSABI_NONE,
[EI_ABIVERSION] = 0x00,
[EI_PAD] = 0x00,
},
- .e_type = ET_REL,
- .e_machine = EM_MIPS,
- .e_version = EV_CURRENT,
+ .e_type = htons(ET_REL),
+ .e_machine = htons(EM_MIPS),
+ .e_version = htonl(EV_CURRENT),
.e_entry = 0x00,
.e_phoff = 0x00,
.e_shoff = 0x00,
- .e_flags = EF_MIPS_ARCH_32R6,
- .e_ehsize = sizeof(Elf32_Ehdr),
- .e_phentsize = sizeof(Elf32_Phdr),
- .e_phnum = assembler->phdr_len,
- .e_shentsize = sizeof(Elf32_Shdr),
- .e_shnum = assembler->shdr_len,
- .e_shstrndx = assembler->shstrtab_shidx,
+ .e_flags = htonl(EF_MIPS_ARCH_32R6),
+ .e_ehsize = htons(sizeof(Elf32_Ehdr)),
+ .e_phentsize = htons(sizeof(Elf32_Phdr)),
+ .e_phnum = htons(assembler->phdr_len),
+ .e_shentsize = htons(sizeof(Elf32_Shdr)),
+ .e_shnum = htons(assembler->shdr_len),
+ .e_shstrndx = htons(assembler->shstrtab_shidx),
};
update_offsets(assembler, &ehdr);