diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-07-18 21:07:17 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-07-18 18:43:12 -0700 |
commit | 9bd1506d5999d7c41a4cf6de2f43b97939bb260e (patch) | |
tree | d3dad5bda2b167af7dfe29cad7cb532406ddb1c4 /output/outbin.c | |
parent | 159178f2aa516718fcb420a281c17adc8b330492 (diff) | |
download | nasm-9bd1506d5999d7c41a4cf6de2f43b97939bb260e.tar.gz nasm-9bd1506d5999d7c41a4cf6de2f43b97939bb260e.tar.bz2 nasm-9bd1506d5999d7c41a4cf6de2f43b97939bb260e.zip |
Remove function pointers in output, simplify error handling
Remove a bunch of function pointers in the output stage; they are
never changed and don't add any value. Also make "ofile" a global
variable and let the backend use it directly.
All we ever did with these variables were stashing it in locals and
using them as-is anyway for no benefit.
Also change the global error function, nasm_error() into a true
function which invokes a function pointer internally. That lets us
use direct calls to it.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'output/outbin.c')
-rw-r--r-- | output/outbin.c | 159 |
1 files changed, 74 insertions, 85 deletions
diff --git a/output/outbin.c b/output/outbin.c index 216397b..79f5d20 100644 --- a/output/outbin.c +++ b/output/outbin.c @@ -92,9 +92,7 @@ #ifdef OF_BIN -static FILE *fp, *rf = NULL; -static efunc error; -static struct ofmt *my_ofmt; +static FILE *rf = NULL; static void (*do_output)(void); /* Section flags keep track of which attributes the user has defined. */ @@ -278,7 +276,7 @@ static void bin_cleanup(int debuginfo) if (s->flags & (START_DEFINED | ALIGN_DEFINED | FOLLOWS_DEFINED)) { /* Check for a mixture of real and virtual section attributes. */ if (s->flags & (VSTART_DEFINED | VALIGN_DEFINED | VFOLLOWS_DEFINED)) - error(ERR_FATAL|ERR_NOFILE, + nasm_error(ERR_FATAL|ERR_NOFILE, "cannot mix real and virtual attributes" " in nobits section (%s)", s->name); /* Real and virtual attributes mean the same thing for nobits sections. */ @@ -349,11 +347,11 @@ static void bin_cleanup(int debuginfo) s && strcmp(s->name, g->follows); sp = &s->next, s = s->next) ; if (!s) - error(ERR_FATAL|ERR_NOFILE, "section %s follows an invalid or" + nasm_error(ERR_FATAL|ERR_NOFILE, "section %s follows an invalid or" " unknown section (%s)", g->name, g->follows); if (s->next && (s->next->flags & FOLLOWS_DEFINED) && !strcmp(s->name, s->next->follows)) - error(ERR_FATAL|ERR_NOFILE, "sections %s and %s can't both follow" + nasm_error(ERR_FATAL|ERR_NOFILE, "sections %s and %s can't both follow" " section %s", g->name, s->next->name, s->name); /* Find the end of the current follows group (gs). */ for (gsp = &g->next, gs = g->next; @@ -397,7 +395,7 @@ static void bin_cleanup(int debuginfo) if (sections->flags & START_DEFINED) { /* Make sure this section doesn't begin before the origin. */ if (sections->start < origin) - error(ERR_FATAL|ERR_NOFILE, "section %s begins" + nasm_error(ERR_FATAL|ERR_NOFILE, "section %s begins" " before program origin", sections->name); } else if (sections->flags & ALIGN_DEFINED) { sections->start = ((origin + sections->align - 1) & @@ -454,13 +452,13 @@ static void bin_cleanup(int debuginfo) /* Check for section overlap. */ if (s) { if (s->start < origin) - error(ERR_FATAL|ERR_NOFILE, "section %s beings before program origin", + nasm_error(ERR_FATAL|ERR_NOFILE, "section %s beings before program origin", s->name); if (g->start > s->start) - error(ERR_FATAL|ERR_NOFILE, "sections %s ~ %s and %s overlap!", + nasm_error(ERR_FATAL|ERR_NOFILE, "sections %s ~ %s and %s overlap!", gs->name, g->name, s->name); if (pend > s->start) - error(ERR_FATAL|ERR_NOFILE, "sections %s and %s overlap!", + nasm_error(ERR_FATAL|ERR_NOFILE, "sections %s and %s overlap!", g->name, s->name); } /* Remember this section as the latest >0 length section. */ @@ -489,7 +487,7 @@ static void bin_cleanup(int debuginfo) for (s = sections; s && strcmp(g->vfollows, s->name); s = s->next) ; if (!s) - error(ERR_FATAL|ERR_NOFILE, + nasm_error(ERR_FATAL|ERR_NOFILE, "section %s vfollows unknown section (%s)", g->name, g->vfollows); } else if (g->ifollows != NULL) @@ -523,13 +521,13 @@ static void bin_cleanup(int debuginfo) for (h = 0, s = sections; s; s = s->next) { if (!(s->flags & VSTART_DEFINED)) { /* Non-fatal errors after assembly has completed are generally a * no-no, but we'll throw a fatal one eventually so it's ok. */ - error(ERR_NONFATAL, "cannot compute vstart for section %s", + nasm_error(ERR_NONFATAL, "cannot compute vstart for section %s", s->name); h++; } } if (h) - error(ERR_FATAL|ERR_NOFILE, "circular vfollows path detected"); + nasm_error(ERR_FATAL|ERR_NOFILE, "circular vfollows path detected"); #ifdef DEBUG fprintf(stdout, @@ -756,13 +754,13 @@ static void bin_out(int32_t segto, const void *data, if (wrt != NO_SEG) { wrt = NO_SEG; /* continue to do _something_ */ - error(ERR_NONFATAL, "WRT not supported by binary output format"); + nasm_error(ERR_NONFATAL, "WRT not supported by binary output format"); } /* Handle absolute-assembly (structure definitions). */ if (segto == NO_SEG) { if (type != OUT_RESERVE) - error(ERR_NONFATAL, "attempt to assemble code in" + nasm_error(ERR_NONFATAL, "attempt to assemble code in" " [ABSOLUTE] space"); return; } @@ -770,7 +768,7 @@ static void bin_out(int32_t segto, const void *data, /* Find the segment we are targeting. */ s = find_section_by_index(segto); if (!s) - error(ERR_PANIC, "code directed to nonexistent segment?"); + nasm_error(ERR_PANIC, "code directed to nonexistent segment?"); /* "Smart" section-type adaptation code. */ if (!(s->flags & TYPE_DEFINED)) { @@ -781,16 +779,16 @@ static void bin_out(int32_t segto, const void *data, } if ((s->flags & TYPE_NOBITS) && (type != OUT_RESERVE)) - error(ERR_WARNING, "attempt to initialize memory in a" + nasm_error(ERR_WARNING, "attempt to initialize memory in a" " nobits section: ignored"); if (type == OUT_ADDRESS) { if (segment != NO_SEG && !find_section_by_index(segment)) { if (segment % 2) - error(ERR_NONFATAL, "binary output format does not support" + nasm_error(ERR_NONFATAL, "binary output format does not support" " segment base references"); else - error(ERR_NONFATAL, "binary output format does not support" + nasm_error(ERR_NONFATAL, "binary output format does not support" " external references"); segment = NO_SEG; } @@ -808,7 +806,7 @@ static void bin_out(int32_t segto, const void *data, s->length += size; } else if (type == OUT_RESERVE) { if (s->flags & TYPE_PROGBITS) { - error(ERR_WARNING, "uninitialized space declared in" + nasm_error(ERR_WARNING, "uninitialized space declared in" " %s section: zeroing", s->name); saa_wbytes(s->contents, NULL, size); } @@ -819,10 +817,10 @@ static void bin_out(int32_t segto, const void *data, size = realsize(type, size); if (segment != NO_SEG && !find_section_by_index(segment)) { if (segment % 2) - error(ERR_NONFATAL, "binary output format does not support" + nasm_error(ERR_NONFATAL, "binary output format does not support" " segment base references"); else - error(ERR_NONFATAL, "binary output format does not support" + nasm_error(ERR_NONFATAL, "binary output format does not support" " external references"); segment = NO_SEG; } @@ -843,12 +841,12 @@ static void bin_deflabel(char *name, int32_t segment, int64_t offset, (void)offset; /* Don't warn that this parameter is unused */ if (special) - error(ERR_NONFATAL, "binary format does not support any" + nasm_error(ERR_NONFATAL, "binary format does not support any" " special symbol types"); else if (name[0] == '.' && name[1] == '.' && name[2] != '@') - error(ERR_NONFATAL, "unrecognised special symbol `%s'", name); + nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name); else if (is_global == 2) - error(ERR_NONFATAL, "binary output format does not support common" + nasm_error(ERR_NONFATAL, "binary output format does not support common" " variables"); else { struct Section *s; @@ -964,14 +962,14 @@ static int bin_read_attribute(char **line, int *attribute, break; } if (!**line) { - error(ERR_NONFATAL, + nasm_error(ERR_NONFATAL, "invalid syntax in `section' directive"); return -1; } ++(*line); } if (!**line) { - error(ERR_NONFATAL, "expecting `)'"); + nasm_error(ERR_NONFATAL, "expecting `)'"); return -1; } } @@ -980,7 +978,7 @@ static int bin_read_attribute(char **line, int *attribute, /* Check for no value given. */ if (!*exp) { - error(ERR_WARNING, "No value given to attribute in" + nasm_error(ERR_WARNING, "No value given to attribute in" " `section' directive"); return -1; } @@ -989,15 +987,15 @@ static int bin_read_attribute(char **line, int *attribute, stdscan_reset(); stdscan_bufptr = exp; tokval.t_type = TOKEN_INVALID; - e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL); + e = evaluate(stdscan, NULL, &tokval, NULL, 1, nasm_error, NULL); if (e) { if (!is_really_simple(e)) { - error(ERR_NONFATAL, "section attribute value must be" + nasm_error(ERR_NONFATAL, "section attribute value must be" " a critical expression"); return -1; } } else { - error(ERR_NONFATAL, "Invalid attribute value" + nasm_error(ERR_NONFATAL, "Invalid attribute value" " specified in `section' directive."); return -1; } @@ -1028,7 +1026,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) *astring = '\0'; astring++; } - error(ERR_WARNING, "ignoring unknown section attribute:" + nasm_error(ERR_WARNING, "ignoring unknown section attribute:" " \"%s\"", p); } continue; @@ -1038,7 +1036,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) case ATTRIB_NOBITS: if ((sec->flags & TYPE_DEFINED) && (sec->flags & TYPE_PROGBITS)) - error(ERR_NONFATAL, + nasm_error(ERR_NONFATAL, "attempt to change section type" " from progbits to nobits"); else @@ -1048,7 +1046,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle progbits attribute. */ case ATTRIB_PROGBITS: if ((sec->flags & TYPE_DEFINED) && (sec->flags & TYPE_NOBITS)) - error(ERR_NONFATAL, "attempt to change section type" + nasm_error(ERR_NONFATAL, "attempt to change section type" " from nobits to progbits"); else sec->flags |= TYPE_DEFINED | TYPE_PROGBITS; @@ -1057,11 +1055,11 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle align attribute. */ case ATTRIB_ALIGN: if (!format_mode && (!strcmp(sec->name, ".text"))) - error(ERR_NONFATAL, "cannot specify an alignment" + nasm_error(ERR_NONFATAL, "cannot specify an alignment" " to the .text section"); else { if (!value || ((value - 1) & value)) - error(ERR_NONFATAL, "argument to `align' is not a" + nasm_error(ERR_NONFATAL, "argument to `align' is not a" " power of two"); else { /* Alignment is already satisfied if the previous * align value is greater. */ @@ -1072,7 +1070,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Don't allow a conflicting align value. */ if ((sec->flags & START_DEFINED) && (sec->start & (value - 1))) - error(ERR_NONFATAL, + nasm_error(ERR_NONFATAL, "`align' value conflicts " "with section start address"); else { @@ -1086,7 +1084,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle valign attribute. */ case ATTRIB_VALIGN: if (!value || ((value - 1) & value)) - error(ERR_NONFATAL, "argument to `valign' is not a" + nasm_error(ERR_NONFATAL, "argument to `valign' is not a" " power of two"); else { /* Alignment is already satisfied if the previous * align value is greater. */ @@ -1096,7 +1094,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Don't allow a conflicting valign value. */ if ((sec->flags & VSTART_DEFINED) && (sec->vstart & (value - 1))) - error(ERR_NONFATAL, + nasm_error(ERR_NONFATAL, "`valign' value conflicts " "with `vstart' address"); else { @@ -1109,16 +1107,16 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle start attribute. */ case ATTRIB_START: if (sec->flags & FOLLOWS_DEFINED) - error(ERR_NONFATAL, "cannot combine `start' and `follows'" + nasm_error(ERR_NONFATAL, "cannot combine `start' and `follows'" " section attributes"); else if ((sec->flags & START_DEFINED) && (value != sec->start)) - error(ERR_NONFATAL, "section start address redefined"); + nasm_error(ERR_NONFATAL, "section start address redefined"); else { sec->start = value; sec->flags |= START_DEFINED; if (sec->flags & ALIGN_DEFINED) { if (sec->start & (sec->align - 1)) - error(ERR_NONFATAL, "`start' address conflicts" + nasm_error(ERR_NONFATAL, "`start' address conflicts" " with section alignment"); sec->flags ^= ALIGN_DEFINED; } @@ -1128,12 +1126,12 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle vstart attribute. */ case ATTRIB_VSTART: if (sec->flags & VFOLLOWS_DEFINED) - error(ERR_NONFATAL, + nasm_error(ERR_NONFATAL, "cannot combine `vstart' and `vfollows'" " section attributes"); else if ((sec->flags & VSTART_DEFINED) && (value != sec->vstart)) - error(ERR_NONFATAL, + nasm_error(ERR_NONFATAL, "section virtual start address" " (vstart) redefined"); else { @@ -1141,7 +1139,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) sec->flags |= VSTART_DEFINED; if (sec->flags & VALIGN_DEFINED) { if (sec->vstart & (sec->valign - 1)) - error(ERR_NONFATAL, "`vstart' address conflicts" + nasm_error(ERR_NONFATAL, "`vstart' address conflicts" " with `valign' value"); sec->flags ^= VALIGN_DEFINED; } @@ -1153,12 +1151,12 @@ static void bin_assign_attributes(struct Section *sec, char *astring) p = astring; astring += strcspn(astring, " \t"); if (astring == p) - error(ERR_NONFATAL, "expecting section name for `follows'" + nasm_error(ERR_NONFATAL, "expecting section name for `follows'" " attribute"); else { *(astring++) = '\0'; if (sec->flags & START_DEFINED) - error(ERR_NONFATAL, + nasm_error(ERR_NONFATAL, "cannot combine `start' and `follows'" " section attributes"); sec->follows = nasm_strdup(p); @@ -1169,14 +1167,14 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle vfollows attribute. */ case ATTRIB_VFOLLOWS: if (sec->flags & VSTART_DEFINED) - error(ERR_NONFATAL, + nasm_error(ERR_NONFATAL, "cannot combine `vstart' and `vfollows'" " section attributes"); else { p = astring; astring += strcspn(astring, " \t"); if (astring == p) - error(ERR_NONFATAL, + nasm_error(ERR_NONFATAL, "expecting section name for `vfollows'" " attribute"); else { @@ -1208,12 +1206,12 @@ static void bin_define_section_labels(void) /* section.<name>.start */ strcpy(label_name + base_len, ".start"); define_label(label_name, sec->start_index, 0L, - NULL, 0, 0, my_ofmt, error); + NULL, 0, 0, ofmt, nasm_error); /* section.<name>.vstart */ strcpy(label_name + base_len, ".vstart"); define_label(label_name, sec->vstart_index, 0L, - NULL, 0, 0, my_ofmt, error); + NULL, 0, 0, ofmt, nasm_error); nasm_free(label_name); } @@ -1263,7 +1261,7 @@ static int32_t bin_secname(char *name, int pass, int *bits) sec->flags |= TYPE_DEFINED | TYPE_NOBITS; sec->ifollows = NULL; } else if (!format_mode) { - error(ERR_NONFATAL, "section name must be " + nasm_error(ERR_NONFATAL, "section name must be " ".text, .data, or .bss"); return current_section; } @@ -1298,23 +1296,23 @@ static int bin_directive(enum directives directive, char *args, int pass) stdscan_reset(); stdscan_bufptr = args; tokval.t_type = TOKEN_INVALID; - e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL); + e = evaluate(stdscan, NULL, &tokval, NULL, 1, nasm_error, NULL); if (e) { if (!is_really_simple(e)) - error(ERR_NONFATAL, "org value must be a critical" + nasm_error(ERR_NONFATAL, "org value must be a critical" " expression"); else { value = reloc_value(e); /* Check for ORG redefinition. */ if (origin_defined && (value != origin)) - error(ERR_NONFATAL, "program origin redefined"); + nasm_error(ERR_NONFATAL, "program origin redefined"); else { origin = value; origin_defined = 1; } } } else - error(ERR_NONFATAL, "No or invalid offset specified" + nasm_error(ERR_NONFATAL, "No or invalid offset specified" " in ORG directive."); return 1; } @@ -1351,14 +1349,14 @@ static int bin_directive(enum directives directive, char *args, int pass) else { /* Must be a filename. */ rf = fopen(p, "wt"); if (!rf) { - error(ERR_WARNING, "unable to open map file `%s'", + nasm_error(ERR_WARNING, "unable to open map file `%s'", p); map_control = 0; return 1; } } } else - error(ERR_WARNING, "map file already specified"); + nasm_error(ERR_WARNING, "map file already specified"); } if (map_control == 0) map_control |= MAP_ORIGIN | MAP_SUMMARY; @@ -1371,23 +1369,23 @@ static int bin_directive(enum directives directive, char *args, int pass) } } -static void bin_filename(char *inname, char *outname, efunc error) +static void bin_filename(char *inname, char *outname) { - standard_extension(inname, outname, "", error); + standard_extension(inname, outname, ""); infile = inname; outfile = outname; } -static void ith_filename(char *inname, char *outname, efunc error) +static void ith_filename(char *inname, char *outname) { - standard_extension(inname, outname, ".ith", error); + standard_extension(inname, outname, ".ith"); infile = inname; outfile = outname; } -static void srec_filename(char *inname, char *outname, efunc error) +static void srec_filename(char *inname, char *outname) { - standard_extension(inname, outname, ".srec", error); + standard_extension(inname, outname, ".srec"); infile = inname; outfile = outname; } @@ -1404,41 +1402,32 @@ static int bin_set_info(enum geninfo type, char **val) return 0; } -static void binfmt_init(FILE *afp, efunc errfunc, ldfunc ldef, evalfunc eval); struct ofmt of_bin, of_ith, of_srec; +static void binfmt_init(void); static void do_output_bin(void); static void do_output_ith(void); static void do_output_srec(void); -static void bin_init(FILE *afp, efunc errfunc, ldfunc ldef, evalfunc eval) +static void bin_init(void) { - my_ofmt = &of_bin; do_output = do_output_bin; - binfmt_init(afp, errfunc, ldef, eval); + binfmt_init(); } -static void ith_init(FILE *afp, efunc errfunc, ldfunc ldef, evalfunc eval) +static void ith_init(void) { - my_ofmt = &of_ith; do_output = do_output_ith; - binfmt_init(afp, errfunc, ldef, eval); + binfmt_init(); } -static void srec_init(FILE *afp, efunc errfunc, ldfunc ldef, evalfunc eval) +static void srec_init(void) { - my_ofmt = &of_srec; do_output = do_output_srec; - binfmt_init(afp, errfunc, ldef, eval); + binfmt_init(); } -static void binfmt_init(FILE *afp, efunc errfunc, ldfunc ldef, evalfunc eval) +static void binfmt_init(void) { - fp = afp; - error = errfunc; - - (void)eval; /* Don't warn that this parameter is unused. */ - (void)ldef; /* Placate optimizers. */ - maxbits = 64; /* Support 64-bit Segments */ relocs = NULL; reloctail = &relocs; @@ -1480,10 +1469,10 @@ static void do_output_bin(void) /* Pad the space between sections. */ nasm_assert(addr <= s->start); - fwritezero(s->start - addr, fp); + fwritezero(s->start - addr, ofile); /* Write the section to the output file. */ - saa_fpwrite(s->contents, fp); + saa_fpwrite(s->contents, ofile); /* Keep track of the current file position */ addr = s->start + s->length; @@ -1511,7 +1500,7 @@ static int write_ith_record(unsigned int len, uint16_t addr, p += sprintf(p, "%02X", dptr[i]); p += sprintf(p, "%02X\n", csum); - if (fwrite(buf, 1, p-buf, fp) != (size_t)(p-buf)) + if (fwrite(buf, 1, p-buf, ofile) != (size_t)(p-buf)) return -1; return 0; @@ -1599,7 +1588,7 @@ static int write_srecord(unsigned int len, unsigned int alen, p += sprintf(p, "%02X", dptr[i]); p += sprintf(p, "%02X\n", csum); - if (fwrite(buf, 1, p-buf, fp) != (size_t)(p-buf)) + if (fwrite(buf, 1, p-buf, ofile) != (size_t)(p-buf)) return -1; return 0; |