mips/masm/asm.h
2024-09-12 09:42:04 -04:00

243 lines
4.8 KiB
C

/* Copyright (c) 2024 Freya Murphy */
#ifndef __ASM_H__
#define __ASM_H__
#include <stddef.h>
#include <elf.h>
#include <mips.h>
#include "mlimits.h"
#include "parse.h"
#include "lex.h"
///
/// ELF string table
///
struct str_table {
// size of the ptr in bytes
size_t size;
// pointer that contains
// the strings
char *ptr;
};
/* initalize a string table */
int strtab_init(struct str_table *strtab);
/* free a string table */
void strtab_free(struct str_table *strtab);
/* get a string form the string table */
int strtab_get_str(struct str_table *strtab, const char *str, size_t *res);
/* get or append a string into the string table */
int strtab_write_str(struct str_table *strtab, const char *str, size_t *res);
///
/// ELF symbol table
///
struct symbol_table {
// length in size in sym ammt
size_t len;
size_t size;
// the Elf symbols
Elf32_Sym *symbols;
// keeps track of what section each ELF symbol is in
// *!!this is NOT the section header index in the ELF ehdr!!*
ssize_t *sections;
// symbols reference a string table that acutally
// holds the strings
//
// *weak* ptr, we do not own this!!!
struct str_table *strtab;
};
/* initalize a symbol table */
int symtab_init(struct symbol_table *symtab);
/* free the symbol table */
void symtab_free(struct symbol_table *symtab);
/* add a symbol to the symbol tbl */
int symtab_push(struct symbol_table *symtab, const Elf32_Sym sym,
ssize_t sec_idx);
/* find a symbol by name in the symbol table */
int symtab_find(struct symbol_table *symtab, Elf32_Sym **sym, size_t *idx,
const char name[MAX_LEX_LENGTH]);
///
/// ELF relocation table
///
struct relocation_table {
size_t len;
size_t size;
Elf32_Rela *data;
};
/* initalize a relocation table */
int reltab_init(struct relocation_table *reltab);
/* free the relocation table */
void reltab_free(struct relocation_table *reltab);
/* add a entry to the relocation table */
int reltab_push(struct relocation_table *reltab, const Elf32_Rela rel);
///
/// section entry
///
enum section_entry_type {
ENT_INS,
ENT_WORD,
ENT_HALF,
ENT_BYTE,
ENT_STR,
ENT_NO_DATA,
};
/* holds a entry inside the section, i.e. a instruction, raw data,
* special directives */
struct section_entry {
size_t size;
enum section_entry_type type;
union {
// to get memory address
char data;
// data
uint32_t ins;
char str[MAX_LEX_LENGTH];
int32_t word;
int16_t half;
int8_t byte;
};
};
///
/// section
///
/* holds a section of the asm file (i.e. .text, .bss, .data) */
struct section {
// length and size of amount of entries
size_t len;
size_t size;
struct section_entry *entries;
// section name
char name[MAX_LEX_LENGTH];
// index of the section in
// all the sections
size_t index;
// index of the sectio in
// the ELF shdr
size_t shdr_idx;
// ELF section data
bool read;
bool write;
bool execute;
uint16_t alignment;
// ELF tables
size_t reltab_shidx;
struct relocation_table reltab;
};
/* get the size of the section in bytes */
size_t sec_size(struct section *section);
/* get the index of a entry in bytes */
size_t sec_index(struct section *section, size_t index);
/* add a section entry to the section */
int sec_push(struct section *section, struct section_entry entry);
/* holds eachs section */
struct section_table {
// length and size of amount of sections
size_t len;
size_t size;
struct section *sections;
// the current section
struct section *current;
};
/* initalize the section table */
int sectab_init(struct section_table *sec_tbl);
/* free the section table */
void sectab_free(struct section_table *sec_tbl);
/* create a new section in the section table */
int sectab_alloc(struct section_table *sec_tbl, struct section **sec,
const char name[MAX_LEX_LENGTH]);
/* get a section by name from the section table */
int sectab_get(struct section_table *sec_tbl, struct section **sec,
const char name[MAX_LEX_LENGTH]);
///
/// assembler
///
struct assembler {
// the token lexer
struct lexer lexer;
// the expression parser
struct parser parser;
/// ELF tables
size_t symtab_shidx;
struct symbol_table symtab;
size_t strtab_shidx;
struct str_table strtab;
size_t shstrtab_shidx;
struct str_table shstrtab;
/// Segments
struct section_table sectab;
uint32_t secalign; // align sections to 0x1000 when writing
/// program header
Elf32_Phdr *phdr;
uint32_t phdr_len;
/// section header
Elf32_Shdr *shdr;
uint32_t shdr_len;
};
/* defines arguments to the assembler */
struct assembler_arguments {
char *in_file;
char *out_file;
};
/* initalize the assembler */
int assembler_init(struct assembler *assembler, const char *path);
/* free the assembler */
void assembler_free(struct assembler *assembler);
/* assemble a file */
int assemble_file(struct assembler_arguments args);
#endif /* __ASM_H__ */