summaryrefslogtreecommitdiff
path: root/masm/main.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-10-09 12:07:59 -0400
committerFreya Murphy <freya@freyacat.org>2024-10-09 12:07:59 -0400
commitb663f827057fc9fb199293bc1920cf27315d1846 (patch)
tree477b481694ad50f28bac538bb9b301861b3af4d6 /masm/main.c
parentupdate generator to support multipe isas, expand grammer syntax (diff)
downloadmips-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.c134
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);
}