diff --git a/include/mips.h b/include/mips.h index 1233693..ff043cd 100644 --- a/include/mips.h +++ b/include/mips.h @@ -159,6 +159,14 @@ struct mips_instruction_branch_data { uint32_t op : 6; } __attribute__((packed)); +union mips_instruction_data { + uint32_t raw; + struct mips_instruction_r_data R; + struct mips_instruction_i_data I; + struct mips_instruction_j_data J; + struct mips_instruction_branch_data B; +} __attribute__((packed)); + /* mips instruction information */ struct mips_instruction { // metadata @@ -167,13 +175,7 @@ struct mips_instruction { const char *name; // data - union { - uint32_t data; - struct mips_instruction_r_data R_data; - struct mips_instruction_i_data I_data; - struct mips_instruction_j_data J_data; - struct mips_instruction_branch_data B_data; - } __attribute__((packed)); + union mips_instruction_data data; }; @@ -182,7 +184,7 @@ struct mips_instruction { MIPS_INS_ ##ins, \ MIPS_FORMAT_ ##format, \ #ins, \ - .format##_data = { __VA_ARGS__ } \ + .data = { .format = { __VA_ARGS__ } } \ }, \ static const struct mips_instruction mips_instructions[] = { 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 #include +#include #include #include #include #include #include +#include #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); diff --git a/masm/asm.h b/masm/asm.h index 267aa1c..81099fc 100644 --- a/masm/asm.h +++ b/masm/asm.h @@ -118,7 +118,7 @@ struct section_entry { char data; // data - struct mips_instruction ins; + uint32_t ins; char str[MAX_LEX_LENGTH]; int32_t word; int16_t half; diff --git a/masm/parse.c b/masm/parse.c index 2a84a91..d0a1f33 100644 --- a/masm/parse.c +++ b/masm/parse.c @@ -364,21 +364,21 @@ static int parse_instruction_r(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rd = reg; + ins->data.R.rd = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rs = reg; + ins->data.R.rs = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rt = reg; + ins->data.R.rt = reg; return M_SUCCESS; } @@ -391,14 +391,14 @@ static int parse_instruction_r2(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rs = reg; + ins->data.R.rs = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rt = reg; + ins->data.R.rt = reg; return M_SUCCESS; } @@ -411,7 +411,7 @@ static int parse_instruction_rs(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rs = reg; + ins->data.R.rs = reg; return M_SUCCESS; } @@ -424,7 +424,7 @@ static int parse_instruction_rd(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rd = reg; + ins->data.R.rd = reg; return M_SUCCESS; } @@ -438,14 +438,14 @@ static int parse_instruction_i(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->I_data.rt = reg; + ins->data.I.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->I_data.rs = reg; + ins->data.I.rs = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; @@ -455,7 +455,7 @@ static int parse_instruction_i(struct parser *parser, if (token.number >= MAX16) return M_ERROR; - ins->I_data.immd = token.number; + ins->data.I.immd = token.number; return M_SUCCESS; } @@ -471,10 +471,10 @@ static int parse_instruction_offset(struct parser *parser, switch (max) { case MAX26: - ins->J_data.target = n; + ins->data.J.target = n; break; case MAX16: - ins->B_data.offset = n; + ins->data.B.offset = n; break; } @@ -488,7 +488,7 @@ static int parse_instruction_j(struct parser *parser, uint32_t n; if (get_target(parser, &n, ref) || n > MAX26) return M_ERROR; - ins->J_data.target = n; + ins->data.J.target = n; return M_SUCCESS; } @@ -500,7 +500,7 @@ static int parse_instruction_jr(struct parser *parser, uint32_t n; if (get_target(parser, &n, ref) || n > MAX26) return M_ERROR; - ins->J_data.target = n; + ins->data.J.target = n; return M_SUCCESS; } @@ -511,7 +511,7 @@ static int parse_instruction_branch_equal(struct parser *parser, enum mips_register reg; if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rs = reg; + ins->data.R.rs = reg; return M_SUCCESS; } @@ -525,14 +525,14 @@ static int parse_instruction_branch(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->B_data.rs = reg; + ins->data.B.rs = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (get_offset(parser, &n, ref) || n > MAX16) return M_ERROR; - ins->B_data.offset = n; + ins->data.B.offset = n; return M_SUCCESS; } @@ -547,7 +547,7 @@ static int parse_instruction_sl(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->I_data.rt = reg; + ins->data.I.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; @@ -558,13 +558,13 @@ static int parse_instruction_sl(struct parser *parser, if (token.type != TOK_LPAREN) if (get_offset(parser, &offset, ref)) return M_ERROR; - ins->I_data.immd = offset; + ins->data.I.immd = offset; if (peek_token(parser, &token)) return M_ERROR; if (token.type == TOK_NL) { - ins->I_data.rs = MIPS_REG_ZERO; + ins->data.I.rs = MIPS_REG_ZERO; return M_SUCCESS; } @@ -573,7 +573,7 @@ static int parse_instruction_sl(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->I_data.rs = reg; + ins->data.I.rs = reg; if (assert_token(parser, TOK_RPAREN, NULL)) return M_ERROR; @@ -589,14 +589,14 @@ static int parse_instruction_sli(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->I_data.rt = reg; + ins->data.I.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX16) return M_ERROR; - ins->I_data.immd = token.number; + ins->data.I.immd = token.number; return M_SUCCESS; } @@ -609,21 +609,21 @@ static int parse_instruction_s(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rd = reg; + ins->data.R.rd = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rt = reg; + ins->data.R.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX5) return M_ERROR; - ins->R_data.shamt = token.number; + ins->data.R.shamt = token.number; return M_SUCCESS; } @@ -635,21 +635,21 @@ static int parse_instruction_sv(struct parser *parser, if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rd = reg; + ins->data.R.rd = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rt = reg; + ins->data.R.rt = reg; if (assert_token(parser, TOK_COMMA, NULL)) return M_ERROR; if (parse_register(parser, ®)) return M_ERROR; - ins->R_data.rs = reg; + ins->data.R.rs = reg; return M_SUCCESS; } diff --git a/masm/symtab.c b/masm/symtab.c index 897c4f9..c6f9aac 100644 --- a/masm/symtab.c +++ b/masm/symtab.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -21,6 +22,10 @@ int symtab_init(struct symbol_table *symtab) return M_ERROR; } + Elf32_Sym null = {0}; + if (symtab_push(symtab, null, -1)) + return M_ERROR; + return M_SUCCESS; } @@ -54,7 +59,7 @@ int symtab_find(struct symbol_table *symtab, Elf32_Sym **ptr, { for (uint32_t i = 0; i < symtab->len; i++) { Elf32_Sym *sym = &symtab->symbols[i]; - const char *str = &symtab->strtab->ptr[sym->st_name]; + const char *str = &symtab->strtab->ptr[ntohl(sym->st_name)]; if (strcmp(str, name) == 0) { if (ptr != NULL) *ptr = sym; diff --git a/masm/test.asm b/masm/test.asm index 3dea7c9..b4c1498 100644 --- a/masm/test.asm +++ b/masm/test.asm @@ -7,7 +7,6 @@ str: .align 2 .globl main -.extern test2 main: add $zero,$t7,$t7 @@ -27,4 +26,4 @@ test: mfhi $s0 mtlo $s7 - j test2 + j test