diff options
Diffstat (limited to 'masm/asm.c')
-rw-r--r-- | masm/asm.c | 142 |
1 files changed, 62 insertions, 80 deletions
@@ -6,7 +6,7 @@ #include <elf.h> #include <string.h> #include <stddef.h> -#include <arpa/inet.h> +#include <melf.h> #include "asm.h" #include "mlimits.h" @@ -30,12 +30,12 @@ static int create_symbol(struct assembler *assembler, return M_ERROR; Elf32_Sym symbol = { - .st_name = htonl(str_off), - .st_value = htonl(section_offset), + .st_name = B32(str_off), + .st_value = B32(section_offset), .st_size = 0, .st_info = ELF32_ST_INFO(bind, STT_NOTYPE), .st_other = ELF32_ST_VISIBILITY(STV_DEFAULT), - .st_shndx = htons(section_idx), + .st_shndx = B16(section_idx), }; // dont put magic flag values inside symbol, only real indexes @@ -92,6 +92,10 @@ static int handle_directive(struct assembler *assembler, case MIPS_DIRECTIVE_ALIGN: { assembler->sectab.current->alignment = 1 << directive->align; + if (assembler->sectab.current->alignment == 0) { + ERROR("cannot align to zero"); + return M_ERROR; + } break; } @@ -212,7 +216,7 @@ static int handle_label(struct assembler *assembler, // we need to update it if (*sec == SYMSEC_STUB) { *sec = cur->index; - ref->st_value = htonl(sec_size(cur)); + ref->st_value = B32(sec_size(cur)); return M_SUCCESS; } @@ -242,7 +246,7 @@ static int handle_ins(struct assembler *assembler, entry.type = ENT_INS; entry.size = sizeof(union mips_instruction_data); - entry.ins = htonl(ins->raw); + entry.ins = B32(ins->raw); if (sec_push(sec, entry)) return M_ERROR; @@ -255,9 +259,9 @@ static int handle_ins(struct assembler *assembler, return M_ERROR; Elf32_Rela rel = { - .r_info = htonl(ELF32_R_INFO(symidx, ref->type)), - .r_addend = htonl(ref->addend), - .r_offset = htonl(sec_index(sec, secidx + i)), + .r_info = B32(ELF32_R_INFO(symidx, ref->type)), + .r_addend = B32(ref->addend), + .r_offset = B32(sec_index(sec, secidx + i)), }; if (reltab_push(&sec->reltab, rel)) @@ -319,17 +323,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 = htonl(PT_LOAD); - hdr->p_flags = htonl( + hdr->p_type = B32(PT_LOAD); + hdr->p_flags = B32( (sec->execute << 0) | (sec->write << 1) | (sec->read << 2)); hdr->p_offset = 0; hdr->p_vaddr = 0; hdr->p_paddr = 0; - hdr->p_filesz = htonl(size); - hdr->p_memsz = htonl(size); - hdr->p_align = htonl(SEC_ALIGN); + hdr->p_filesz = B32(size); + hdr->p_memsz = B32(size); + hdr->p_align = B32(SEC_ALIGN); } *res = phdr; @@ -376,16 +380,16 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res, sec->reltab_shidx = count; shdr[count++] = (Elf32_Shdr) { - .sh_name = htonl(str_off), - .sh_type = htonl(SHT_RELA), + .sh_name = B32(str_off), + .sh_type = B32(SHT_RELA), .sh_flags = 0, .sh_addr = 0, .sh_offset = 0, .sh_size = 0, .sh_link = 0, .sh_info = 0, - .sh_addralign = htonl(1), - .sh_entsize = htonl(sizeof(Elf32_Rela)), + .sh_addralign = B32(1), + .sh_entsize = B32(sizeof(Elf32_Rela)), }; } @@ -402,12 +406,12 @@ 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 = htonl(count); + shdr[sec->reltab_shidx].sh_info = B32(count); shdr[count++] = (Elf32_Shdr){ - .sh_name = htonl(str_off), - .sh_type = htonl(SHT_PROGBITS), - .sh_flags = htonl( + .sh_name = B32(str_off), + .sh_type = B32(SHT_PROGBITS), + .sh_flags = B32( (sec->write << 0) | (sec->execute << 2) | SHF_ALLOC), @@ -416,7 +420,7 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res, .sh_size = 0, .sh_link = 0, .sh_info = 0, - .sh_addralign = htonl(sec->alignment), + .sh_addralign = B32(sec->alignment), .sh_entsize = 0, }; } @@ -429,16 +433,16 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res, assembler->symtab_shidx = count; shdr[count++] = (Elf32_Shdr) { - .sh_name = htonl(str_off), - .sh_type = htonl(SHT_SYMTAB), + .sh_name = B32(str_off), + .sh_type = B32(SHT_SYMTAB), .sh_flags = 0, .sh_addr = 0, .sh_offset = 0, .sh_size = 0, .sh_link = 1, .sh_info = 0, - .sh_addralign = htonl(1), - .sh_entsize = htonl(sizeof(Elf32_Sym)), + .sh_addralign = B32(1), + .sh_entsize = B32(sizeof(Elf32_Sym)), }; // string table @@ -449,15 +453,15 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res, assembler->strtab_shidx = count; shdr[count++] = (Elf32_Shdr) { - .sh_name = htonl(str_off), - .sh_type = htonl(SHT_STRTAB), - .sh_flags = htonl(SHF_STRINGS), + .sh_name = B32(str_off), + .sh_type = B32(SHT_STRTAB), + .sh_flags = B32(SHF_STRINGS), .sh_addr = 0, .sh_offset = 0, .sh_size = 0, .sh_link = 0, .sh_info = 0, - .sh_addralign = htonl(1), + .sh_addralign = B32(1), .sh_entsize = 0, }; @@ -469,15 +473,15 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res, assembler->shstrtab_shidx = count; shdr[count++] = (Elf32_Shdr) { - .sh_name = htonl(str_off), - .sh_type = htonl(SHT_STRTAB), - .sh_flags = htonl(SHF_STRINGS), + .sh_name = B32(str_off), + .sh_type = B32(SHT_STRTAB), + .sh_flags = B32(SHF_STRINGS), .sh_addr = 0, .sh_offset = 0, .sh_size = 0, .sh_link = 0, .sh_info = 0, - .sh_addralign = htonl(1), + .sh_addralign = B32(1), .sh_entsize = 0, }; @@ -486,7 +490,7 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res, if (sec->reltab.len == 0) continue; shdr[sec->reltab_shidx].sh_link = - htonl(assembler->symtab_shidx); + B32(assembler->symtab_shidx); } *res = shdr; @@ -506,7 +510,7 @@ static void update_offsets(struct assembler *assembler, Elf32_Ehdr *ehdr) ptr += sizeof(Elf32_Ehdr); // phdr - ehdr->e_phoff = htonl(ptr); + ehdr->e_phoff = B32(ptr); ptr += assembler->phdr_len * sizeof(Elf32_Phdr); // reltbls @@ -516,8 +520,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 = htonl(ptr); - shdr[idx].sh_size = htonl(len * sizeof(Elf32_Rela)); + shdr[idx].sh_offset = B32(ptr); + shdr[idx].sh_size = B32(len * sizeof(Elf32_Rela)); ptr += len * sizeof(Elf32_Rela); } @@ -537,10 +541,10 @@ static void update_offsets(struct assembler *assembler, Elf32_Ehdr *ehdr) struct section *sec = &assembler->sectab.sections[i]; uint32_t idx = sec->shdr_idx; uint32_t size = ntohl(phdr[i].p_filesz); - phdr[i].p_offset = htonl(ptr); - phdr[i].p_vaddr = htonl(v_addr); - phdr[i].p_paddr = htonl(v_addr); - shdr[idx].sh_offset = htonl(ptr); + phdr[i].p_offset = B32(ptr); + phdr[i].p_vaddr = B32(v_addr); + phdr[i].p_paddr = B32(v_addr); + shdr[idx].sh_offset = B32(ptr); shdr[idx].sh_size = phdr[i].p_filesz; shdr[idx].sh_addr = phdr[i].p_vaddr; v_addr += size; @@ -548,25 +552,25 @@ static void update_offsets(struct assembler *assembler, Elf32_Ehdr *ehdr) } // symtab - shdr[assembler->symtab_shidx].sh_offset = htonl(ptr); - shdr[assembler->symtab_shidx].sh_link = htonl(assembler->strtab_shidx); + shdr[assembler->symtab_shidx].sh_offset = B32(ptr); + shdr[assembler->symtab_shidx].sh_link = B32(assembler->strtab_shidx); shdr[assembler->symtab_shidx].sh_size = - htonl(assembler->symtab.len * sizeof(Elf32_Sym)); + B32(assembler->symtab.len * sizeof(Elf32_Sym)); ptr += assembler->symtab.len * sizeof(Elf32_Sym); // strtab - shdr[assembler->strtab_shidx].sh_offset = htonl(ptr); - shdr[assembler->strtab_shidx].sh_size = htonl(assembler->strtab.size); + shdr[assembler->strtab_shidx].sh_offset = B32(ptr); + shdr[assembler->strtab_shidx].sh_size = B32(assembler->strtab.size); ptr += assembler->strtab.size; // shstrtab - shdr[assembler->shstrtab_shidx].sh_offset = htonl(ptr); + shdr[assembler->shstrtab_shidx].sh_offset = B32(ptr); shdr[assembler->shstrtab_shidx].sh_size = - htonl(assembler->shstrtab.size); + B32(assembler->shstrtab.size); ptr += assembler->shstrtab.size; // shdr - ehdr->e_shoff = htonl(ptr); + ehdr->e_shoff = B32(ptr); } static void update_sym_shindx(struct assembler *assembler) @@ -576,7 +580,7 @@ static void update_sym_shindx(struct assembler *assembler) ssize_t sec = assembler->symtab.sections[i]; if (sec >= 0) { - sym->st_shndx = htons(assembler-> + sym->st_shndx = B16(assembler-> sectab.sections[sec].shdr_idx); } } @@ -587,7 +591,8 @@ static int write_file(struct assembler *assembler, Elf32_Ehdr *ehdr, { FILE *out = fopen(path, "w"); - if (out == NULL) { + if (out == NULL) + { ERROR("cannot write '%s'", path); return M_ERROR; } @@ -662,33 +667,10 @@ static int assemble_elf(struct assembler *assembler, const char *out) return M_ERROR; }; - Elf32_Ehdr ehdr = { - .e_ident = { - [EI_MAG0] = ELFMAG0, - [EI_MAG1] = ELFMAG1, - [EI_MAG2] = ELFMAG2, - [EI_MAG3] = ELFMAG3, - [EI_CLASS] = ELFCLASS32, - [EI_DATA] = ELFDATA2MSB, - [EI_VERSION] = EV_CURRENT, - [EI_OSABI] = ELFOSABI_NONE, - [EI_ABIVERSION] = 0x00, - [EI_PAD] = 0x00, - }, - .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 = 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), - }; + Elf32_Ehdr ehdr = MIPS_ELF_EHDR; + ehdr.e_phnum = B16(assembler->phdr_len); + ehdr.e_shnum = B16(assembler->shdr_len); + ehdr.e_shstrndx = B16(assembler->shstrtab_shidx); update_offsets(assembler, &ehdr); update_sym_shindx(assembler); |