|
From: Knut S. O. <bir...@an...> - 2015-11-10 21:45:51
|
Hi!
Using NASM to do some boot strapping code and ran into trouble when trying to emit a few 64-bit instructions in the OMF object file doing the mode switching. While I can see how the "error: obj output format does not support 64-bit code" message can be a useful reality check for application programmers, it prevents low-level programmers from doing what they want. It if was just a harmless warning, it wouldn't be so bad, but it turns BITS 64 into BITS 16. The main trick to mixing 64-bit code into OMF and other 32-bit output formats is to avoid 64-bit sized fixups, which normally isn't too hard.
My proposal is to add a switch to NASM to allow emitting 64-bit code in output formats that aren't 64-bit capable:
--allow-64bit-code-anywhere
Kind Regards,
bird.
Signed-off-by: Knut St. Osmundsen <bir...@an...>
---
From 4f54c40fa3f23eaf85f3b4d672900690252cca70 Mon Sep 17 00:00:00 2001
From: "Knut St. Osmundsen" <bir...@an...>
Date: Tue, 10 Nov 2015 22:00:21 +0100
Subject: [PATCH] New option --allow-64bit-code-anywhere for allowing 64-bit
code in output formats that aren't 64-bit capable, at the user's own risk.
From: bird <bi...@an...>
---
doc/nasmdoc.src | 10 ++++++++++
nasm.c | 13 +++++++++++--
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src
index e468248..51c8c56 100644
--- a/doc/nasmdoc.src
+++ b/doc/nasmdoc.src
@@ -1010,6 +1010,16 @@ underscore to all global and external variables, as C sometimes
(but not always) likes it.
+\S{opt-64bitcode} The \i\c{--allow-64bit-code-anywhere} Option.
+
+The \c{--allow-64bit-code-anywhere} option allows using 64-bit
+instructions in a 32-bit or 16-bit output format. This is useful
+in a few situations, such as when writing code switching from
+32-bit to 64-bit mode and linking into a 32-bit module. However,
+it is important to be aware of the restriction the output format
+poses on you in terms of relocations. Use with caution!
+
+
\S{nasmenv} The \i\c{NASMENV} \i{Environment} Variable
If you define an environment variable called \c{NASMENV}, the program
diff --git a/nasm.c b/nasm.c
index 8557b4d..401eb78 100644
--- a/nasm.c
+++ b/nasm.c
@@ -88,6 +88,7 @@ static int using_debug_info, opt_verbose_info;
bool tasm_compatible_mode = false;
int pass0, passn;
int maxbits = 0;
+static bool allow_64bit_code_anywhere = false;
int globalrel = 0;
int globalbnd = 0;
@@ -616,9 +617,11 @@ struct textargs {
#define OPT_PREFIX 0
#define OPT_POSTFIX 1
+#define OPT_64BIT_CODE_ANYWHERE 2
struct textargs textopts[] = {
{"prefix", OPT_PREFIX},
{"postfix", OPT_POSTFIX},
+ {"allow-64bit-code-anywhere", OPT_64BIT_CODE_ANYWHERE},
{NULL, 0}
};
@@ -804,7 +807,10 @@ static bool process_arg(char *p, char *q)
" -h show invocation summary and exit\n\n"
"--prefix,--postfix\n"
" this options prepend or append the given argument to all\n"
- " extern and global variables\n\n"
+ " extern and global variables\n"
+ "--allow-64bit-code-anywhere\n"
+ " do not restrict 64-bit code to 64-bit capable output\n"
+ " formats (use with care, no complaining)\n\n"
"Warnings:\n");
for (i = 0; i <= ERR_WARN_MAX; i++)
printf(" %-23s %s (default %s)\n",
@@ -971,6 +977,9 @@ set_warning:
}
break;
}
+ case OPT_64BIT_CODE_ANYWHERE:
+ allow_64bit_code_anywhere = true;
+ break;
default:
{
nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
@@ -2088,7 +2097,7 @@ static int get_bits(char *value)
"cannot specify 64-bit segment on processor below an x86-64");
i = 16;
}
- if (i != maxbits) {
+ if (i != maxbits && !allow_64bit_code_anywhere) {
nasm_error(ERR_NONFATAL,
"%s output format does not support 64-bit code",
ofmt->shortname);
--
2.4.1
|