242 lines
4.8 KiB
C
242 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__ */
|