From b663f827057fc9fb199293bc1920cf27315d1846 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Wed, 9 Oct 2024 12:07:59 -0400 Subject: refactor elf32 assembler, add support for multiple isa's in cmdline --- masm/main.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 126 insertions(+), 8 deletions(-) (limited to 'masm/main.c') diff --git a/masm/main.c b/masm/main.c index caa8420..a97d949 100644 --- a/masm/main.c +++ b/masm/main.c @@ -1,33 +1,151 @@ #include #include #include +#include -#include "asm.h" +#include "gen.h" +#include "masm.h" +#include "asm/elf32.h" void help(void) { - printf("usage: masm [options] source.asm\n\n"); - printf("options:\n"); - printf("\t-h\t\tprints this help message\n"); - printf("\t-o \tselect a output file destination\n"); + printf( +"usage: masm [options] source.asm\n" +"\n" +"options: \n" +" -h print the help message \n" +" -g assume undefined symbols are external\n" +" -o specify the object file output name \n" +" -a specify mips abi used [none, o32] \n" +" default: o32 \n" +" -i mips machine isa to assemble for [mips1, mips32r2, mips32r6] \n" +" default: mips32r6\n" +" -f specify the object file format [elf32] \n" +" defualt: elf32\n" + ); +} + +static int read_isa(enum isa *isa, const char *str) +{ + #define __ISA_CHK(name) \ + if (strcasecmp(#name, str) == 0) { \ + *isa = ISA_ ##name; \ + return M_SUCCESS; \ + } \ + + __ISA_CHK(MIPS1); + __ISA_CHK(MIPS32R2); + __ISA_CHK(MIPS32R6); + + ERROR("invalid isa '%s'", str); + return M_ERROR; +} + +static int read_abi(enum abi *abi, const char *str) +{ + #define __ABI_CHK(name) \ + if (strcasecmp(#name, str) == 0) { \ + *abi = ABI_ ##name; \ + return M_SUCCESS; \ + } \ + + + __ABI_CHK(O32); + __ABI_CHK(NONE); + + ERROR("invalid abi '%s'", str); + return M_ERROR; +} + +static int read_format(enum format *format, const char *str) +{ + #define __FORMAT_CHK(name) \ + if (strcasecmp(#name, str) == 0) { \ + *format = FORMAT_ ##name; \ + return M_SUCCESS; \ + } \ + + + __FORMAT_CHK(ELF32); + + ERROR("invalid format '%s'", str); + return M_ERROR; +} + +static int generate(struct generator *gen, struct arguments *args) +{ + if (generator_init(args->in_file, gen)) + return M_ERROR; + + switch (args->isa) { + case ISA_MIPS1: + return generate_mips1(gen); + case ISA_MIPS32R2: + return generate_mips32r2(gen); + case ISA_MIPS32R6: + return generate_mips32r6(gen); + } + + return M_ERROR; +} + +static int assemble(struct arguments *args) +{ + struct generator gen; + int res = M_SUCCESS; + + if (generate(&gen, args)) + return M_ERROR; + + switch (args->format) { + case FORMAT_ELF32: + res = assemble_elf32(&gen, args); + break; + default: + res = M_ERROR; + break; + } + + generator_free(&gen); + + return res; } int main(int argc, char **argv) { - struct assembler_arguments args = { + struct arguments args = { .in_file = NULL, .out_file = "out.o", + .extern_undefined = false, + .isa = ISA_MIPS32R6, + .abi = ABI_O32, + .format = FORMAT_ELF32 }; int c; - while ((c = getopt(argc, argv, "ho:")) != 1) { + while ((c = getopt(argc, argv, "hgo:a:i:f:")) != 1) { switch(c) { case 'h': help(); return M_SUCCESS; + case 'g': + args.extern_undefined = true; + break; case 'o': args.out_file = optarg; break; + case 'a': + if (read_abi(&args.abi, optarg)) + return M_ERROR; + break; + case 'i': + if (read_isa(&args.isa, optarg)) + return M_ERROR; + break; + case 'f': + if (read_format(&args.format, optarg)) + return M_ERROR; + break; case '?': return M_ERROR; default: @@ -48,5 +166,5 @@ next: args.in_file = argv[optind]; - return assemble_file(args); + return assemble(&args); } -- cgit v1.2.3-freya