summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2018-06-12 13:50:37 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2018-06-12 13:54:42 -0700
commit987dc9c9dbe36601789aae4552a7c0ceb1ca0852 (patch)
tree75eb0e85bd86584ff82263de70c32a8781bdb643
parentd49e6dc08e5625ea393cfc7e17a99f66f41840e3 (diff)
downloadnasm-987dc9c9dbe36601789aae4552a7c0ceb1ca0852.tar.gz
Make any execution limit configurable, add eval limit
Make any "deadman"-style execution limit configurable on the command line (--limit-foo) or via a pragma (%pragma limit foo). Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--asm/directiv.dat1
-rw-r--r--asm/error.c3
-rw-r--r--asm/eval.c10
-rw-r--r--asm/nasm.c284
-rw-r--r--asm/pragma.c8
-rw-r--r--asm/preproc.c25
-rw-r--r--include/error.h3
-rw-r--r--include/nasm.h16
-rw-r--r--include/nasmlib.h2
-rw-r--r--nasmlib/readnum.c4
10 files changed, 255 insertions, 101 deletions
diff --git a/asm/directiv.dat b/asm/directiv.dat
index 96649488..185568a6 100644
--- a/asm/directiv.dat
+++ b/asm/directiv.dat
@@ -93,6 +93,7 @@ gprefix
gsuffix
lprefix
lsuffix
+limit
; --- Pragma operations
subsections_via_symbols ; macho
diff --git a/asm/error.c b/asm/error.c
index 1f91cd78..3fdaa027 100644
--- a/asm/error.c
+++ b/asm/error.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 1996-2017 The NASM Authors - All Rights Reserved
+ * Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@@ -68,6 +68,7 @@ const struct warning warnings[ERR_WARN_ALL+1] = {
{"unknown-pragma", "unknown %pragma facility or directive", false},
{"not-my-pragma", "%pragma not applicable to this compilation", false},
{"unknown-warning", "unknown warning in -W/-w or warning directive", false},
+ {"negative-rep", "regative %rep count", true},
/* THIS ENTRY MUST COME LAST */
{"all", "all possible warnings", false}
diff --git a/asm/eval.c b/asm/eval.c
index 72d6a0e2..582f9503 100644
--- a/asm/eval.c
+++ b/asm/eval.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 1996-2017 The NASM Authors - All Rights Reserved
+ * Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@@ -72,6 +72,7 @@ static void *scpriv;
static int *opflags;
static struct eval_hints *hint;
+static int deadman;
/*
@@ -769,6 +770,11 @@ static expr *expr6(int critical)
bool rn_warn;
const char *scope;
+ if (++deadman > nasm_limit[LIMIT_EVAL]) {
+ nasm_error(ERR_NONFATAL, "expression too long");
+ return NULL;
+ }
+
switch (i) {
case '-':
i = scan(scpriv, tokval);
@@ -954,6 +960,8 @@ expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv,
expr *e;
expr *f = NULL;
+ deadman = 0;
+
hint = hints;
if (hint)
hint->type = EAH_NOHINT;
diff --git a/asm/nasm.c b/asm/nasm.c
index 6db5cce2..f7f02ac8 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -82,6 +82,7 @@ static void nasm_verror_gnu(int severity, const char *fmt, va_list args);
static void nasm_verror_vc(int severity, const char *fmt, va_list args);
static void nasm_verror_common(int severity, const char *fmt, va_list args);
static void usage(void);
+static void help(char xopt);
static bool using_debug_info, opt_verbose_info;
static const char *debug_format;
@@ -153,6 +154,60 @@ static char *quote_for_pmake(const char *str);
static char *quote_for_wmake(const char *str);
static char *(*quote_for_make)(const char *) = quote_for_pmake;
+/*
+ * Execution limits that can be set via a command-line option or %pragma
+ */
+
+#define LIMIT_MAX_VAL (INT_MAX >> 1) /* Effectively unlimited */
+
+int nasm_limit[LIMIT_MAX+1] =
+{ LIMIT_MAX_VAL, 1000, 1000000, 1000000, 1000000 };
+
+struct limit_info {
+ const char *name;
+ const char *help;
+};
+static const struct limit_info limit_info[LIMIT_MAX+1] = {
+ { "passes", "total number of passes" },
+ { "stalled-passes", "number of passes without forward progress" },
+ { "macro-levels", "levels of macro expansion"},
+ { "rep", "%rep count" },
+ { "eval", "expression evaluation descent"}
+};
+
+enum directive_result nasm_set_limit(const char *limit, const char *valstr)
+{
+ int i;
+ int64_t val;
+ bool rn_error;
+
+ for (i = 0; i <= LIMIT_MAX; i++) {
+ if (!nasm_stricmp(limit, limit_info[i].name))
+ break;
+ }
+ if (i > LIMIT_MAX) {
+ nasm_error(ERR_WARNING|ERR_PASS1|ERR_WARN_UNKNOWN_PRAGMA,
+ "unknown limit: `%s'", limit);
+ return DIRR_ERROR;
+ }
+
+ if (!nasm_stricmp(valstr, "unlimited")) {
+ val = LIMIT_MAX_VAL;
+ } else {
+ val = readnum(valstr, &rn_error);
+ if (rn_error || val < 0) {
+ nasm_error(ERR_WARNING|ERR_PASS1|ERR_WARN_BAD_PRAGMA,
+ "invalid limit value: `%s'", limit);
+ return DIRR_ERROR;
+ } else if (val > LIMIT_MAX_VAL) {
+ val = LIMIT_MAX_VAL;
+ }
+ }
+
+ nasm_limit[i] = val;
+ return DIRR_OK;
+}
+
int64_t switch_segment(int32_t segment)
{
location.segment = segment;
@@ -717,11 +772,13 @@ static char *quote_for_wmake(const char *str)
enum text_options {
OPT_BOGUS,
OPT_VERSION,
+ OPT_HELP,
OPT_ABORT_ON_PANIC,
OPT_MANGLE,
OPT_INCLUDE,
OPT_PRAGMA,
- OPT_BEFORE
+ OPT_BEFORE,
+ OPT_LIMIT
};
struct textargs {
const char *label;
@@ -732,6 +789,7 @@ struct textargs {
static const struct textargs textopts[] = {
{"v", OPT_VERSION, false, 0},
{"version", OPT_VERSION, false, 0},
+ {"help", OPT_HELP, false, 0},
{"abort-on-panic", OPT_ABORT_ON_PANIC, false, 0},
{"prefix", OPT_MANGLE, true, LM_GPREFIX},
{"postfix", OPT_MANGLE, true, LM_GSUFFIX},
@@ -742,6 +800,7 @@ static const struct textargs textopts[] = {
{"include", OPT_INCLUDE, true, 0},
{"pragma", OPT_PRAGMA, true, 0},
{"before", OPT_BEFORE, true, 0},
+ {"limit-", OPT_LIMIT, true, 0},
{NULL, OPT_BOGUS, false, 0}
};
@@ -756,7 +815,6 @@ static bool stopoptions = false;
static bool process_arg(char *p, char *q, int pass)
{
char *param;
- int i;
bool advance = false;
if (!p || !p[0])
@@ -900,71 +958,7 @@ static bool process_arg(char *p, char *q, int pass)
break;
case 'h':
- printf
- ("usage: nasm [-@ response file] [-o outfile] [-f format] "
- "[-l listfile]\n"
- " [options...] [--] filename\n"
- " or nasm -v (or --v) for version info\n\n"
- " -t assemble in SciTech TASM compatible mode\n");
- printf
- (" -E (or -e) preprocess only (writes output to stdout by default)\n"
- " -a don't preprocess (assemble only)\n"
- " -M generate Makefile dependencies on stdout\n"
- " -MG d:o, missing files assumed generated\n"
- " -MF file set Makefile dependency file\n"
- " -MD file assemble and generate dependencies\n"
- " -MT file dependency target name\n"
- " -MQ file dependency target name (quoted)\n"
- " -MP emit phony target\n\n"
- " -Zfile redirect error messages to file\n"
- " -s redirect error messages to stdout\n\n"
- " -g generate debugging information\n\n"
- " -F format select a debugging format\n\n"
- " -gformat same as -g -F format\n\n"
- " -o outfile write output to an outfile\n\n"
- " -f format select an output format\n\n"
- " -l listfile write listing to a listfile\n\n"
- " -Ipath add a pathname to the include file path\n");
- printf
- (" -Olevel optimize opcodes, immediates and branch offsets\n"
- " -O0 no optimization\n"
- " -O1 minimal optimization\n"
- " -Ox multipass optimization (default)\n"
- " -Pfile pre-include a file (also --include)\n"
- " -Dmacro[=str] pre-define a macro\n"
- " -Umacro undefine a macro\n"
- " -Xformat specifiy error reporting format (gnu or vc)\n"
- " -w+foo enable warning foo (equiv. -Wfoo)\n"
- " -w-foo disable warning foo (equiv. -Wno-foo)\n"
- " -w[+-]error[=foo]\n"
- " promote [specific] warnings to errors\n"
- " -h show invocation summary and exit\n\n"
- " --pragma str pre-executes a specific %%pragma\n"
- " --before str add line (usually a preprocessor statement) before the input\n"
- " --prefix str prepend the given string to all the given string\n"
- " to all extern, common and global symbols\n"
- " --suffix str append the given string to all the given string\n"
- " to all extern, common and global symbols\n"
- " --lprefix str prepend the given string to all other symbols\n"
- "\n"
- "Response files should contain command line parameters,\n"
- "one per line.\n"
- "\n"
- "Warnings for the -W/-w options:\n");
- for (i = 0; i <= ERR_WARN_ALL; i++)
- printf(" %-23s %s%s\n",
- warnings[i].name, warnings[i].help,
- i == ERR_WARN_ALL ? "\n" :
- warnings[i].enabled ? " (default on)" :
- " (default off)");
- if (p[2] == 'f') {
- printf("valid output formats for -f are"
- " (`*' denotes default):\n");
- ofmt_list(ofmt, stdout);
- } else {
- printf("For a list of valid output formats, use -hf.\n");
- printf("For a list of debug formats, use -f <form> -y.\n");
- }
+ help(p[2]);
exit(0); /* never need usage message here */
break;
@@ -1068,25 +1062,61 @@ static bool process_arg(char *p, char *q, int pass)
case '-':
{
const struct textargs *tx;
+ size_t olen, plen;
+
+ p += 2;
- if (p[2] == 0) { /* -- => stop processing options */
+ if (!*p) { /* -- => stop processing options */
stopoptions = true;
break;
}
+ plen = strlen(p);
for (tx = textopts; tx->label; tx++) {
- if (!nasm_stricmp(p + 2, tx->label))
- break;
+ olen = strlen(tx->label);
+
+ if (olen > plen)
+ continue;
+
+ if (nasm_memicmp(p, tx->label, olen))
+ continue;
+
+ if (tx->label[olen-1] == '-')
+ break; /* Incomplete option */
+
+ if (!p[olen] || p[olen] == '=')
+ break; /* Complete option */
}
+ if (!tx->label) {
+ nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
+ "unrecognized option `--%s'", p);
+ }
+
+ param = strchr(p+olen, '=');
+ if (param)
+ *param++ = '\0';
+
if (tx->need_arg) {
- if (!q) {
+ if (!param) {
+ param = q;
+ advance = true;
+ }
+
+ /* Note: a null string is a valid parameter */
+ if (!param) {
nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
"option `--%s' requires an argument",
- p + 2);
+ p);
break;
}
- advance = true;
+ } else {
+ if (param) {
+ nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
+ "option `--%s' does not take an argument",
+ p);
+
+ }
}
switch (tx->opt) {
@@ -1098,7 +1128,7 @@ static bool process_arg(char *p, char *q, int pass)
break;
case OPT_MANGLE:
if (pass == 2)
- set_label_mangle(tx->pvt, q);
+ set_label_mangle(tx->pvt, param);
break;
case OPT_INCLUDE:
if (pass == 2)
@@ -1106,16 +1136,19 @@ static bool process_arg(char *p, char *q, int pass)
break;
case OPT_PRAGMA:
if (pass == 2)
- preproc->pre_command("pragma", q);
+ preproc->pre_command("pragma", param);
break;
case OPT_BEFORE:
if (pass == 2)
- preproc->pre_command(NULL, q);
+ preproc->pre_command(NULL, param);
break;
- case OPT_BOGUS:
- nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
- "unrecognized option `--%s'", p + 2);
+ case OPT_LIMIT:
+ if (pass == 2)
+ nasm_set_limit(p+olen, param);
break;
+ case OPT_HELP:
+ help(0);
+ exit(0);
default:
panic();
}
@@ -1325,9 +1358,8 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
char *line;
insn output_ins;
int i;
- int pass_max;
uint64_t prev_offset_changed;
- unsigned int stall_count = 0; /* Make sure we make forward progress... */
+ int stall_count = 0; /* Make sure we make forward progress... */
switch (cmd_sb) {
case 16:
@@ -1348,7 +1380,7 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
/* Any segment numbers allocated before this point are permanent */
seg_alloc_setup_done();
- pass_max = prev_offset_changed = (INT_MAX >> 1) + 2; /* Almost unlimited */
+ prev_offset_changed = nasm_limit[LIMIT_PASSES];
for (passn = 1; pass0 <= 2; passn++) {
pass1 = pass0 == 2 ? 2 : 1; /* 1, 1, 1, ..., 1, 2 */
pass2 = passn > 1 ? 2 : 1; /* 1, 2, 2, ..., 2, 2 */
@@ -1585,7 +1617,8 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
if (terminate_after_phase)
break;
- if ((stall_count > 997U) || (passn >= pass_max)) {
+ if ((stall_count > nasm_limit[LIMIT_STALLED]) ||
+ (passn >= nasm_limit[LIMIT_PASSES])) {
/* We get here if the labels don't converge
* Example: FOO equ FOO + 1
*/
@@ -1844,3 +1877,88 @@ static void usage(void)
{
fputs("type `nasm -h' for help\n", error_file);
}
+
+static void help(const char xopt)
+{
+ int i;
+
+ printf
+ ("usage: nasm [-@ response file] [-o outfile] [-f format] "
+ "[-l listfile]\n"
+ " [options...] [--] filename\n"
+ " or nasm -v (or --v) for version info\n\n"
+ "\n"
+ "Response files should contain command line parameters,\n"
+ "one per line.\n"
+ "\n"
+ " -t assemble in SciTech TASM compatible mode\n");
+ printf
+ (" -E (or -e) preprocess only (writes output to stdout by default)\n"
+ " -a don't preprocess (assemble only)\n"
+ " -M generate Makefile dependencies on stdout\n"
+ " -MG d:o, missing files assumed generated\n"
+ " -MF file set Makefile dependency file\n"
+ " -MD file assemble and generate dependencies\n"
+ " -MT file dependency target name\n"
+ " -MQ file dependency target name (quoted)\n"
+ " -MP emit phony target\n\n"
+ " -Zfile redirect error messages to file\n"
+ " -s redirect error messages to stdout\n\n"
+ " -g generate debugging information\n\n"
+ " -F format select a debugging format\n\n"
+ " -gformat same as -g -F format\n\n"
+ " -o outfile write output to an outfile\n\n"
+ " -f format select an output format\n\n"
+ " -l listfile write listing to a listfile\n\n"
+ " -Ipath add a pathname to the include file path\n");
+ printf
+ (" -Olevel optimize opcodes, immediates and branch offsets\n"
+ " -O0 no optimization\n"
+ " -O1 minimal optimization\n"
+ " -Ox multipass optimization (default)\n"
+ " -Pfile pre-include a file (also --include)\n"
+ " -Dmacro[=str] pre-define a macro\n"
+ " -Umacro undefine a macro\n"
+ " -Xformat specifiy error reporting format (gnu or vc)\n"
+ " -w+foo enable warning foo (equiv. -Wfoo)\n"
+ " -w-foo disable warning foo (equiv. -Wno-foo)\n"
+ " -w[+-]error[=foo]\n"
+ " promote [specific] warnings to errors\n"
+ " -h show invocation summary and exit\n\n"
+ " --pragma str pre-executes a specific %%pragma\n"
+ " --before str add line (usually a preprocessor statement) before the input\n"
+ " --prefix str prepend the given string to all the given string\n"
+ " to all extern, common and global symbols\n"
+ " --suffix str append the given string to all the given string\n"
+ " to all extern, common and global symbols\n"
+ " --lprefix str prepend the given string to all other symbols\n"
+ " --limit-X val set execution limit X\n");
+
+ for (i = 0; i <= LIMIT_MAX; i++) {
+ printf(" %-15s %s (default ",
+ limit_info[i].name, limit_info[i].help);
+ if (nasm_limit[i] < LIMIT_MAX_VAL) {
+ printf("%d)\n", nasm_limit[i]);
+ } else {
+ printf("unlimited)\n");
+ }
+ }
+
+ printf("\nWarnings for the -W/-w options:\n");
+
+ for (i = 0; i <= ERR_WARN_ALL; i++)
+ printf(" %-23s %s%s\n",
+ warnings[i].name, warnings[i].help,
+ i == ERR_WARN_ALL ? "\n" :
+ warnings[i].enabled ? " (default on)" :
+ " (default off)");
+
+ if (xopt == 'f') {
+ printf("valid output formats for -f are"
+ " (`*' denotes default):\n");
+ ofmt_list(ofmt, stdout);
+ } else {
+ printf("For a list of valid output formats, use -hf.\n");
+ printf("For a list of debug formats, use -f <format> -y.\n");
+ }
+}
diff --git a/asm/pragma.c b/asm/pragma.c
index e7dba760..71861a94 100644
--- a/asm/pragma.c
+++ b/asm/pragma.c
@@ -50,6 +50,7 @@
#include "error.h"
static enum directive_result asm_pragma(const struct pragma *pragma);
+static enum directive_result limit_pragma(const struct pragma *pragma);
/*
* Handle [pragma] directives. [pragma] is generally produced by
@@ -66,6 +67,7 @@ static enum directive_result asm_pragma(const struct pragma *pragma);
* so far none of these have any defined pragmas at all:
*
* preproc - preprocessor
+ * limit - limit setting
* asm - assembler
* list - listing generator
* file - generic file handling
@@ -86,6 +88,7 @@ static enum directive_result asm_pragma(const struct pragma *pragma);
static struct pragma_facility global_pragmas[] =
{
{ "asm", asm_pragma },
+ { "limit", limit_pragma },
{ "list", NULL },
{ "file", NULL },
{ "input", NULL },
@@ -254,3 +257,8 @@ static enum directive_result asm_pragma(const struct pragma *pragma)
return DIRR_UNKNOWN;
}
}
+
+static enum directive_result limit_pragma(const struct pragma *pragma)
+{
+ return nasm_set_limit(pragma->opname, pragma->tail);
+}
diff --git a/asm/preproc.c b/asm/preproc.c
index acdbaac6..88bc6971 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -339,12 +339,6 @@ enum {
#define NO_DIRECTIVE_FOUND 0
#define DIRECTIVE_FOUND 1
-/*
- * This define sets the upper limit for smacro and recursive mmacro
- * expansions
- */
-#define DEADMAN_LIMIT (1 << 20)
-
/* max reps */
#define REP_LIMIT ((INT64_C(1) << 62))
@@ -2875,8 +2869,8 @@ issue_error:
return DIRECTIVE_FOUND;
}
defining = nasm_zalloc(sizeof(MMacro));
- defining->max_depth =
- (i == PP_RMACRO) || (i == PP_IRMACRO) ? DEADMAN_LIMIT : 0;
+ defining->max_depth = ((i == PP_RMACRO) || (i == PP_IRMACRO))
+ ? nasm_limit[LIMIT_MACROS] : 0;
defining->casesense = (i == PP_MACRO) || (i == PP_RMACRO);
if (!parse_mmacro_spec(tline, defining, pp_directives[i])) {
nasm_free(defining);
@@ -3048,11 +3042,18 @@ issue_error:
return DIRECTIVE_FOUND;
}
count = reloc_value(evalresult);
- if (count >= REP_LIMIT) {
- nasm_error(ERR_NONFATAL, "`%%rep' value exceeds limit");
+ if (count > nasm_limit[LIMIT_REP]) {
+ nasm_error(ERR_NONFATAL,
+ "`%%rep' count %"PRId64" exceeds limit (currently %d)",
+ count, nasm_limit[LIMIT_REP]);
count = 0;
- } else
+ } else if (count < 0) {
+ nasm_error(ERR_WARNING|ERR_PASS2|ERR_WARN_NEG_REP,
+ "negative `%%rep' count: %"PRId64, count);
+ count = 0;
+ } else {
count++;
+ }
} else {
nasm_error(ERR_NONFATAL, "`%%rep' expects a repeat count");
count = 0;
@@ -4194,7 +4195,7 @@ static Token *expand_smacro(Token * tline)
Token *org_tline = tline;
Context *ctx;
const char *mname;
- int deadman = DEADMAN_LIMIT;
+ int deadman = nasm_limit[LIMIT_MACROS];
bool expanded;
/*
diff --git a/include/error.h b/include/error.h
index 55cb1278..83b28da0 100644
--- a/include/error.h
+++ b/include/error.h
@@ -112,9 +112,10 @@ static inline vefunc nasm_set_verror(vefunc ve)
#define ERR_WARN_UNKNOWN_PRAGMA WARN(18) /* unknown pragma */
#define ERR_WARN_NOTMY_PRAGMA WARN(19) /* pragma inapplicable */
#define ERR_WARN_UNK_WARNING WARN(20) /* unknown warning */
+#define ERR_WARN_NEG_REP WARN(21) /* negative repeat count */
/* The "all" warning acts as a global switch, it must come last */
-#define ERR_WARN_ALL 21 /* Do not use WARN() here */
+#define ERR_WARN_ALL 22 /* Do not use WARN() here */
struct warning {
const char *name;
diff --git a/include/nasm.h b/include/nasm.h
index 477cb65e..c1ecf8a1 100644
--- a/include/nasm.h
+++ b/include/nasm.h
@@ -759,6 +759,22 @@ struct pragma {
};
/*
+ * These are semi-arbitrary limits to keep the assembler from going
+ * into a black hole on certain kinds of bugs. They can be overridden
+ * by command-line options or %pragma.
+ */
+enum nasm_limit {
+ LIMIT_PASSES,
+ LIMIT_STALLED,
+ LIMIT_MACROS,
+ LIMIT_REP,
+ LIMIT_EVAL
+};
+#define LIMIT_MAX LIMIT_EVAL
+extern int nasm_limit[LIMIT_MAX+1];
+extern enum directive_result nasm_set_limit(const char *, const char *);
+
+/*
* The data structure defining an output format driver, and the
* interfaces to the functions therein.
*/
diff --git a/include/nasmlib.h b/include/nasmlib.h
index 2cfe9a37..f25ef827 100644
--- a/include/nasmlib.h
+++ b/include/nasmlib.h
@@ -180,7 +180,7 @@ size_t pure_func strnlen(const char *, size_t);
* Convert a string into a number, using NASM number rules. Sets
* `*error' to true if an error occurs, and false otherwise.
*/
-int64_t readnum(char *str, bool *error);
+int64_t readnum(const char *str, bool *error);
/*
* Convert a character constant into a number. Sets
diff --git a/nasmlib/readnum.c b/nasmlib/readnum.c
index e5b1cd69..47080884 100644
--- a/nasmlib/readnum.c
+++ b/nasmlib/readnum.c
@@ -65,9 +65,9 @@ static int radix_letter(char c)
}
}
-int64_t readnum(char *str, bool *error)
+int64_t readnum(const char *str, bool *error)
{
- char *r = str, *q;
+ const char *r = str, *q;
int32_t pradix, sradix, radix;
int plen, slen, len;
uint64_t result, checklimit;