Selaa lähdekoodia

Implement header offset check; fix error handling.

master
Ben Kurtovic 9 vuotta sitten
vanhempi
commit
40066b06aa
1 muutettua tiedostoa jossa 32 lisäystä ja 19 poistoa
  1. +32
    -19
      src/assembler/preprocessor.c

+ 32
- 19
src/assembler/preprocessor.c Näytä tiedosto

@@ -3,6 +3,7 @@


#include <libgen.h> #include <libgen.h>
#include <limits.h> #include <limits.h>
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -24,16 +25,15 @@
if (first && oldval != newval) { \ if (first && oldval != newval) { \
ei = error_info_create(line, ET_PREPROC, ED_PP_DUPLICATE); \ ei = error_info_create(line, ET_PREPROC, ED_PP_DUPLICATE); \
error_info_append(ei, first); \ error_info_append(ei, first); \
asm_lines_free(condemned); \
return ei; \
goto cleanup; \
} \ } \
oldval = newval; \ oldval = newval; \
first = line; first = line;


#define FAIL_ON_COND(cond, err_desc) \ #define FAIL_ON_COND(cond, err_desc) \
if ((cond)) { \ if ((cond)) { \
asm_lines_free(condemned); \
return error_info_create(line, ET_PREPROC, err_desc); \
ei = error_info_create(line, ET_PREPROC, err_desc); \
goto cleanup; \
} }


#define REQUIRE_ARG(line, d) \ #define REQUIRE_ARG(line, d) \
@@ -306,6 +306,14 @@ static bool parse_region_string(uint8_t *result, const ASMLine *line)
} }


/* /*
Return whether the given header offset is a valid location.
*/
static inline bool is_header_offset_valid(uint16_t offset)
{
return offset == 0x7FF0 || offset == 0x3FF0 || offset == 0x1FF0;
}

/*
Preprocess the LineBuffer into ASMLines. Change some state along the way. Preprocess the LineBuffer into ASMLines. Change some state along the way.


This function processes include directives, so read_source_file() may be This function processes include directives, so read_source_file() may be
@@ -317,9 +325,9 @@ static bool parse_region_string(uint8_t *result, const ASMLine *line)
*/ */
ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source) ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
{ {
ErrorInfo* ei = NULL;
DEBUG("Running preprocessor:") DEBUG("Running preprocessor:")


ErrorInfo* ei;
if ((ei = build_asm_lines(source, source, &state->lines, NULL, if ((ei = build_asm_lines(source, source, &state->lines, NULL,
&state->includes))) &state->includes)))
return ei; return ei;
@@ -327,9 +335,9 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
ASMLine dummy = {.next = state->lines}; ASMLine dummy = {.next = state->lines};
ASMLine *prev, *line = &dummy, *next = state->lines, *condemned = NULL; ASMLine *prev, *line = &dummy, *next = state->lines, *condemned = NULL;


const ASMLine *first_optimizer = NULL, *first_checksum = NULL,
*first_product = NULL, *first_version = NULL,
*first_region = NULL;
const ASMLine *first_optimizer = NULL, *first_offset = NULL,
*first_checksum = NULL, *first_product = NULL,
*first_version = NULL, *first_region = NULL;


while ((prev = line, line = next)) { while ((prev = line, line = next)) {
next = line->next; next = line->next;
@@ -348,10 +356,14 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
else if (IS_DIRECTIVE(line, DIR_ROM_SIZE)) { else if (IS_DIRECTIVE(line, DIR_ROM_SIZE)) {
// TODO // TODO
// state->rom_size <-- value check // state->rom_size <-- value check
// auto
} }
else if (IS_DIRECTIVE(line, DIR_ROM_HEADER)) { else if (IS_DIRECTIVE(line, DIR_ROM_HEADER)) {
// TODO
// state->header.offset <-- check in list of acceptable values
REQUIRE_ARG(line, DIR_ROM_HEADER)
uint16_t arg;
VALIDATE(parse_uint16(&arg, line, DIR_ROM_HEADER)) // auto
VALIDATE(is_header_offset_valid(arg))
SAVE_ARG(line, first_offset, state->header.offset, arg)
} }
else if (IS_DIRECTIVE(line, DIR_ROM_CHECKSUM)) { else if (IS_DIRECTIVE(line, DIR_ROM_CHECKSUM)) {
REQUIRE_ARG(line, DIR_ROM_CHECKSUM) REQUIRE_ARG(line, DIR_ROM_CHECKSUM)
@@ -362,21 +374,21 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
else if (IS_DIRECTIVE(line, DIR_ROM_PRODUCT)) { else if (IS_DIRECTIVE(line, DIR_ROM_PRODUCT)) {
REQUIRE_ARG(line, DIR_ROM_PRODUCT) REQUIRE_ARG(line, DIR_ROM_PRODUCT)
uint32_t arg; uint32_t arg;
VALIDATE(parse_uint32(&arg, line, DIR_ROM_PRODUCT))
VALIDATE(parse_uint32(&arg, line, DIR_ROM_PRODUCT)) // auto
RANGE_CHECK(arg, 160000) RANGE_CHECK(arg, 160000)
SAVE_ARG(line, first_product, state->header.product_code, arg) SAVE_ARG(line, first_product, state->header.product_code, arg)
} }
else if (IS_DIRECTIVE(line, DIR_ROM_VERSION)) { else if (IS_DIRECTIVE(line, DIR_ROM_VERSION)) {
REQUIRE_ARG(line, DIR_ROM_VERSION) REQUIRE_ARG(line, DIR_ROM_VERSION)
uint8_t arg; uint8_t arg;
VALIDATE(parse_uint8(&arg, line, DIR_ROM_VERSION))
VALIDATE(parse_uint8(&arg, line, DIR_ROM_VERSION)) // auto
RANGE_CHECK(arg, 0x10) RANGE_CHECK(arg, 0x10)
SAVE_ARG(line, first_version, state->header.version, arg) SAVE_ARG(line, first_version, state->header.version, arg)
} }
else if (IS_DIRECTIVE(line, DIR_ROM_REGION)) { else if (IS_DIRECTIVE(line, DIR_ROM_REGION)) {
REQUIRE_ARG(line, DIR_ROM_REGION) REQUIRE_ARG(line, DIR_ROM_REGION)
uint8_t arg; uint8_t arg;
if (parse_uint8(&arg, line, DIR_ROM_REGION)) {
if (parse_uint8(&arg, line, DIR_ROM_REGION)) { // auto
RANGE_CHECK(arg, 0x10) RANGE_CHECK(arg, 0x10)
VALIDATE(region_code_to_string(arg)) VALIDATE(region_code_to_string(arg))
} else { } else {
@@ -387,10 +399,11 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
else if (IS_DIRECTIVE(line, DIR_ROM_DECLSIZE)) { else if (IS_DIRECTIVE(line, DIR_ROM_DECLSIZE)) {
// TODO // TODO
// state->header.rom_size <-- value/range check // state->header.rom_size <-- value/range check
// auto
} }
else { else {
asm_lines_free(condemned);
return error_info_create(line, ET_PREPROC, ED_PP_UNKNOWN);
ei = error_info_create(line, ET_PREPROC, ED_PP_UNKNOWN);
goto cleanup;
} }


// Remove directive from lines, and schedule it for deletion: // Remove directive from lines, and schedule it for deletion:
@@ -406,9 +419,6 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)


state->rom_size = 8; // TODO state->rom_size = 8; // TODO


asm_lines_free(condemned);
state->lines = dummy.next; // Fix list head if first line was a directive

#ifdef DEBUG_MODE #ifdef DEBUG_MODE
DEBUG("Dumping ASMLines:") DEBUG("Dumping ASMLines:")
const ASMLine *temp = state->lines; const ASMLine *temp = state->lines;
@@ -419,5 +429,8 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
} }
#endif #endif


return NULL;
cleanup:
asm_lines_free(condemned);
state->lines = dummy.next; // Fix list head if first line was a directive
return ei;
} }

Ladataan…
Peruuta
Tallenna