mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-21 03:14:19 +08:00
Halt assembly if addresses are not converging.
Change global_offset_changed from bool to int so that progress of convergence can be monitored. If change count does not decrease from previous pass, increment stall counter. If stall count reaches threshold, terminate assembly with error message.
This commit is contained in:
parent
4252823e95
commit
c1905c2169
4
labels.c
4
labels.c
@ -77,7 +77,7 @@ struct permts { /* permanent text storage */
|
||||
char data[PERMTS_SIZE]; /* ... the data block itself */
|
||||
};
|
||||
|
||||
extern bool global_offset_changed; /* defined in nasm.c */
|
||||
extern int64_t global_offset_changed; /* defined in nasm.c */
|
||||
|
||||
static struct hash_table ltab; /* labels hash table */
|
||||
static union label *ldata; /* all label data blocks */
|
||||
@ -209,7 +209,7 @@ void redefine_label(char *label, int32_t segment, int64_t offset, char *special,
|
||||
prevlabel = lptr->defn.label;
|
||||
}
|
||||
|
||||
global_offset_changed |= (lptr->defn.offset != offset);
|
||||
if (lptr->defn.offset != offset) global_offset_changed++;
|
||||
lptr->defn.offset = offset;
|
||||
lptr->defn.segment = segment;
|
||||
|
||||
|
25
nasm.c
25
nasm.c
@ -73,7 +73,9 @@ int optimizing = -1; /* number of optimization passes to take */
|
||||
static int sb, cmd_sb = 16; /* by default */
|
||||
static uint32_t cmd_cpu = IF_PLEVEL; /* highest level by default */
|
||||
static uint32_t cpu = IF_PLEVEL; /* passed to insn_size & assemble.c */
|
||||
bool global_offset_changed; /* referenced in labels.c */
|
||||
int64_t global_offset_changed; /* referenced in labels.c */
|
||||
int64_t prev_offset_changed;
|
||||
int32_t stall_count;
|
||||
|
||||
static struct location location;
|
||||
int in_abs_seg; /* Flag we are in ABSOLUTE seg */
|
||||
@ -1166,9 +1168,7 @@ static void assemble_file(char *fname, StrList **depend_ptr)
|
||||
report_error(ERR_FATAL, "command line: "
|
||||
"32-bit segment size requires a higher cpu");
|
||||
|
||||
pass_max = 1000; /* Always terminate in a reasonable time */
|
||||
/* No real program should need this many passes */
|
||||
|
||||
pass_max = prev_offset_changed = (INT_MAX >> 1) + 2; /* Almost unlimited */
|
||||
for (passn = 1; pass0 <= 2; passn++) {
|
||||
int pass1, pass2;
|
||||
ldfunc def_label;
|
||||
@ -1186,7 +1186,7 @@ static void assemble_file(char *fname, StrList **depend_ptr)
|
||||
nasmlist.init(listname, report_error);
|
||||
}
|
||||
in_abs_seg = false;
|
||||
global_offset_changed = false; /* set by redefine_label */
|
||||
global_offset_changed = 0; /* set by redefine_label */
|
||||
location.segment = ofmt->section(NULL, pass2, &sb);
|
||||
globalbits = sb;
|
||||
if (passn > 1) {
|
||||
@ -1717,7 +1717,6 @@ static void assemble_file(char *fname, StrList **depend_ptr)
|
||||
nasm_free(line);
|
||||
location.offset = offs = GET_CURR_OFFS;
|
||||
} /* end while (line = preproc->getline... */
|
||||
|
||||
if (pass1 == 2 && global_offset_changed)
|
||||
report_error(ERR_NONFATAL,
|
||||
"phase error detected at end of assembly.");
|
||||
@ -1732,26 +1731,30 @@ static void assemble_file(char *fname, StrList **depend_ptr)
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (passn > 1 && !global_offset_changed)
|
||||
pass0++;
|
||||
else if (global_offset_changed && global_offset_changed < prev_offset_changed) {
|
||||
prev_offset_changed = global_offset_changed;
|
||||
stall_count = 0;
|
||||
}
|
||||
else stall_count++;
|
||||
|
||||
if(passn >= pass_max)
|
||||
if((stall_count > 997) || (passn >= pass_max))
|
||||
/* We get here if the labels don't converge
|
||||
* Example: FOO equ FOO + 1
|
||||
*/
|
||||
report_error(ERR_NONFATAL,
|
||||
"Can't find valid values for all labels "
|
||||
"after %d passes, giving up. "
|
||||
"Possible cause: recursive equ's.", passn);
|
||||
"after %d passes, giving up.\n"
|
||||
" Possible cause: recursive equ's.", passn);
|
||||
}
|
||||
|
||||
preproc->cleanup(0);
|
||||
nasmlist.cleanup();
|
||||
#if 1
|
||||
if (opt_verbose_info) /* -On and -Ov switches */
|
||||
fprintf(stdout,
|
||||
"info:: assembly required 1+%d+1 passes\n", passn-3);
|
||||
#endif
|
||||
} /* exit from assemble_file (...) */
|
||||
|
||||
static enum directives getkw(char **directive, char **value)
|
||||
|
Loading…
Reference in New Issue
Block a user