mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-27 08:10:07 +08:00
labels: add a subsection field available for backend use
Allow the subsection to store a subsection value directly in the label, rather than having to do strange encoding hacks. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
parent
13587802fe
commit
29695c85fb
@ -92,6 +92,7 @@ static const char * const types[] =
|
||||
union label { /* actual label structures */
|
||||
struct {
|
||||
int32_t segment;
|
||||
int32_t subsection; /* Available for ofmt->herelabel() */
|
||||
int64_t offset;
|
||||
int64_t size;
|
||||
char *label, *mangled, *special;
|
||||
@ -231,6 +232,7 @@ static union label *find_label(const char *label, bool create, bool *created)
|
||||
nasm_zero(*lfree);
|
||||
lfree->admin.movingon = BOGUS_VALUE;
|
||||
lfree->defn.label = perm_copy(label);
|
||||
lfree->defn.subsection = NO_SEG;
|
||||
if (label_str)
|
||||
nasm_free(label_str);
|
||||
|
||||
@ -321,7 +323,7 @@ static const char *mangle_label_name(union label *lptr)
|
||||
}
|
||||
|
||||
static void
|
||||
handle_herelabel(const union label *lptr, int32_t *segment, int64_t *offset)
|
||||
handle_herelabel(union label *lptr, int32_t *segment, int64_t *offset)
|
||||
{
|
||||
int32_t oldseg;
|
||||
|
||||
@ -338,7 +340,8 @@ handle_herelabel(const union label *lptr, int32_t *segment, int64_t *offset)
|
||||
int32_t newseg;
|
||||
|
||||
nasm_assert(lptr->defn.mangled);
|
||||
newseg = ofmt->herelabel(lptr->defn.mangled, lptr->defn.type, oldseg);
|
||||
newseg = ofmt->herelabel(lptr->defn.mangled, lptr->defn.type,
|
||||
oldseg, &lptr->defn.subsection);
|
||||
if (likely(newseg == oldseg))
|
||||
return;
|
||||
|
||||
|
20
asm/nasm.c
20
asm/nasm.c
@ -91,6 +91,7 @@ static const char *debug_format;
|
||||
# define ABORT_ON_PANIC 0
|
||||
#endif
|
||||
static bool abort_on_panic = ABORT_ON_PANIC;
|
||||
static bool keep_all;
|
||||
|
||||
bool tasm_compatible_mode = false;
|
||||
int pass0, passn;
|
||||
@ -540,7 +541,7 @@ int main(int argc, char **argv)
|
||||
preproc->cleanup(0);
|
||||
if (ofile)
|
||||
fclose(ofile);
|
||||
if (ofile && terminate_after_phase)
|
||||
if (ofile && terminate_after_phase && !keep_all)
|
||||
remove(outname);
|
||||
ofile = NULL;
|
||||
}
|
||||
@ -576,7 +577,7 @@ int main(int argc, char **argv)
|
||||
|
||||
if (ofile) {
|
||||
fclose(ofile);
|
||||
if (terminate_after_phase)
|
||||
if (terminate_after_phase && !keep_all)
|
||||
remove(outname);
|
||||
ofile = NULL;
|
||||
}
|
||||
@ -786,7 +787,8 @@ enum text_options {
|
||||
OPT_INCLUDE,
|
||||
OPT_PRAGMA,
|
||||
OPT_BEFORE,
|
||||
OPT_LIMIT
|
||||
OPT_LIMIT,
|
||||
OPT_KEEP_ALL
|
||||
};
|
||||
struct textargs {
|
||||
const char *label;
|
||||
@ -809,6 +811,7 @@ static const struct textargs textopts[] = {
|
||||
{"pragma", OPT_PRAGMA, true, 0},
|
||||
{"before", OPT_BEFORE, true, 0},
|
||||
{"limit-", OPT_LIMIT, true, 0},
|
||||
{"keep-all", OPT_KEEP_ALL, false, 0},
|
||||
{NULL, OPT_BOGUS, false, 0}
|
||||
};
|
||||
|
||||
@ -1155,6 +1158,9 @@ static bool process_arg(char *p, char *q, int pass)
|
||||
if (pass == 2)
|
||||
nasm_set_limit(p+olen, param);
|
||||
break;
|
||||
case OPT_KEEP_ALL:
|
||||
keep_all = true;
|
||||
break;
|
||||
case OPT_HELP:
|
||||
help(0);
|
||||
exit(0);
|
||||
@ -1400,7 +1406,7 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
|
||||
cpu = cmd_cpu;
|
||||
if (pass0 == 2) {
|
||||
lfmt->init(listname);
|
||||
} else if (passn == 1 && listname) {
|
||||
} else if (passn == 1 && listname && !keep_all) {
|
||||
/* Remove the list file in case we die before the output pass */
|
||||
remove(listname);
|
||||
}
|
||||
@ -1859,7 +1865,8 @@ static void nasm_verror_common(int severity, const char *fmt, va_list args)
|
||||
case ERR_FATAL:
|
||||
if (ofile) {
|
||||
fclose(ofile);
|
||||
remove(outname);
|
||||
if (!keep_all)
|
||||
remove(outname);
|
||||
ofile = NULL;
|
||||
}
|
||||
if (want_usage)
|
||||
@ -1874,7 +1881,8 @@ static void nasm_verror_common(int severity, const char *fmt, va_list args)
|
||||
|
||||
if (ofile) {
|
||||
fclose(ofile);
|
||||
remove(outname);
|
||||
if (!keep_all)
|
||||
remove(outname);
|
||||
ofile = NULL;
|
||||
}
|
||||
exit(3);
|
||||
|
@ -915,8 +915,11 @@ struct ofmt {
|
||||
* This is *only* called if the symbol defined is at the
|
||||
* current offset, i.e. "foo:" or "foo equ $".
|
||||
* The offset isn't passed; and may not be stable at this point.
|
||||
* The subsection number is a field available for use by the
|
||||
* backend. It is initialized to NO_SEG.
|
||||
*/
|
||||
int32_t (*herelabel)(const char *name, enum label_type type, int32_t seg);
|
||||
int32_t (*herelabel)(const char *name, enum label_type type,
|
||||
int32_t seg, int32_t *subsection);
|
||||
|
||||
/*
|
||||
* This procedure is called to modify section alignment,
|
||||
|
@ -136,15 +136,17 @@ static int32_t dbg_section_names(char *name, int pass, int *bits)
|
||||
}
|
||||
|
||||
static int32_t dbg_herelabel(const char *name, enum label_type type,
|
||||
int32_t seg)
|
||||
int32_t oldseg, int32_t *subsection)
|
||||
{
|
||||
int32_t newseg = seg;
|
||||
|
||||
if (subsections_via_symbols && type != LBL_LOCAL)
|
||||
newseg += 0x10000;
|
||||
int32_t newseg = oldseg;
|
||||
|
||||
if (subsections_via_symbols && type != LBL_LOCAL) {
|
||||
newseg = *subsection;
|
||||
if (newseg == NO_SEG)
|
||||
newseg = *subsection = seg_alloc();
|
||||
}
|
||||
fprintf(ofile, "herelabel %s type %d (seg %08x) -> %08x\n",
|
||||
name, type, seg, newseg);
|
||||
name, type, oldseg, newseg);
|
||||
|
||||
return newseg;
|
||||
}
|
||||
|
@ -1003,10 +1003,11 @@ static int32_t macho_section(char *name, int pass, int *bits)
|
||||
}
|
||||
|
||||
static int32_t macho_herelabel(const char *name, enum label_type type,
|
||||
int32_t section)
|
||||
int32_t section, int32_t *subsection)
|
||||
{
|
||||
struct section *s;
|
||||
(void)name;
|
||||
(void)subsection;
|
||||
|
||||
if (!(head_flags & MH_SUBSECTIONS_VIA_SYMBOLS))
|
||||
return section;
|
||||
@ -1014,7 +1015,7 @@ static int32_t macho_herelabel(const char *name, enum label_type type,
|
||||
/* No subsection only for local labels */
|
||||
if (type == LBL_LOCAL)
|
||||
return section;
|
||||
|
||||
|
||||
s = get_section_by_index(section);
|
||||
if (!s)
|
||||
return section;
|
||||
|
Loading…
Reference in New Issue
Block a user