#include #include #include #include #include "gen.h" #include "masm.h" #include "asm/elf32.h" void help(void) { 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 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, "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: goto next; } } next: if (optind < argc - 1) { ERROR("too many source files passed"); return M_ERROR; } if (optind >= argc) { ERROR("no source files passed"); return M_ERROR; } args.in_file = argv[optind]; return assemble(&args); }