diff --git a/asm/directiv.c b/asm/directiv.c index e8bb42d38..1c6bfa38c 100644 --- a/asm/directiv.c +++ b/asm/directiv.c @@ -206,10 +206,22 @@ bool process_directives(char *directive) break; default: /* It's a backend-specific directive */ - if (ofmt->directive(d, value, pass2)) + switch (ofmt->directive(d, value, pass2)) { + case DIRR_UNKNOWN: + goto unknown; + case DIRR_OK: + case DIRR_ERROR: break; - /* else fall through */ + case DIRR_BADPARAM: + bad_param = true; + break; + default: + panic(); + } + break; + case D_unknown: + unknown: nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_PANIC, "unrecognised directive [%s]", directive); break; diff --git a/include/nasm.h b/include/nasm.h index 2a231411d..5351d1993 100644 --- a/include/nasm.h +++ b/include/nasm.h @@ -711,6 +711,21 @@ struct pragma { const char *tail; /* Anything after the operation */ }; +/* + * What to return from a directive-handling function. + * Currently DIRR_OK and DIRR_ERROR are treated the same way; + * in both cases the backend is expected to produce the appropriate + * error message on its own. + * + * DIRR_BADPARAM causes a generic error message to be printed. + */ +enum directive_result { + DIRR_UNKNOWN, /* Directive not handled by backend */ + DIRR_OK, /* Directive processed */ + DIRR_ERROR, /* Directive processed unsuccessfully */ + DIRR_BADPARAM /* Print bad argument error message */ +}; + /* * The data structure defining an output format driver, and the * interfaces to the functions therein. @@ -870,14 +885,17 @@ struct ofmt { * `value'. It is called in both assembly passes, and `pass' * will be either 1 or 2. * - * This procedure should return zero if it does not _recognise_ - * the directive, so that the main program can report an error. - * If it recognises the directive but then has its own errors, - * it should report them itself and then return non-zero. It - * should also return non-zero if it correctly processes the - * directive. + * The following values are (currently) possible for + * directive_result: + * + * 0 - DIRR_UNKNOWN - directive not recognized by backend + * 1 - DIRR_OK - directive processed ok + * 2 - DIRR_ERROR - backend printed its own error message + * 3 - DIRR_BADPARAM - print the generic message + * "invalid parameter to [*] directive" */ - int (*directive)(enum directives directive, char *value, int pass); + enum directive_result + (*directive)(enum directives directive, char *value, int pass); /* * This procedure is called before anything else - even before diff --git a/output/nullout.c b/output/nullout.c index aa3a47e13..862c00837 100644 --- a/output/nullout.c +++ b/output/nullout.c @@ -42,12 +42,13 @@ int null_setinfo(enum geninfo type, char **string) return 0; } -int null_directive(enum directives directive, char *value, int pass) +enum directive_result +null_directive(enum directives directive, char *value, int pass) { (void)directive; (void)value; (void)pass; - return 0; + return DIRR_UNKNOWN; } void null_sectalign(int32_t seg, unsigned int value) diff --git a/output/outbin.c b/output/outbin.c index 25fdfcc76..6100ceb13 100644 --- a/output/outbin.c +++ b/output/outbin.c @@ -1285,7 +1285,8 @@ static int32_t bin_secname(char *name, int pass, int *bits) return sec->vstart_index; } -static int bin_directive(enum directives directive, char *args, int pass) +static enum directive_result +bin_directive(enum directives directive, char *args, int pass) { switch (directive) { case D_ORG: @@ -1315,7 +1316,7 @@ static int bin_directive(enum directives directive, char *args, int pass) } else nasm_error(ERR_NONFATAL, "No or invalid offset specified" " in ORG directive."); - return 1; + return DIRR_OK; } case D_MAP: { @@ -1324,7 +1325,7 @@ static int bin_directive(enum directives directive, char *args, int pass) char *p; if (pass != 1) - return 1; + return DIRR_OK; args += strspn(args, " \t"); while (*args) { p = args; @@ -1353,7 +1354,7 @@ static int bin_directive(enum directives directive, char *args, int pass) nasm_error(ERR_WARNING, "unable to open map file `%s'", p); map_control = 0; - return 1; + return DIRR_OK; } } } else @@ -1363,10 +1364,10 @@ static int bin_directive(enum directives directive, char *args, int pass) map_control |= MAP_ORIGIN | MAP_SUMMARY; if (!rf) rf = stdout; - return 1; + return DIRR_OK; } default: - return 0; + return DIRR_UNKNOWN; } } diff --git a/output/outcoff.c b/output/outcoff.c index ee576d9f8..86a7ff852 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -768,7 +768,8 @@ static void BuildExportTable(STRING **rvp) *rvp = NULL; } -static int coff_directives(enum directives directive, char *value, int pass) +static enum directive_result +coff_directives(enum directives directive, char *value, int pass) { switch (directive) { case D_EXPORT: @@ -776,7 +777,7 @@ static int coff_directives(enum directives directive, char *value, int pass) char *q, *name; if (pass == 2) - return 1; /* ignore in pass two */ + return DIRR_OK; /* ignore in pass two */ name = q = value; while (*q && !nasm_isspace(*q)) q++; @@ -788,14 +789,14 @@ static int coff_directives(enum directives directive, char *value, int pass) if (!*name) { nasm_error(ERR_NONFATAL, "`export' directive requires export name"); - return 1; + return DIRR_ERROR; } if (*q) { nasm_error(ERR_NONFATAL, "unrecognized export qualifier `%s'", q); - return 1; + return DIRR_ERROR; } AddExport(name); - return 1; + return DIRR_OK; } case D_SAFESEH: { @@ -855,12 +856,13 @@ static int coff_directives(enum directives directive, char *value, int pass) if (n == coff_nsyms) { nasm_error(ERR_NONFATAL, "`safeseh' directive requires valid symbol"); + return DIRR_ERROR; } } - return 1; + return DIRR_OK; } default: - return 0; + return DIRR_UNKNOWN; } } diff --git a/output/outdbg.c b/output/outdbg.c index acc4cd865..73a823ea9 100644 --- a/output/outdbg.c +++ b/output/outdbg.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2013 The NASM Authors - All Rights Reserved + * Copyright 1996-2017 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -183,11 +183,12 @@ static int32_t dbg_segbase(int32_t segment) return segment; } -static int dbg_directive(enum directives directive, char *value, int pass) +static enum directive_result +dbg_directive(enum directives directive, char *value, int pass) { fprintf(ofile, "directive [%s] value [%s] (pass %d)\n", directives[directive], value, pass); - return 1; + return DIRR_OK; } static void dbg_filename(char *inname, char *outname) diff --git a/output/outelf.c b/output/outelf.c index 6ccfcf642..b347fdfdd 100644 --- a/output/outelf.c +++ b/output/outelf.c @@ -269,7 +269,8 @@ void elf_section_attrib(char *name, char *attr, int pass, } } -int elf_directive(enum directives directive, char *value, int pass) +static enum directive_result +elf_directive(enum directives directive, char *value, int pass) { int64_t n; bool err; @@ -278,17 +279,17 @@ int elf_directive(enum directives directive, char *value, int pass) switch (directive) { case D_OSABI: if (pass == 2) - return 1; /* ignore in pass 2 */ + return DIRR_OK; /* ignore in pass 2 */ n = readnum(value, &err); if (err) { nasm_error(ERR_NONFATAL, "`osabi' directive requires a parameter"); - return 1; + return DIRR_ERROR; } if (n < 0 || n > 255) { nasm_error(ERR_NONFATAL, "valid osabi numbers are 0 to 255"); - return 1; + return DIRR_ERROR; } elf_osabi = n; @@ -296,19 +297,19 @@ int elf_directive(enum directives directive, char *value, int pass) p = strchr(value,','); if (!p) - return 1; + return DIRR_OK; n = readnum(p + 1, &err); if (err || n < 0 || n > 255) { nasm_error(ERR_NONFATAL, "invalid ABI version number (valid: 0 to 255)"); - return 1; + return DIRR_ERROR; } elf_abiver = n; - return 1; + return DIRR_OK; default: - return 0; + return DIRR_UNKNOWN; } } diff --git a/output/outelf.h b/output/outelf.h index 5eaea4d34..0f718d9eb 100644 --- a/output/outelf.h +++ b/output/outelf.h @@ -103,7 +103,6 @@ struct stabentry { extern uint8_t elf_osabi; extern uint8_t elf_abiver; -int elf_directive(enum directives directive, char *value, int pass); void elf_section_attrib(char *name, char *attr, int pass, uint32_t *flags_and, uint32_t *flags_or, uint64_t *align, int *type); diff --git a/output/outieee.c b/output/outieee.c index 7607e6739..a043ec517 100644 --- a/output/outieee.c +++ b/output/outieee.c @@ -832,7 +832,8 @@ static int32_t ieee_segment(char *name, int pass, int *bits) /* * directives supported */ -static int ieee_directive(enum directives directive, char *value, int pass) +static enum directive_result +ieee_directive(enum directives directive, char *value, int pass) { (void)value; @@ -841,10 +842,10 @@ static int ieee_directive(enum directives directive, char *value, int pass) switch (directive) { case D_UPPERCASE: ieee_uppercase = true; - return 1; + return DIRR_OK; default: - return 0; + return DIRR_UNKNOWN; } } diff --git a/output/outlib.h b/output/outlib.h index f7deeaeb4..2406978c4 100644 --- a/output/outlib.h +++ b/output/outlib.h @@ -41,7 +41,8 @@ uint64_t realsize(enum out_type type, uint64_t size); /* Do-nothing versions of some output routines */ int null_setinfo(enum geninfo type, char **string); -int null_directive(enum directives directive, char *value, int pass); +enum directive_result +null_directive(enum directives directive, char *value, int pass); void null_sectalign(int32_t seg, unsigned int value); /* Do-nothing versions of all the debug routines */ diff --git a/output/outobj.c b/output/outobj.c index 39712a743..1f9cac311 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -634,7 +634,7 @@ static struct Segment *current_seg; static int32_t obj_segment(char *, int, int *); static void obj_write_file(void); -static int obj_directive(enum directives, char *, int); +static enum directive_result obj_directive(enum directives, char *, int); static void obj_init(void) { @@ -1598,7 +1598,8 @@ static int32_t obj_segment(char *name, int pass, int *bits) } } -static int obj_directive(enum directives directive, char *value, int pass) +static enum directive_result +obj_directive(enum directives directive, char *value, int pass) { switch (directive) { case D_GROUP: @@ -1629,7 +1630,7 @@ static int obj_directive(enum directives directive, char *value, int pass) * * if (!*q) { * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments"); - * return 1; + * return DIRR_ERROR; * } */ @@ -1638,7 +1639,7 @@ static int obj_directive(enum directives directive, char *value, int pass) obj_idx++; if (!strcmp(grp->name, v)) { nasm_error(ERR_NONFATAL, "group `%s' defined twice", v); - return 1; + return DIRR_ERROR; } } @@ -1709,11 +1710,11 @@ static int obj_directive(enum directives directive, char *value, int pass) extp = &(*extp)->next_dws; } } - return 1; + return DIRR_OK; } case D_UPPERCASE: obj_uppercase = true; - return 1; + return DIRR_OK; case D_IMPORT: { @@ -1760,7 +1761,7 @@ static int obj_directive(enum directives directive, char *value, int pass) imp->impname = NULL; } - return 1; + return DIRR_OK; } case D_EXPORT: { @@ -1770,7 +1771,7 @@ static int obj_directive(enum directives directive, char *value, int pass) unsigned int ordinal = 0; if (pass == 2) - return 1; /* ignore in pass two */ + return DIRR_OK; /* ignore in pass two */ intname = q = value; while (*q && !nasm_isspace(*q)) q++; @@ -1791,7 +1792,7 @@ static int obj_directive(enum directives directive, char *value, int pass) if (!*intname) { nasm_error(ERR_NONFATAL, "`export' directive requires export name"); - return 1; + return DIRR_OK; } if (!*extname) { extname = intname; @@ -1816,7 +1817,7 @@ static int obj_directive(enum directives directive, char *value, int pass) if (err) { nasm_error(ERR_NONFATAL, "value `%s' for `parm' is non-numeric", v + 5); - return 1; + return DIRR_ERROR; } } else { bool err = false; @@ -1824,7 +1825,7 @@ static int obj_directive(enum directives directive, char *value, int pass) if (err) { nasm_error(ERR_NONFATAL, "unrecognised export qualifier `%s'", v); - return 1; + return DIRR_ERROR; } flags |= EXPDEF_FLAG_ORDINAL; } @@ -1838,10 +1839,10 @@ static int obj_directive(enum directives directive, char *value, int pass) export->ordinal = ordinal; export->flags = flags; - return 1; + return DIRR_OK; } default: - return 0; + return DIRR_UNKNOWN; } } diff --git a/output/outrdf2.c b/output/outrdf2.c index eaba9329a..1491fd250 100644 --- a/output/outrdf2.c +++ b/output/outrdf2.c @@ -720,7 +720,8 @@ static int32_t rdf2_segbase(int32_t segment) /* * Handle RDOFF2 specific directives */ -static int rdf2_directive(enum directives directive, char *value, int pass) +static enum directive_result +rdf2_directive(enum directives directive, char *value, int pass) { size_t n; @@ -729,7 +730,7 @@ static int rdf2_directive(enum directives directive, char *value, int pass) n = strlen(value); if (n >= MODLIB_NAME_MAX) { nasm_error(ERR_NONFATAL, "name size exceeds %d bytes", MODLIB_NAME_MAX); - return 1; + return DIRR_ERROR; } if (pass == 1) { struct DLLRec r; @@ -738,12 +739,12 @@ static int rdf2_directive(enum directives directive, char *value, int pass) strcpy(r.libname, value); write_dll_rec(&r); } - return 1; + return DIRR_OK; case D_MODULE: if ((n = strlen(value)) >= MODLIB_NAME_MAX) { nasm_error(ERR_NONFATAL, "name size exceeds %d bytes", MODLIB_NAME_MAX); - return 1; + return DIRR_ERROR; } if (pass == 1) { struct ModRec r; @@ -752,10 +753,10 @@ static int rdf2_directive(enum directives directive, char *value, int pass) strcpy(r.modname, value); write_modname_rec(&r); } - return 1; + return DIRR_OK; default: - return 0; + return DIRR_UNKNOWN; } }