add ascii and asciiz directives, fix symtab bug

This commit is contained in:
Murphy 2024-09-11 12:47:27 -04:00
parent e3d2e31377
commit c1a44ed41d
Signed by: freya
GPG key ID: 744AB800E383AE52
7 changed files with 76 additions and 30 deletions

View file

@ -475,30 +475,4 @@ MIPS_INS(XORI, I, .op = MIPS_OP_XORI)
#undef MIPS_INS
/* mips directive types */
enum mips_directive_type {
MIPS_DIRECTIVE_ALIGN,
MIPS_DIRECTIVE_SPACE,
MIPS_DIRECTIVE_WORD,
MIPS_DIRECTIVE_HALF,
MIPS_DIRECTIVE_BYTE,
MIPS_DIRECTIVE_SECTION,
MIPS_DIRECTIVE_EXTERN,
MIPS_DIRECTIVE_GLOBL,
};
/* mip32 directive */
struct mips_directive {
enum mips_directive_type type;
uint32_t len; // used for words, halfs, bytes
union {
uint16_t align;
uint16_t space;
uint32_t words[MAX_ARG_LENGTH];
uint16_t halfs[MAX_ARG_LENGTH];
uint8_t bytes[MAX_ARG_LENGTH];
char name[MAX_ARG_LENGTH];
};
};
#endif /* __MIPS_H__ */

View file

@ -165,6 +165,26 @@ static int handle_directive(struct assembler *assembler,
break;
}
case MIPS_DIRECTIVE_ASCII: {
struct section_entry entry;
entry.type = ENT_STR;
entry.size = strlen(directive->name);
memcpy(entry.str, directive->name, entry.size);
if (sec_push(assembler->sectab.current, entry))
return M_ERROR;
break;
}
case MIPS_DIRECTIVE_ASCIIZ: {
struct section_entry entry;
entry.type = ENT_STR;
entry.size = strlen(directive->name) + 1;
memcpy(entry.str, directive->name, entry.size);
if (sec_push(assembler->sectab.current, entry))
return M_ERROR;
break;
}
}
return M_SUCCESS;

View file

@ -7,6 +7,7 @@
#include <elf.h>
#include <mips.h>
#include "mlimits.h"
#include "parse.h"
#include "lex.h"
@ -102,6 +103,7 @@ enum section_entry_type {
ENT_WORD,
ENT_HALF,
ENT_BYTE,
ENT_STR,
ENT_NO_DATA,
};
@ -117,6 +119,7 @@ struct section_entry {
// data
struct mips_instruction ins;
char str[MAX_LEX_LENGTH];
int32_t word;
int16_t half;
int8_t byte;

View file

@ -875,6 +875,20 @@ static int parse_directive_globl(struct parser *parser,
return M_SUCCESS;
}
static int parse_directive_ascii(struct parser *parser,
struct mips_directive *directive,
enum mips_directive_type type)
{
struct token token;
if (assert_token(parser, TOK_STRING, &token))
return M_ERROR;
directive->type = type;
strcpy(directive->name, token.text);
return M_SUCCESS;
}
static int parse_section(struct mips_directive *directive,
char name[MAX_LEX_LENGTH])
{
@ -909,6 +923,12 @@ static int parse_directive(struct parser *parser,
return parse_directive_extern(parser, directive);
else if (strcmp(token.text, "globl") == 0)
return parse_directive_globl(parser, directive);
else if (strcmp(token.text, "ascii") == 0)
return parse_directive_ascii(parser, directive,
MIPS_DIRECTIVE_ASCII);
else if (strcmp(token.text, "asciiz") == 0)
return parse_directive_ascii(parser, directive,
MIPS_DIRECTIVE_ASCIIZ);
else
return parse_section(directive, token.text);
}

View file

@ -9,9 +9,33 @@
#include <mips.h>
#include <stdint.h>
///
/// reference
///
/* mips directive types */
enum mips_directive_type {
MIPS_DIRECTIVE_ALIGN,
MIPS_DIRECTIVE_SPACE,
MIPS_DIRECTIVE_WORD,
MIPS_DIRECTIVE_HALF,
MIPS_DIRECTIVE_BYTE,
MIPS_DIRECTIVE_SECTION,
MIPS_DIRECTIVE_EXTERN,
MIPS_DIRECTIVE_GLOBL,
MIPS_DIRECTIVE_ASCII,
MIPS_DIRECTIVE_ASCIIZ,
};
/* mip32 directive */
struct mips_directive {
enum mips_directive_type type;
uint32_t len; // used for words, halfs, bytes
union {
uint16_t align;
uint16_t space;
uint32_t words[MAX_ARG_LENGTH];
uint16_t halfs[MAX_ARG_LENGTH];
uint8_t bytes[MAX_ARG_LENGTH];
char name[MAX_ARG_LENGTH];
};
};
enum reference_type {
REF_NONE,

View file

@ -61,7 +61,7 @@ int symtab_find(struct symbol_table *symtab, Elf32_Sym **ptr,
ptrdiff_t diff = sym - symtab->symbols;
if (idx != NULL)
*idx = diff / sizeof(Elf32_Sym);
*idx = diff;
return M_SUCCESS;
}

View file

@ -1,3 +1,8 @@
.data
str:
.ascii "hello world"
.text
.align 2