summaryrefslogtreecommitdiff
path: root/masm/asm.c
blob: 099bfe6c78b3d183725fc912eeffc1dd20d34c3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <merror.h>
#include <stdlib.h>

#include "asm.h"

int assembler_init(struct assembler *assembler, const char *path)
{
	if (lexer_init(path, &assembler->lexer))
		return M_ERROR;

	if (parser_init(&assembler->lexer, &assembler->parser)) {
		lexer_free(&assembler->lexer);
		return M_ERROR;
	}

	if (strtbl_init(&assembler->shstr_tbl)) {
		parser_free(&assembler->parser);
		lexer_free(&assembler->lexer);
		return M_ERROR;
	}

	if (strtbl_init(&assembler->str_tbl)) {
		strtbl_free(&assembler->shstr_tbl);
		parser_free(&assembler->parser);
		lexer_free(&assembler->lexer);
		return M_ERROR;
	}

	if (symtbl_init(&assembler->sym_tbl)) {
		strtbl_free(&assembler->str_tbl);
		strtbl_free(&assembler->shstr_tbl);
		parser_free(&assembler->parser);
		lexer_free(&assembler->lexer);
		return M_ERROR;
	}

	assembler->meta = NULL;
	assembler->phdr = NULL;
	assembler->shdr = NULL;
	assembler->symtab = NULL;

	return M_SUCCESS;
}

void assembler_free(struct assembler *assembler)
{
	if (assembler->meta) {
		for (uint32_t i = 0; i < assembler->parser.sec_tbl.count; i++) {
			if (assembler->meta[i].reltbl != NULL) {
				free(assembler->meta[i].reltbl);
			}
		}
		free(assembler->meta);
	}

	if (assembler->phdr)
		free(assembler->phdr);
	if (assembler->shdr)
		free(assembler->shdr);
	if (assembler->symtab)
		free(assembler->symtab);

	symtbl_free(&assembler->sym_tbl);
	strtbl_free(&assembler->str_tbl);
	strtbl_free(&assembler->shstr_tbl);

	parser_free(&assembler->parser);
	lexer_free(&assembler->lexer);
}

int assemble_file(struct assembler_arguments args) {
	switch (args.isa) {
        case ISA_MIPS32:
		return assemble_file_mips32(args);
        }
	return M_ERROR;
}