output: make the return value from the directives method more meaningful

The directives code is already trying to do a bit more unified error
handling, so give ourselves a bit richer interface.  At this point,
the conversion was pretty automatic so we probably return DIRR_OK
instead of DIRR_ERROR in a fair number of places, but that's okay.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
H. Peter Anvin 2017-03-07 22:40:00 -08:00
parent a6e26d9cca
commit e562b70cea
12 changed files with 98 additions and 59 deletions

View file

@ -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;

View file

@ -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

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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 */

View file

@ -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;
}
}

View file

@ -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;
}
}