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 |