mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-02-17 17:19:35 +08:00
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:
parent
a6e26d9cca
commit
e562b70cea
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user