big endian
This commit is contained in:
parent
c1a44ed41d
commit
0c8ad22d45
6 changed files with 135 additions and 114 deletions
|
@ -159,6 +159,14 @@ struct mips_instruction_branch_data {
|
||||||
uint32_t op : 6;
|
uint32_t op : 6;
|
||||||
} __attribute__((packed));
|
} __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 */
|
/* mips instruction information */
|
||||||
struct mips_instruction {
|
struct mips_instruction {
|
||||||
// metadata
|
// metadata
|
||||||
|
@ -167,13 +175,7 @@ struct mips_instruction {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
union {
|
union mips_instruction_data data;
|
||||||
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));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,7 +184,7 @@ struct mips_instruction {
|
||||||
MIPS_INS_ ##ins, \
|
MIPS_INS_ ##ins, \
|
||||||
MIPS_FORMAT_ ##format, \
|
MIPS_FORMAT_ ##format, \
|
||||||
#ins, \
|
#ins, \
|
||||||
.format##_data = { __VA_ARGS__ } \
|
.data = { .format = { __VA_ARGS__ } } \
|
||||||
}, \
|
}, \
|
||||||
|
|
||||||
static const struct mips_instruction mips_instructions[] = {
|
static const struct mips_instruction mips_instructions[] = {
|
||||||
|
|
161
masm/asm.c
161
masm/asm.c
|
@ -1,10 +1,12 @@
|
||||||
#include <merror.h>
|
#include <merror.h>
|
||||||
#include <mips.h>
|
#include <mips.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "asm.h"
|
#include "asm.h"
|
||||||
#include "mlimits.h"
|
#include "mlimits.h"
|
||||||
|
@ -26,12 +28,12 @@ static int create_symbol(struct assembler *assembler,
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
Elf32_Sym symbol = {
|
Elf32_Sym symbol = {
|
||||||
.st_name = str_off,
|
.st_name = htonl(str_off),
|
||||||
.st_value = section_offset,
|
.st_value = htonl(section_offset),
|
||||||
.st_size = 0,
|
.st_size = 0,
|
||||||
.st_info = ELF32_ST_INFO(bind, STT_NOTYPE),
|
.st_info = ELF32_ST_INFO(bind, STT_NOTYPE),
|
||||||
.st_other = ELF32_ST_VISIBILITY(STV_DEFAULT),
|
.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
|
// 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;
|
struct section_entry entry;
|
||||||
entry.type = ENT_WORD;
|
entry.type = ENT_WORD;
|
||||||
entry.word = directive->words[i];
|
entry.word = directive->words[i];
|
||||||
|
entry.size = sizeof(uint32_t);
|
||||||
if (sec_push(assembler->sectab.current,
|
if (sec_push(assembler->sectab.current,
|
||||||
entry))
|
entry))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -117,6 +120,7 @@ static int handle_directive(struct assembler *assembler,
|
||||||
struct section_entry entry;
|
struct section_entry entry;
|
||||||
entry.type = ENT_HALF;
|
entry.type = ENT_HALF;
|
||||||
entry.half = directive->halfs[i];
|
entry.half = directive->halfs[i];
|
||||||
|
entry.size = sizeof(uint16_t);
|
||||||
if (sec_push(assembler->sectab.current,
|
if (sec_push(assembler->sectab.current,
|
||||||
entry))
|
entry))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -129,6 +133,7 @@ static int handle_directive(struct assembler *assembler,
|
||||||
struct section_entry entry;
|
struct section_entry entry;
|
||||||
entry.type = ENT_BYTE;
|
entry.type = ENT_BYTE;
|
||||||
entry.byte = directive->bytes[i];
|
entry.byte = directive->bytes[i];
|
||||||
|
entry.size = sizeof(uint8_t);
|
||||||
if (sec_push(assembler->sectab.current,
|
if (sec_push(assembler->sectab.current,
|
||||||
entry))
|
entry))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -205,7 +210,7 @@ static int handle_label(struct assembler *assembler,
|
||||||
// we need to update it
|
// we need to update it
|
||||||
if (*sec == SYMSEC_STUB) {
|
if (*sec == SYMSEC_STUB) {
|
||||||
*sec = cur->index;
|
*sec = cur->index;
|
||||||
ref->st_value = sec_size(cur);
|
ref->st_value = htonl(sec_size(cur));
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,15 +232,15 @@ static int handle_ins(struct assembler *assembler,
|
||||||
size_t secidx = sec->len;
|
size_t secidx = sec->len;
|
||||||
|
|
||||||
for (size_t i = 0; i < expr->ins_len; i++) {
|
for (size_t i = 0; i < expr->ins_len; i++) {
|
||||||
struct mips_instruction *ins =
|
union mips_instruction_data *ins =
|
||||||
&expr->ins[i];
|
&expr->ins[i].data;
|
||||||
struct reference *ref =
|
struct reference *ref =
|
||||||
&expr->ref[i];
|
&expr->ref[i];
|
||||||
struct section_entry entry;
|
struct section_entry entry;
|
||||||
|
|
||||||
entry.type = ENT_INS;
|
entry.type = ENT_INS;
|
||||||
entry.size = sizeof(struct mips_instruction);
|
entry.size = sizeof(union mips_instruction_data);
|
||||||
entry.ins = *ins;
|
entry.ins = htonl(ins->raw);
|
||||||
|
|
||||||
if (sec_push(sec, entry))
|
if (sec_push(sec, entry))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -257,9 +262,9 @@ static int handle_ins(struct assembler *assembler,
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
Elf32_Rela rel = {
|
Elf32_Rela rel = {
|
||||||
.r_info = ELF32_R_INFO(symidx, type),
|
.r_info = htonl(ELF32_R_INFO(symidx, type)),
|
||||||
.r_addend = ref->addend,
|
.r_addend = htonl(ref->addend),
|
||||||
.r_offset = sec_index(sec, secidx + i),
|
.r_offset = htonl(sec_index(sec, secidx + i)),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (reltab_push(&sec->reltab, rel))
|
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];
|
Elf32_Phdr *hdr = &phdr[i];
|
||||||
struct section *sec = &assembler->sectab.sections[i];
|
struct section *sec = &assembler->sectab.sections[i];
|
||||||
size_t size = sec_size(sec);
|
size_t size = sec_size(sec);
|
||||||
hdr->p_type = PT_LOAD;
|
hdr->p_type = htonl(PT_LOAD);
|
||||||
hdr->p_flags = (sec->execute << 0) |
|
hdr->p_flags = htonl(
|
||||||
|
(sec->execute << 0) |
|
||||||
(sec->write << 1) |
|
(sec->write << 1) |
|
||||||
(sec->read << 2);
|
(sec->read << 2));
|
||||||
hdr->p_offset = 0;
|
hdr->p_offset = 0;
|
||||||
hdr->p_vaddr = 0;
|
hdr->p_vaddr = 0;
|
||||||
hdr->p_paddr = 0;
|
hdr->p_paddr = 0;
|
||||||
hdr->p_filesz = size;
|
hdr->p_filesz = htonl(size);
|
||||||
hdr->p_memsz = size;
|
hdr->p_memsz = htonl(size);
|
||||||
hdr->p_align = sec->alignment;
|
hdr->p_align = htonl(0x1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
*res = phdr;
|
*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,
|
static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
|
||||||
uint32_t *res2)
|
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; // sections
|
||||||
max_entries += assembler->sectab.len; // reltabs per section
|
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;
|
size_t str_off;
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
|
|
||||||
// eeltables
|
// null
|
||||||
|
shdr[count++] = (Elf32_Shdr) {0};
|
||||||
|
|
||||||
|
// reltables
|
||||||
for (uint32_t i = 0; i < assembler->sectab.len; i++) {
|
for (uint32_t i = 0; i < assembler->sectab.len; i++) {
|
||||||
struct section *sec = &assembler->sectab.sections[i];
|
struct section *sec = &assembler->sectab.sections[i];
|
||||||
const char *prefix = ".reltab.";
|
const char *prefix = ".reltab.";
|
||||||
|
@ -372,16 +385,16 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
|
||||||
|
|
||||||
sec->reltab_shidx = count;
|
sec->reltab_shidx = count;
|
||||||
shdr[count++] = (Elf32_Shdr) {
|
shdr[count++] = (Elf32_Shdr) {
|
||||||
.sh_name = str_off,
|
.sh_name = htonl(str_off),
|
||||||
.sh_type = SHT_RELA,
|
.sh_type = htonl(SHT_RELA),
|
||||||
.sh_flags = 0,
|
.sh_flags = 0,
|
||||||
.sh_addr = 0,
|
.sh_addr = 0,
|
||||||
.sh_offset = 0,
|
.sh_offset = 0,
|
||||||
.sh_size = 0,
|
.sh_size = 0,
|
||||||
.sh_link = 0,
|
.sh_link = 0,
|
||||||
.sh_info = 0,
|
.sh_info = 0,
|
||||||
.sh_addralign = 1,
|
.sh_addralign = htonl(1),
|
||||||
.sh_entsize = sizeof(Elf32_Rela),
|
.sh_entsize = htonl(sizeof(Elf32_Rela)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,20 +411,22 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
|
||||||
|
|
||||||
sec->shdr_idx = count;
|
sec->shdr_idx = count;
|
||||||
if (sec->reltab.len != 0)
|
if (sec->reltab.len != 0)
|
||||||
shdr[sec->reltab_shidx].sh_info = count;
|
shdr[sec->reltab_shidx].sh_info = htonl(count);
|
||||||
|
|
||||||
shdr[count++] = (Elf32_Shdr){
|
shdr[count++] = (Elf32_Shdr){
|
||||||
.sh_name = str_off,
|
.sh_name = htonl(str_off),
|
||||||
.sh_type = SHT_PROGBITS,
|
.sh_type = htonl(SHT_PROGBITS),
|
||||||
.sh_flags = (sec->write << 0) | (sec->execute << 2) |
|
.sh_flags = htonl(
|
||||||
SHF_ALLOC,
|
(sec->write << 0) |
|
||||||
|
(sec->execute << 2) |
|
||||||
|
SHF_ALLOC),
|
||||||
.sh_addr = 0,
|
.sh_addr = 0,
|
||||||
.sh_offset = 0,
|
.sh_offset = 0,
|
||||||
.sh_size = 0,
|
.sh_size = 0,
|
||||||
.sh_link = 0,
|
.sh_link = 0,
|
||||||
.sh_info = 0,
|
.sh_info = 0,
|
||||||
.sh_addralign = sec->alignment,
|
.sh_addralign = htonl(sec->alignment),
|
||||||
.sh_entsize = sizeof(struct mips_instruction),
|
.sh_entsize = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,16 +438,16 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
|
||||||
|
|
||||||
assembler->symtab_shidx = count;
|
assembler->symtab_shidx = count;
|
||||||
shdr[count++] = (Elf32_Shdr) {
|
shdr[count++] = (Elf32_Shdr) {
|
||||||
.sh_name = str_off,
|
.sh_name = htonl(str_off),
|
||||||
.sh_type = SHT_SYMTAB,
|
.sh_type = htonl(SHT_SYMTAB),
|
||||||
.sh_flags = 0,
|
.sh_flags = 0,
|
||||||
.sh_addr = 0,
|
.sh_addr = 0,
|
||||||
.sh_offset = 0,
|
.sh_offset = 0,
|
||||||
.sh_size = 0,
|
.sh_size = 0,
|
||||||
.sh_link = 1,
|
.sh_link = 1,
|
||||||
.sh_info = 0,
|
.sh_info = 0,
|
||||||
.sh_addralign = 1,
|
.sh_addralign = htonl(1),
|
||||||
.sh_entsize = sizeof(Elf32_Sym),
|
.sh_entsize = htonl(sizeof(Elf32_Sym)),
|
||||||
};
|
};
|
||||||
|
|
||||||
// string table
|
// string table
|
||||||
|
@ -443,15 +458,15 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
|
||||||
|
|
||||||
assembler->strtab_shidx = count;
|
assembler->strtab_shidx = count;
|
||||||
shdr[count++] = (Elf32_Shdr) {
|
shdr[count++] = (Elf32_Shdr) {
|
||||||
.sh_name = str_off,
|
.sh_name = htonl(str_off),
|
||||||
.sh_type = SHT_STRTAB,
|
.sh_type = htonl(SHT_STRTAB),
|
||||||
.sh_flags = SHF_STRINGS,
|
.sh_flags = htonl(SHF_STRINGS),
|
||||||
.sh_addr = 0,
|
.sh_addr = 0,
|
||||||
.sh_offset = 0,
|
.sh_offset = 0,
|
||||||
.sh_size = 0,
|
.sh_size = 0,
|
||||||
.sh_link = 0,
|
.sh_link = 0,
|
||||||
.sh_info = 0,
|
.sh_info = 0,
|
||||||
.sh_addralign = 1,
|
.sh_addralign = htonl(1),
|
||||||
.sh_entsize = 0,
|
.sh_entsize = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -463,15 +478,15 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
|
||||||
|
|
||||||
assembler->shstrtab_shidx = count;
|
assembler->shstrtab_shidx = count;
|
||||||
shdr[count++] = (Elf32_Shdr) {
|
shdr[count++] = (Elf32_Shdr) {
|
||||||
.sh_name = str_off,
|
.sh_name = htonl(str_off),
|
||||||
.sh_type = SHT_STRTAB,
|
.sh_type = htonl(SHT_STRTAB),
|
||||||
.sh_flags = SHF_STRINGS,
|
.sh_flags = htonl(SHF_STRINGS),
|
||||||
.sh_addr = 0,
|
.sh_addr = 0,
|
||||||
.sh_offset = 0,
|
.sh_offset = 0,
|
||||||
.sh_size = 0,
|
.sh_size = 0,
|
||||||
.sh_link = 0,
|
.sh_link = 0,
|
||||||
.sh_info = 0,
|
.sh_info = 0,
|
||||||
.sh_addralign = 1,
|
.sh_addralign = htonl(1),
|
||||||
.sh_entsize = 0,
|
.sh_entsize = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -480,7 +495,7 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
|
||||||
if (sec->reltab.len == 0)
|
if (sec->reltab.len == 0)
|
||||||
continue;
|
continue;
|
||||||
shdr[sec->reltab_shidx].sh_link =
|
shdr[sec->reltab_shidx].sh_link =
|
||||||
assembler->symtab_shidx;
|
htonl(assembler->symtab_shidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
*res = shdr;
|
*res = shdr;
|
||||||
|
@ -500,7 +515,7 @@ static void update_offsets(struct assembler *assembler, Elf32_Ehdr *ehdr)
|
||||||
ptr += sizeof(Elf32_Ehdr);
|
ptr += sizeof(Elf32_Ehdr);
|
||||||
|
|
||||||
// phdr
|
// phdr
|
||||||
ehdr->e_phoff = ptr;
|
ehdr->e_phoff = htonl(ptr);
|
||||||
ptr += assembler->phdr_len * sizeof(Elf32_Phdr);
|
ptr += assembler->phdr_len * sizeof(Elf32_Phdr);
|
||||||
|
|
||||||
// reltbls
|
// reltbls
|
||||||
|
@ -510,8 +525,8 @@ static void update_offsets(struct assembler *assembler, Elf32_Ehdr *ehdr)
|
||||||
continue;
|
continue;
|
||||||
int idx = sec->reltab_shidx;
|
int idx = sec->reltab_shidx;
|
||||||
int len = sec->reltab.len;
|
int len = sec->reltab.len;
|
||||||
shdr[idx].sh_offset = ptr;
|
shdr[idx].sh_offset = htonl(ptr);
|
||||||
shdr[idx].sh_size = len * sizeof(Elf32_Rela);
|
shdr[idx].sh_size = htonl(len * sizeof(Elf32_Rela));
|
||||||
ptr += 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++) {
|
for (uint32_t i = 0; i < assembler->sectab.len; i++) {
|
||||||
struct section *sec = &assembler->sectab.sections[i];
|
struct section *sec = &assembler->sectab.sections[i];
|
||||||
int idx = sec->shdr_idx;
|
int idx = sec->shdr_idx;
|
||||||
phdr[i].p_offset = ptr;
|
phdr[i].p_offset = htonl(ptr);
|
||||||
phdr[i].p_vaddr = ptr;
|
phdr[i].p_vaddr = htonl(ptr);
|
||||||
phdr[i].p_paddr = ptr;
|
phdr[i].p_paddr = htonl(ptr);
|
||||||
shdr[idx].sh_offset = ptr;
|
shdr[idx].sh_offset = htonl(ptr);
|
||||||
shdr[idx].sh_size = phdr[i].p_filesz;
|
shdr[idx].sh_size = phdr[i].p_filesz;
|
||||||
shdr[idx].sh_addr = phdr[i].p_vaddr;
|
shdr[idx].sh_addr = phdr[i].p_vaddr;
|
||||||
shdr[idx].sh_addralign = phdr[i].p_align;
|
ptr += ntohl(phdr[i].p_filesz);
|
||||||
ptr += phdr[i].p_filesz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// symtab
|
// symtab
|
||||||
shdr[assembler->symtab_shidx].sh_offset = ptr;
|
shdr[assembler->symtab_shidx].sh_offset = htonl(ptr);
|
||||||
shdr[assembler->symtab_shidx].sh_link = assembler->strtab_shidx;
|
shdr[assembler->symtab_shidx].sh_link = htonl(assembler->strtab_shidx);
|
||||||
shdr[assembler->symtab_shidx].sh_size =
|
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);
|
ptr += assembler->symtab.len * sizeof(Elf32_Sym);
|
||||||
|
|
||||||
// strtab
|
// strtab
|
||||||
shdr[assembler->strtab_shidx].sh_offset = ptr;
|
shdr[assembler->strtab_shidx].sh_offset = htonl(ptr);
|
||||||
shdr[assembler->strtab_shidx].sh_size = assembler->strtab.size;
|
shdr[assembler->strtab_shidx].sh_size = htonl(assembler->strtab.size);
|
||||||
ptr += assembler->strtab.size;
|
ptr += assembler->strtab.size;
|
||||||
|
|
||||||
// shstrtab
|
// shstrtab
|
||||||
shdr[assembler->shstrtab_shidx].sh_offset = ptr;
|
shdr[assembler->shstrtab_shidx].sh_offset = htonl(ptr);
|
||||||
shdr[assembler->shstrtab_shidx].sh_size = assembler->shstrtab.size;
|
shdr[assembler->shstrtab_shidx].sh_size =
|
||||||
|
htonl(assembler->shstrtab.size);
|
||||||
ptr += assembler->shstrtab.size;
|
ptr += assembler->shstrtab.size;
|
||||||
|
|
||||||
// shdr
|
// shdr
|
||||||
ehdr->e_shoff = ptr;
|
ehdr->e_shoff = htonl(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_sym_shindx(struct assembler *assembler)
|
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];
|
ssize_t sec = assembler->symtab.sections[i];
|
||||||
|
|
||||||
if (sec >= 0) {
|
if (sec >= 0) {
|
||||||
sym->st_shndx = assembler->
|
sym->st_shndx = htons(assembler->
|
||||||
sectab.sections[sec].shdr_idx;
|
sectab.sections[sec].shdr_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -642,25 +657,25 @@ static int assemble_elf(struct assembler *assembler, const char *out)
|
||||||
[EI_MAG2] = ELFMAG2,
|
[EI_MAG2] = ELFMAG2,
|
||||||
[EI_MAG3] = ELFMAG3,
|
[EI_MAG3] = ELFMAG3,
|
||||||
[EI_CLASS] = ELFCLASS32,
|
[EI_CLASS] = ELFCLASS32,
|
||||||
[EI_DATA] = ELFDATA2LSB,
|
[EI_DATA] = ELFDATA2MSB,
|
||||||
[EI_VERSION] = EV_CURRENT,
|
[EI_VERSION] = EV_CURRENT,
|
||||||
[EI_OSABI] = ELFOSABI_NONE,
|
[EI_OSABI] = ELFOSABI_NONE,
|
||||||
[EI_ABIVERSION] = 0x00,
|
[EI_ABIVERSION] = 0x00,
|
||||||
[EI_PAD] = 0x00,
|
[EI_PAD] = 0x00,
|
||||||
},
|
},
|
||||||
.e_type = ET_REL,
|
.e_type = htons(ET_REL),
|
||||||
.e_machine = EM_MIPS,
|
.e_machine = htons(EM_MIPS),
|
||||||
.e_version = EV_CURRENT,
|
.e_version = htonl(EV_CURRENT),
|
||||||
.e_entry = 0x00,
|
.e_entry = 0x00,
|
||||||
.e_phoff = 0x00,
|
.e_phoff = 0x00,
|
||||||
.e_shoff = 0x00,
|
.e_shoff = 0x00,
|
||||||
.e_flags = EF_MIPS_ARCH_32R6,
|
.e_flags = htonl(EF_MIPS_ARCH_32R6),
|
||||||
.e_ehsize = sizeof(Elf32_Ehdr),
|
.e_ehsize = htons(sizeof(Elf32_Ehdr)),
|
||||||
.e_phentsize = sizeof(Elf32_Phdr),
|
.e_phentsize = htons(sizeof(Elf32_Phdr)),
|
||||||
.e_phnum = assembler->phdr_len,
|
.e_phnum = htons(assembler->phdr_len),
|
||||||
.e_shentsize = sizeof(Elf32_Shdr),
|
.e_shentsize = htons(sizeof(Elf32_Shdr)),
|
||||||
.e_shnum = assembler->shdr_len,
|
.e_shnum = htons(assembler->shdr_len),
|
||||||
.e_shstrndx = assembler->shstrtab_shidx,
|
.e_shstrndx = htons(assembler->shstrtab_shidx),
|
||||||
};
|
};
|
||||||
|
|
||||||
update_offsets(assembler, &ehdr);
|
update_offsets(assembler, &ehdr);
|
||||||
|
|
|
@ -118,7 +118,7 @@ struct section_entry {
|
||||||
char data;
|
char data;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
struct mips_instruction ins;
|
uint32_t ins;
|
||||||
char str[MAX_LEX_LENGTH];
|
char str[MAX_LEX_LENGTH];
|
||||||
int32_t word;
|
int32_t word;
|
||||||
int16_t half;
|
int16_t half;
|
||||||
|
|
58
masm/parse.c
58
masm/parse.c
|
@ -364,21 +364,21 @@ static int parse_instruction_r(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rd = reg;
|
ins->data.R.rd = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rs = reg;
|
ins->data.R.rs = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rt = reg;
|
ins->data.R.rt = reg;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -391,14 +391,14 @@ static int parse_instruction_r2(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rs = reg;
|
ins->data.R.rs = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rt = reg;
|
ins->data.R.rt = reg;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,7 @@ static int parse_instruction_rs(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rs = reg;
|
ins->data.R.rs = reg;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -424,7 +424,7 @@ static int parse_instruction_rd(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rd = reg;
|
ins->data.R.rd = reg;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -438,14 +438,14 @@ static int parse_instruction_i(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->I_data.rt = reg;
|
ins->data.I.rt = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->I_data.rs = reg;
|
ins->data.I.rs = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -455,7 +455,7 @@ static int parse_instruction_i(struct parser *parser,
|
||||||
|
|
||||||
if (token.number >= MAX16)
|
if (token.number >= MAX16)
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->I_data.immd = token.number;
|
ins->data.I.immd = token.number;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -471,10 +471,10 @@ static int parse_instruction_offset(struct parser *parser,
|
||||||
|
|
||||||
switch (max) {
|
switch (max) {
|
||||||
case MAX26:
|
case MAX26:
|
||||||
ins->J_data.target = n;
|
ins->data.J.target = n;
|
||||||
break;
|
break;
|
||||||
case MAX16:
|
case MAX16:
|
||||||
ins->B_data.offset = n;
|
ins->data.B.offset = n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ static int parse_instruction_j(struct parser *parser,
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
if (get_target(parser, &n, ref) || n > MAX26)
|
if (get_target(parser, &n, ref) || n > MAX26)
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->J_data.target = n;
|
ins->data.J.target = n;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -500,7 +500,7 @@ static int parse_instruction_jr(struct parser *parser,
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
if (get_target(parser, &n, ref) || n > MAX26)
|
if (get_target(parser, &n, ref) || n > MAX26)
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->J_data.target = n;
|
ins->data.J.target = n;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -511,7 +511,7 @@ static int parse_instruction_branch_equal(struct parser *parser,
|
||||||
enum mips_register reg;
|
enum mips_register reg;
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rs = reg;
|
ins->data.R.rs = reg;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -525,14 +525,14 @@ static int parse_instruction_branch(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->B_data.rs = reg;
|
ins->data.B.rs = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (get_offset(parser, &n, ref) || n > MAX16)
|
if (get_offset(parser, &n, ref) || n > MAX16)
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->B_data.offset = n;
|
ins->data.B.offset = n;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -547,7 +547,7 @@ static int parse_instruction_sl(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->I_data.rt = reg;
|
ins->data.I.rt = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -558,13 +558,13 @@ static int parse_instruction_sl(struct parser *parser,
|
||||||
if (token.type != TOK_LPAREN)
|
if (token.type != TOK_LPAREN)
|
||||||
if (get_offset(parser, &offset, ref))
|
if (get_offset(parser, &offset, ref))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->I_data.immd = offset;
|
ins->data.I.immd = offset;
|
||||||
|
|
||||||
if (peek_token(parser, &token))
|
if (peek_token(parser, &token))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (token.type == TOK_NL) {
|
if (token.type == TOK_NL) {
|
||||||
ins->I_data.rs = MIPS_REG_ZERO;
|
ins->data.I.rs = MIPS_REG_ZERO;
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,7 +573,7 @@ static int parse_instruction_sl(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->I_data.rs = reg;
|
ins->data.I.rs = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_RPAREN, NULL))
|
if (assert_token(parser, TOK_RPAREN, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
@ -589,14 +589,14 @@ static int parse_instruction_sli(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->I_data.rt = reg;
|
ins->data.I.rt = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX16)
|
if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX16)
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->I_data.immd = token.number;
|
ins->data.I.immd = token.number;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -609,21 +609,21 @@ static int parse_instruction_s(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rd = reg;
|
ins->data.R.rd = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rt = reg;
|
ins->data.R.rt = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX5)
|
if (assert_token(parser, TOK_NUMBER, &token) || token.number > MAX5)
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.shamt = token.number;
|
ins->data.R.shamt = token.number;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -635,21 +635,21 @@ static int parse_instruction_sv(struct parser *parser,
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rd = reg;
|
ins->data.R.rd = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rt = reg;
|
ins->data.R.rt = reg;
|
||||||
|
|
||||||
if (assert_token(parser, TOK_COMMA, NULL))
|
if (assert_token(parser, TOK_COMMA, NULL))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
|
||||||
if (parse_register(parser, ®))
|
if (parse_register(parser, ®))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
ins->R_data.rs = reg;
|
ins->data.R.rs = reg;
|
||||||
|
|
||||||
return M_SUCCESS;
|
return M_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#include <merror.h>
|
#include <merror.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -21,6 +22,10 @@ int symtab_init(struct symbol_table *symtab)
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Elf32_Sym null = {0};
|
||||||
|
if (symtab_push(symtab, null, -1))
|
||||||
|
return M_ERROR;
|
||||||
|
|
||||||
return M_SUCCESS;
|
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++) {
|
for (uint32_t i = 0; i < symtab->len; i++) {
|
||||||
Elf32_Sym *sym = &symtab->symbols[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 (strcmp(str, name) == 0) {
|
||||||
if (ptr != NULL)
|
if (ptr != NULL)
|
||||||
*ptr = sym;
|
*ptr = sym;
|
||||||
|
|
|
@ -7,7 +7,6 @@ str:
|
||||||
.align 2
|
.align 2
|
||||||
|
|
||||||
.globl main
|
.globl main
|
||||||
.extern test2
|
|
||||||
|
|
||||||
main:
|
main:
|
||||||
add $zero,$t7,$t7
|
add $zero,$t7,$t7
|
||||||
|
@ -27,4 +26,4 @@ test:
|
||||||
mfhi $s0
|
mfhi $s0
|
||||||
mtlo $s7
|
mtlo $s7
|
||||||
|
|
||||||
j test2
|
j test
|
||||||
|
|
Loading…
Reference in a new issue