diff options
| author | Freya Murphy <freya@freyacat.org> | 2024-10-09 12:07:59 -0400 |
|---|---|---|
| committer | Freya Murphy <freya@freyacat.org> | 2024-10-09 12:07:59 -0400 |
| commit | b663f827057fc9fb199293bc1920cf27315d1846 (patch) | |
| tree | 477b481694ad50f28bac538bb9b301861b3af4d6 /masm/main.c | |
| parent | update generator to support multipe isas, expand grammer syntax (diff) | |
| download | mips-b663f827057fc9fb199293bc1920cf27315d1846.tar.gz mips-b663f827057fc9fb199293bc1920cf27315d1846.tar.bz2 mips-b663f827057fc9fb199293bc1920cf27315d1846.zip | |
refactor elf32 assembler, add support for multiple isa's in cmdline
Diffstat (limited to 'masm/main.c')
| -rw-r--r-- | masm/main.c | 134 |
1 files changed, 126 insertions, 8 deletions
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 <unistd.h> #include <merror.h> #include <string.h> +#include <stdio.h> -#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 <output>\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 <output> specify the object file output name \n" +" -a <abi> specify mips abi used [none, o32] \n" +" default: o32 \n" +" -i <isa> mips machine isa to assemble for [mips1, mips32r2, mips32r6] \n" +" default: mips32r6\n" +" -f <format> 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); } |