summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2018-06-14 17:04:32 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2018-06-14 17:04:32 -0700
commit29695c85fbf1f343b02c49502482727294645728 (patch)
treedd1d0cd631616cc45db1a55defb1b96b699abfb6
parent13587802fe602556abe5c00b7a236bfbdd98a337 (diff)
downloadnasm-29695c85fbf1f343b02c49502482727294645728.tar.gz
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>
-rw-r--r--asm/labels.c7
-rw-r--r--asm/nasm.c20
-rw-r--r--include/nasm.h5
-rw-r--r--output/outdbg.c14
-rw-r--r--output/outmacho.c5
5 files changed, 34 insertions, 17 deletions
diff --git a/asm/labels.c b/asm/labels.c
index 94a57ac2..eec5a844 100644
--- a/asm/labels.c
+++ b/asm/labels.c
@@ -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;
diff --git a/asm/nasm.c b/asm/nasm.c
index 4e922b4a..94bbc6b2 100644
--- a/asm/nasm.c
+++ b/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);
diff --git a/include/nasm.h b/include/nasm.h
index c1ecf8a1..a801da46 100644
--- a/include/nasm.h
+++ b/include/nasm.h
@@ -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,
diff --git a/output/outdbg.c b/output/outdbg.c
index 4d41d4db..84cccf73 100644
--- a/output/outdbg.c
+++ b/output/outdbg.c
@@ -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;
}
diff --git a/output/outmacho.c b/output/outmacho.c
index ed1366b3..e4aa8000 100644
--- a/output/outmacho.c
+++ b/output/outmacho.c
@@ -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;