#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
#include "my_assert.h"
#include "my_str.h"
char last_sym[32];
unsigned long val;
unsigned long cnt;
+ uint64_t val64;
const char *sym;
enum dx_type type;
char **pub_syms;
if (header_mode)
continue;
- val = parse_number(words[1]);
+ val = parse_number(words[1], 0);
fprintf(fout, "\t\t .align %d", align_value(val));
goto fin;
}
fprintf(fout, "%s", escape_string(word));
}
else {
- val = parse_number(words[w]);
+ val = parse_number(words[w], 0);
if (val & ~0xff)
aerr("bad string trailing byte?\n");
// unfortunately \xHH is unusable - gas interprets
if (w == wordc - 2) {
if (IS_START(words[w + 1], "dup(")) {
- cnt = parse_number(words[w]);
+ cnt = parse_number(words[w], 0);
p = words[w + 1] + 4;
p2 = strchr(p, ')');
if (p2 == NULL)
val = 0;
if (!IS(word, "?"))
- val = parse_number(word);
+ val = parse_number(word, 0);
fprintf(fout, ".fill 0x%02lx,%d,0x%02lx",
cnt, type_size(type), val);
}
}
else {
- val = parse_number(words[w]);
- if (val < 10)
- fprintf(fout, "%ld", val);
+ val64 = parse_number(words[w], 1);
+ if (val64 < 10)
+ fprintf(fout, "%d", (int)val64);
else
- fprintf(fout, "0x%lx", val);
+ fprintf(fout, "0x%" PRIx64, val64);
}
first = 0;
-static unsigned long parse_number(const char *number)
+#include <errno.h>
+#include <stdint.h>
+
+static uint64_t parse_number(const char *number, int is64)
{
int len = strlen(number);
const char *p = number;
char *endp = NULL;
- unsigned long ret;
+ uint64_t ret;
int neg = 0;
int bad;
}
if (len > 1 && *p == '0')
p++;
+
+ errno = 0;
if (number[len - 1] == 'h') {
- ret = strtoul(p, &endp, 16);
+ ret = strtouq(p, &endp, 16);
bad = (*endp != 'h');
}
else {
- ret = strtoul(p, &endp, 10);
+ ret = strtouq(p, &endp, 10);
bad = (*endp != 0);
}
- if (bad)
- aerr("number parsing failed (%s)\n", number);
-#if __SIZEOF_LONG__ > 4
+ if (errno != 0 || bad)
+ aerr("number parsing failed (%s): %d\n", number, errno);
// if this happens, callers must be fixed too
- if (ret > 0xfffffffful)
+ if (!is64 && ret > 0xfffffffful)
aerr("number too large? (%s)\n", number);
-#endif
if (neg) {
- if (ret > 0x7fffffff)
+ if (!is64 && ret > 0x7fffffff)
aerr("too large negative? (%s)\n", number);
ret = -ret;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include "my_assert.h"
#include "my_str.h"
}
if ('0' <= w[0] && w[0] <= '9') {
- number = parse_number(w);
+ number = parse_number(w, 0);
printf_number(d, sizeof(cvtbuf) - (d - cvtbuf), number);
continue;
}
if (len < sizeof(buf) - 1) {
strncpy(buf, s, len);
buf[len] = 0;
+ errno = 0;
val = strtol(buf, &endp, 16);
- if (val == 0 || *endp != 0) {
+ if (val == 0 || *endp != 0 || errno != 0) {
aerr("%s num parse fail for '%s'\n", __func__, buf);
return NULL;
}
else if (('0' <= words[w][0] && words[w][0] <= '9')
|| words[w][0] == '-')
{
- number = parse_number(words[w]);
+ number = parse_number(words[w], 0);
opr->type = OPT_CONST;
opr->val = number;
printf_number(opr->name, sizeof(opr->name), number);
if (namelen <= 0)
ferr(po, "equ parse failed for '%s'\n", name);
+ errno = 0;
*extra_offs = strtol(p, &endp, 16);
- if (*endp != 0)
+ if (*endp != 0 || errno != 0)
ferr(po, "equ parse failed for '%s'\n", name);
}
p = name + 4;
if (IS_START(p, "0x"))
p += 2;
+ errno = 0;
offset = strtoul(p, &endp, 16);
if (name[3] == '-')
offset = -offset;
- if (*endp != 0)
+ if (*endp != 0 || errno != 0)
ferr(po, "ebp- parse of '%s' failed\n", name);
}
else {
// just plain offset?
if (!IS_START(name, "esp+"))
return -1;
+ errno = 0;
offset = strtol(name + 4, &endp, 0);
- if (endp == NULL || *endp != 0)
+ if (endp == NULL || *endp != 0 || errno != 0)
return -1;
*offset_out = offset;
return 0;
if (pd->type == OPT_OFFSET)
pd->d[pd->count].u.label = strdup(words[i]);
else
- pd->d[pd->count].u.val = parse_number(words[i]);
+ pd->d[pd->count].u.val = parse_number(words[i], 0);
pd->d[pd->count].bt_i = -1;
pd->count++;
}
else
aerr("bad lmod: '%s'\n", words[2]);
- g_eqs[g_eqcnt].offset = parse_number(words[4]);
+ g_eqs[g_eqcnt].offset = parse_number(words[4], 0);
g_eqcnt++;
continue;
}