/* Copyright (c) 2024 Freya Murphy */ #ifndef __ASM_H__ #define __ASM_H__ #include #include #include #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_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 struct mips_instruction ins; 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; /// 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__ */