/*@null@*/ /*@dependent@*/ static FILE *open_file(const char *filename,
const char *mode);
-static void cleanup(/*@null@*/ yasm_object *object);
+static void check_errors(/*@only@*/ yasm_errwarns *errwarns,
+ /*@only@*/ yasm_object *object);
+static void cleanup(/*@null@*/ /*@only@*/ yasm_object *object);
/* Forward declarations: cmd line parser handlers */
static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra);
static /*@exits@*/ void handle_yasm_fatal(const char *message, va_list va);
static const char *handle_yasm_gettext(const char *msgid);
static void print_yasm_error(const char *filename, unsigned long line,
- const char *msg);
+ const char *msg, unsigned long xrefline,
+ /*@null@*/ const char *xrefmsg);
static void print_yasm_warning(const char *filename, unsigned long line,
const char *msg);
size_t i;
yasm_arch_create_error arch_error;
const char *base_filename;
+ yasm_errwarns *errwarns;
#if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES)
setlocale(LC_MESSAGES, "");
yasm_fatal = handle_yasm_fatal;
yasm_gettext_hook = handle_yasm_gettext;
yasm_errwarn_initialize();
+ errwarns = yasm_errwarns_create();
/* Initialize parameter storage */
STAILQ_INIT(&preproc_options);
/* Pre-process until done */
cur_preproc = yasm_preproc_create(cur_preproc_module, in, in_filename,
- linemap);
+ linemap, errwarns);
apply_preproc_builtins();
apply_preproc_saved_options();
if (obj != stdout)
fclose(obj);
- if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(linemap, warning_error, print_yasm_error,
- print_yasm_warning);
+ if (yasm_errwarns_num_errors(errwarns, warning_error) > 0) {
+ yasm_errwarns_output_all(errwarns, linemap, warning_error,
+ print_yasm_error, print_yasm_warning);
if (obj != stdout)
remove(obj_filename);
yasm_xfree(preproc_buf);
yasm_linemap_destroy(linemap);
+ yasm_errwarns_destroy(errwarns);
cleanup(NULL);
return EXIT_FAILURE;
}
yasm_xfree(preproc_buf);
yasm_linemap_destroy(linemap);
+ yasm_errwarns_destroy(errwarns);
cleanup(NULL);
return EXIT_SUCCESS;
}
}
cur_preproc = cur_preproc_module->create(in, in_filename,
- yasm_object_get_linemap(object));
+ yasm_object_get_linemap(object),
+ errwarns);
apply_preproc_builtins();
apply_preproc_saved_options();
/* Parse! */
cur_parser_module->do_parse(object, cur_preproc, cur_arch, cur_objfmt,
cur_dbgfmt, in, in_filename,
- list_filename != NULL, def_sect);
+ list_filename != NULL, def_sect, errwarns);
/* Close input file */
if (in != stdin)
fclose(in);
+ check_errors(errwarns, object);
+
/* Check for undefined symbols */
yasm_symtab_parser_finalize(yasm_object_get_symtab(object),
strcmp(cur_parser_module->keyword, "gas")==0,
- cur_objfmt);
-
- if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
- print_yasm_error, print_yasm_warning);
- cleanup(object);
- return EXIT_FAILURE;
- }
+ cur_objfmt, errwarns);
+ check_errors(errwarns, object);
/* Finalize parse */
- yasm_object_finalize(object);
-
- if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
- print_yasm_error, print_yasm_warning);
- cleanup(object);
- return EXIT_FAILURE;
- }
+ yasm_object_finalize(object, errwarns);
+ check_errors(errwarns, object);
/* Optimize */
- cur_optimizer_module->optimize(object);
-
- if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
- print_yasm_error, print_yasm_warning);
- cleanup(object);
- return EXIT_FAILURE;
- }
+ cur_optimizer_module->optimize(object, errwarns);
+ check_errors(errwarns, object);
/* generate any debugging information */
- yasm_dbgfmt_generate(cur_dbgfmt);
+ yasm_dbgfmt_generate(cur_dbgfmt, errwarns);
+ check_errors(errwarns, object);
/* open the object file for output (if not already opened by dbg objfmt) */
if (!obj && strcmp(cur_objfmt_module->keyword, "dbg") != 0) {
/* Write the object file */
yasm_objfmt_output(cur_objfmt, obj?obj:stderr,
- strcmp(cur_dbgfmt_module->keyword, "null"), cur_dbgfmt);
+ strcmp(cur_dbgfmt_module->keyword, "null"), cur_dbgfmt,
+ errwarns);
/* Close object file */
if (obj)
/* If we had an error at this point, we also need to delete the output
* object file (to make sure it's not left newer than the source).
*/
- if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
- print_yasm_error, print_yasm_warning);
+ if (yasm_errwarns_num_errors(errwarns, warning_error) > 0)
remove(obj_filename);
- cleanup(object);
- return EXIT_FAILURE;
- }
+ check_errors(errwarns, object);
/* Open and write the list file */
if (list_filename) {
fclose(list);
}
- yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
- print_yasm_error, print_yasm_warning);
+ yasm_errwarns_output_all(errwarns, yasm_object_get_linemap(object),
+ warning_error, print_yasm_error,
+ print_yasm_warning);
cleanup(object);
return EXIT_SUCCESS;
return f;
}
+static void
+check_errors(yasm_errwarns *errwarns, yasm_object *object)
+{
+ if (yasm_errwarns_num_errors(errwarns, warning_error) > 0) {
+ yasm_errwarns_output_all(errwarns, yasm_object_get_linemap(object),
+ warning_error, print_yasm_error,
+ print_yasm_warning);
+ yasm_errwarns_destroy(errwarns);
+ cleanup(object);
+ exit(EXIT_FAILURE);
+ }
+}
+
/* Define DO_FREE to 1 to enable deallocation of all data structures.
* Useful for detecting memory leaks, but slows down execution unnecessarily
* (as the OS will free everything we miss here).
return gettext(msgid);
}
-const char *fmt[2] = {
+static const char *fmt[2] = {
"%s:%lu: %s%s\n", /* GNU */
"%s(%lu) : %s%s\n" /* VC */
};
+static const char *fmt_noline[2] = {
+ "%s: %s%s\n", /* GNU */
+ "%s : %s%s\n" /* VC */
+};
+
static void
-print_yasm_error(const char *filename, unsigned long line, const char *msg)
+print_yasm_error(const char *filename, unsigned long line, const char *msg,
+ unsigned long xrefline, const char *xrefmsg)
{
- fprintf(stderr, fmt[ewmsg_style], filename, line, "", msg);
+ if (line)
+ fprintf(stderr, fmt[ewmsg_style], filename, line, "", msg);
+ else
+ fprintf(stderr, fmt_noline[ewmsg_style], filename, "", msg);
+
+ if (xrefmsg) {
+ if (xrefline)
+ fprintf(stderr, fmt[ewmsg_style], filename, xrefline, "", xrefmsg);
+ else
+ fprintf(stderr, fmt_noline[ewmsg_style], filename, "", xrefmsg);
+ }
}
static void
print_yasm_warning(const char *filename, unsigned long line, const char *msg)
{
- fprintf(stderr, fmt[ewmsg_style], filename, line, _("warning: "), msg);
+ if (line)
+ fprintf(stderr, fmt[ewmsg_style], filename, line, _("warning: "), msg);
+ else
+ fprintf(stderr, fmt_noline[ewmsg_style], filename, _("warning: "), msg);
}
/** Module-level implementation of yasm_arch_parse_cpu().
* Call yasm_arch_parse_cpu() instead of calling this function.
*/
- void (*parse_cpu) (yasm_arch *arch, const char *cpuid, size_t cpuid_len,
- unsigned long line);
+ void (*parse_cpu) (yasm_arch *arch, const char *cpuid, size_t cpuid_len);
/** Module-level implementation of yasm_arch_parse_check_insnprefix().
* Call yasm_arch_parse_check_insnprefix() instead of calling this function.
*/
yasm_arch_insnprefix (*parse_check_insnprefix)
(yasm_arch *arch, /*@out@*/ unsigned long data[4], const char *id,
- size_t id_len, unsigned long line);
+ size_t id_len);
/** Module-level implementation of yasm_arch_parse_check_regtmod().
* Call yasm_arch_parse_check_regtmod() instead of calling this function.
*/
yasm_arch_regtmod (*parse_check_regtmod)
(yasm_arch *arch, /*@out@*/ unsigned long *data, const char *id,
- size_t id_len, unsigned long line);
+ size_t id_len);
/** Module-level implementation of yasm_arch_parse_directive().
* Call yasm_arch_parse_directive() instead of calling this function.
*/
int (*floatnum_tobytes) (yasm_arch *arch, const yasm_floatnum *flt,
unsigned char *buf, size_t destsize,
- size_t valsize, size_t shift, int warn,
- unsigned long line);
+ size_t valsize, size_t shift, int warn);
/** Module-level implementation of yasm_arch_intnum_tobytes().
* Call yasm_arch_intnum_tobytes() instead of calling this function.
int (*intnum_tobytes) (yasm_arch *arch, const yasm_intnum *intn,
unsigned char *buf, size_t destsize, size_t valsize,
int shift, const yasm_bytecode *bc,
- int warn, unsigned long line);
+ int warn);
/** Module-level implementation of yasm_arch_get_reg_size().
* Call yasm_arch_get_reg_size() instead of calling this function.
* \param arch architecture
* \param cpuid cpu identifier as in the input file
* \param cpuid_len length of cpu identifier string
- * \param line virtual line (from yasm_linemap)
*/
-void yasm_arch_parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
- unsigned long line);
+void yasm_arch_parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len);
/** Check an generic identifier to see if it matches architecture specific
* names for instructions or instruction prefixes. Unrecognized identifiers
* [output]
* \param id identifier as in the input file
* \param id_len length of id string
- * \param line virtual line (from yasm_linemap)
* \return Identifier type (#YASM_ARCH_NOTINSNPREFIX if unrecognized)
*/
yasm_arch_insnprefix yasm_arch_parse_check_insnprefix
(yasm_arch *arch, /*@out@*/ unsigned long data[4], const char *id,
- size_t id_len, unsigned long line);
+ size_t id_len);
/** Check an generic identifier to see if it matches architecture specific
* names for registers or target modifiers. Unrecognized identifiers should
* [output]
* \param id identifier as in the input file
* \param id_len length of id string
- * \param line virtual line (from yasm_linemap)
* \return Identifier type (#YASM_ARCH_NOTREGTMOD if unrecognized)
*/
yasm_arch_regtmod yasm_arch_parse_check_regtmod
(yasm_arch *arch, /*@out@*/ unsigned long *data, const char *id,
- size_t id_len, unsigned long line);
+ size_t id_len);
/** Handle architecture-specific directives.
* Should modify behavior ONLY of parse functions, much like parse_cpu().
* \param valsize size (in bits)
* \param shift left shift (in bits)
* \param warn enables standard overflow/underflow warnings
- * \param line virtual line; may be 0 if warn is 0.
* \return Nonzero on error.
*/
int yasm_arch_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
unsigned char *buf, size_t destsize,
- size_t valsize, size_t shift, int warn,
- unsigned long line);
+ size_t valsize, size_t shift, int warn);
/** Output #yasm_intnum to buffer. Puts the value into the least
* significant bits of the destination, or may be shifted into more
* \param bc bytecode being output ("parent" of value)
* \param warn enables standard warnings (value doesn't fit into
* valsize bits)
- * \param line virtual line; may be 0 if warn is 0
* \return Nonzero on error.
*/
int yasm_arch_intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
unsigned char *buf, size_t destsize,
size_t valsize, int shift,
- const yasm_bytecode *bc, int warn,
- unsigned long line);
+ const yasm_bytecode *bc, int warn);
/** Get the equivalent byte size of a register.
* \param arch architecture
((yasm_arch_base *)arch)->module->get_address_size(arch)
#define yasm_arch_set_var(arch, var, val) \
((yasm_arch_base *)arch)->module->set_var(arch, var, val)
-#define yasm_arch_parse_cpu(arch, cpuid, cpuid_len, line) \
- ((yasm_arch_base *)arch)->module->parse_cpu(arch, cpuid, cpuid_len, line)
-#define yasm_arch_parse_check_insnprefix(arch, data, id, id_len, line) \
+#define yasm_arch_parse_cpu(arch, cpuid, cpuid_len) \
+ ((yasm_arch_base *)arch)->module->parse_cpu(arch, cpuid, cpuid_len)
+#define yasm_arch_parse_check_insnprefix(arch, data, id, id_len) \
((yasm_arch_base *)arch)->module->parse_check_insnprefix(arch, data, id, \
- id_len, line)
-#define yasm_arch_parse_check_regtmod(arch, data, id, id_len, line) \
+ id_len)
+#define yasm_arch_parse_check_regtmod(arch, data, id, id_len) \
((yasm_arch_base *)arch)->module->parse_check_regtmod(arch, data, id, \
- id_len, line)
+ id_len)
#define yasm_arch_parse_directive(arch, name, valparams, objext_valparams, \
object, line) \
((yasm_arch_base *)arch)->module->parse_directive \
(arch, bc, prev_bc, data, num_operands, operands, num_prefixes, \
prefixes, num_segregs, segregs)
#define yasm_arch_floatnum_tobytes(arch, flt, buf, destsize, valsize, shift, \
- warn, line) \
+ warn) \
((yasm_arch_base *)arch)->module->floatnum_tobytes \
- (arch, flt, buf, destsize, valsize, shift, warn, line)
+ (arch, flt, buf, destsize, valsize, shift, warn)
#define yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, shift, \
- bc, warn, line) \
+ bc, warn) \
((yasm_arch_base *)arch)->module->intnum_tobytes \
- (arch, intn, buf, destsize, valsize, shift, bc, warn, line)
+ (arch, intn, buf, destsize, valsize, shift, bc, warn)
#define yasm_arch_get_reg_size(arch, reg) \
((yasm_arch_base *)arch)->module->get_reg_size(arch, reg)
#define yasm_arch_reggroup_get_reg(arch, regg, regi) \
yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));
if (yasm_value_finalize_expr(&im->val, e))
- yasm__error(e->line, N_("immediate expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("immediate expression too complex"));
im->len = 0;
im->sign = 0;
}
void
-yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg, unsigned long line)
+yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg)
{
if (!ea)
return;
if (segreg != 0 && ea->segreg != 0)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("multiple segment overrides, using leftmost"));
ea->segreg = segreg;
STAILQ_FOREACH(dv, &bc_data->datahead, link) {
if (dv->type == DV_VALUE) {
if (yasm_value_finalize(&dv->data.val))
- yasm__error(bc->line, N_("expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("data expression too complex"));
}
}
}
case DV_VALUE:
intn = yasm_expr_get_intnum(&dv->data.val.abs, NULL);
if (!intn) {
- yasm__error(bc->line,
- N_("LEB128 requires constant values"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("LEB128 requires constant values"));
return;
}
/* Warn for negative values in unsigned environment.
* desired is very low!
*/
if (yasm_intnum_sign(intn) == -1 && !bc_leb128->sign)
- yasm__warning(YASM_WARN_GENERAL, bc->line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("negative value in unsigned LEB128"));
bc_leb128->len +=
yasm_intnum_size_leb128(intn, bc_leb128->sign);
break;
case DV_STRING:
- yasm__error(bc->line,
- N_("LEB128 does not allow string constants"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("LEB128 does not allow string constants"));
return;
}
}
yasm_value val;
if (yasm_value_finalize_expr(&val, reserve->numitems))
- yasm__error(bc->line, N_("expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("reserve expression too complex"));
else if (val.rel)
- yasm__error(bc->line, N_("reserve expression not absolute"));
+ yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
+ N_("reserve expression not absolute"));
else if (val.abs && yasm_expr__contains(val.abs, YASM_EXPR_FLOAT))
- yasm__error(bc->line,
- N_("expression must not contain floating point value"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("expression must not contain floating point value"));
reserve->numitems = val.abs;
}
/* For reserve, just say non-constant quantity instead of allowing
* the circular reference error to filter through.
*/
- yasm__error(bc->line,
- N_("attempt to reserve non-constant quantity of space"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("attempt to reserve non-constant quantity of space"));
retval = YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
} else
bc->len += yasm_intnum_get_uint(num)*reserve->itemsize;
yasm_value val;
if (yasm_value_finalize_expr(&val, incbin->start))
- yasm__error(bc->line, N_("start expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("start expression too complex"));
else if (val.rel)
- yasm__error(bc->line, N_("start expression not absolute"));
+ yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
+ N_("start expression not absolute"));
incbin->start = val.abs;
if (yasm_value_finalize_expr(&val, incbin->maxlen))
- yasm__error(bc->line, N_("maximum length expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("maximum length expression too complex"));
else if (val.rel)
- yasm__error(bc->line, N_("maximum length expression not absolute"));
+ yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
+ N_("maximum length expression not absolute"));
incbin->maxlen = val.abs;
}
/* Open file and determine its length */
f = fopen(incbin->filename, "rb");
if (!f) {
- yasm__error(bc->line, N_("`incbin': unable to open file `%s'"),
- incbin->filename);
+ yasm_error_set(YASM_ERROR_IO,
+ N_("`incbin': unable to open file `%s'"),
+ incbin->filename);
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
if (fseek(f, 0L, SEEK_END) < 0) {
- yasm__error(bc->line, N_("`incbin': unable to seek on file `%s'"),
- incbin->filename);
+ yasm_error_set(YASM_ERROR_IO,
+ N_("`incbin': unable to seek on file `%s'"),
+ incbin->filename);
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
flen = (unsigned long)ftell(f);
/* Compute length of incbin from start, maxlen, and len */
if (start > flen) {
- yasm__warning(YASM_WARN_GENERAL, bc->line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("`incbin': start past end of file `%s'"),
incbin->filename);
start = flen;
/* Open file */
f = fopen(incbin->filename, "rb");
if (!f) {
- yasm__error(bc->line, N_("`incbin': unable to open file `%s'"),
- incbin->filename);
+ yasm_error_set(YASM_ERROR_IO, N_("`incbin': unable to open file `%s'"),
+ incbin->filename);
return 1;
}
/* Seek to start of data */
if (fseek(f, (long)start, SEEK_SET) < 0) {
- yasm__error(bc->line, N_("`incbin': unable to seek on file `%s'"),
- incbin->filename);
+ yasm_error_set(YASM_ERROR_IO,
+ N_("`incbin': unable to seek on file `%s'"),
+ incbin->filename);
fclose(f);
return 1;
}
/* Read len bytes */
if (fread(*bufp, 1, (size_t)bc->len, f) < (size_t)bc->len) {
- yasm__error(bc->line,
- N_("`incbin': unable to read %lu bytes from file `%s'"),
- bc->len, incbin->filename);
+ yasm_error_set(YASM_ERROR_IO,
+ N_("`incbin': unable to read %lu bytes from file `%s'"),
+ bc->len, incbin->filename);
fclose(f);
return 1;
}
{
bytecode_align *align = (bytecode_align *)bc->contents;
if (!yasm_expr_get_intnum(&align->boundary, NULL))
- yasm__error(bc->line, N_("align boundary must be a constant"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("align boundary must be a constant"));
if (align->fill && !yasm_expr_get_intnum(&align->fill, NULL))
- yasm__error(bc->line, N_("align fill must be a constant"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("align fill must be a constant"));
if (align->maxskip && !yasm_expr_get_intnum(&align->maxskip, NULL))
- yasm__error(bc->line, N_("align maximum skip must be a constant"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("align maximum skip must be a constant"));
}
static yasm_bc_resolve_flags
while (!align->code_fill[maxlen] && maxlen>0)
maxlen--;
if (maxlen == 0) {
- yasm__error(bc->line, N_("could not find any code alignment size"));
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("could not find any code alignment size"));
return 1;
}
}
if (!align->code_fill[len]) {
- yasm__error(bc->line, N_("invalid alignment size %d"), len);
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("invalid alignment size %d"), len);
return 1;
}
/* Handle rest of code fill */
/* Check for overrun */
if (bc->offset > org->start) {
- yasm__error(bc->line, N_("ORG overlap with already existing data"));
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("ORG overlap with already existing data"));
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
/* Sanity check for overrun */
if (bc->offset > org->start) {
- yasm__error(bc->line, N_("ORG overlap with already existing data"));
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("ORG overlap with already existing data"));
return 1;
}
len = org->start - bc->offset;
{
bytecode_insn *insn = (bytecode_insn *)bc->contents;
int i;
- int error = 0;
yasm_insn_operand *op;
+ yasm_error_class eclass;
+ char *str, *xrefstr;
+ unsigned long xrefline;
/* Simplify the operands' expressions first. */
for (i = 0, op = yasm_ops_first(&insn->operands);
if (op->data.ea)
op->data.ea->disp.abs =
yasm_expr__level_tree(op->data.ea->disp.abs, 1, 1, 0,
- NULL, NULL, NULL, NULL, &error);
- if (error) {
- /* Follow up error with a pointer to where it was used */
- yasm__error(bc->line, N_("(used in memory expression)"));
+ NULL, NULL, NULL, NULL);
+ if (yasm_error_occurred()) {
+ /* Add a pointer to where it was used to the error */
+ yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
+ if (xrefstr) {
+ yasm_error_set_xref(xrefline, "%s", xrefstr);
+ yasm_xfree(xrefstr);
+ }
+ if (str) {
+ yasm_error_set(eclass, "%s in memory expression", str);
+ yasm_xfree(str);
+ }
return;
}
break;
case YASM_INSN__OPERAND_IMM:
op->data.val =
yasm_expr__level_tree(op->data.val, 1, 1, 1, NULL, NULL,
- NULL, NULL, &error);
- if (error) {
- /* Follow up error with a pointer to where it was used */
- yasm__error(bc->line,
- N_("(used in immediate expression)"));
+ NULL, NULL);
+ if (yasm_error_occurred()) {
+ /* Add a pointer to where it was used to the error */
+ yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
+ if (xrefstr) {
+ yasm_error_set_xref(xrefline, "%s", xrefstr);
+ yasm_xfree(xrefstr);
+ }
+ if (str) {
+ yasm_error_set(eclass, "%s in immediate expression",
+ str);
+ yasm_xfree(str);
+ }
return;
}
break;
yasm_value val;
if (yasm_value_finalize_expr(&val, bc->multiple))
- yasm__error(bc->line, N_("multiple expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("multiple expression too complex"));
else if (val.rel)
- yasm__error(bc->line, N_("multiple expression not absolute"));
+ yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
+ N_("multiple expression not absolute"));
bc->multiple = val.abs;
}
}
dist = precbc2->offset + precbc2->len;
if (dist < precbc1->offset + precbc1->len) {
intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len - dist);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
return intn;
}
dist -= precbc1->offset + precbc1->len;
if (!num) {
retval = YASM_BC_RESOLVE_UNKNOWN_LEN;
if (temp && yasm_expr__contains(temp, YASM_EXPR_FLOAT)) {
- yasm__error(bc->line,
+ yasm_error_set(YASM_ERROR_VALUE,
N_("expression must not contain floating point value"));
retval |= YASM_BC_RESOLVE_ERROR;
}
yasm_internal_error(
N_("could not determine multiple in bc_tobytes"));
if (yasm_intnum_sign(num) < 0) {
- yasm__error(bc->line, N_("multiple is negative"));
+ yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
*bufsize = 0;
return NULL;
}
* addresses. A override of an override will result in a warning.
* \param ea effective address
* \param segreg segment register (0 if none)
- * \param line virtual line number
*/
-void yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg,
- unsigned long line);
+void yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg);
/** Delete (free allocated memory for) an effective address.
* \param ea effective address (only pointer to it).
void (*print) (void *data, FILE *f, int indent_level);
} yasm_assoc_data_callback;
+/** Set of collected error/warnings (opaque type).
+ * \see errwarn.h for details.
+ */
+typedef struct yasm_errwarns yasm_errwarns;
+
/** Bytecode (opaque type).
* \see bytecode.h for related functions.
* Define YASM_BC_INTERNAL to get visible internals.
/** Module-level implementation of yasm_dbgfmt_generate().
* Call yasm_dbgfmt_generate() instead of calling this function.
*/
- void (*generate) (yasm_dbgfmt *dbgfmt);
+ void (*generate) (yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns);
} yasm_dbgfmt_module;
/** Get the keyword used to select a debug format.
/** Generate debugging information bytecodes.
* \param dbgfmt debug format
+ * \param errwarns error/warning set
+ * \note Errors and warnings are stored into errwarns.
*/
-void yasm_dbgfmt_generate(yasm_dbgfmt *dbgfmt);
+void yasm_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns);
#ifndef YASM_DOXYGEN
#define yasm_dbgfmt_directive(dbgfmt, name, sect, valparams, line) \
((yasm_dbgfmt_base *)dbgfmt)->module->directive(dbgfmt, name, sect, \
valparams, line)
-#define yasm_dbgfmt_generate(dbgfmt) \
- ((yasm_dbgfmt_base *)dbgfmt)->module->generate(dbgfmt)
+#define yasm_dbgfmt_generate(dbgfmt, ews) \
+ ((yasm_dbgfmt_base *)dbgfmt)->module->generate(dbgfmt, ews)
#endif
/*@exits@*/ void (*yasm_fatal) (const char *message, va_list va) = def_fatal;
const char * (*yasm_gettext_hook) (const char *msgid) = def_gettext_hook;
+/* Error indicator */
+/* yasm_eclass is not static so that yasm_error_occurred macro can access it */
+yasm_error_class yasm_eclass;
+static /*@only@*/ /*@null@*/ char *yasm_estr;
+static unsigned long yasm_exrefline;
+static /*@only@*/ /*@null@*/ char *yasm_exrefstr;
+
+/* Warning indicator */
+typedef struct warn {
+ /*@reldef@*/ STAILQ_ENTRY(warn) link;
+
+ yasm_warn_class wclass;
+ /*@owned@*/ /*@null@*/ char *wstr;
+} warn;
+static STAILQ_HEAD(, warn) yasm_warns;
+
/* Enabled warnings. See errwarn.h for a list. */
static unsigned long warn_class_enabled;
-/* Total error count */
-static unsigned int error_count;
-
-/* Total warning count */
-static unsigned int warning_count;
-
-typedef /*@reldef@*/ SLIST_HEAD(errwarndatahead_s, errwarn_data)
- errwarndatahead;
-static /*@only@*/ /*@null@*/ errwarndatahead errwarns;
-
typedef struct errwarn_data {
/*@reldef@*/ SLIST_ENTRY(errwarn_data) link;
enum { WE_UNKNOWN, WE_ERROR, WE_WARNING, WE_PARSERERROR } type;
unsigned long line;
- unsigned long displine;
-
- /* FIXME: This should not be a fixed size. But we don't have vasprintf()
- * right now. */
- char msg[MSG_MAXSIZE];
+ unsigned long xrefline;
+ /*@owned@*/ char *msg;
+ /*@owned@*/ char *xrefmsg;
} errwarn_data;
-/* Last inserted error/warning. Used to speed up insertions. */
-static /*@null@*/ errwarn_data *previous_we;
+struct yasm_errwarns {
+ /*@reldef@*/ SLIST_HEAD(, errwarn_data) errwarns;
+
+ /* Total error count */
+ unsigned int ecount;
+
+ /* Total warning count */
+ unsigned int wcount;
+
+ /* Last inserted error/warning. Used to speed up insertions. */
+ /*@null@*/ errwarn_data *previous_we;
+};
/* Static buffer for use by conv_unprint(). */
static char unprint[5];
(1UL<<YASM_WARN_PREPROC) | (0UL<<YASM_WARN_ORPHAN_LABEL) |
(1UL<<YASM_WARN_UNINIT_CONTENTS);
- error_count = 0;
- warning_count = 0;
- SLIST_INIT(&errwarns);
- previous_we = NULL;
+ yasm_eclass = YASM_ERROR_NONE;
+ yasm_estr = NULL;
+ yasm_exrefline = 0;
+ yasm_exrefstr = NULL;
+
+ STAILQ_INIT(&yasm_warns);
}
void
yasm_errwarn_cleanup(void)
{
- errwarn_data *we;
-
- /* Delete all error/warnings */
- while (!SLIST_EMPTY(&errwarns)) {
- we = SLIST_FIRST(&errwarns);
-
- SLIST_REMOVE_HEAD(&errwarns, link);
- yasm_xfree(we);
- }
+ yasm_error_clear();
+ yasm_warn_clear();
}
/* Convert a possibly unprintable character into a printable string, using
* type is WE_PARSERERROR.
*/
static errwarn_data *
-errwarn_data_new(unsigned long line, unsigned long displine,
+errwarn_data_new(yasm_errwarns *errwarns, unsigned long line,
int replace_parser_error)
{
errwarn_data *first, *next, *ins_we, *we;
/* Find the entry with either line=line or the last one with line<line.
* Start with the last entry added to speed the search.
*/
- ins_we = previous_we;
- first = SLIST_FIRST(&errwarns);
+ ins_we = errwarns->previous_we;
+ first = SLIST_FIRST(&errwarns->errwarns);
if (!ins_we || !first)
action = INS_HEAD;
while (action == INS_NONE) {
we->type = WE_UNKNOWN;
we->line = line;
- we->displine = displine;
+ we->xrefline = 0;
+ we->msg = NULL;
+ we->xrefmsg = NULL;
if (action == INS_HEAD)
- SLIST_INSERT_HEAD(&errwarns, we, link);
+ SLIST_INSERT_HEAD(&errwarns->errwarns, we, link);
else if (action == INS_AFTER) {
assert(ins_we != NULL);
SLIST_INSERT_AFTER(ins_we, we, link);
}
/* Remember previous err/warn */
- previous_we = we;
+ errwarns->previous_we = we;
return we;
}
-/* Register an error at line line, displaying line displine. Does not print
- * the error, only stores it for output_all() to print.
- */
void
-yasm__error_va_at(unsigned long line, unsigned long displine, const char *fmt,
- va_list va)
+yasm_error_clear(void)
{
- errwarn_data *we = errwarn_data_new(line, displine, 1);
+ if (yasm_estr)
+ yasm_xfree(yasm_estr);
+ if (yasm_exrefstr)
+ yasm_xfree(yasm_exrefstr);
+ yasm_eclass = YASM_ERROR_NONE;
+ yasm_estr = NULL;
+ yasm_exrefline = 0;
+ yasm_exrefstr = NULL;
+}
- we->type = WE_ERROR;
+void
+yasm_error_set_va(yasm_error_class eclass, const char *format, va_list va)
+{
+ if (yasm_eclass != YASM_ERROR_NONE)
+ return;
+ yasm_eclass = eclass;
+ yasm_estr = yasm_xmalloc(MSG_MAXSIZE+1);
#ifdef HAVE_VSNPRINTF
- vsnprintf(we->msg, MSG_MAXSIZE, yasm_gettext_hook(fmt), va);
+ vsnprintf(yasm_estr, MSG_MAXSIZE, yasm_gettext_hook(format), va);
#else
- vsprintf(we->msg, yasm_gettext_hook(fmt), va);
+ vsprintf(yasm_estr, yasm_gettext_hook(format), va);
#endif
-
- error_count++;
}
-/* Register an warning at line line, displaying line displine. Does not print
- * the warning, only stores it for output_all() to print.
- */
void
-yasm__warning_va_at(yasm_warn_class num, unsigned long line,
- unsigned long displine, const char *fmt, va_list va)
+yasm_error_set(yasm_error_class eclass, const char *format, ...)
{
- errwarn_data *we;
-
- if (!(warn_class_enabled & (1UL<<num)))
- return; /* warning is part of disabled class */
+ va_list va;
+ va_start(va, format);
+ yasm_error_set_va(eclass, format, va);
+ va_end(va);
+}
- we = errwarn_data_new(line, displine, 0);
+void
+yasm_error_set_xref_va(unsigned long xrefline, const char *format, va_list va)
+{
+ if (yasm_eclass != YASM_ERROR_NONE)
+ return;
- we->type = WE_WARNING;
+ yasm_exrefline = xrefline;
+ yasm_exrefstr = yasm_xmalloc(MSG_MAXSIZE+1);
#ifdef HAVE_VSNPRINTF
- vsnprintf(we->msg, MSG_MAXSIZE, yasm_gettext_hook(fmt), va);
+ vsnprintf(yasm_exrefstr, MSG_MAXSIZE, yasm_gettext_hook(format), va);
#else
- vsprintf(we->msg, yasm_gettext_hook(fmt), va);
+ vsprintf(yasm_exrefstr, yasm_gettext_hook(format), va);
#endif
-
- warning_count++;
}
-/* Register an error at line line. Does not print the error, only stores it
- * for output_all() to print.
- */
void
-yasm__error(unsigned long line, const char *fmt, ...)
+yasm_error_set_xref(unsigned long xrefline, const char *format, ...)
{
va_list va;
- va_start(va, fmt);
- yasm__error_va_at(line, line, fmt, va);
+ va_start(va, format);
+ yasm_error_set_xref_va(xrefline, format, va);
va_end(va);
}
-/* Register an error at line line, displaying line displine. Does not print
- * the error, only stores it for output_all() to print.
- */
void
-yasm__error_at(unsigned long line, unsigned long displine, const char *fmt,
- ...)
+yasm_error_fetch(yasm_error_class *eclass, char **str, unsigned long *xrefline,
+ char **xrefstr)
{
- va_list va;
- va_start(va, fmt);
- yasm__error_va_at(line, displine, fmt, va);
- va_end(va);
+ *eclass = yasm_eclass;
+ *str = yasm_estr;
+ *xrefline = yasm_exrefline;
+ *xrefstr = yasm_exrefstr;
+ yasm_eclass = YASM_ERROR_NONE;
+ yasm_estr = NULL;
+ yasm_exrefline = 0;
+ yasm_exrefstr = NULL;
+}
+
+void yasm_warn_clear(void)
+{
+ /* Delete all error/warnings */
+ while (!STAILQ_EMPTY(&yasm_warns)) {
+ warn *w = STAILQ_FIRST(&yasm_warns);
+
+ if (w->wstr)
+ yasm_xfree(w->wstr);
+
+ STAILQ_REMOVE_HEAD(&yasm_warns, link);
+ yasm_xfree(w);
+ }
}
-/* Register an warning at line line. Does not print the warning, only stores
- * it for output_all() to print.
- */
void
-yasm__warning(yasm_warn_class num, unsigned long line, const char *fmt, ...)
+yasm_warn_set_va(yasm_warn_class wclass, const char *format, va_list va)
{
- va_list va;
- va_start(va, fmt);
- yasm__warning_va_at(num, line, line, fmt, va);
- va_end(va);
+ warn *w;
+
+ if (!(warn_class_enabled & (1UL<<wclass)))
+ return; /* warning is part of disabled class */
+
+ w = yasm_xmalloc(sizeof(warn));
+ w->wclass = wclass;
+ w->wstr = yasm_xmalloc(MSG_MAXSIZE+1);
+#ifdef HAVE_VSNPRINTF
+ vsnprintf(w->wstr, MSG_MAXSIZE, yasm_gettext_hook(format), va);
+#else
+ vsprintf(w->wstr, yasm_gettext_hook(format), va);
+#endif
+ STAILQ_INSERT_TAIL(&yasm_warns, w, link);
}
-/* Register an warning at line line, displaying line displine. Does not print
- * the warning, only stores it for output_all() to print.
- */
void
-yasm__warning_at(yasm_warn_class num, unsigned long line,
- unsigned long displine, const char *fmt, ...)
+yasm_warn_set(yasm_warn_class wclass, const char *format, ...)
{
va_list va;
- va_start(va, fmt);
- yasm__warning_va_at(num, line, line, fmt, va);
+ va_start(va, format);
+ yasm_warn_set_va(wclass, format, va);
va_end(va);
}
-/* Parser error handler. Moves YACC-style error into our error handling
- * system.
- */
void
-yasm__parser_error(unsigned long line, const char *s)
+yasm_warn_fetch(yasm_warn_class *wclass, char **str)
{
- yasm__error(line, N_("parser error: %s"), s);
- previous_we->type = WE_PARSERERROR;
+ warn *w = STAILQ_FIRST(&yasm_warns);
+
+ *wclass = w->wclass;
+ *str = w->wstr;
+
+ STAILQ_REMOVE_HEAD(&yasm_warns, link);
+ yasm_xfree(w);
}
void
warn_class_enabled = 0;
}
+yasm_errwarns *
+yasm_errwarns_create(void)
+{
+ yasm_errwarns *errwarns = yasm_xmalloc(sizeof(yasm_errwarns));
+ SLIST_INIT(&errwarns->errwarns);
+ errwarns->ecount = 0;
+ errwarns->wcount = 0;
+ errwarns->previous_we = NULL;
+ return errwarns;
+}
+
+void
+yasm_errwarns_destroy(yasm_errwarns *errwarns)
+{
+ errwarn_data *we;
+
+ /* Delete all error/warnings */
+ while (!SLIST_EMPTY(&errwarns->errwarns)) {
+ we = SLIST_FIRST(&errwarns->errwarns);
+ if (we->msg)
+ yasm_xfree(we->msg);
+ if (we->xrefmsg)
+ yasm_xfree(we->xrefmsg);
+
+ SLIST_REMOVE_HEAD(&errwarns->errwarns, link);
+ yasm_xfree(we);
+ }
+
+ yasm_xfree(errwarns);
+}
+
+void
+yasm_errwarn_propagate(yasm_errwarns *errwarns, unsigned long line)
+{
+ if (yasm_eclass != YASM_ERROR_NONE) {
+ errwarn_data *we = errwarn_data_new(errwarns, line, 1);
+ yasm_error_class eclass;
+
+ yasm_error_fetch(&eclass, &we->msg, &we->xrefline, &we->xrefmsg);
+ if (eclass != YASM_ERROR_GENERAL
+ && (eclass & YASM_ERROR_PARSE) == YASM_ERROR_PARSE)
+ we->type = WE_PARSERERROR;
+ else
+ we->type = WE_ERROR;
+ errwarns->ecount++;
+ }
+
+ while (!STAILQ_EMPTY(&yasm_warns)) {
+ errwarn_data *we = errwarn_data_new(errwarns, line, 0);
+ yasm_warn_class wclass;
+
+ yasm_warn_fetch(&wclass, &we->msg);
+ we->type = WE_WARNING;
+ errwarns->wcount++;
+ }
+}
+
unsigned int
-yasm_get_num_errors(int warning_as_error)
+yasm_errwarns_num_errors(yasm_errwarns *errwarns, int warning_as_error)
{
if (warning_as_error)
- return error_count+warning_count;
+ return errwarns->ecount+errwarns->wcount;
else
- return error_count;
+ return errwarns->ecount;
}
void
-yasm_errwarn_output_all(yasm_linemap *lm, int warning_as_error,
- yasm_print_error_func print_error, yasm_print_warning_func print_warning)
+yasm_errwarns_output_all(yasm_errwarns *errwarns, yasm_linemap *lm,
+ int warning_as_error,
+ yasm_print_error_func print_error,
+ yasm_print_warning_func print_warning)
{
errwarn_data *we;
const char *filename;
/* If we're treating warnings as errors, tell the user about it. */
if (warning_as_error && warning_as_error != 2) {
print_error("", 0,
- yasm_gettext_hook(N_("warnings being treated as errors")));
+ yasm_gettext_hook(N_("warnings being treated as errors")),
+ 0, NULL);
warning_as_error = 2;
}
/* Output error/warnings. */
- SLIST_FOREACH(we, &errwarns, link) {
+ SLIST_FOREACH(we, &errwarns->errwarns, link) {
/* Output error/warning */
- yasm_linemap_lookup(lm, we->displine, &filename, &line);
- if (we->type == WE_ERROR)
- print_error(filename, line, we->msg);
+ yasm_linemap_lookup(lm, we->line, &filename, &line);
+ if (we->type == WE_ERROR || we->type == WE_PARSERERROR)
+ print_error(filename, line, we->msg, we->xrefline, we->xrefmsg);
else
print_warning(filename, line, we->msg);
}
/** Warning classes (that may be enabled/disabled). */
typedef enum {
- YASM_WARN_GENERAL = 0, /**< Non-specific warnings */
+ YASM_WARN_NONE = 0, /**< No warning */
+ YASM_WARN_GENERAL, /**< Non-specific warnings */
YASM_WARN_UNREC_CHAR, /**< Unrecognized characters (while tokenizing) */
YASM_WARN_PREPROC, /**< Preprocessor warnings */
YASM_WARN_ORPHAN_LABEL, /**< Label alone on a line without a colon */
- YASM_WARN_UNINIT_CONTENTS /**< Uninitialized space in code/data section */
+ YASM_WARN_UNINIT_CONTENTS /**< Uninitialized space in code/data section */
} yasm_warn_class;
+/** Error classes. Bitmask-based to support limited subclassing. */
+typedef enum {
+ YASM_ERROR_NONE = 0x0000, /**< No error */
+ YASM_ERROR_GENERAL = 0xFFFF, /**< Non-specific */
+ YASM_ERROR_ARITHMETIC = 0x0001, /**< Arithmetic error (general) */
+ YASM_ERROR_OVERFLOW = 0x8001, /**< Arithmetic overflow */
+ YASM_ERROR_FLOATING_POINT = 0x4001, /**< Floating point error */
+ YASM_ERROR_ZERO_DIVISION = 0x2001, /**< Divide-by-zero */
+ YASM_ERROR_ASSERTION = 0x0002, /**< Assertion error */
+ YASM_ERROR_VALUE = 0x0004, /**< Value inappropriate
+ * (e.g. not in range) */
+ YASM_ERROR_NOT_ABSOLUTE = 0x8004, /**< Absolute expression required */
+ YASM_ERROR_TOO_COMPLEX = 0x4004, /**< Expression too complex */
+ YASM_ERROR_NOT_CONSTANT = 0x2004, /**< Constant expression required */
+ YASM_ERROR_IO = 0x0008, /**< I/O error */
+ YASM_ERROR_NOT_IMPLEMENTED = 0x0010, /**< Not implemented error */
+ YASM_ERROR_TYPE = 0x0020, /**< Type error */
+ YASM_ERROR_SYNTAX = 0x0040, /**< Syntax error */
+ YASM_ERROR_PARSE = 0x8040 /**< Parser error */
+} yasm_error_class;
+
/** Initialize any internal data structures. */
void yasm_errwarn_initialize(void);
*/
/*@exits@*/ void yasm__fatal(const char *message, ...);
-/** Log an error at a given line, displaying a different line. va_list version
- * of yasm__error_at().
- * \internal
- * \param line virtual line
- * \param displine displayed virtual line
- * \param message printf-like-format message
- * \param va argument list for message
+/** Unconditionally clear the error indicator, freeing any associated data.
+ * Has no effect if the error indicator is not set.
*/
-void yasm__error_va_at(unsigned long line, unsigned long displine,
- const char *message, va_list va);
+void yasm_error_clear(void);
-/** Log an error. va_list version of yasm__error().
- * \internal
- * \param line virtual line
- * \param message printf-like-format message
- * \param va argument list for message
+/** Get the error indicator. YASM_ERROR_NONE is returned if no error has
+ * been set. Note that as YASM_ERROR_NONE is 0, the return value can also
+ * be treated as a boolean value.
+ * \return Current error indicator.
*/
-#define yasm__error_va(line, message, va) \
- yasm__error_va_at(line, line, message, va)
+yasm_error_class yasm_error_occurred(void);
-/** Log a warning at a given line, displaying a different line. va_list
- * version of yasm__warning_at().
- * \internal
- * \param wclass warning class
- * \param line virtual line
- * \param displine displayed virtual line
- * \param message printf-like-format message
- * \param va argument list for message
+/** Check the error indicator against an error class. To check if any error
+ * has been set, check against the YASM_ERROR_GENERAL class. This function
+ * properly checks error subclasses.
+ * \param eclass base error class to check against
+ * \return Nonzero if error indicator is set and a subclass of eclass, 0
+ * otherwise.
*/
-void yasm__warning_va_at(yasm_warn_class wclass, unsigned long line,
- unsigned long displine, const char *message,
- va_list va);
+int yasm_error_matches(yasm_error_class eclass);
-/** Log a warning. va_list version of yasm__warning().
- * \internal
- * \param wclass warning class
- * \param line virtual line
- * \param message printf-like-format message
- * \param va argument list for message
+#ifndef YASM_DOXYGEN
+extern yasm_error_class yasm_eclass;
+#define yasm_error_occurred() yasm_eclass
+#define yasm_error_matches(eclass) (yasm_eclass != YASM_ERROR_NONE && \
+ ((eclass) == YASM_ERROR_GENERAL || \
+ (yasm_eclass & (eclass)) == (eclass)))
+#endif
+
+/** Set the error indicator (va_list version). Has no effect if the error
+ * indicator is already set.
+ * \param eclass error class
+ * \param format printf format string
+ * \param va argument list for format
*/
-#define yasm__warning_va(wclass, line, message, va) \
- yasm__warning_va_at(wclass, line, line, message, va)
+void yasm_error_set_va(yasm_error_class eclass, const char *format, va_list va);
-/** Log an error. Does not print it out immediately; yasm_errwarn_output_all()
- * outputs errors and warnings.
- * \internal
- * \param line virtual line
- * \param message printf-like-format message
- * \param ... argument list for message
+/** Set the error indicator. Has no effect if the error indicator is already
+ * set.
+ * \param eclass error class
+ * \param format printf format string
+ * \param ... argument list for format
*/
-void yasm__error(unsigned long line, const char *message, ...)
+void yasm_error_set(yasm_error_class eclass, const char *format, ...)
/*@printflike@*/;
-/** Log an error at a given line, displaying a different line. Does not print
- * it out immediately; yasm_errwarn_output_all() outputs errors and warnings.
- * \internal
- * \param line virtual line
- * \param displine displayed virtual line
- * \param message printf-like-format message
- * \param ... argument list for message
+/** Set a cross-reference for a new error (va_list version). Has no effect
+ * if the error indicator is already set (e.g. with yasm_error_set()). This
+ * function must be called prior to its corresponding yasm_error_set() call.
+ * \param xrefline virtual line to cross-reference to (should not be 0)
+ * \param format printf format string
+ * \param va argument list for format
*/
-void yasm__error_at(unsigned long line, unsigned long displine,
- const char *message, ...) /*@printflike@*/;
+void yasm_error_set_xref_va(unsigned long xrefline, const char *format,
+ va_list va);
-/** Log a warning. Does not print it out immediately;
- * yasm_errwarn_output_all() outputs errors and warnings.
- * \internal
+/** Set a cross-reference for a new error. Has no effect if the error
+ * indicator is already set (e.g. with yasm_error_set()). This function
+ * must be called prior to its corresponding yasm_error_set() call.
+ * \param xrefline virtual line to cross-reference to (should not be 0)
+ * \param format printf format string
+ * \param ... argument list for format
+ */
+void yasm_error_set_xref(unsigned long xrefline, const char *format, ...)
+ /*@printflike@*/;
+
+/** Fetch the error indicator and all associated data. If the error
+ * indicator is set, the output pointers are set to the current error
+ * indicator values, and the error indicator is cleared.
+ * The code using this function is then responsible for yasm_xfree()'ing
+ * str and xrefstr (if non-NULL). If the error indicator is not set,
+ * all output values are set to 0 (including eclass, which is set to
+ * YASM_ERROR_NONE).
+ * \param eclass error class (output)
+ * \param str error message
+ * \param xrefline virtual line used for cross-referencing (0 if no xref)
+ * \param xrefstr cross-reference error message (NULL if no xref)
+ */
+void yasm_error_fetch(/*@out@*/ yasm_error_class *eclass,
+ /*@out@*/ /*@only@*/ /*@null@*/ char **str,
+ /*@out@*/ unsigned long *xrefline,
+ /*@out@*/ /*@only@*/ /*@null@*/ char **xrefstr);
+
+/** Unconditionally clear all warning indicators, freeing any associated data.
+ * Has no effect if no warning indicators have been set.
+ */
+void yasm_warn_clear(void);
+
+/** Add a warning indicator (va_list version).
* \param wclass warning class
- * \param line virtual line
* \param message printf-like-format message
- * \param ... argument list for message
+ * \param va argument list for message
*/
-void yasm__warning(yasm_warn_class wclass, unsigned long line,
- const char *message, ...) /*@printflike@*/;
+void yasm_warn_set_va(yasm_warn_class wclass, const char *format, va_list va);
-/** Log a warning at a given line, displaying a different line. Does not print
- * it out immediately; yasm_errwarn_output_all() outputs errors and warnings.
- * \internal
+/** Add a warning indicator.
* \param wclass warning class
- * \param line virtual line
- * \param displine displayed virtual line
* \param message printf-like-format message
* \param ... argument list for message
*/
-void yasm__warning_at(yasm_warn_class wclass, unsigned long line,
- unsigned long displine, const char *message, ...)
+void yasm_warn_set(yasm_warn_class wclass, const char *format, ...)
/*@printflike@*/;
-/** Log a parser error. Parser errors can be overwritten by non-parser errors
- * on the same line.
- * \internal
- * \param line virtual line
- * \param message parser error message
+/** Fetch the first warning indicator and all associated data. If there
+ * is at least one warning indicator, the output pointers are set to the
+ * first warning indicator values, and first warning indicator is removed.
+ * The code using this function is then responsible for yasm_xfree()'ing
+ * str and xrefstr (if non-NULL). If there is no warning indicator set,
+ * all output values are set to 0 (including wclass, which is set to
+ * YASM_WARN_NONE).
+ * \param wclass warning class (output)
+ * \param str warning message
*/
-void yasm__parser_error(unsigned long line, const char *message);
+void yasm_warn_fetch(/*@out@*/ yasm_warn_class *wclass,
+ /*@out@*/ /*@only@*/ char **str);
/** Enable a class of warnings.
* \param wclass warning class
/** Disable all classes of warnings. */
void yasm_warn_disable_all(void);
+/** Create an error/warning set for collection of multiple error/warnings.
+ * \return Newly allocated set.
+ */
+/*@only@*/ yasm_errwarns *yasm_errwarns_create(void);
+
+/** Destroy an error/warning set.
+ * \param errwarns error/warning set
+ */
+void yasm_errwarns_destroy(/*@only@*/ yasm_errwarns *errwarns);
+
+/** Propagate error indicator and warning indicator(s) to an error/warning set.
+ * Has no effect if the error indicator and warning indicator are not set.
+ * Does not print immediately; yasm_errwarn_output_all() outputs
+ * accumulated errors and warnings.
+ * Generally multiple errors on the same line will be reported, but errors
+ * of class YASM_ERROR_PARSE will get overwritten by any other class on the
+ * same line.
+ * \param errwarns error/warning set
+ * \param line virtual line
+ */
+void yasm_errwarn_propagate(yasm_errwarns *errwarns, unsigned long line);
+
/** Get total number of errors logged.
+ * \param errwarns error/warning set
* \param warning_as_error if nonzero, warnings are treated as errors.
* \return Number of errors.
*/
-unsigned int yasm_get_num_errors(int warning_as_error);
+unsigned int yasm_errwarns_num_errors(yasm_errwarns *errwarns,
+ int warning_as_error);
/** Print out an error.
* \param fn filename of source file
* \param msg error message
*/
typedef void (*yasm_print_error_func)
- (const char *fn, unsigned long line, const char *msg);
+ (const char *fn, unsigned long line, const char *msg,
+ unsigned long xrefline, /*@null@*/ const char *xrefmsg);
/** Print out a warning.
* \param fn filename of source file
typedef void (*yasm_print_warning_func)
(const char *fn, unsigned long line, const char *msg);
-/** Outputs all errors and warnings.
+/** Outputs error/warning set in sorted order (sorted by virtual line number).
+ * \param errwarns error/warning set
* \param lm line map (to convert virtual lines into filename/line pairs)
- * \param warning_as_error if nonzero, treat warnings as errors
+ * \param warning_as_error if nonzero, treat warnings as errors.
* \param print_error function called to print out errors
* \param print_warning function called to print out warnings
*/
-void yasm_errwarn_output_all
- (yasm_linemap *lm, int warning_as_error, yasm_print_error_func print_error,
- yasm_print_warning_func print_warning);
+void yasm_errwarns_output_all
+ (yasm_errwarns *errwarns, yasm_linemap *lm, int warning_as_error,
+ yasm_print_error_func print_error, yasm_print_warning_func print_warning);
/** Convert a possibly unprintable character into a printable string.
* \internal
* floatnums present below; if there ARE floatnums, recurse.
*/
if (e->terms[0].type == YASM_EXPR_FLOAT)
- yasm_floatnum_calc(e->terms[0].data.flt, YASM_EXPR_NEG, NULL,
- e->line);
+ yasm_floatnum_calc(e->terms[0].data.flt, YASM_EXPR_NEG, NULL);
else if (e->terms[0].type == YASM_EXPR_EXPR &&
yasm_expr__contains(e->terms[0].data.expn, YASM_EXPR_FLOAT))
expr_xform_neg_helper(e->terms[0].data.expn);
if (numterms == 1 && int_term == 0 &&
(e->op == YASM_EXPR_NOT || e->op == YASM_EXPR_NEG ||
e->op == YASM_EXPR_LNOT))
- yasm_intnum_calc(e->terms[0].data.intn, e->op, NULL, e->line);
+ yasm_intnum_calc(e->terms[0].data.intn, e->op, NULL);
/* Change expression to IDENT if possible. */
if (numterms == 1)
for (i=first_int_term+1, o=first_int_term+1; i<e->numterms; i++) {
if (e->terms[i].type == YASM_EXPR_INT) {
yasm_intnum_calc(e->terms[first_int_term].data.intn, e->op,
- e->terms[i].data.intn, e->line);
+ e->terms[i].data.intn);
fold_numterms--;
level_numterms--;
/* make sure to delete folded intnum */
e->terms[first_int_term] = sube->terms[j]; /* struc */
} else {
yasm_intnum_calc(e->terms[first_int_term].data.intn,
- e->op, sube->terms[j].data.intn,
- e->line);
+ e->op, sube->terms[j].data.intn);
/* make sure to delete folded intnum */
yasm_intnum_destroy(sube->terms[j].data.intn);
}
yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident,
int simplify_reg_mul, yasm_calc_bc_dist_func calc_bc_dist,
yasm_expr_xform_func expr_xform_extra,
- void *expr_xform_extra_data, yasm__exprhead *eh,
- int *error)
+ void *expr_xform_extra_data, yasm__exprhead *eh)
{
int i;
yasm__exprhead eh_local;
/* Check for circular reference */
SLIST_FOREACH(np, eh, next) {
if (np->e == equ_expr) {
- yasm__error(e->line,
- N_("circular reference detected"));
- if (error)
- *error = 1;
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("circular reference detected"));
return e;
}
}
/* Check for circular reference */
SLIST_FOREACH(np, eh, next) {
if (np->e == start) {
- yasm__error(e->line,
- N_("circular reference detected"));
- if (error)
- *error = 1;
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("circular reference detected"));
return e;
}
}
yasm_expr__level_tree(e->terms[i].data.expn, fold_const,
simplify_ident, simplify_reg_mul,
calc_bc_dist, expr_xform_extra,
- expr_xform_extra_data, eh, error);
+ expr_xform_extra_data, eh);
if (ee.e) {
SLIST_REMOVE_HEAD(eh, next);
if (expr_xform_extra)
e = expr_xform_extra(e, expr_xform_extra_data);
e = yasm_expr__level_tree(e, fold_const, simplify_ident,
- simplify_reg_mul, NULL, NULL, NULL, NULL,
- error);
+ simplify_reg_mul, NULL, NULL, NULL, NULL);
}
return e;
}
* \param expr_xform_extra extra transformation function
* \param expr_xform_extra_data data to pass to expr_xform_extra
* \param eh call with NULL (for internal use in recursion)
- * \param error if non-NULL, set to 1 if an error is encountered
- * (e.g. circular reference errors)
* \return Leveled expression.
*/
/*@only@*/ /*@null@*/ yasm_expr *yasm_expr__level_tree
int simplify_ident, int simplify_reg_mul,
/*@null@*/ yasm_calc_bc_dist_func calc_bc_dist,
/*@null@*/ yasm_expr_xform_func expr_xform_extra,
- /*@null@*/ void *expr_xform_extra_data, /*@null@*/ yasm__exprhead *eh,
- /*@null@*/ int *error);
+ /*@null@*/ void *expr_xform_extra_data, /*@null@*/ yasm__exprhead *eh);
/** Simplify an expression as much as possible. Eliminates extraneous
* branches and simplifies integer-only subexpressions. Simplified version
* \return Simplified expression.
*/
#define yasm_expr_simplify(e, cbd) \
- yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL, NULL, NULL)
+ yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL, NULL)
/** Extract the segment portion of a SEG:OFF expression, leaving the offset.
* \param ep expression (pointer to)
yasm_xfree(flt);
}
-void
+int
yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
- /*@unused@*/ yasm_floatnum *operand, unsigned long line)
+ /*@unused@*/ yasm_floatnum *operand)
{
- if (op != YASM_EXPR_NEG)
- yasm__error(line,
- N_("Unsupported floating-point arithmetic operation"));
- else
- acc->sign ^= 1;
+ if (op != YASM_EXPR_NEG) {
+ yasm_error_set(YASM_ERROR_FLOATING_POINT,
+ N_("Unsupported floating-point arithmetic operation"));
+ return 1;
+ }
+ acc->sign ^= 1;
+ return 0;
}
int
{
unsigned char t[4];
- if (yasm_floatnum_get_sized(flt, t, 4, 32, 0, 0, 0, 0)) {
+ if (yasm_floatnum_get_sized(flt, t, 4, 32, 0, 0, 0)) {
*ret_val = 0xDEADBEEFUL; /* Obviously incorrect return value */
return 1;
}
int
yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
size_t destsize, size_t valsize, size_t shift,
- int bigendian, int warn, unsigned long line)
+ int bigendian, int warn)
{
int retval;
if (destsize*8 != valsize || shift>0 || bigendian) {
}
if (warn) {
if (retval < 0)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("underflow in floating point expression"));
else if (retval > 0)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("overflow in floating point expression"));
}
return retval;
/* 32-bit (single precision) format */
fprintf(f, "32-bit: %d: ",
- yasm_floatnum_get_sized(flt, out, 4, 32, 0, 0, 0, 0));
+ yasm_floatnum_get_sized(flt, out, 4, 32, 0, 0, 0));
for (i=0; i<4; i++)
fprintf(f, "%02x ", out[i]);
fprintf(f, "\n");
/* 64-bit (double precision) format */
fprintf(f, "64-bit: %d: ",
- yasm_floatnum_get_sized(flt, out, 8, 64, 0, 0, 0, 0));
+ yasm_floatnum_get_sized(flt, out, 8, 64, 0, 0, 0));
for (i=0; i<8; i++)
fprintf(f, "%02x ", out[i]);
fprintf(f, "\n");
/* 80-bit (extended precision) format */
fprintf(f, "80-bit: %d: ",
- yasm_floatnum_get_sized(flt, out, 10, 80, 0, 0, 0, 0));
+ yasm_floatnum_get_sized(flt, out, 10, 80, 0, 0, 0));
for (i=0; i<10; i++)
fprintf(f, "%02x ", out[i]);
fprintf(f, "\n");
* \param acc floatnum accumulator
* \param op operation
* \param operand floatnum operand
- * \param line virtual line (of expression)
+ * \return Nonzero on error.
*/
-void yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
- yasm_floatnum *operand, unsigned long line);
+int yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
+ yasm_floatnum *operand);
/** Convert a floatnum to single-precision and return as 32-bit value.
* The 32-bit value is a "standard" C value (eg, of unknown endian).
* \param shift left shift (in bits)
* \param bigendian endianness (nonzero=big, zero=little)
* \param warn enables standard overflow/underflow warnings
- * \param line virtual line; may be 0 if warn is 0.
* \return Nonzero if flt can't fit into the specified precision: -1 if
* underflow occurred, 1 if overflow occurred.
*/
int yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
size_t destsize, size_t valsize, size_t shift,
- int bigendian, int warn, unsigned long line);
+ int bigendian, int warn);
/** Basic check to see if size is valid for flt conversion (using
* yasm_floatnum_get_sized()). Doesn't actually check for underflow/overflow
}
yasm_intnum *
-yasm_intnum_create_dec(char *str, unsigned long line)
+yasm_intnum_create_dec(char *str)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
if (BitVector_from_Dec_static(from_dec_data, conv_bv,
(unsigned char *)str) == ErrCode_Ovfl)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Numeric constant too large for internal format"));
if (Set_Max(conv_bv) < 32) {
intn->type = INTNUM_UL;
}
yasm_intnum *
-yasm_intnum_create_bin(char *str, unsigned long line)
+yasm_intnum_create_bin(char *str)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
intn->origsize = (unsigned char)strlen(str);
if(intn->origsize > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Numeric constant too large for internal format"));
BitVector_from_Bin(conv_bv, (unsigned char *)str);
}
yasm_intnum *
-yasm_intnum_create_oct(char *str, unsigned long line)
+yasm_intnum_create_oct(char *str)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
intn->origsize = strlen(str)*3;
if(intn->origsize > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Numeric constant too large for internal format"));
BitVector_from_Oct(conv_bv, (unsigned char *)str);
}
yasm_intnum *
-yasm_intnum_create_hex(char *str, unsigned long line)
+yasm_intnum_create_hex(char *str)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
intn->origsize = strlen(str)*4;
if(intn->origsize > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Numeric constant too large for internal format"));
BitVector_from_Hex(conv_bv, (unsigned char *)str);
/*@-usedef -compdef -uniondef@*/
yasm_intnum *
-yasm_intnum_create_charconst_nasm(const char *str, unsigned long line)
+yasm_intnum_create_charconst_nasm(const char *str)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
size_t len = strlen(str);
intn->origsize = len*8;
if(intn->origsize > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Character constant too large for internal format"));
if (len > 4) {
yasm_intnum *
yasm_intnum_create_leb128(const unsigned char *ptr, int sign,
- unsigned long *size, unsigned long line)
+ unsigned long *size)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
const unsigned char *ptr_orig = ptr;
*size = (ptr-ptr_orig)+1;
if(i > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Numeric constant too large for internal format"));
else if (sign && (*ptr & 0x40) == 0x40)
BitVector_Interval_Fill(conv_bv, i, BITVECT_NATIVE_SIZE-1);
yasm_intnum *
yasm_intnum_create_sized(unsigned char *ptr, int sign, size_t srcsize,
- int bigendian, unsigned long line)
+ int bigendian)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
unsigned long i = 0;
intn->origsize = 0;
if (srcsize*8 > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Numeric constant too large for internal format"));
/* Read the buffer into a bitvect */
}
/*@-nullderef -nullpass -branchstate@*/
-void
-yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
- unsigned long line)
+int
+yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand)
{
boolean carry = 0;
wordptr op1, op2 = NULL;
}
if (!operand && op != YASM_EXPR_NEG && op != YASM_EXPR_NOT &&
- op != YASM_EXPR_LNOT)
- yasm_internal_error(N_("Operation needs an operand"));
+ op != YASM_EXPR_LNOT) {
+ yasm_error_set(YASM_ERROR_ARITHMETIC,
+ N_("operation needs an operand"));
+ BitVector_Empty(result);
+ return 1;
+ }
/* A operation does a bitvector computation if result is allocated. */
switch (op) {
break;
case YASM_EXPR_DIV:
/* TODO: make sure op1 and op2 are unsigned */
- BitVector_Divide(result, op1, op2, spare);
+ if (BitVector_is_empty(op2)) {
+ yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
+ BitVector_Empty(result);
+ return 1;
+ } else
+ BitVector_Divide(result, op1, op2, spare);
break;
case YASM_EXPR_SIGNDIV:
- BitVector_Divide(result, op1, op2, spare);
+ if (BitVector_is_empty(op2)) {
+ yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
+ BitVector_Empty(result);
+ return 1;
+ } else
+ BitVector_Divide(result, op1, op2, spare);
break;
case YASM_EXPR_MOD:
/* TODO: make sure op1 and op2 are unsigned */
- BitVector_Divide(spare, op1, op2, result);
+ if (BitVector_is_empty(op2)) {
+ yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
+ BitVector_Empty(result);
+ return 1;
+ } else
+ BitVector_Divide(spare, op1, op2, result);
break;
case YASM_EXPR_SIGNMOD:
- BitVector_Divide(spare, op1, op2, result);
+ if (BitVector_is_empty(op2)) {
+ yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
+ BitVector_Empty(result);
+ return 1;
+ } else
+ BitVector_Divide(spare, op1, op2, result);
break;
case YASM_EXPR_NEG:
BitVector_Negate(result, op1);
BitVector_LSB(result, !BitVector_equal(op1, op2));
break;
case YASM_EXPR_SEG:
- yasm__error(line, N_("invalid use of '%s'"), "SEG");
+ yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
+ "SEG");
break;
case YASM_EXPR_WRT:
- yasm__error(line, N_("invalid use of '%s'"), "WRT");
+ yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
+ "WRT");
break;
case YASM_EXPR_SEGOFF:
- yasm__error(line, N_("invalid use of '%s'"), ":");
+ yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
+ ":");
break;
case YASM_EXPR_IDENT:
if (result)
BitVector_Copy(result, op1);
break;
default:
- yasm_internal_error(N_("invalid operation in intnum calculation"));
+ yasm_error_set(YASM_ERROR_ARITHMETIC,
+ N_("invalid operation in intnum calculation"));
+ BitVector_Empty(result);
+ return 1;
}
/* Try to fit the result into 32 bits if possible */
acc->val.bv = BitVector_Clone(result);
}
}
+ return 0;
}
/*@=nullderef =nullpass =branchstate@*/
void
yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
size_t destsize, size_t valsize, int shift,
- int bigendian, int warn, unsigned long line)
+ int bigendian, int warn)
{
wordptr op1 = op1static, op2;
unsigned char *buf;
/* General size warnings */
if (warn<0 && !yasm_intnum_check_size(intn, valsize, rshift, 1))
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("value does not fit in signed %d bit field"),
valsize);
if (warn>0 && !yasm_intnum_check_size(intn, valsize, rshift, 2))
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("value does not fit in %d bit field"), valsize);
/* Read the original data into a bitvect */
BitVector_Copy(conv_bv, op2);
BitVector_Move_Left(conv_bv, BITVECT_NATIVE_SIZE-rshift);
if (!BitVector_is_empty(conv_bv))
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("misaligned value, truncating to boundary"));
}
/** Create a new intnum from a decimal string.
* \param str decimal string
- * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_create_dec(char *str, unsigned long line);
+/*@only@*/ yasm_intnum *yasm_intnum_create_dec(char *str);
/** Create a new intnum from a binary string.
* \param str binary string
- * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_create_bin(char *str, unsigned long line);
+/*@only@*/ yasm_intnum *yasm_intnum_create_bin(char *str);
/** Create a new intnum from an octal string.
* \param str octal string
- * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_create_oct(char *str, unsigned long line);
+/*@only@*/ yasm_intnum *yasm_intnum_create_oct(char *str);
/** Create a new intnum from a hexidecimal string.
* \param str hexidecimal string
- * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_create_hex(char *str, unsigned long line);
+/*@only@*/ yasm_intnum *yasm_intnum_create_hex(char *str);
/** Convert character constant to integer value, using NASM rules. NASM syntax
* supports automatic conversion from strings such as 'abcd' to a 32-bit
* integer value. This function performs those conversions.
* \param str character constant string
- * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str,
- unsigned long line);
+/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str);
/** Create a new intnum from an unsigned integer value.
* \param i unsigned integer value
* \param ptr pointer to start of LEB128 encoded form
* \param sign signed (1) or unsigned (0) LEB128 format
* \param size number of bytes read from ptr (output)
- * \param line virtual line (where the number came from)
* \return Newly allocated intnum. Number of bytes read returned into
* bytes_read parameter.
*/
/*@only@*/ yasm_intnum *yasm_intnum_create_leb128
- (const unsigned char *ptr, int sign, /*@out@*/ unsigned long *size,
- unsigned long line);
+ (const unsigned char *ptr, int sign, /*@out@*/ unsigned long *size);
/** Create a new intnum from a little-endian or big-endian buffer.
* In little endian, the LSB is in ptr[0].
* \param sign signed (1) or unsigned (0) source
* \param srcsize source buffer size (in bytes)
* \param bigendian endianness (nonzero=big, zero=little)
- * \param line virtual line; may be 0 if warn is 0
*/
/*@only@*/ yasm_intnum *yasm_intnum_create_sized
- (unsigned char *ptr, int sign, size_t srcsize, int bigendian,
- unsigned long line);
+ (unsigned char *ptr, int sign, size_t srcsize, int bigendian);
/** Duplicate an intnum.
* \param intn intnum
* \param acc intnum accumulator
* \param op operation
* \param operand intnum operand
- * \param line virtual line (of expression)
+ * \return Nonzero if error occurred.
*/
-void yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
- unsigned long line);
+int yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand);
/** Zero an intnum.
* \param intn intnum
* shift (standard warnings include truncation to boundary)
* \param bigendian endianness (nonzero=big, zero=little)
* \param warn enables standard warnings (value doesn't fit into valsize
- * bits)
- * \param line virtual line; may be 0 if warn is 0
+ * bits): <0=signed warnings, >0=unsigned warnings, 0=no warn
*/
void yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
size_t destsize, size_t valsize, int shift,
- int bigendian, int warn, unsigned long line);
+ int bigendian, int warn);
/** Check to see if intnum will fit without overflow into size bits.
* \param intn intnum
/** Module-level implementation of yasm_objfmt_output().
* Call yasm_objfmt_output() instead of calling this function.
*/
- void (*output) (yasm_objfmt *of, FILE *f, int all_syms, yasm_dbgfmt *df);
+ void (*output) (yasm_objfmt *of, FILE *f, int all_syms, yasm_dbgfmt *df,
+ yasm_errwarns *errwarns);
/** Module-level implementation of yasm_objfmt_destroy().
* Call yasm_objfmt_destroy() instead of calling this function.
* \param all_syms if nonzero, all symbols should be included in
* the object file
* \param df debug format in use
+ * \param errwarns error/warning set
+ * \note Errors and warnings are stored into errwarns.
*/
void yasm_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms,
- yasm_dbgfmt *df);
+ yasm_dbgfmt *df, yasm_errwarns *errwarns);
/** Cleans up any allocated object format memory.
* \param objfmt object format
#define yasm_objfmt_create(module, object, a) module->create(object, a)
-#define yasm_objfmt_output(objfmt, f, all_syms, df) \
- ((yasm_objfmt_base *)objfmt)->module->output(objfmt, f, all_syms, df)
+#define yasm_objfmt_output(objfmt, f, all_syms, df, ews) \
+ ((yasm_objfmt_base *)objfmt)->module->output(objfmt, f, all_syms, df, ews)
#define yasm_objfmt_destroy(objfmt) \
((yasm_objfmt_base *)objfmt)->module->destroy(objfmt)
#define yasm_objfmt_section_switch(objfmt, vpms, oe_vpms, line) \
/** Optimize an object. Takes the unoptimized object and optimizes it.
* If successful, the object is ready for output to an object file.
* \param object object
- * \note Optimization failures are indicated by this function calling
- * yasm__error_at(); see errwarn.h for details.
+ * \param errwarns error/warning set
+ * \note Optimization failures are stored into errwarns.
*/
- void (*optimize) (yasm_object *object);
+ void (*optimize) (yasm_object *object, yasm_errwarns *errwarns);
} yasm_optimizer_module;
#endif
* lines of source into the object's linemap (via
* yasm_linemap_add_data()).
* \param def_sect default (starting) section in the object
- * \note Parse failures are indicated by this function calling
- * yasm__error(); see errwarn.h for details.
+ * \param errwarns error/warning set
+ * \note Parse errors and warnings are stored into errwarns.
*/
- void (*do_parse) (yasm_object *object, yasm_preproc *pp, yasm_arch *a,
- yasm_objfmt *of, yasm_dbgfmt *df, FILE *f,
- const char *in_filename, int save_input,
- yasm_section *def_sect);
+ void (*do_parse)
+ (yasm_object *object, yasm_preproc *pp, yasm_arch *a, yasm_objfmt *of,
+ yasm_dbgfmt *df, FILE *f, const char *in_filename, int save_input,
+ yasm_section *def_sect, yasm_errwarns *errwarns);
} yasm_parser_module;
#endif
* Module-level implementation of yasm_preproc_create().
* Call yasm_preproc_create() instead of calling this function.
*
- * The preprocessor needs access to the object format module to find out
- * any output format specific macros.
- *
* \param f initial starting file
* \param in_filename initial starting filename
* \param lm line mapping repository
+ * \param errwarns error/warnning set.
* \return New preprocessor.
+ *
+ * \note Any preprocessor errors and warnings are stored into errwarns.
*/
/*@only@*/ yasm_preproc * (*create) (FILE *f, const char *in_filename,
- yasm_linemap *lm);
+ yasm_linemap *lm,
+ yasm_errwarns *errwarns);
/** Module-level implementation of yasm_preproc_destroy().
* Call yasm_preproc_destroy() instead of calling this function.
* \param f initial starting file
* \param in_filename initial starting file filename
* \param lm line mapping repository
+ * \param errwarns error/warning set
* \return New preprocessor.
+ * \note Errors/warnings are stored into errwarns.
*/
/*@only@*/ yasm_preproc *yasm_preproc_create
(yasm_preproc_module *module, FILE *f, const char *in_filename,
- yasm_linemap *lm);
+ yasm_linemap *lm, yasm_errwarns *errwarns);
/** Cleans up any allocated preproc memory.
* \param preproc preprocessor
/* Inline macro implementations for preproc functions */
-#define yasm_preproc_create(module, f, in_filename, lm) \
- module->create(f, in_filename, lm)
+#define yasm_preproc_create(module, f, in_filename, lm, ews) \
+ module->create(f, in_filename, lm, ews)
#define yasm_preproc_destroy(preproc) \
((yasm_preproc_base *)preproc)->module->destroy(preproc)
}
void
-yasm_object_finalize(yasm_object *object)
+yasm_object_finalize(yasm_object *object, yasm_errwarns *errwarns)
{
yasm_section *sect;
while (cur) {
/* Finalize */
yasm_bc_finalize(cur, prev);
+ yasm_errwarn_propagate(errwarns, cur->line);
prev = cur;
cur = STAILQ_NEXT(cur, link);
}
}
int
-yasm_section_bcs_traverse(yasm_section *sect, void *d,
+yasm_section_bcs_traverse(yasm_section *sect,
+ /*@null@*/ yasm_errwarns *errwarns,
+ /*@null@*/ void *d,
int (*func) (yasm_bytecode *bc, /*@null@*/ void *d))
{
yasm_bytecode *cur = STAILQ_FIRST(§->bcs);
/* Iterate through the remainder, if any. */
while (cur) {
int retval = func(cur, d);
+ if (errwarns)
+ yasm_errwarn_propagate(errwarns, cur->line);
if (retval != 0)
return retval;
cur = STAILQ_NEXT(cur, link);
/** Finalize an object after parsing.
* \param object object
+ * \param errwarns error/warning set
+ * \note Errors/warnings are stored into errwarns.
*/
-void yasm_object_finalize(yasm_object *object);
+void yasm_object_finalize(yasm_object *object, yasm_errwarns *errwarns);
/** Traverses all sections in an object, calling a function on each section.
* \param object object
/*@returned@*/ /*@only@*/ /*@null@*/ yasm_bytecode *bc);
/** Traverses all bytecodes in a section, calling a function on each bytecode.
- * \param sect section
- * \param d data pointer passed to func on each call
- * \param func function
+ * \param sect section
+ * \param errwarns error/warning set (may be NULL)
+ * \param d data pointer passed to func on each call (may be NULL)
+ * \param func function
* \return Stops early (and returns func's return value) if func returns a
* nonzero value; otherwise 0.
+ * \note If errwarns is non-NULL, yasm_errwarn_propagate() is called after
+ * each call to func (with the bytecode's line number).
*/
int yasm_section_bcs_traverse
- (yasm_section *sect, /*@null@*/ void *d,
- int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
+ (yasm_section *sect, /*@null@*/ yasm_errwarns *errwarns,
+ /*@null@*/ void *d, int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
/** Get name of a section.
* \param sect section
/* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
if (rec->status & SYM_DEFINED) {
- yasm__error(line, N_("redefinition of `%s'"), name);
- yasm__error_at(line, rec->line, N_("`%s' previously defined here"),
+ yasm_error_set_xref(rec->line, N_("`%s' previously defined here"),
+ name);
+ yasm_error_set(YASM_ERROR_GENERAL, N_("redefinition of `%s'"),
name);
} else {
if (rec->visibility & YASM_SYM_EXTERN)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("`%s' both defined and declared extern"), name);
rec->line = line; /* set line number of definition */
rec->type = type;
((rec->visibility & YASM_SYM_EXTERN) && (vis == YASM_SYM_EXTERN)))))
rec->visibility |= vis;
else
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_GENERAL,
N_("duplicate definition of `%s'; first defined on line %lu"),
rec->name, rec->line);
}
unsigned long firstundef_line;
int undef_extern;
/*@null@*/ yasm_objfmt *objfmt;
+ yasm_errwarns *errwarns;
} symtab_finalize_info;
static int
if (info->undef_extern && info->objfmt)
yasm_objfmt_extern_declare(info->objfmt, sym->name, NULL, 1);
else {
- yasm__error(sym->line, N_("undefined symbol `%s' (first use)"),
- sym->name);
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("undefined symbol `%s' (first use)"), sym->name);
+ yasm_errwarn_propagate(info->errwarns, sym->line);
if (sym->line < info->firstundef_line)
info->firstundef_line = sym->line;
}
void
yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern,
- yasm_objfmt *objfmt)
+ yasm_objfmt *objfmt, yasm_errwarns *errwarns)
{
symtab_finalize_info info;
info.firstundef_line = ULONG_MAX;
info.undef_extern = undef_extern;
info.objfmt = objfmt;
+ info.errwarns = errwarns;
yasm_symtab_traverse(symtab, &info, symtab_parser_finalize_checksym);
- if (info.firstundef_line < ULONG_MAX)
- yasm__error(info.firstundef_line,
- N_(" (Each undefined symbol is reported only once.)"));
+ if (info.firstundef_line < ULONG_MAX) {
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_(" (Each undefined symbol is reported only once.)"));
+ yasm_errwarn_propagate(errwarns, info.firstundef_line);
+ }
}
void
* \param undef_extern if nonzero, all undef syms should be declared extern
* \param objfmt object format to notify about new extern decls
* (may be NULL if undef_extern is 0)
+ * \param errwarns error/warning set
+ * \note Errors/warnings are stored into errwarns.
*/
void yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern,
- /*@null@*/ yasm_objfmt *objfmt);
+ /*@null@*/ yasm_objfmt *objfmt,
+ yasm_errwarns *errwarns);
/** Print the symbol table. For debugging purposes.
* \param symtab symbol table
--:1: circular reference detected
--:6: (used in memory expression)
+-:6: circular reference detected in memory expression
for (i=0; i<num; i++) {
get_common_setup(vals, i);
- if (yasm_floatnum_get_sized(flt, outval, 4, 32, 0, 0, 0, 0) !=
+ if (yasm_floatnum_get_sized(flt, outval, 4, 32, 0, 0, 0) !=
vals[i].ret32)
return 1;
if (get_common_check_result(4, outval, vals[i].result32) != 0)
for (i=0; i<num; i++) {
get_common_setup(vals, i);
- if (yasm_floatnum_get_sized(flt, outval, 4, 32, 0, 0, 0, 0) !=
+ if (yasm_floatnum_get_sized(flt, outval, 4, 32, 0, 0, 0) !=
vals[i].ret32)
return 1;
if (get_common_check_result(4, outval, vals[i].result32) != 0)
for (i=0; i<num; i++) {
get_common_setup(vals, i);
- if (yasm_floatnum_get_sized(flt, outval, 8, 64, 0, 0, 0, 0) !=
+ if (yasm_floatnum_get_sized(flt, outval, 8, 64, 0, 0, 0) !=
vals[i].ret64)
return 1;
if (get_common_check_result(8, outval, vals[i].result64) != 0)
for (i=0; i<num; i++) {
get_common_setup(vals, i);
- if (yasm_floatnum_get_sized(flt, outval, 8, 64, 0, 0, 0, 0) !=
+ if (yasm_floatnum_get_sized(flt, outval, 8, 64, 0, 0, 0) !=
vals[i].ret64)
return 1;
if (get_common_check_result(8, outval, vals[i].result64) != 0)
for (i=0; i<num; i++) {
get_common_setup(vals, i);
- if (yasm_floatnum_get_sized(flt, outval, 10, 80, 0, 0, 0, 0) !=
+ if (yasm_floatnum_get_sized(flt, outval, 10, 80, 0, 0, 0) !=
vals[i].ret80)
return 1;
if (get_common_check_result(10, outval, vals[i].result80) != 0)
for (i=0; i<num; i++) {
get_common_setup(vals, i);
- if (yasm_floatnum_get_sized(flt, outval, 10, 80, 0, 0, 0, 0) !=
+ if (yasm_floatnum_get_sized(flt, outval, 10, 80, 0, 0, 0) !=
vals[i].ret80)
return 1;
if (get_common_check_result(10, outval, vals[i].result80) != 0)
run_output_test(Test_Entry *test)
{
char *valstr = yasm__xstrdup(test->input);
- yasm_intnum *intn = yasm_intnum_create_hex(valstr, 0);
+ yasm_intnum *intn = yasm_intnum_create_hex(valstr);
unsigned long size, i;
unsigned char out[100];
int bad;
yasm_xfree(valstr);
if (test->negate)
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, 0);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
size = yasm_intnum_size_leb128(intn, test->sign);
if (size != test->outsize) {
run_input_test(Test_Entry *test)
{
char *valstr = yasm__xstrdup(test->input);
- yasm_intnum *intn = yasm_intnum_create_hex(valstr, 0);
+ yasm_intnum *intn = yasm_intnum_create_hex(valstr);
yasm_intnum *testn;
unsigned long size;
yasm_xfree(valstr);
if (test->negate)
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, 0);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
- testn = yasm_intnum_create_leb128(test->result, test->sign, &size, 0);
+ testn = yasm_intnum_create_leb128(test->result, test->sign, &size);
if (size != test->outsize) {
yasm_intnum_destroy(testn);
yasm_intnum_destroy(intn);
return 1;
}
- yasm_intnum_calc(intn, YASM_EXPR_EQ, testn, 0);
+ yasm_intnum_calc(intn, YASM_EXPR_EQ, testn);
if (!yasm_intnum_is_pos1(intn)) {
yasm_intnum_destroy(testn);
yasm_intnum_destroy(intn);
-:2: effective address too complex
-:3: immediate expression too complex
--:8: expression too complex
+-:8: data expression too complex
int
yasm_value_finalize_expr(yasm_value *value, yasm_expr *e)
{
- int error = 0;
-
if (!e) {
yasm_value_initialize(value, NULL);
return 0;
}
yasm_value_initialize(value, yasm_expr__level_tree
- (e, 1, 1, 0, NULL, NULL, NULL, NULL, &error));
+ (e, 1, 1, 0, NULL, NULL, NULL, NULL));
/* quit early if there was an issue in simplify() */
- if (error)
+ if (yasm_error_occurred())
return 1;
/* Handle trivial (IDENT) cases immediately */
return 1;
value->abs = yasm_expr__level_tree(value->abs, 1, 1, 0, NULL, NULL, NULL,
- NULL, NULL);
+ NULL);
/* Simplify 0 in abs to NULL */
if (value->abs->op == YASM_EXPR_IDENT
yasm_internal_error(N_("attempting to negative shift a float"));
if (yasm_arch_floatnum_tobytes(arch, value->abs->terms[0].data.flt,
buf, destsize, valsize,
- (unsigned int)shift, warn,
- bc->line))
+ (unsigned int)shift, warn))
return -1;
else
return 1;
/* Check for complex float expressions */
if (yasm_expr__contains(value->abs, YASM_EXPR_FLOAT)) {
- yasm__error(bc->line, N_("floating point expression too complex"));
+ yasm_error_set(YASM_ERROR_FLOATING_POINT,
+ N_("floating point expression too complex"));
return -1;
}
/* Handle integer expressions */
intn = yasm_expr_get_intnum(&value->abs, calc_bc_dist);
if (!intn) {
- yasm__error(bc->line, N_("expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("expression too complex"));
return -1;
}
}
dist = rel_prevbc->offset + rel_prevbc->len;
if (dist < bc->offset) {
outval = yasm_intnum_create_uint(bc->offset - dist);
- yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL, bc->line);
+ yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL);
} else {
dist -= bc->offset;
outval = yasm_intnum_create_uint(dist);
if (value->rshift > 0) {
/*@only@*/ yasm_intnum *shamt =
yasm_intnum_create_uint((unsigned long)value->rshift);
- yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt, bc->line);
+ yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt);
yasm_intnum_destroy(shamt);
}
/* Add in absolute portion */
if (intn)
- yasm_intnum_calc(outval, YASM_EXPR_ADD, intn, bc->line);
+ yasm_intnum_calc(outval, YASM_EXPR_ADD, intn);
/* Output! */
if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize,
- shift, bc, warn, bc->line))
+ shift, bc, warn))
retval = -1;
yasm_intnum_destroy(outval);
} else if (intn) {
/* Output just absolute portion */
if (yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize,
- shift, bc, warn, bc->line))
+ shift, bc, warn))
retval = -1;
} else {
/* No absolute or relative portions: output 0 */
outval = yasm_intnum_create_uint(0);
if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize,
- shift, bc, warn, bc->line))
+ shift, bc, warn))
retval = -1;
yasm_intnum_destroy(outval);
}
static int
lc3b_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
unsigned char *buf, size_t destsize, size_t valsize,
- size_t shift, int warn, unsigned long line)
+ size_t shift, int warn)
{
- yasm__error(line, N_("LC-3b does not support floating point"));
+ yasm_error_set(YASM_ERROR_FLOATING_POINT,
+ N_("LC-3b does not support floating point"));
return 1;
}
void yasm_lc3b__bc_transform_insn(yasm_bytecode *bc, lc3b_insn *insn);
-void yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
- unsigned long line);
+void yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len);
yasm_arch_insnprefix yasm_lc3b__parse_check_insnprefix
- (yasm_arch *arch, unsigned long data[4], const char *id, size_t id_len,
- unsigned long line);
+ (yasm_arch *arch, unsigned long data[4], const char *id, size_t id_len);
yasm_arch_regtmod yasm_lc3b__parse_check_regtmod
- (yasm_arch *arch, unsigned long *data, const char *id, size_t id_len,
- unsigned long line);
+ (yasm_arch *arch, unsigned long *data, const char *id, size_t id_len);
void yasm_lc3b__finalize_insn
(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
int yasm_lc3b__intnum_tobytes
(yasm_arch *arch, const yasm_intnum *intn, unsigned char *buf,
size_t destsize, size_t valsize, int shift, const yasm_bytecode *bc,
- int warn, unsigned long line);
+ int warn);
#endif
/*@dependent@*/ /*@null@*/ yasm_intnum *num2;
num2 = yasm_expr_get_intnum(&temp, calc_bc_dist);
if (!num2) {
- yasm__error(bc->line, N_("jump target too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("jump target too complex"));
yasm_expr_destroy(temp);
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
- yasm_intnum_calc(num, YASM_EXPR_ADD, num2, bc->line);
+ yasm_intnum_calc(num, YASM_EXPR_ADD, num2);
yasm_expr_destroy(temp);
}
rel -= 2;
/* 9-bit signed, word-multiple displacement */
if (rel < -512 || rel > 511) {
- yasm__error(bc->line, N_("target out of range"));
+ yasm_error_set(YASM_ERROR_OVERFLOW, N_("target out of range"));
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
return YASM_BC_RESOLVE_MIN_LEN;
int
yasm_lc3b__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
unsigned char *buf, size_t destsize, size_t valsize,
- int shift, const yasm_bytecode *bc, int warn,
- unsigned long line)
+ int shift, const yasm_bytecode *bc, int warn)
{
/* Write value out. */
- yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn,
- line);
+ yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn);
return 0;
}
if (!found) {
/* Didn't find a matching one */
- yasm__error(bc->line,
- N_("invalid combination of opcode and operands"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("invalid combination of opcode and operands"));
return;
}
case YASM_INSN__OPERAND_IMM:
if (yasm_value_finalize_expr(&insn->imm,
op->data.val))
- yasm__error(bc->line,
- N_("immediate expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("immediate expression too complex"));
break;
case YASM_INSN__OPERAND_REG:
if (yasm_value_finalize_expr(&insn->imm,
insn->origin_prevbc = prev_bc;
if (insn->imm.seg_of || insn->imm.rshift
|| insn->imm.curpos_rel)
- yasm__error(bc->line, N_("invalid jump target"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("invalid jump target"));
insn->imm.curpos_rel = 1;
}
}
#define YYFILL(n) (void)(n)
void
-yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
- unsigned long line)
+yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len)
{
}
yasm_arch_regtmod
yasm_lc3b__parse_check_regtmod(yasm_arch *arch, unsigned long *data,
- const char *oid, size_t id_len,
- unsigned long line)
+ const char *oid, size_t id_len)
{
const YYCTYPE *id = (const YYCTYPE *)oid;
/*const char *marker;*/
yasm_arch_insnprefix
yasm_lc3b__parse_check_insnprefix(yasm_arch *arch, unsigned long data[4],
- const char *oid, size_t id_len,
- unsigned long line)
+ const char *oid, size_t id_len)
{
const YYCTYPE *id = (const YYCTYPE *)oid;
/*const char *marker;*/
yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- /*@unused@*/ yasm_object *object, unsigned long line)
+ /*@unused@*/ yasm_object *object,
+ /*@unused@*/ unsigned long line)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
yasm_valparam *vp;
(lval == 16 || lval == 32 || lval == 64))
arch_x86->mode_bits = (unsigned char)lval;
else
- yasm__error(line, N_("invalid argument to [%s]"), "BITS");
+ yasm_error_set(YASM_ERROR_VALUE, N_("invalid argument to [%s]"),
+ "BITS");
return 0;
} else
return 1;
case 64:
return (const unsigned char **)fill64;
default:
- yasm_internal_error(N_("Invalid mode_bits in x86_get_fill"));
- /*@notreached@*/
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("Invalid mode_bits in x86_get_fill"));
return NULL;
}
}
case X86_FPUREG:
return 10;
default:
- yasm_internal_error(N_("unknown register size"));
+ yasm_error_set(YASM_ERROR_VALUE, N_("unknown register size"));
}
return 0;
}
return 0;
return reggroup | (regindex & 7);
default:
- yasm_internal_error(N_("bad register group"));
+ yasm_error_set(YASM_ERROR_VALUE, N_("bad register group"));
}
return 0;
}
fprintf(f, "st%d", (int)(reg&0xF));
break;
default:
- yasm_internal_error(N_("unknown register size"));
+ yasm_error_set(YASM_ERROR_VALUE, N_("unknown register size"));
}
}
0xff if unknown */
} x86_effaddr;
-void yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare,
- unsigned long line);
+void yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare);
void yasm_x86__ea_set_disponly(x86_effaddr *x86_ea);
x86_effaddr *yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
void yasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc,
unsigned int addrsize);
void yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc,
- unsigned int prefix,
- unsigned long line);
+ unsigned int prefix);
/* Bytecode types */
typedef struct x86_common {
void yasm_x86__bc_apply_prefixes
(x86_common *common, unsigned char *rex, int num_prefixes,
- unsigned long **prefixes, unsigned long line);
+ unsigned long **prefixes);
/* Check an effective address. Returns 0 if EA was successfully determined,
* 1 if invalid EA, or 2 if indeterminate EA.
int yasm_x86__expr_checkea
(x86_effaddr *x86_ea, unsigned char *addrsize, unsigned int bits,
int address16_op, unsigned char *rex,
- yasm_calc_bc_dist_func calc_bc_dist, unsigned long line);
+ yasm_calc_bc_dist_func calc_bc_dist);
-void yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
- unsigned long line);
+void yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len);
yasm_arch_insnprefix yasm_x86__parse_check_insnprefix
(yasm_arch *arch, /*@out@*/ unsigned long data[4], const char *id,
- size_t id_len, unsigned long line);
+ size_t id_len);
yasm_arch_regtmod yasm_x86__parse_check_regtmod
(yasm_arch *arch, /*@out@*/ unsigned long *data, const char *id,
- size_t id_len, unsigned long line);
+ size_t id_len);
void yasm_x86__finalize_insn
(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
int yasm_x86__floatnum_tobytes
(yasm_arch *arch, const yasm_floatnum *flt, unsigned char *buf,
- size_t destsize, size_t valsize, size_t shift, int warn,
- unsigned long line);
+ size_t destsize, size_t valsize, size_t shift, int warn);
int yasm_x86__intnum_tobytes
(yasm_arch *arch, const yasm_intnum *intn, unsigned char *buf,
size_t destsize, size_t valsize, int shift, const yasm_bytecode *bc,
- int warn, unsigned long line);
+ int warn);
unsigned int yasm_x86__get_reg_size(yasm_arch *arch, unsigned long reg);
#endif
}
void
-yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare, unsigned long line)
+yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare)
{
if (yasm_value_finalize(&x86_ea->ea.disp))
- yasm__error(line, N_("effective address too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("effective address too complex"));
x86_ea->modrm &= 0xC7; /* zero spare/reg bits */
x86_ea->modrm |= (spare << 3) & 0x38; /* plug in provided bits */
}
void
yasm_x86__bc_apply_prefixes(x86_common *common, unsigned char *rex,
- int num_prefixes, unsigned long **prefixes,
- unsigned long line)
+ int num_prefixes, unsigned long **prefixes)
{
int i;
int first = 1;
switch ((x86_parse_insn_prefix)prefixes[i][0]) {
case X86_LOCKREP:
if (common->lockrep_pre != 0)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("multiple LOCK or REP prefixes, using leftmost"));
common->lockrep_pre = (unsigned char)prefixes[i][1];
break;
break;
case X86_REX:
if (!rex)
- yasm__warning(YASM_WARN_GENERAL, line,
- N_("ignoring REX prefix on jump"));
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("ignoring REX prefix on jump"));
else if (*rex == 0xff)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("REX prefix not allowed on this instruction, ignoring"));
else {
if (*rex != 0) {
if (first)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("overriding generated REX prefix"));
else
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("multiple REX prefixes, using leftmost"));
}
/* Here we assume that we can't get this prefix in non
*/
switch (yasm_x86__expr_checkea(&eat, &insn->common.addrsize,
insn->common.mode_bits, insn->postop == X86_POSTOP_ADDRESS16,
- &insn->rex, calc_bc_dist, bc->line)) {
+ &insn->rex, calc_bc_dist)) {
case 1:
yasm_expr_destroy(eat.ea.disp.abs);
/* failed, don't bother checking rest of insn */
if (save) {
/* does a short form exist? */
if (jmp->shortop.len == 0) {
- yasm__error(bc->line, N_("short jump does not exist"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("short jump does not exist"));
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
num2 = yasm_expr_get_intnum(&temp, calc_bc_dist);
if (!num2) {
yasm_expr_destroy(temp);
- yasm__error(bc->line, N_("jump target too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("jump target too complex"));
return YASM_BC_RESOLVE_ERROR |
YASM_BC_RESOLVE_UNKNOWN_LEN;
}
- yasm_intnum_calc(num, YASM_EXPR_ADD, num2, bc->line);
+ yasm_intnum_calc(num, YASM_EXPR_ADD, num2);
yasm_expr_destroy(temp);
}
rel -= jmp->shortop.len+1;
/* short displacement must fit in -128 <= rel <= +127 */
if (rel < -128 || rel > 127) {
- yasm__error(bc->line, N_("short jump out of range"));
+ yasm_error_set(YASM_ERROR_OVERFLOW,
+ N_("short jump out of range"));
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
}
jrtype = JMP_NEAR;
if (save) {
if (jmp->nearop.len == 0) {
- yasm__error(bc->line, N_("near jump does not exist"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("near jump does not exist"));
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
}
num2 = yasm_expr_get_intnum(&temp, calc_bc_dist);
if (!num2) {
yasm_expr_destroy(temp);
- yasm__error(bc->line, N_("jump target too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("jump target too complex"));
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
- yasm_intnum_calc(num, YASM_EXPR_ADD, num2, bc->line);
+ yasm_intnum_calc(num, YASM_EXPR_ADD, num2);
yasm_expr_destroy(temp);
}
if (yasm_x86__expr_checkea
(&eat, &addrsize, insn->common.mode_bits,
insn->postop == X86_POSTOP_ADDRESS16, &insn->rex,
- yasm_common_calc_bc_dist, bc->line))
+ yasm_common_calc_bc_dist))
yasm_internal_error(N_("checkea failed"));
x86_ea->ea.disp.abs = eat.ea.disp.abs;
}
case JMP_NEAR:
/* 2/4 byte relative displacement (depending on operand size) */
if (jmp->nearop.len == 0) {
- yasm__error(bc->line, N_("near jump does not exist"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("near jump does not exist"));
return 1;
}
int
yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
unsigned char *buf, size_t destsize, size_t valsize,
- int shift, const yasm_bytecode *bc, int warn,
- unsigned long line)
+ int shift, const yasm_bytecode *bc, int warn)
{
/* Write value out. */
- yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn,
- line);
+ yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn);
return 0;
}
/*@-unqualifiedtrans@*/
*ep = yasm_expr__level_tree(*ep, 1, 1, indexreg == 0, calc_bc_dist, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
/* Check for WRT rip first */
wrt = yasm_expr_extract_wrt(ep);
case 2:
/* Need to simplify again */
*ep = yasm_expr__level_tree(*ep, 1, 1, indexreg == 0, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
e = *ep;
break;
default:
/*@-nullstate@*/
static int
x86_checkea_calc_displen(x86_effaddr *x86_ea, unsigned int wordsize, int noreg,
- int dispreq, unsigned long line)
+ int dispreq)
{
/*@null@*/ const yasm_intnum *intn = NULL;
long dispval;
/* Byte is not valid override in noreg case; fix it. */
if (noreg) {
x86_ea->ea.disp_len = 0;
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("invalid displacement size; fixed"));
} else
x86_ea->modrm |= 0100;
case 2:
case 4:
if (wordsize != x86_ea->ea.disp_len) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_VALUE,
N_("invalid effective address (displacement size)"));
return 1;
}
/* 2/4 is not valid override in noreg case; fix it. */
if (noreg) {
if (wordsize != x86_ea->ea.disp_len)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("invalid displacement size; fixed"));
x86_ea->ea.disp_len = 0;
} else
int
yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
unsigned int bits, int address16_op, unsigned char *rex,
- yasm_calc_bc_dist_func calc_bc_dist, unsigned long line)
+ yasm_calc_bc_dist_func calc_bc_dist)
{
int retval;
* otherwise illegal. It's also illegal in non-64-bit mode.
*/
if (x86_ea->need_modrm || x86_ea->need_sib) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_VALUE,
N_("invalid effective address (displacement size)"));
return 1;
}
/* We can only do 64-bit addresses in 64-bit mode. */
if (*addrsize == 64 && bits != 64) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("invalid effective address (64-bit in non-64-bit mode)"));
return 1;
}
®3264_data, x86_expr_checkea_get_reg3264,
calc_bc_dist)) {
case 1:
- yasm__error(line, N_("invalid effective address"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("invalid effective address"));
return 1;
case 2:
if (pcrel) {
*/
for (i=0; i<17; i++) {
if (reg3264mult[i] < 0) {
- yasm__error(line, N_("invalid effective address"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("invalid effective address"));
return 1;
}
if (i != indexreg && reg3264mult[i] == 1 &&
*/
for (i=0; i<17; i++)
if (i != basereg && i != indexreg && reg3264mult[i] != 0) {
- yasm__error(line, N_("invalid effective address"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("invalid effective address"));
return 1;
}
if (indexreg != REG3264_NONE && reg3264mult[indexreg] != 1 &&
reg3264mult[indexreg] != 2 && reg3264mult[indexreg] != 4 &&
reg3264mult[indexreg] != 8) {
- yasm__error(line, N_("invalid effective address"));
+ yasm_error_set(YASM_ERROR_VALUE, N_("invalid effective address"));
return 1;
}
* legal.
*/
if (reg3264mult[REG3264_ESP] > 1 || basereg == REG3264_ESP) {
- yasm__error(line, N_("invalid effective address"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("invalid effective address"));
return 1;
}
/* If mult==1 and basereg is not ESP, swap indexreg w/basereg. */
/* RIP is only legal if it's the ONLY register used. */
if (indexreg == REG64_RIP ||
(basereg == REG64_RIP && indexreg != REG3264_NONE)) {
- yasm__error(line, N_("invalid effective address"));
+ yasm_error_set(YASM_ERROR_VALUE, N_("invalid effective address"));
return 1;
}
if (yasm_x86__set_rex_from_reg(rex, &low3,
(unsigned int)(X86_REG64 | basereg),
bits, X86_REX_B)) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("invalid combination of operands and effective address"));
return 1;
}
if (yasm_x86__set_rex_from_reg(rex, &low3, (unsigned int)
(X86_REG64 | basereg), bits,
X86_REX_B)) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("invalid combination of operands and effective address"));
return 1;
}
if (yasm_x86__set_rex_from_reg(rex, &low3, (unsigned int)
(X86_REG64 | indexreg), bits,
X86_REX_X)) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("invalid combination of operands and effective address"));
return 1;
}
/* Calculate displacement length (if possible) */
retval = x86_checkea_calc_displen
(x86_ea, 4, basereg == REG3264_NONE,
- basereg == REG3264_EBP || basereg == REG64_R13, line);
+ basereg == REG3264_EBP || basereg == REG64_R13);
return retval;
} else if (*addrsize == 16 && x86_ea->need_modrm && !x86_ea->valid_modrm) {
static const unsigned char modrm16[16] = {
/* 64-bit mode does not allow 16-bit addresses */
if (bits == 64 && !address16_op) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("16-bit addresses not supported in 64-bit mode"));
return 1;
}
(&x86_ea->ea.disp.abs, (int *)NULL, &pcrel, bits,
®16mult, x86_expr_checkea_get_reg16, calc_bc_dist)) {
case 1:
- yasm__error(line, N_("invalid effective address"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("invalid effective address"));
return 1;
case 2:
if (pcrel) {
/* reg multipliers not 0 or 1 are illegal. */
if (reg16mult.bx & ~1 || reg16mult.si & ~1 || reg16mult.di & ~1 ||
reg16mult.bp & ~1) {
- yasm__error(line, N_("invalid effective address"));
+ yasm_error_set(YASM_ERROR_VALUE, N_("invalid effective address"));
return 1;
}
/* Check the modrm value for invalid combinations. */
if (modrm16[havereg] & 0070) {
- yasm__error(line, N_("invalid effective address"));
+ yasm_error_set(YASM_ERROR_VALUE, N_("invalid effective address"));
return 1;
}
/* Calculate displacement length (if possible) */
retval = x86_checkea_calc_displen
- (x86_ea, 2, havereg == HAVE_NONE, havereg == HAVE_BP, line);
+ (x86_ea, 2, havereg == HAVE_NONE, havereg == HAVE_BP);
return retval;
} else if (!x86_ea->need_modrm && !x86_ea->need_sib) {
/* Special case for MOV MemOffs opcode: displacement but no modrm. */
switch (*addrsize) {
case 64:
if (bits != 64) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("invalid effective address (64-bit in non-64-bit mode)"));
return 1;
}
case 16:
/* 64-bit mode does not allow 16-bit addresses */
if (bits == 64 && !address16_op) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("16-bit addresses not supported in 64-bit mode"));
return 1;
}
int
yasm_x86__floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
unsigned char *buf, size_t destsize, size_t valsize,
- size_t shift, int warn, unsigned long line)
+ size_t shift, int warn)
{
if (!yasm_floatnum_check_size(flt, valsize)) {
- yasm__error(line, N_("invalid floating point constant size"));
+ yasm_error_set(YASM_ERROR_FLOATING_POINT,
+ N_("invalid floating point constant size"));
return 1;
}
- yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn, line);
+ yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn);
return 0;
}
if (yasm_value_finalize_expr(&jmpfar->offset,
yasm_expr_copy(op->data.val))
|| yasm_value_finalize_expr(&jmpfar->segment, op->data.val))
- yasm__error(bc->line, N_("jump target expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("jump target expression too complex"));
jmpfar->segment.seg_of = 1;
break;
case X86_FAR_SEGOFF:
if (!segment)
yasm_internal_error(N_("didn't get SEG:OFF expression in jmpfar"));
if (yasm_value_finalize_expr(&jmpfar->segment, segment))
- yasm__error(bc->line, N_("jump target segment too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("jump target segment too complex"));
if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val))
- yasm__error(bc->line, N_("jump target offset too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("jump target offset too complex"));
break;
default:
yasm_internal_error(N_("didn't get FAR expression in jmpfar"));
}
yasm_x86__bc_apply_prefixes((x86_common *)jmpfar, NULL, num_prefixes,
- prefixes, bc->line);
+ prefixes);
/* Transform the bytecode */
yasm_x86__bc_transform_jmpfar(bc, jmpfar);
jmp = yasm_xmalloc(sizeof(x86_jmp));
x86_finalize_common(&jmp->common, jinfo, mode_bits);
if (yasm_value_finalize_expr(&jmp->target, op->data.val))
- yasm__error(bc->line, N_("jump target expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("jump target expression too complex"));
if (jmp->target.seg_of || jmp->target.rshift || jmp->target.curpos_rel)
- yasm__error(bc->line, N_("invalid jump target"));
+ yasm_error_set(YASM_ERROR_VALUE, N_("invalid jump target"));
jmp->target.curpos_rel = 1;
/* Need to save jump origin for relative jumps. */
}
if ((jmp->op_sel == JMP_SHORT_FORCED) && (jmp->nearop.len == 0))
- yasm__error(bc->line,
- N_("no SHORT form of that jump instruction exists"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("no SHORT form of that jump instruction exists"));
if ((jmp->op_sel == JMP_NEAR_FORCED) && (jmp->shortop.len == 0))
- yasm__error(bc->line,
- N_("no NEAR form of that jump instruction exists"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("no NEAR form of that jump instruction exists"));
if (jmp->op_sel == JMP_NONE) {
if (jmp->nearop.len == 0)
}
yasm_x86__bc_apply_prefixes((x86_common *)jmp, NULL, num_prefixes,
- prefixes, bc->line);
+ prefixes);
/* Transform the bytecode */
yasm_x86__bc_transform_jmp(bc, jmp);
* of 3 operands.
*/
if (num_operands > 3) {
- yasm__error(bc->line, N_("too many operands"));
+ yasm_error_set(YASM_ERROR_TYPE, N_("too many operands"));
return;
}
ops[0] = ops[1] = ops[2] = ops[3] = NULL;
if (!op->deref && (op->type == YASM_INSN__OPERAND_REG
|| (op->type == YASM_INSN__OPERAND_MEMORY
&& op->data.ea->strong)))
- yasm__warning(YASM_WARN_GENERAL, bc->line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("indirect call without `*'"));
if (!op->deref && op->type == YASM_INSN__OPERAND_MEMORY
&& !op->data.ea->strong) {
* actually an immediate for the purposes of relative jumps.
*/
if (op->data.ea->segreg != 0)
- yasm__warning(YASM_WARN_GENERAL, bc->line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("skipping prefixes on this instruction"));
imm = op->data.ea->disp.abs;
op->data.ea->disp.abs = NULL;
if (!found) {
/* Didn't find a matching one */
- yasm__error(bc->line,
- N_("invalid combination of opcode and operands"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("invalid combination of opcode and operands"));
return;
}
switch ((int)((info->modifiers & MOD_ExtIndex_MASK)
>> MOD_ExtIndex_SHIFT)) {
case 0:
- yasm__error(bc->line, N_("mismatch in operand sizes"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("mismatch in operand sizes"));
break;
case 1:
- yasm__error(bc->line, N_("operand size not specified"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("operand size not specified"));
break;
default:
yasm_internal_error(N_("unrecognized x86 ext mod index"));
else if (op->type == YASM_INSN__OPERAND_REG) {
if (yasm_x86__set_rex_from_reg(&insn->rex, &spare,
op->data.reg, mode_bits, X86_REX_R)) {
- yasm__error(bc->line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("invalid combination of opcode and operands"));
return;
}
unsigned char opadd;
if (yasm_x86__set_rex_from_reg(&insn->rex, &opadd,
op->data.reg, mode_bits, X86_REX_B)) {
- yasm__error(bc->line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("invalid combination of opcode and operands"));
return;
}
unsigned char opadd;
if (yasm_x86__set_rex_from_reg(&insn->rex, &opadd,
op->data.reg, mode_bits, X86_REX_B)) {
- yasm__error(bc->line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("invalid combination of opcode and operands"));
return;
}
if (!insn->x86_ea ||
yasm_x86__set_rex_from_reg(&insn->rex, &spare,
op->data.reg, mode_bits, X86_REX_R)) {
- yasm__error(bc->line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("invalid combination of opcode and operands"));
if (insn->x86_ea)
yasm_xfree(insn->x86_ea);
}
if (insn->x86_ea) {
- yasm_x86__ea_init(insn->x86_ea, spare, bc->line);
+ yasm_x86__ea_init(insn->x86_ea, spare);
for (i=0; i<num_segregs; i++)
- yasm_ea_set_segreg(&insn->x86_ea->ea, segregs[i], bc->line);
+ yasm_ea_set_segreg(&insn->x86_ea->ea, segregs[i]);
} else if (num_segregs > 0 && insn->special_prefix == 0) {
if (num_segregs > 1)
- yasm__warning(YASM_WARN_GENERAL, bc->line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("multiple segment overrides, using leftmost"));
insn->special_prefix = segregs[num_segregs-1]>>8;
}
insn->imm = NULL;
yasm_x86__bc_apply_prefixes((x86_common *)insn, &insn->rex, num_prefixes,
- prefixes, bc->line);
+ prefixes);
if (insn->postop == X86_POSTOP_ADDRESS16 && insn->common.addrsize) {
- yasm__warning(YASM_WARN_GENERAL, bc->line,
- N_("address size override ignored"));
+ yasm_warn_set(YASM_WARN_GENERAL, N_("address size override ignored"));
insn->common.addrsize = 0;
}
yasm_arch_insnprefix
yasm_x86__parse_check_insnprefix(yasm_arch *arch, unsigned long data[4],
- const char *id, size_t id_len,
- unsigned long line)
+ const char *id, size_t id_len)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
/*@null@*/ const insnprefix_parse_data *pdata;
unsigned long cpu = pdata->data2;
if ((cpu & CPU_64) && arch_x86->mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("`%s' is an instruction in 64-bit mode"), id);
return YASM_ARCH_NOTINSNPREFIX;
}
if ((cpu & CPU_Not64) && arch_x86->mode_bits == 64) {
- yasm__error(line, N_("`%s' invalid in 64-bit mode"), id);
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("`%s' invalid in 64-bit mode"), id);
data[0] = (unsigned long)not64_insn;
data[1] = NELEMS(not64_insn);
data[2] = CPU_Not64;
unsigned long value = pdata->data2;
if (arch_x86->mode_bits == 64 && type == X86_OPERSIZE && value == 32) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_GENERAL,
N_("Cannot override data size to 32 bits in 64-bit mode"));
return YASM_ARCH_NOTINSNPREFIX;
}
if (arch_x86->mode_bits == 64 && type == X86_ADDRSIZE && value == 16) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_GENERAL,
N_("Cannot override address size to 16 bits in 64-bit mode"));
return YASM_ARCH_NOTINSNPREFIX;
}
if ((type == X86_REX ||
(value == 64 && (type == X86_OPERSIZE || type == X86_ADDRSIZE)))
&& arch_x86->mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("`%s' is a prefix in 64-bit mode"), id);
return YASM_ARCH_NOTINSNPREFIX;
}
}
void
-yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
- unsigned long line)
+yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
/*@null@*/ const cpu_parse_data *pdata;
pdata = cpu_find(lcaseid, cpuid_len);
if (!pdata) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("unrecognized CPU identifier `%s'"), cpuid);
return;
}
yasm_arch_regtmod
yasm_x86__parse_check_regtmod(yasm_arch *arch, unsigned long *data,
- const char *id, size_t id_len, unsigned long line)
+ const char *id, size_t id_len)
{
yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
/*@null@*/ const regtmod_parse_data *pdata;
bits = (pdata->regtmod >> 16) & 0xFF;
if (type == YASM_ARCH_REG && bits != 0 && arch_x86->mode_bits != bits) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("`%s' is a register in %u-bit mode"), id, bits);
return YASM_ARCH_NOTREGTMOD;
}
if (type == YASM_ARCH_SEGREG && bits != 0 && arch_x86->mode_bits == bits) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("`%s' segment register ignored in %u-bit mode"), id,
bits);
}
}
static void
-cv_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
+cv_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns)
{
yasm_dbgfmt_cv *dbgfmt_cv = (yasm_dbgfmt_cv *)dbgfmt;
- yasm_cv__generate_symline(dbgfmt_cv);
+ yasm_cv__generate_symline(dbgfmt_cv, errwarns);
yasm_cv__generate_type(dbgfmt_cv);
}
yasm_bytecode *yasm_cv__append_bc(yasm_section *sect, yasm_bytecode *bc);
/* Symbol/Line number functions */
-yasm_section *yasm_cv__generate_symline(yasm_dbgfmt_cv *dbgfmt_cv);
+yasm_section *yasm_cv__generate_symline(yasm_dbgfmt_cv *dbgfmt_cv,
+ yasm_errwarns *errwarns);
/* Type functions */
yasm_section *yasm_cv__generate_type(yasm_dbgfmt_cv *dbgfmt_cv);
typedef struct cv_line_info {
yasm_section *debug_symline;
yasm_dbgfmt_cv *dbgfmt_cv;
+ yasm_errwarns *errwarns;
unsigned int num_lineinfos;
STAILQ_HEAD(, cv8_lineinfo) cv8_lineinfos;
/*@null@*/ cv8_lineinfo *cv8_cur_li;
info->cv8_cur_li = NULL;
info->cv8_cur_ls = NULL;
- yasm_section_bcs_traverse(sect, info, cv_generate_line_bc);
+ yasm_section_bcs_traverse(sect, info->errwarns, info, cv_generate_line_bc);
return 0;
}
}
yasm_section *
-yasm_cv__generate_symline(yasm_dbgfmt_cv *dbgfmt_cv)
+yasm_cv__generate_symline(yasm_dbgfmt_cv *dbgfmt_cv, yasm_errwarns *errwarns)
{
cv_line_info info;
int new;
cv_generate_filename);
info.dbgfmt_cv = dbgfmt_cv;
+ info.errwarns = errwarns;
info.debug_symline = yasm_object_get_general(dbgfmt_cv->object,
".debug$S", 0, 1, 0, 0, &new,
0);
off = 1;
for (i=0; i<dbgfmt_cv->filenames_size; i++) {
if (!dbgfmt_cv->filenames[i].pathname) {
- yasm__error(0, N_("codeview file number %d unassigned"), i+1);
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("codeview file number %d unassigned"), i+1);
+ yasm_errwarn_propagate(errwarns, 0);
continue;
}
bc = cv_append_str(info.debug_symline,
cval = yasm_intnum_create_uint(4);
/* Output "version" if first */
if (head->first) {
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0,
- 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
buf += 4;
}
/* Type contained - 4 bytes */
yasm_intnum_set_uint(cval, head->type);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
buf += 4;
/* Total length of info (following this field) - 4 bytes */
yasm_intnum_set_uint(cval, bc->len);
intn = yasm_common_calc_bc_dist(head->start_prevbc, head->end_prevbc);
- yasm_intnum_calc(intn, YASM_EXPR_SUB, cval, bc->line);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, intn, buf, 4, 32, 0, bc, 0, 0);
+ yasm_intnum_calc(intn, YASM_EXPR_SUB, cval);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, intn, buf, 4, 32, 0, bc, 0);
buf += 4;
yasm_intnum_destroy(intn);
/* Offset in filename string table */
cval = yasm_intnum_create_uint(fi->fn->str_off);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
buf += 4;
/* Checksum type/length */
yasm_intnum_set_uint(cval, 0x0110);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 0);
buf += 2;
/* Checksum */
/* Section length covered by line number info */
cval = yasm_common_calc_bc_dist(yasm_section_bcs_first(li->sect),
yasm_section_bcs_last(li->sect));
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
buf += 4;
/* Offset of source file in info table */
yasm_intnum_set_uint(cval, li->fn->info_off);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
buf += 4;
/* Number of line number pairs */
yasm_intnum_set_uint(cval, li->num_linenums);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
buf += 4;
/* Number of bytes of line number pairs + 12 (no, I don't know why) */
yasm_intnum_set_uint(cval, li->num_linenums*8+12);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
buf += 4;
/* Offset / line number pairs */
/* offset in section */
yasm_intnum_set_uint(cval, ls->pairs[j].offset);
yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc,
- 0, 0);
+ 0);
buf += 4;
/* line number in file */
yasm_intnum_set_uint(cval, ls->pairs[j].line);
yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc,
- 0, 0);
+ 0);
buf += 4;
}
}
/* Total length of record (following this field) - 2 bytes */
cval = yasm_intnum_create_uint(bc->len-2);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 1, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 1);
buf += 2;
/* Type contained - 2 bytes */
yasm_intnum_set_uint(cval, cvs->type);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 0);
buf += 2;
while (*ch) {
case 'h':
yasm_intnum_set_uint(cval, cvs->args[arg++].i);
yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0,
- bc, 0, 0);
+ bc, 0);
buf += 2;
break;
case 'w':
yasm_intnum_set_uint(cval, cvs->args[arg++].i);
yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0,
- bc, 0, 0);
+ bc, 0);
buf += 4;
break;
case 'Y':
case 'T':
yasm_intnum_set_uint(cval, cvs->args[arg++].i);
yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0,
- bc, 0, 0);
+ bc, 0);
buf += 4; /* XXX: will be 2 in CV4 */
break;
case 'S':
/* leaf type */
yasm_intnum_set_uint(cval, leaf->type);
- yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0);
buf += 2;
while (*ch) {
break;
case 'h':
yasm_intnum_set_uint(cval, leaf->args[arg++].i);
- yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0);
buf += 2;
break;
case 'w':
yasm_intnum_set_uint(cval, leaf->args[arg++].i);
- yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0);
buf += 4;
break;
case 'L':
case 'T':
yasm_intnum_set_uint(cval,
((const cv_type *)leaf->args[arg++].p)->indx);
- yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0, 0);
+ yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0);
buf += 4; /* XXX: will be 2 in CV4 */
break;
case 'S':
cval = yasm_intnum_create_uint(4); /* version */
if (type->indx == CV_FIRST_NONPRIM) {
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 1,
- 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 1);
buf += 4;
reclen -= 4;
}
/* Total length of record (following this field) - 2 bytes */
yasm_intnum_set_uint(cval, reclen);
- yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 1, 0);
+ yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 1);
buf += 2;
/* Leaves */
info.debug_aranges = debug_aranges;
info.dbgfmt_dwarf2 = dbgfmt_dwarf2;
+
yasm_object_sections_traverse(dbgfmt_dwarf2->object, (void *)&info,
dwarf2_generate_aranges_section);
}
static void
-dwarf2_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
+dwarf2_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns)
{
yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)dbgfmt;
size_t num_line_sections;
/* If we don't have any .file directives, generate line information
* based on the asm source.
*/
- debug_line = yasm_dwarf2__generate_line(dbgfmt_dwarf2,
+ debug_line = yasm_dwarf2__generate_line(dbgfmt_dwarf2, errwarns,
dbgfmt_dwarf2->filenames_size == 0,
&main_code, &num_line_sections);
/* Total length of aranges info (following this field) */
cval = yasm_intnum_create_uint(dbgfmt_dwarf2->sizeof_offset);
intn = yasm_common_calc_bc_dist(head->start_prevbc, head->end_prevbc);
- yasm_intnum_calc(intn, YASM_EXPR_SUB, cval, bc->line);
+ yasm_intnum_calc(intn, YASM_EXPR_SUB, cval);
yasm_arch_intnum_tobytes(dbgfmt_dwarf2->arch, intn, buf,
dbgfmt_dwarf2->sizeof_offset,
- dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0, 0);
+ dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0);
buf += dbgfmt_dwarf2->sizeof_offset;
yasm_intnum_destroy(intn);
/* DWARF version */
yasm_intnum_set_uint(cval, 2);
- yasm_arch_intnum_tobytes(dbgfmt_dwarf2->arch, cval, buf, 2, 16, 0, bc, 0,
- 0);
+ yasm_arch_intnum_tobytes(dbgfmt_dwarf2->arch, cval, buf, 2, 16, 0, bc, 0);
buf += 2;
/* Pointer to another debug section */
/* Line number functions */
yasm_section *yasm_dwarf2__generate_line
- (yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, int asm_source,
- /*@out@*/ yasm_section **main_code, /*@out@*/ size_t *num_line_sections);
+ (yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, yasm_errwarns *errwarns,
+ int asm_source, /*@out@*/ yasm_section **main_code,
+ /*@out@*/ size_t *num_line_sections);
int yasm_dwarf2__line_directive
(yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, const char *name, yasm_section *sect,
yasm_valparamhead *valparams, unsigned long line);
/* Set the starting address for the section */
if (!loc->sym) {
/* shouldn't happen! */
- yasm__error(loc->line, N_("could not find label prior to loc"));
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("could not find label prior to loc"));
return 1;
}
dwarf2_dbgfmt_append_line_ext_op(debug_line, DW_LNE_set_address,
typedef struct dwarf2_line_info {
yasm_section *debug_line; /* section to which line number info goes */
yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
+ yasm_errwarns *errwarns;
/* Generate based on bytecodes (1) or locs (0)? Use bytecodes if we're
* generating line numbers for the actual assembly source file.
}
}
- yasm_section_bcs_traverse(sect, &bcinfo, dwarf2_generate_line_bc);
+ yasm_section_bcs_traverse(sect, info->errwarns, &bcinfo,
+ dwarf2_generate_line_bc);
} else {
/*@null@*/ dwarf2_loc *loc;
}
yasm_section *
-yasm_dwarf2__generate_line(yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, int asm_source,
+yasm_dwarf2__generate_line(yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2,
+ yasm_errwarns *errwarns, int asm_source,
/*@out@*/ yasm_section **main_code,
/*@out@*/ size_t *num_line_sections)
{
/* filename list */
for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
if (!dbgfmt_dwarf2->filenames[i].filename) {
- yasm__error(0, N_("dwarf2 file number %d unassigned"), i+1);
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("dwarf2 file number %d unassigned"), i+1);
+ yasm_errwarn_propagate(errwarns, 0);
continue;
}
sppbc->len += strlen(dbgfmt_dwarf2->filenames[i].filename) + 1 +
dbgfmt_dwarf2->sizeof_offset);
yasm_arch_intnum_tobytes(dbgfmt_dwarf2->arch, cval, buf,
dbgfmt_dwarf2->sizeof_offset,
- dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0, 0);
+ dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0);
buf += dbgfmt_dwarf2->sizeof_offset;
YASM_WRITE_8(buf, dbgfmt_dwarf2->min_insn_len); /* minimum_instr_len */
/* File number (required) */
yasm_valparam *vp = yasm_vps_first(valparams);
if (!vp || !vp->param) {
- yasm__error(line, N_("file number required"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required"));
yasm_xfree(loc);
return 0;
}
intn = yasm_expr_get_intnum(&vp->param, NULL);
if (!intn) {
- yasm__error(line, N_("file number is not a constant"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("file number is not a constant"));
yasm_xfree(loc);
return 0;
}
if (yasm_intnum_sign(intn) != 1) {
- yasm__error(line, N_("file number less than one"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("file number less than one"));
yasm_xfree(loc);
return 0;
}
/* Line number (required) */
vp = yasm_vps_next(vp);
if (!vp || !vp->param) {
- yasm__error(line, N_("line number required"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("line number required"));
yasm_xfree(loc);
return 0;
}
intn = yasm_expr_get_intnum(&vp->param, NULL);
if (!intn) {
- yasm__error(line, N_("file number is not a constant"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("file number is not a constant"));
yasm_xfree(loc);
return 0;
}
if (vp && vp->param) {
intn = yasm_expr_get_intnum(&vp->param, NULL);
if (!intn) {
- yasm__error(line, N_("column number is not a constant"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("column number is not a constant"));
yasm_xfree(loc);
return 0;
}
loc->epilogue_begin = 1;
else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) {
if (!vp->param) {
- yasm__error(line, N_("is_stmt requires value"));
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("is_stmt requires value"));
yasm_xfree(loc);
return 0;
}
intn = yasm_expr_get_intnum(&vp->param, NULL);
if (!intn) {
- yasm__error(line, N_("is_stmt value is not a constant"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("is_stmt value is not a constant"));
yasm_xfree(loc);
return 0;
}
else if (yasm_intnum_is_pos1(intn))
loc->is_stmt = IS_STMT_CLEAR;
else {
- yasm__error(line, N_("is_stmt value not 0 or 1"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("is_stmt value not 0 or 1"));
yasm_xfree(loc);
return 0;
}
} else if (yasm__strcasecmp(vp->val, "isa") == 0) {
if (!vp->param) {
- yasm__error(line, N_("isa requires value"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("isa requires value"));
yasm_xfree(loc);
return 0;
}
intn = yasm_expr_get_intnum(&vp->param, NULL);
if (!intn) {
- yasm__error(line, N_("isa value is not a constant"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("isa value is not a constant"));
yasm_xfree(loc);
return 0;
}
if (yasm_intnum_sign(intn) < 0) {
- yasm__error(line, N_("isa value less than zero"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("isa value less than zero"));
yasm_xfree(loc);
return 0;
}
loc->isa_change = 1;
loc->isa = yasm_intnum_get_uint(intn);
} else
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("unrecognized loc option `%s'"), vp->val);
}
/* Otherwise.. first vp is the file number */
file_intn = yasm_expr_get_intnum(&vp->param, NULL);
if (!file_intn) {
- yasm__error(line, N_("file number is not a constant"));
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("file number is not a constant"));
return 0;
}
filenum = (size_t)yasm_intnum_get_uint(file_intn);
vp = yasm_vps_next(vp);
if (!vp || !vp->val) {
- yasm__error(line, N_("file number given but no filename"));
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("file number given but no filename"));
return 0;
}
}
static void
-null_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
+null_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns)
{
}
yasm_bytecode *basebc; /* base bytecode from which to track SLINEs */
yasm_dbgfmt_stabs *dbgfmt_stabs;
+ yasm_errwarns *errwarns;
} stabs_info;
typedef struct {
/* handle first (pseudo) bc separately */
stabs_dbgfmt_generate_n_fun(d, yasm_section_bcs_first(sect));
- yasm_section_bcs_traverse(sect, d, stabs_dbgfmt_generate_bcs);
+ yasm_section_bcs_traverse(sect, info->errwarns, d,
+ stabs_dbgfmt_generate_bcs);
if (yasm__strcasecmp(sectname, ".text")==0) {
/* Close out last function by appending a null SO stab after last bc */
}
static void
-stabs_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
+stabs_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns)
{
yasm_dbgfmt_stabs *dbgfmt_stabs = (yasm_dbgfmt_stabs *)dbgfmt;
stabs_info info;
return;
info.dbgfmt_stabs = dbgfmt_stabs;
+ info.errwarns = errwarns;
info.lastline = 0;
info.stabcount = 0;
info.stab = yasm_object_get_general(dbgfmt_stabs->object, ".stab", 0, 4, 0,
0, &new, 0);
if (!new) {
yasm_bytecode *last = yasm_section_bcs_last(info.stab);
- if (last == NULL)
- yasm__error(yasm_section_bcs_first(info.stab)->line,
+ if (last == NULL) {
+ yasm_error_set(YASM_ERROR_GENERAL,
N_("stabs debugging conflicts with user-defined section .stab"));
- else
- yasm__warning(YASM_WARN_GENERAL, 0,
+ yasm_errwarn_propagate(errwarns,
+ yasm_section_bcs_first(info.stab)->line);
+ } else {
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("stabs debugging overrides empty section .stab"));
+ yasm_errwarn_propagate(errwarns, 0);
+ }
}
info.stabstr = yasm_object_get_general(dbgfmt_stabs->object, ".stabstr", 0,
1, 0, 0, &new, 0);
if (!new) {
yasm_bytecode *last = yasm_section_bcs_last(info.stabstr);
- if (last == NULL)
- yasm__error(yasm_section_bcs_first(info.stabstr)->line,
+ if (last == NULL) {
+ yasm_error_set(YASM_ERROR_GENERAL,
N_("stabs debugging conflicts with user-defined section .stabstr"));
- else
- yasm__warning(YASM_WARN_GENERAL, 0,
+ yasm_errwarn_propagate(errwarns,
+ yasm_section_bcs_first(info.stab)->line);
+ } else {
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("stabs debugging overrides empty section .stabstr"));
+ yasm_errwarn_propagate(errwarns, 0);
+ }
}
intn = yasm_expr_get_intnum(&value->abs, NULL);
if (intn)
return yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize,
- valsize, shift, bc, 0, bc->line);
+ valsize, shift, bc, 0);
else {
- yasm__error(bc->line, N_("relocation too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("relocation too complex"));
return 1;
}
} else {
int retval;
intn = yasm_intnum_create_uint(0);
retval = yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize,
- valsize, shift, bc, 0, bc->line);
+ valsize, shift, bc, 0);
yasm_intnum_destroy(intn);
return retval;
}
/* Simplify absolute portion of value, transforming symrecs */
if (value->abs)
value->abs = yasm_expr__level_tree
- (value->abs, 1, 1, 1, NULL, bin_objfmt_expr_xform, NULL, NULL,
- NULL);
+ (value->abs, 1, 1, 1, NULL, bin_objfmt_expr_xform, NULL, NULL);
/* Output */
switch (yasm_value_output_basic(value, buf, destsize, valsize, shift,
}
/* Couldn't output, assume it contains an external reference. */
- yasm__error(bc->line,
+ yasm_error_set(YASM_ERROR_GENERAL,
N_("binary object format does not support external references"));
return 1;
}
/* Warn that gaps are converted to 0 and write out the 0's. */
if (gap) {
unsigned long left;
- yasm__warning(YASM_WARN_UNINIT_CONTENTS, bc->line,
+ yasm_warn_set(YASM_WARN_UNINIT_CONTENTS,
N_("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
static void
bin_objfmt_output(yasm_objfmt *objfmt, FILE *f, /*@unused@*/ int all_syms,
- /*@unused@*/ yasm_dbgfmt *df)
+ /*@unused@*/ yasm_dbgfmt *df, yasm_errwarns *errwarns)
{
yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt;
/*@observer@*/ /*@null@*/ yasm_section *text, *data, *bss, *prevsect;
assert(startexpr != NULL);
startnum = yasm_expr_get_intnum(&startexpr, NULL);
if (!startnum) {
- yasm__error(startexpr->line, N_("ORG expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("ORG expression too complex"));
+ yasm_errwarn_propagate(errwarns, startexpr->line);
return;
}
start = yasm_intnum_get_uint(startnum);
/* Output .text first. */
info.sect = text;
info.start = textstart;
- yasm_section_bcs_traverse(text, &info, bin_objfmt_output_bytecode);
+ yasm_section_bcs_traverse(text, errwarns, &info,
+ bin_objfmt_output_bytecode);
/* If .data is present, output it */
if (data) {
/* Output .data bytecodes */
info.sect = data;
info.start = datastart;
- yasm_section_bcs_traverse(data, &info, bin_objfmt_output_bytecode);
+ yasm_section_bcs_traverse(data, errwarns,
+ &info, bin_objfmt_output_bytecode);
}
/* If .bss is present, check it for non-reserve bytecodes */
resonly = 1;
} else {
/* other section names not recognized. */
- yasm__error(line, N_("segment name `%s' not recognized"),
- sectname);
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("segment name `%s' not recognized"), sectname);
return NULL;
}
/* Check for ALIGN qualifier */
while ((vp = yasm_vps_next(vp))) {
if (!vp->val) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized numeric qualifier"));
continue;
}
/*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
if (strcmp(sectname, ".text") == 0) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_GENERAL,
N_("cannot specify an alignment to the `%s' section"),
sectname);
return NULL;
align_expr = yasm_expr_get_intnum(&vp->param, NULL);
if (!align_expr) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_VALUE,
N_("argument to `%s' is not a power of two"),
vp->val);
return NULL;
/* Alignments must be a power of two. */
if ((align & (align - 1)) != 0) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_VALUE,
N_("argument to `%s' is not a power of two"),
vp->val);
return NULL;
yasm_section_set_default(retval, 0);
yasm_section_set_align(retval, align, line);
} else if (have_align)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("alignment value ignored on section redeclaration"));
return retval;
yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt;
yasm_symrec *sym;
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("binary object format does not support extern variables"));
sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_EXTERN, line);
yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt;
yasm_symrec *sym;
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("binary object format does not support global variables"));
sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_GLOBAL, line);
yasm_symrec *sym;
yasm_expr_destroy(size);
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_TYPE,
N_("binary object format does not support common variables"));
sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_COMMON, line);
}
if (!start) {
- yasm__error(line, N_("argument to ORG must be expression"));
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("argument to ORG must be expression"));
return 0;
}
typedef struct coff_objfmt_output_info {
yasm_objfmt_coff *objfmt_coff;
+ yasm_errwarns *errwarns;
/*@dependent@*/ FILE *f;
/*@only@*/ unsigned char *buf;
yasm_section *sect;
if (value->rshift > 0
|| (value->seg_of && (value->wrt || value->curpos_rel))
|| (value->section_rel && (value->wrt || value->curpos_rel))) {
- yasm__error(bc->line, N_("coff: relocation too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("coff: relocation too complex"));
return 1;
}
/*@dependent@*/ /*@null@*/ yasm_bytecode *rel_precbc, *wrt_precbc;
if (!yasm_symrec_get_label(sym, &rel_precbc)
|| !yasm_symrec_get_label(value->wrt, &wrt_precbc)) {
- yasm__error(bc->line, N_("coff: wrt expression too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("coff: wrt expression too complex"));
return 1;
}
dist = yasm_common_calc_bc_dist(wrt_precbc, rel_precbc);
if (!dist) {
- yasm__error(bc->line, N_("coff: cannot wrt across sections"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("coff: cannot wrt across sections"));
return 1;
}
sym = value->wrt;
common_size = yasm_expr_get_intnum(&csymd->size,
yasm_common_calc_bc_dist);
if (!common_size) {
- yasm__error(bc->line, N_("coff: common size too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("coff: common size too complex"));
return 1;
}
if (yasm_intnum_sign(common_size) < 0) {
- yasm__error(bc->line, N_("coff: common size is negative"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("coff: common size is negative"));
return 1;
}
if (valsize == 32)
reloc->type = COFF_RELOC_I386_REL32;
else {
- yasm__error(bc->line, N_("coff: invalid relocation size"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("coff: invalid relocation size"));
return 1;
}
} else if (objfmt_coff->machine == COFF_MACHINE_AMD64) {
if (valsize != 32) {
- yasm__error(bc->line, N_("coff: invalid relocation size"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("coff: invalid relocation size"));
return 1;
}
if (!value->ip_rel)
reloc->type = COFF_RELOC_AMD64_REL32_5;
break;
default:
- yasm__error(bc->line,
- N_("coff: invalid relocation size"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("coff: invalid relocation size"));
return 1;
}
} else
} else if (valsize == 64)
reloc->type = COFF_RELOC_AMD64_ADDR64;
else {
- yasm__error(bc->line, N_("coff: invalid relocation size"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("coff: invalid relocation size"));
return 1;
}
} else
intn = yasm_intnum_create_uint(intn_val-intn_minus);
else {
intn = yasm_intnum_create_uint(intn_minus-intn_val);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, bc->line);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
}
if (value->abs) {
yasm_intnum *intn2 = yasm_expr_get_intnum(&value->abs, NULL);
if (!intn2) {
- yasm__error(bc->line, N_("coff: relocation too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("coff: relocation too complex"));
yasm_intnum_destroy(intn);
if (dist)
yasm_intnum_destroy(dist);
return 1;
}
- yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2, bc->line);
+ yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2);
}
if (dist) {
- yasm_intnum_calc(intn, YASM_EXPR_ADD, dist, bc->line);
+ yasm_intnum_calc(intn, YASM_EXPR_ADD, dist);
yasm_intnum_destroy(dist);
}
retval = yasm_arch_intnum_tobytes(objfmt_coff->arch, intn, buf, destsize,
- valsize, shift, bc, warn, bc->line);
+ valsize, shift, bc, warn);
yasm_intnum_destroy(intn);
return retval;
}
/* Warn that gaps are converted to 0 and write out the 0's. */
if (gap) {
unsigned long left;
- yasm__warning(YASM_WARN_UNINIT_CONTENTS, bc->line,
+ yasm_warn_set(YASM_WARN_UNINIT_CONTENTS,
N_("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
info->sect = sect;
info->csd = csd;
- yasm_section_bcs_traverse(sect, info, coff_objfmt_output_bytecode);
+ yasm_section_bcs_traverse(sect, info->errwarns, info,
+ coff_objfmt_output_bytecode);
/* Sanity check final section size */
if (csd->size != (last->offset + last->len))
yasm_internal_error(
N_("coff: no symbol data for relocated symbol"));
- yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0, 0);
+ yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0);
localbuf += 4; /* address of relocation */
YASM_WRITE_32_L(localbuf, csymd->index); /* relocated symbol */
YASM_WRITE_16_L(localbuf, reloc->type); /* type of relocation */
YASM_WRITE_32_L(localbuf, csd->relptr); /* file ptr to relocs */
YASM_WRITE_32_L(localbuf, 0); /* file ptr to line nums */
if (csd->nreloc >= 64*1024) {
- yasm__warning(YASM_WARN_GENERAL, 0,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("too many relocations in section `%s'"),
yasm_section_get_name(sect));
+ yasm_errwarn_propagate(info->errwarns, 0);
YASM_WRITE_16_L(localbuf, 0xFFFF); /* max out */
} else
YASM_WRITE_16_L(localbuf, csd->nreloc); /* num of relocation entries */
abs_start = yasm_expr_copy(yasm_section_get_start(sect));
intn = yasm_expr_get_intnum(&abs_start,
yasm_common_calc_bc_dist);
- if (!intn)
- yasm__error(abs_start->line,
+ if (!intn) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("absolute section start not an integer expression"));
- else
+ yasm_errwarn_propagate(info->errwarns,
+ abs_start->line);
+ } else
value = yasm_intnum_get_uint(intn);
yasm_expr_destroy(abs_start);
intn = yasm_expr_get_intnum(&equ_val_copy,
yasm_common_calc_bc_dist);
if (!intn) {
- if (vis & YASM_SYM_GLOBAL)
- yasm__error(equ_val->line,
+ if (vis & YASM_SYM_GLOBAL) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("global EQU value not an integer expression"));
+ yasm_errwarn_propagate(info->errwarns, equ_val->line);
+ }
} else
value = yasm_intnum_get_uint(intn);
yasm_expr_destroy(equ_val_copy);
if (vis & YASM_SYM_COMMON) {
intn = yasm_expr_get_intnum(&csymd->size,
yasm_common_calc_bc_dist);
- if (!intn)
- yasm__error(csymd->size->line,
+ if (!intn) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("COMMON data size not an integer expression"));
- else
+ yasm_errwarn_propagate(info->errwarns, csymd->size->line);
+ } else
value = yasm_intnum_get_uint(intn);
scnum = 0;
}
}
static void
-coff_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df)
+coff_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df,
+ yasm_errwarns *errwarns)
{
yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt;
coff_objfmt_output_info info;
info.strtab_offset = 4;
info.objfmt_coff = objfmt_coff;
+ info.errwarns = errwarns;
info.f = f;
info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
* files via "/nnnn" (where nnnn is decimal offset into string table),
* so only warn for regular COFF.
*/
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("COFF section names limited to 8 characters: truncating"));
sectname[8] = '\0';
}
flags |= COFF_STYP_READ;
align = 8;
} else
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Standard COFF does not support read-only data sections"));
} else if (strcmp(sectname, ".drectve") == 0) {
flags = COFF_STYP_INFO;
win32warn = 0;
if (!vp->val) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized numeric qualifier"));
continue;
}
readonly = 0;
break;
default:
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("unrecognized section attribute: `%c'"),
vp->val[i]);
}
/*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
align_expr = yasm_expr_get_intnum(&vp->param, NULL);
if (!align_expr) {
- yasm__error(line,
- N_("argument to `%s' is not a power of two"),
- vp->val);
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("argument to `%s' is not a power of two"),
+ vp->val);
return NULL;
}
align = yasm_intnum_get_uint(align_expr);
/* Alignments must be a power of two. */
if ((align & (align - 1)) != 0) {
- yasm__error(line,
- N_("argument to `%s' is not a power of two"),
- vp->val);
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("argument to `%s' is not a power of two"),
+ vp->val);
return NULL;
}
/* Check to see if alignment is supported size */
if (align > 8192) {
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_VALUE,
N_("Win32 does not support alignments > 8192"));
return NULL;
}
} else
win32warn = 1;
} else
- yasm__warning(YASM_WARN_GENERAL, line,
- N_("Unrecognized qualifier `%s'"), vp->val);
+ yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized qualifier `%s'"),
+ vp->val);
if (win32warn)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Standard COFF does not support qualifier `%s'"), vp->val);
}
csd->flags2 = flags2;
yasm_section_set_align(retval, align, line);
} else if (flags_override)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("section flags ignored on section redeclaration"));
return retval;
}
if (vp->val)
yasm_symtab_use(objfmt_coff->symtab, vp->val, line);
else {
- yasm__error(line, N_("argument to EXPORT must be symbol name"));
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("argument to EXPORT must be symbol name"));
return 0;
}
}
static void
-dbg_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df)
+dbg_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df,
+ yasm_errwarns *errwarns)
{
yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt;
char buf[1024];
#define YASM_WRITE_32I_L(p, i) do {\
assert(yasm_intnum_check_size(i, 32, 0, 2)); \
- yasm_intnum_get_sized(i, p, 4, 32, 0, 0, 0, 0); \
+ yasm_intnum_get_sized(i, p, 4, 32, 0, 0, 0); \
p += 4; } while (0)
#define YASM_WRITE_64I_L(p, i) do {\
assert(yasm_intnum_check_size(i, 64, 0, 2)); \
- yasm_intnum_get_sized(i, p, 8, 64, 0, 0, 0, 0); \
+ yasm_intnum_get_sized(i, p, 8, 64, 0, 0, 0); \
p += 8; } while (0)
#define YASM_WRITE_64C_L(p, hi, lo) do {\
typedef struct {
yasm_objfmt_elf *objfmt_elf;
+ yasm_errwarns *errwarns;
FILE *f;
elf_secthead *shead;
yasm_section *sect;
pos = ftell(f);
if (pos == -1) {
- yasm__error(0, N_("could not get file position on output file"));
+ yasm_error_set(YASM_ERROR_IO,
+ N_("could not get file position on output file"));
return -1;
}
delta = align - (pos & (align-1));
if (delta != align) {
pos += delta;
if (fseek(f, pos, SEEK_SET) < 0) {
- yasm__error(0, N_("could not set file position on output file"));
+ yasm_error_set(YASM_ERROR_IO,
+ N_("could not set file position on output file"));
return -1;
}
}
reloc = elf_reloc_entry_create(sym, NULL,
yasm_intnum_create_uint(bc->offset), 0, valsize);
if (reloc == NULL) {
- yasm__error(bc->line, N_("elf: invalid relocation size"));
+ yasm_error_set(YASM_ERROR_TYPE, N_("elf: invalid relocation size"));
return 1;
}
/* allocate .rel[a] sections on a need-basis */
zero = yasm_intnum_create_uint(0);
elf_handle_reloc_addend(zero, reloc);
retval = yasm_arch_intnum_tobytes(info->objfmt_elf->arch, zero, buf,
- destsize, valsize, 0, bc, warn,
- bc->line);
+ destsize, valsize, 0, bc, warn);
yasm_intnum_destroy(zero);
return retval;
}
/* Handle other expressions, with relocation if necessary */
if (value->seg_of || value->section_rel || value->rshift > 0) {
- yasm__error(bc->line, N_("elf: relocation too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("elf: relocation too complex"));
return 1;
}
yasm_intnum_create_uint(bc->offset + offset), value->curpos_rel,
valsize);
if (reloc == NULL) {
- yasm__error(bc->line, N_("elf: invalid relocation (WRT or size)"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("elf: invalid relocation (WRT or size)"));
return 1;
}
/* allocate .rel[a] sections on a need-basis */
if (value->abs) {
yasm_intnum *intn2 = yasm_expr_get_intnum(&value->abs, NULL);
if (!intn2) {
- yasm__error(bc->line, N_("elf: relocation too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("elf: relocation too complex"));
yasm_intnum_destroy(intn);
return 1;
}
- yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2, bc->line);
+ yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2);
}
if (reloc)
elf_handle_reloc_addend(intn, reloc);
retval = yasm_arch_intnum_tobytes(info->objfmt_elf->arch, intn, buf,
- destsize, valsize, shift, bc, warn,
- bc->line);
+ destsize, valsize, shift, bc, warn);
yasm_intnum_destroy(intn);
return retval;
}
yasm_intnum *bcsize = yasm_intnum_create_uint(size);
yasm_intnum *mult = yasm_intnum_create_uint(multiple);
- yasm_intnum_calc(bcsize, YASM_EXPR_MUL, mult, 0);
+ yasm_intnum_calc(bcsize, YASM_EXPR_MUL, mult);
elf_secthead_add_size(info->shead, bcsize);
yasm_intnum_destroy(bcsize);
/* Warn that gaps are converted to 0 and write out the 0's. */
if (gap) {
unsigned long left;
- yasm__warning(YASM_WARN_UNINIT_CONTENTS, bc->line,
+ yasm_warn_set(YASM_WARN_UNINIT_CONTENTS,
N_("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(buf, 0, 256);
}
static int
-elf_objfmt_create_dbg_secthead(yasm_section *sect, void *d)
+elf_objfmt_create_dbg_secthead(yasm_section *sect, /*@null@*/ void *d)
{
/*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
elf_secthead *shead;
return 0;
}
- if ((pos = ftell(info->f)) == -1)
- yasm__error(0, N_("couldn't read position on output stream"));
+ if ((pos = ftell(info->f)) == -1) {
+ yasm_error_set(YASM_ERROR_IO,
+ N_("couldn't read position on output stream"));
+ yasm_errwarn_propagate(info->errwarns, 0);
+ }
pos = elf_secthead_set_file_offset(shead, pos);
- if (fseek(info->f, pos, SEEK_SET) < 0)
- yasm__error(0, N_("couldn't seek on output stream"));
+ if (fseek(info->f, pos, SEEK_SET) < 0) {
+ yasm_error_set(YASM_ERROR_IO, N_("couldn't seek on output stream"));
+ yasm_errwarn_propagate(info->errwarns, 0);
+ }
info->sect = sect;
info->shead = shead;
- yasm_section_bcs_traverse(sect, info, elf_objfmt_output_bytecode);
+ yasm_section_bcs_traverse(sect, info->errwarns, info,
+ elf_objfmt_output_bytecode);
elf_secthead_set_index(shead, ++info->sindex);
/* No relocations to output? Go on to next section */
- if (elf_secthead_write_relocs_to_file(info->f, sect, shead) == 0)
+ if (elf_secthead_write_relocs_to_file(info->f, sect, shead,
+ info->errwarns) == 0)
return 0;
elf_secthead_set_rel_index(shead, ++info->sindex);
}
static void
-elf_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df)
+elf_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df,
+ yasm_errwarns *errwarns)
{
yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;
elf_objfmt_output_info info;
unsigned long elf_symtab_nlocal;
info.objfmt_elf = objfmt_elf;
+ info.errwarns = errwarns;
info.f = f;
/* Update filename strtab */
/* Allocate space for Ehdr by seeking forward */
if (fseek(f, (long)(elf_proghead_get_size()), SEEK_SET) < 0) {
- yasm__error(0, N_("could not seek on output file"));
+ yasm_error_set(YASM_ERROR_IO, N_("could not seek on output file"));
+ yasm_errwarn_propagate(errwarns, 0);
return;
}
".shstrtab");
/* output .shstrtab */
- if ((pos = elf_objfmt_output_align(f, 4)) == -1)
+ if ((pos = elf_objfmt_output_align(f, 4)) == -1) {
+ yasm_errwarn_propagate(errwarns, 0);
return;
+ }
elf_shstrtab_offset = (unsigned long) pos;
elf_shstrtab_size = elf_strtab_output_to_file(f, objfmt_elf->shstrtab);
/* output .strtab */
- if ((pos = elf_objfmt_output_align(f, 4)) == -1)
+ if ((pos = elf_objfmt_output_align(f, 4)) == -1) {
+ yasm_errwarn_propagate(errwarns, 0);
return;
+ }
elf_strtab_offset = (unsigned long) pos;
elf_strtab_size = elf_strtab_output_to_file(f, objfmt_elf->strtab);
/* output .symtab - last section so all others have indexes */
- if ((pos = elf_objfmt_output_align(f, 4)) == -1)
+ if ((pos = elf_objfmt_output_align(f, 4)) == -1) {
+ yasm_errwarn_propagate(errwarns, 0);
return;
+ }
elf_symtab_offset = (unsigned long) pos;
- elf_symtab_size = elf_symtab_write_to_file(f, objfmt_elf->elf_symtab);
+ elf_symtab_size = elf_symtab_write_to_file(f, objfmt_elf->elf_symtab,
+ errwarns);
/* output section header table */
- if ((pos = elf_objfmt_output_align(f, 16)) == -1)
+ if ((pos = elf_objfmt_output_align(f, 16)) == -1) {
+ yasm_errwarn_propagate(errwarns, 0);
return;
+ }
elf_shead_addr = (unsigned long) pos;
/* stabs debugging support */
/* output Ehdr */
if (fseek(f, 0, SEEK_SET) < 0) {
- yasm__error(0, N_("could not seek on output file"));
+ yasm_error_set(YASM_ERROR_IO, N_("could not seek on output file"));
+ yasm_errwarn_propagate(errwarns, 0);
return;
}
int match;
if (!vp->val) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized numeric qualifier"));
continue;
}
flags |= SHF_TLS;
break;
default:
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("unrecognized section attribute: `%c'"),
vp->val[i]);
}
align_expr = yasm_expr_get_intnum(&vp->param, NULL);
if (!align_expr) {
- yasm__error(line,
- N_("argument to `%s' is not a power of two"),
- vp->val);
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("argument to `%s' is not a power of two"),
+ vp->val);
return NULL;
}
align = yasm_intnum_get_uint(align_expr);
/* Alignments must be a power of two. */
if ((align & (align - 1)) != 0) {
- yasm__error(line,
- N_("argument to `%s' is not a power of two"),
- vp->val);
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("argument to `%s' is not a power of two"),
+ vp->val);
return NULL;
}
} else
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized qualifier `%s'"), vp->val);
}
/* Handle merge entity size */
merge_intn = yasm_expr_get_intnum(&vp->param, NULL);
if (!merge_intn)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("invalid merge entity size"));
} else {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("entity size for SHF_MERGE not specified"));
flags &= ~SHF_MERGE;
}
elf_secthead_set_entsize(esd, yasm_intnum_get_uint(merge_intn));
yasm_section_set_align(retval, align, line);
} else if (flags_override)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("section flags ignored on section redeclaration"));
return retval;
}
for (; vp; vp = yasm_vps_next(vp))
{
if (vp->val)
- yasm__error(line, N_("unrecognized symbol type `%s'"), vp->val);
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("unrecognized symbol type `%s'"), vp->val);
}
}
return sym;
vis_overrides++;
}
else
- yasm__error(line, N_("unrecognized symbol type `%s'"),
- vp->val);
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("unrecognized symbol type `%s'"),
+ vp->val);
}
else if (vp->param && !size) {
size = vp->param;
}
}
if (vis_overrides > 1) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("More than one symbol visibility provided; using last"));
}
}
align_expr = yasm_expr_get_intnum(&vp->param, NULL);
if (!align_expr) {
- yasm__error(line,
- N_("alignment constraint is not a power of two"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("alignment constraint is not a power of two"));
return sym;
}
addralign = yasm_intnum_get_uint(align_expr);
/* Alignments must be a power of two. */
if ((addralign & (addralign - 1)) != 0) {
- yasm__error(line,
- N_("alignment constraint is not a power of two"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("alignment constraint is not a power of two"));
return sym;
}
} else if (vp->val)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized qualifier `%s'"), vp->val);
}
}
elf_symtab_entry *entry;
if (!symname) {
- yasm__error(line, N_("Symbol name not specified"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("Symbol name not specified"));
return 0;
}
else if (yasm__strcasecmp(vp->val, "object") == 0)
elf_sym_set_type(entry, STT_OBJECT);
else
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("unrecognized symbol type `%s'"), vp->val);
} else
- yasm__error(line, N_("no type specified"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("no type specified"));
} else if (yasm__strcasecmp(name, "size") == 0) {
/* Get symbol elf data */
sym = yasm_symtab_use(objfmt_elf->symtab, symname, line);
elf_sym_set_size(entry, yasm_expr_create_ident(yasm_expr_sym(
yasm_symtab_use(objfmt_elf->symtab, vp->val, line)), line));
else
- yasm__error(line, N_("no size specified"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("no size specified"));
} else if (yasm__strcasecmp(name, "weak") == 0) {
sym = yasm_symtab_declare(objfmt_elf->symtab, symname, YASM_SYM_GLOBAL,
line);
nreloc = yasm_intnum_create_uint(shead->nreloc);
relocsize = yasm_intnum_create_uint(RELOC64A_SIZE);
- yasm_intnum_calc(relocsize, YASM_EXPR_MUL, nreloc, 0);
+ yasm_intnum_calc(relocsize, YASM_EXPR_MUL, nreloc);
YASM_WRITE_64I_L(bufp, relocsize); /* size */
yasm_intnum_destroy(nreloc);
yasm_intnum_destroy(relocsize);
}
unsigned long
-elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab)
+elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab,
+ yasm_errwarns *errwarns)
{
unsigned char buf[SYMTAB_MAXSIZE], *bufp;
elf_symtab_entry *entry, *prev;
if (entry->xsize) {
size_intn = yasm_intnum_copy(
yasm_expr_get_intnum(&entry->xsize, yasm_common_calc_bc_dist));
- if (!size_intn)
- yasm__error(entry->xsize->line,
- N_("size specifier not an integer expression"));
+ if (!size_intn) {
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("size specifier not an integer expression"));
+ yasm_errwarn_propagate(errwarns, entry->xsize->line);
+ }
}
else
size_intn = yasm_intnum_create_uint(entry->size);
yasm_common_calc_bc_dist);
if (equ_intn == NULL) {
- yasm__error(equ_expr->line,
- N_("EQU value not an integer expression"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("EQU value not an integer expression"));
+ yasm_errwarn_propagate(errwarns, equ_expr->line);
}
value_intn = yasm_intnum_copy(equ_intn);
unsigned long
elf_secthead_write_relocs_to_file(FILE *f, yasm_section *sect,
- elf_secthead *shead)
+ elf_secthead *shead, yasm_errwarns *errwarns)
{
elf_reloc_entry *reloc;
unsigned char buf[RELOC_MAXSIZE], *bufp;
/* first align section to multiple of 4 */
pos = ftell(f);
- if (pos == -1)
- yasm__error(0, N_("couldn't read position on output stream"));
+ if (pos == -1) {
+ yasm_error_set(YASM_ERROR_IO,
+ N_("couldn't read position on output stream"));
+ yasm_errwarn_propagate(errwarns, 0);
+ }
pos = (pos + 3) & ~3;
- if (fseek(f, pos, SEEK_SET) < 0)
- yasm__error(0, N_("couldn't seek on output stream"));
+ if (fseek(f, pos, SEEK_SET) < 0) {
+ yasm_error_set(YASM_ERROR_IO, N_("couldn't seek on output stream"));
+ yasm_errwarn_propagate(errwarns, 0);
+ }
shead->rel_offset = (unsigned long)pos;
elf_secthead_add_size(elf_secthead *shead, yasm_intnum *size)
{
if (size) {
- yasm_intnum_calc(shead->size, YASM_EXPR_ADD, size, 0);
+ yasm_intnum_calc(shead->size, YASM_EXPR_ADD, size);
}
}
elf_symtab_entry *entry);
void elf_symtab_destroy(elf_symtab_head *head);
unsigned long elf_symtab_assign_indices(elf_symtab_head *symtab);
-unsigned long elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab);
+unsigned long elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab,
+ yasm_errwarns *errwarns);
void elf_symtab_set_nonzero(elf_symtab_entry *entry,
struct yasm_section *sect,
elf_section_index sectidx,
elf_secthead *esd,
elf_section_index sindex);
unsigned long elf_secthead_write_relocs_to_file(FILE *f, yasm_section *sect,
- elf_secthead *shead);
+ elf_secthead *shead,
+ yasm_errwarns *errwarns);
long elf_secthead_set_file_offset(elf_secthead *shead, long pos);
/* program header function */
--:15: expression too complex
--:21: expression too complex
+-:15: data expression too complex
+-:21: data expression too complex
typedef struct xdf_objfmt_output_info {
yasm_objfmt_xdf *objfmt_xdf;
+ yasm_errwarns *errwarns;
/*@dependent@*/ FILE *f;
/*@only@*/ unsigned char *buf;
yasm_section *sect;
}
if (value->section_rel) {
- yasm__error(bc->line, N_("xdf: relocation too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("xdf: relocation too complex"));
return 1;
}
if (intn_minus > 0) {
intn = yasm_intnum_create_uint(intn_minus);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, bc->line);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
} else
intn = yasm_intnum_create_uint(0);
if (value->abs) {
yasm_intnum *intn2 = yasm_expr_get_intnum(&value->abs, NULL);
if (!intn2) {
- yasm__error(bc->line, N_("xdf: relocation too complex"));
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("xdf: relocation too complex"));
yasm_intnum_destroy(intn);
return 1;
}
- yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2, bc->line);
+ yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2);
}
retval = yasm_arch_intnum_tobytes(objfmt_xdf->arch, intn, buf, destsize,
- valsize, shift, bc, warn, bc->line);
+ valsize, shift, bc, warn);
yasm_intnum_destroy(intn);
return retval;
}
/* Warn that gaps are converted to 0 and write out the 0's. */
if (gap) {
unsigned long left;
- yasm__warning(YASM_WARN_UNINIT_CONTENTS, bc->line,
- N_("uninitialized space: zeroing"));
+ yasm_warn_set(YASM_WARN_UNINIT_CONTENTS,
+ N_("uninitialized space: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
left = multiple*size;
info->sect = sect;
info->xsd = xsd;
- yasm_section_bcs_traverse(sect, info, xdf_objfmt_output_bytecode);
+ yasm_section_bcs_traverse(sect, info->errwarns, info,
+ xdf_objfmt_output_bytecode);
/* Sanity check final section size */
if (xsd->size != (last->offset + last->len))
yasm_internal_error(
N_("xdf: no symbol data for relocated symbol"));
- yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0, 0);
+ yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0);
localbuf += 4; /* address of relocation */
YASM_WRITE_32_L(localbuf, xsymd->index); /* relocated symbol */
if (reloc->base) {
YASM_WRITE_32_L(localbuf, xsymd->index); /* section name symbol */
if (xsd->addr) {
- yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0, 0);
+ yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0);
localbuf += 8; /* physical address */
} else {
YASM_WRITE_32_L(localbuf, 0);
YASM_WRITE_32_L(localbuf, 0);
}
if (xsd->vaddr) {
- yasm_intnum_get_sized(xsd->vaddr, localbuf, 8, 64, 0, 0, 0, 0);
+ yasm_intnum_get_sized(xsd->vaddr, localbuf, 8, 64, 0, 0, 0);
localbuf += 8; /* virtual address */
} else if (xsd->addr) {
- yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0, 0);
+ yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0);
localbuf += 8; /* VA=PA */
} else {
YASM_WRITE_32_L(localbuf, 0);
abs_start = yasm_expr_copy(yasm_section_get_start(sect));
intn = yasm_expr_get_intnum(&abs_start,
yasm_common_calc_bc_dist);
- if (!intn)
- yasm__error(abs_start->line,
+ if (!intn) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("absolute section start not an integer expression"));
- else
+ yasm_errwarn_propagate(info->errwarns, abs_start->line);
+ } else
value = yasm_intnum_get_uint(intn);
yasm_expr_destroy(abs_start);
intn = yasm_expr_get_intnum(&equ_val_copy,
yasm_common_calc_bc_dist);
if (!intn) {
- if (vis & YASM_SYM_GLOBAL)
- yasm__error(equ_val->line,
+ if (vis & YASM_SYM_GLOBAL) {
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
N_("global EQU value not an integer expression"));
+ yasm_errwarn_propagate(info->errwarns, equ_val->line);
+ }
} else
value = yasm_intnum_get_uint(intn);
yasm_expr_destroy(equ_val_copy);
static void
xdf_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms,
- /*@unused@*/ yasm_dbgfmt *df)
+ /*@unused@*/ yasm_dbgfmt *df, yasm_errwarns *errwarns)
{
yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;
xdf_objfmt_output_info info;
unsigned long symtab_count = 0;
info.objfmt_xdf = objfmt_xdf;
+ info.errwarns = errwarns;
info.f = f;
info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
while ((vp = yasm_vps_next(vp))) {
if (!vp->val) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("Unrecognized numeric qualifier"));
continue;
}
flags |= XDF_SECT_ABSOLUTE;
absaddr = yasm_expr_get_intnum(&vp->param, NULL);
if (!absaddr) {
- yasm__error(line, N_("argument to `%s' is not an integer"),
- vp->val);
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("argument to `%s' is not an integer"),
+ vp->val);
return NULL;
}
} else if (yasm__strcasecmp(vp->val, "virtual") == 0 && vp->param) {
vaddr = yasm_expr_get_intnum(&vp->param, NULL);
if (!vaddr) {
- yasm__error(line, N_("argument to `%s' is not an integer"),
- vp->val);
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+ N_("argument to `%s' is not an integer"),
+ vp->val);
return NULL;
}
} else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {
align_expr = yasm_expr_get_intnum(&vp->param, NULL);
if (!align_expr) {
- yasm__error(line, N_("argument to `%s' is not a power of two"),
- vp->val);
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("argument to `%s' is not a power of two"),
+ vp->val);
return NULL;
}
align = yasm_intnum_get_uint(align_expr);
/* Alignments must be a power of two. */
if ((align & (align - 1)) != 0) {
- yasm__error(line, N_("argument to `%s' is not a power of two"),
- vp->val);
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("argument to `%s' is not a power of two"),
+ vp->val);
return NULL;
}
/* Check to see if alignment is supported size */
if (align > 4096) {
- yasm__error(line,
- N_("XDF does not support alignments > 4096"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("XDF does not support alignments > 4096"));
return NULL;
}
} else
- yasm__warning(YASM_WARN_GENERAL, line,
- N_("Unrecognized qualifier `%s'"), vp->val);
+ yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized qualifier `%s'"),
+ vp->val);
}
retval = yasm_object_get_general(objfmt_xdf->object, sectname, 0, align, 1,
}
yasm_section_set_align(retval, align, line);
} else if (flags_override)
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("section flags ignored on section redeclaration"));
return retval;
}
yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;
yasm_expr_destroy(size);
- yasm__error(line,
+ yasm_error_set(YASM_ERROR_GENERAL,
N_("XDF object format does not support common variables"));
return yasm_symtab_declare(objfmt_xdf->symtab, name, YASM_SYM_COMMON,
if (dist < precbc1->offset + precbc1->len) {
intn = yasm_intnum_create_uint(precbc1->offset +
precbc1->len - dist);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL,
- precbc1->line);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
return intn;
}
dist -= precbc1->offset + precbc1->len;
if (precbc1 != yasm_section_bcs_first(precbc1->section)) {
if (precbc1->opt_flags == BCFLAG_DONE) {
intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
return intn;
} else {
return NULL;
typedef struct basic_optimize_data {
/*@observer@*/ yasm_bytecode *precbc;
int saw_unknown;
+ yasm_errwarns *errwarns;
} basic_optimize_data;
static int
bcr_retval = yasm_bc_resolve(bc, 0, basic_optimize_calc_bc_dist_1);
if (bcr_retval & YASM_BC_RESOLVE_UNKNOWN_LEN) {
if (!(bcr_retval & YASM_BC_RESOLVE_ERROR))
- yasm__error(bc->line, N_("circular reference detected."));
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("circular reference detected."));
data->saw_unknown = -1;
return 0;
}
static int
basic_optimize_section_1(yasm_section *sect, /*@null@*/ void *d)
{
- /*@null@*/ int *saw_unknown = (int *)d;
- basic_optimize_data data;
+ basic_optimize_data *data = (basic_optimize_data *)d;
+ basic_optimize_data localdata;
unsigned long flags;
int retval;
- data.precbc = yasm_section_bcs_first(sect);
- data.saw_unknown = 0;
+ if (!data) {
+ data = &localdata;
+ localdata.saw_unknown = 0;
+ localdata.errwarns = NULL;
+ }
+
+ data->precbc = yasm_section_bcs_first(sect);
/* Don't even bother if we're in-progress or done. */
flags = yasm_section_get_opt_flags(sect);
yasm_section_set_opt_flags(sect, SECTFLAG_INPROGRESS);
- retval = yasm_section_bcs_traverse(sect, &data, basic_optimize_bytecode_1);
+ retval = yasm_section_bcs_traverse(sect, data->errwarns, data,
+ basic_optimize_bytecode_1);
if (retval != 0)
return retval;
- if (data.saw_unknown != 0 && saw_unknown)
- *saw_unknown = data.saw_unknown;
-
yasm_section_set_opt_flags(sect, SECTFLAG_DONE);
return 0;
if (yasm_section_get_opt_flags(sect) != SECTFLAG_DONE)
yasm_internal_error(N_("Optimizer pass 1 missed a section!"));
- return yasm_section_bcs_traverse(sect, &data, basic_optimize_bytecode_2);
+ return yasm_section_bcs_traverse(sect, NULL, &data,
+ basic_optimize_bytecode_2);
}
static void
-basic_optimize(yasm_object *object)
+basic_optimize(yasm_object *object, yasm_errwarns *errwarns)
{
- int saw_unknown = 0;
+ basic_optimize_data data;
+
+ data.saw_unknown = 0;
+ data.errwarns = errwarns;
/* Optimization process: (essentially NASM's pass 1)
* Determine the size of all bytecodes.
* - not strictly top->bottom scanning; we scan through a section and
* hop to other sections as necessary.
*/
- if (yasm_object_sections_traverse(object, &saw_unknown,
+ if (yasm_object_sections_traverse(object, &data,
basic_optimize_section_1) < 0 ||
- saw_unknown != 0)
+ data.saw_unknown != 0)
return;
/* Check completion of all sections and save bytecode changes */
yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams);
-#define gas_parser_error(s) yasm__parser_error(cur_line, s)
+#define gas_parser_error(s) \
+ yasm_error_set(YASM_ERROR_PARSE, "%s", s)
#define YYPARSE_PARAM parser_gas_arg
#define YYLEX_PARAM parser_gas_arg
#define parser_gas ((yasm_parser_gas *)parser_gas_arg)
%%
input: /* empty */
| input line {
+ yasm_errwarn_propagate(parser_gas->errwarns, cur_line);
if (parser_gas->save_input)
yasm_linemap_add_source(parser_gas->linemap,
parser_gas->prev_bc,
line: '\n'
| linebcs '\n'
| error '\n' {
- yasm__error(cur_line,
- N_("label or instruction expected at start of line"));
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("label or instruction expected at start of line"));
yyerrok;
}
;
| DIR_LINE INTNUM {
$$ = (yasm_bytecode *)NULL;
if (yasm_intnum_sign($2) < 0)
- yasm__error(cur_line, N_("line number is negative"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("line number is negative"));
else
yasm_linemap_set(parser_gas->linemap, NULL,
yasm_intnum_get_uint($2), 1);
$$ = (yasm_bytecode *)NULL;
if (!intn) {
- yasm__error(cur_line, N_("rept expression not absolute"));
+ yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
+ N_("rept expression not absolute"));
} else if (yasm_intnum_sign(intn) < 0) {
- yasm__error(cur_line, N_("rept expression is negative"));
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("rept expression is negative"));
} else {
gas_rept *rept = yasm_xmalloc(sizeof(gas_rept));
STAILQ_INIT(&rept->lines);
| DIR_ENDR {
$$ = (yasm_bytecode *)NULL;
/* Shouldn't ever get here unless we didn't get a DIR_REPT first */
- yasm__error(cur_line, N_("endr without matching rept"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("endr without matching rept"));
}
/* Alignment directives */
| DIR_ALIGN dirvals2 {
$$ = NULL;
}
| DIR_ID dirvals {
- yasm__warning(YASM_WARN_GENERAL, cur_line,
- N_("directive `%s' not recognized"), $1);
+ yasm_warn_set(YASM_WARN_GENERAL, N_("directive `%s' not recognized"),
+ $1);
$$ = (yasm_bytecode *)NULL;
yasm_xfree($1);
yasm_vps_delete(&$2);
}
| DIR_ID error {
- yasm__warning(YASM_WARN_GENERAL, cur_line,
- N_("directive `%s' not recognized"), $1);
+ yasm_warn_set(YASM_WARN_GENERAL, N_("directive `%s' not recognized"),
+ $1);
$$ = (yasm_bytecode *)NULL;
yasm_xfree($1);
}
&$2.operands, cur_line);
}
| INSN error {
- yasm__error(cur_line, N_("expression syntax error"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("expression syntax error"));
$$ = NULL;
}
| PREFIX instr {
yasm_bc_insn_add_seg_prefix($$, $1[0]);
}
| ID {
- yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("instruction not recognized: `%s'"), $1);
$$ = NULL;
}
| ID operands {
- yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("instruction not recognized: `%s'"), $1);
$$ = NULL;
}
| ID error {
- yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("instruction not recognized: `%s'"), $1);
$$ = NULL;
}
;
}
| '(' ',' INTNUM ')' {
if (yasm_intnum_get_uint($3) != 1)
- yasm__warning(YASM_WARN_GENERAL, cur_line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("scale factor of %u without an index register"),
yasm_intnum_get_uint($3));
$$ = p_expr_new(yasm_expr_int(yasm_intnum_create_uint(0)),
}
| SEGREG ':' memaddr {
$$ = $3;
- yasm_ea_set_segreg($$, $1[0], cur_line);
+ yasm_ea_set_segreg($$, $1[0]);
}
;
yasm_arch_reggroup_get_reg(parser_gas->arch, $1[0],
yasm_intnum_get_uint($3));
if (reg == 0) {
- yasm__error(cur_line, N_("bad register index `%u'"),
- yasm_intnum_get_uint($3));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("bad register index `%u'"),
+ yasm_intnum_get_uint($3));
$$ = yasm_operand_create_reg($1[0]);
} else
$$ = yasm_operand_create_reg(reg);
parser_gas->cur_section = new_section;
parser_gas->prev_bc = yasm_section_bcs_last(new_section);
} else
- yasm__error(cur_line, N_("invalid section name `%s'"), name);
+ yasm_error_set(YASM_ERROR_GENERAL, N_("invalid section name `%s'"),
+ name);
yasm_xfree(name);
if (bound && boundval) {
fill = yasm_vps_next(bound);
} else {
- yasm__error(cur_line, N_("align directive must specify alignment"));
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("align directive must specify alignment"));
return NULL;
}
/*@dependent@*/ /*@null@*/ yasm_intnum *intn;
intn = yasm_expr_get_intnum(&size, NULL);
if (!intn) {
- yasm__error(cur_line, N_("size must be an absolute expression"));
+ yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
+ N_("size must be an absolute expression"));
yasm_expr_destroy(repeat);
yasm_expr_destroy(size);
if (value)
;
} else if (yasm_objfmt_directive(parser_gas->objfmt, name, valparams,
objext_valparams, line)) {
- yasm__error(line, N_("unrecognized directive [%s]"), name);
+ yasm_error_set(YASM_ERROR_GENERAL, N_("unrecognized directive [%s]"),
+ name);
}
yasm_vps_delete(valparams);
gas_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a,
yasm_objfmt *of, yasm_dbgfmt *df, FILE *f,
const char *in_filename, int save_input,
- yasm_section *def_sect)
+ yasm_section *def_sect, yasm_errwarns *errwarns)
{
yasm_parser_gas parser_gas;
parser_gas.arch = a;
parser_gas.objfmt = of;
parser_gas.dbgfmt = df;
+ parser_gas.errwarns = errwarns;
parser_gas.cur_section = def_sect;
parser_gas.prev_bc = yasm_section_bcs_first(def_sect);
gas_parser_parse(&parser_gas);
/* Check for ending inside a rept */
- if (parser_gas.rept)
- yasm__error(parser_gas.rept->startline,
- N_("rept without matching endr"));
+ if (parser_gas.rept) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("rept without matching endr"));
+ yasm_errwarn_propagate(errwarns, parser_gas.rept->startline);
+ }
gas_parser_cleanup(&parser_gas);
/*@dependent@*/ yasm_arch *arch;
/*@dependent@*/ yasm_objfmt *objfmt;
/*@dependent@*/ yasm_dbgfmt *dbgfmt;
+ /*@dependent@*/ yasm_errwarns *errwarns;
/*@dependent@*/ yasm_linemap *linemap;
/*@dependent@*/ yasm_symtab *symtab;
int ch)
{
if (cursor == s->eof)
- yasm__error(line, N_("unexpected end of file in string"));
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("unexpected end of file in string"));
if (count >= strbuf_size) {
strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
([1-9] digit*) | "0" {
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
- lvalp->intn = yasm_intnum_create_dec(TOK, cur_line);
+ lvalp->intn = yasm_intnum_create_dec(TOK);
s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
'0b' bindigit+ {
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
- lvalp->intn = yasm_intnum_create_bin(TOK+2, cur_line);
+ lvalp->intn = yasm_intnum_create_bin(TOK+2);
s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
"0" octdigit+ {
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
- lvalp->intn = yasm_intnum_create_oct(TOK, cur_line);
+ lvalp->intn = yasm_intnum_create_oct(TOK);
s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
/* skip 0 and x */
- lvalp->intn = yasm_intnum_create_hex(TOK+2, cur_line);
+ lvalp->intn = yasm_intnum_create_hex(TOK+2);
s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
switch (yasm_arch_parse_check_regtmod
- (parser_gas->arch, lvalp->arch_data, TOK+1, TOKLEN-1,
- cur_line)) {
+ (parser_gas->arch, lvalp->arch_data, TOK+1, TOKLEN-1)) {
case YASM_ARCH_REG:
s->tok[TOKLEN] = savech;
RETURN(REG);
default:
break;
}
- yasm__error(cur_line, N_("Unrecognized register name `%s'"),
- s->tok);
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("Unrecognized register name `%s'"), s->tok);
s->tok[TOKLEN] = savech;
lvalp->arch_data[0] = 0;
lvalp->arch_data[1] = 0;
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
switch (yasm_arch_parse_check_insnprefix
- (parser_gas->arch, lvalp->arch_data, TOK, TOKLEN,
- cur_line)) {
+ (parser_gas->arch, lvalp->arch_data, TOK, TOKLEN)) {
case YASM_ARCH_INSN:
s->tok[TOKLEN] = savech;
parser_gas->state = INSTDIR;
}
any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
+ yasm_warn_set(YASM_WARN_UNREC_CHAR,
N_("ignoring unrecognized character `%s'"),
yasm__conv_unprint(s->tok[0]));
goto scan;
}
any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
+ yasm_warn_set(YASM_WARN_UNREC_CHAR,
N_("ignoring unrecognized character `%s'"),
yasm__conv_unprint(s->tok[0]));
goto section_directive;
"\\" digit digit digit {
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
- lvalp->intn = yasm_intnum_create_oct(TOK+1, cur_line);
+ lvalp->intn = yasm_intnum_create_oct(TOK+1);
s->tok[TOKLEN] = savech;
strbuf_append(count++, cursor, s, cur_line,
'\\x' hexdigit+ {
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
- lvalp->intn = yasm_intnum_create_hex(TOK+2, cur_line);
+ lvalp->intn = yasm_intnum_create_hex(TOK+2);
s->tok[TOKLEN] = savech;
strbuf_append(count++, cursor, s, cur_line,
int i;
if (linestart) {
/* We don't support nested right now, error */
- yasm__error(cur_line, N_("nested rept not supported"));
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("nested rept not supported"));
+ yasm_errwarn_propagate(parser_gas->errwarns, cur_line);
}
for (i=0; i<6; i++)
strbuf_append(count++, cursor, s, cur_line, s->tok[i]);
static void define_label(yasm_parser_nasm *parser_nasm, /*@only@*/ char *name,
int local);
-#define nasm_parser_error(s) yasm__parser_error(cur_line, s)
+#define nasm_parser_error(s) yasm_error_set(YASM_ERROR_PARSE, "%s", s)
#define YYPARSE_PARAM parser_nasm_arg
#define YYLEX_PARAM parser_nasm_arg
#define parser_nasm ((yasm_parser_nasm *)parser_nasm_arg)
%%
input: /* empty */
| input line {
+ yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
parser_nasm->temp_bc =
yasm_section_bcs_append(parser_nasm->cur_section, $2);
if (parser_nasm->temp_bc)
$$ = (yasm_bytecode *)NULL;
}
| error '\n' {
- yasm__error(cur_line,
- N_("label or instruction expected at start of line"));
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("label or instruction expected at start of line"));
$$ = (yasm_bytecode *)NULL;
yyerrok;
}
lineexp: exp
| TIMES expr exp { $$ = $3; yasm_bc_set_multiple($$, $2); }
| label_id {
- yasm__warning(YASM_WARN_ORPHAN_LABEL, cur_line,
- N_("label alone on a line without a colon might be in error"));
+ yasm_warn_set(YASM_WARN_ORPHAN_LABEL,
+ N_("label alone on a line without a colon might be in error"));
$$ = (yasm_bytecode *)NULL;
define_label(parser_nasm, $1.name, $1.local);
}
&$2.operands, cur_line);
}
| INSN error {
- yasm__error(cur_line, N_("expression syntax error"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("expression syntax error"));
$$ = NULL;
}
| PREFIX instr {
$$ = yasm_dv_create_string($1.contents, $1.len);
}
| error {
- yasm__error(cur_line, N_("expression syntax error"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("expression syntax error"));
$$ = (yasm_dataval *)NULL;
}
;
yasm_xfree($1);
}
| DIRECTIVE_NAME error {
- yasm__error(cur_line, N_("invalid arguments to [%s]"), $1);
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid arguments to [%s]"), $1);
yasm_xfree($1);
}
;
}
| SEGREG ':' memaddr {
$$ = $3;
- yasm_ea_set_segreg($$, $1[0], cur_line);
+ yasm_ea_set_segreg($$, $1[0]);
}
| SIZE_OVERRIDE memaddr { $$ = $2; yasm_ea_set_len($$, $1); }
| NOSPLIT memaddr { $$ = $2; yasm_ea_set_nosplit($$, 1); }
$$ = $2;
if ($$->type == YASM_INSN__OPERAND_REG &&
yasm_arch_get_reg_size(parser_nasm->arch, $$->data.reg) != $1)
- yasm__error(cur_line, N_("cannot override register size"));
+ yasm_error_set(YASM_ERROR_TYPE,
+ N_("cannot override register size"));
else
$$->size = $1;
}
| REG { $$ = p_expr_new_ident(yasm_expr_reg($1[0])); }
| STRING {
$$ = p_expr_new_ident(yasm_expr_int(
- yasm_intnum_create_charconst_nasm($1.contents, cur_line)));
+ yasm_intnum_create_charconst_nasm($1.contents)));
yasm_xfree($1.contents);
}
| explabel { $$ = p_expr_new_ident(yasm_expr_sym($1)); }
yasm_objfmt_extern_declare(parser_nasm->objfmt, vp->val,
objext_valparams, line);
} else
- yasm__error(line, N_("invalid argument to [%s]"), "EXTERN");
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
+ "EXTERN");
} else if (yasm__strcasecmp(name, "global") == 0) {
vp = yasm_vps_first(valparams);
if (vp->val) {
yasm_objfmt_global_declare(parser_nasm->objfmt, vp->val,
objext_valparams, line);
} else
- yasm__error(line, N_("invalid argument to [%s]"), "GLOBAL");
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
+ "GLOBAL");
} else if (yasm__strcasecmp(name, "common") == 0) {
vp = yasm_vps_first(valparams);
if (vp->val) {
vp2 = yasm_vps_next(vp);
if (!vp2 || (!vp2->val && !vp2->param))
- yasm__error(line, N_("no size specified in %s declaration"),
- "COMMON");
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("no size specified in %s declaration"),
+ "COMMON");
else {
if (vp2->val) {
yasm_objfmt_common_declare(parser_nasm->objfmt, vp->val,
}
}
} else
- yasm__error(line, N_("invalid argument to [%s]"), "COMMON");
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
+ "COMMON");
} else if (yasm__strcasecmp(name, "section") == 0 ||
yasm__strcasecmp(name, "segment") == 0) {
yasm_section *new_section =
parser_nasm->cur_section = new_section;
parser_nasm->prev_bc = yasm_section_bcs_last(new_section);
} else
- yasm__error(line, N_("invalid argument to [%s]"), "SECTION");
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
+ "SECTION");
} else if (yasm__strcasecmp(name, "absolute") == 0) {
/* it can be just an ID or a complete expression, so handle both. */
vp = yasm_vps_first(valparams);
yasm_vps_foreach(vp, valparams) {
if (vp->val)
yasm_arch_parse_cpu(parser_nasm->arch, vp->val,
- strlen(vp->val), line);
+ strlen(vp->val));
else if (vp->param) {
const yasm_intnum *intcpu;
intcpu = yasm_expr_get_intnum(&vp->param, NULL);
if (!intcpu)
- yasm__error(line, N_("invalid argument to [%s]"), "CPU");
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("invalid argument to [%s]"), "CPU");
else {
char strcpu[16];
sprintf(strcpu, "%lu", yasm_intnum_get_uint(intcpu));
yasm_arch_parse_cpu(parser_nasm->arch, strcpu,
- strlen(strcpu), line);
+ strlen(strcpu));
}
}
}
;
} else if (yasm_objfmt_directive(parser_nasm->objfmt, name, valparams,
objext_valparams, line)) {
- yasm__error(line, N_("unrecognized directive [%s]"), name);
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("unrecognized directive [%s]"),
+ name);
}
yasm_vps_delete(valparams);
nasm_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a,
yasm_objfmt *of, yasm_dbgfmt *df, FILE *f,
const char *in_filename, int save_input,
- yasm_section *def_sect)
+ yasm_section *def_sect, yasm_errwarns *errwarns)
{
yasm_parser_nasm parser_nasm;
parser_nasm.arch = a;
parser_nasm.objfmt = of;
parser_nasm.dbgfmt = df;
+ parser_nasm.errwarns = errwarns;
parser_nasm.cur_section = def_sect;
parser_nasm.prev_bc = yasm_section_bcs_first(def_sect);
/*@dependent@*/ yasm_arch *arch;
/*@dependent@*/ yasm_objfmt *objfmt;
/*@dependent@*/ yasm_dbgfmt *dbgfmt;
+ /*@dependent@*/ yasm_errwarns *errwarns;
/*@dependent@*/ yasm_linemap *linemap;
/*@dependent@*/ yasm_symtab *symtab;
digit+ {
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
- lvalp->intn = yasm_intnum_create_dec(TOK, cur_line);
+ lvalp->intn = yasm_intnum_create_dec(TOK);
s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
bindigit+ 'b' {
s->tok[TOKLEN-1] = '\0'; /* strip off 'b' */
- lvalp->intn = yasm_intnum_create_bin(TOK, cur_line);
+ lvalp->intn = yasm_intnum_create_bin(TOK);
RETURN(INTNUM);
}
/* 777q or 777o - octal number */
octdigit+ [qQoO] {
s->tok[TOKLEN-1] = '\0'; /* strip off 'q' or 'o' */
- lvalp->intn = yasm_intnum_create_oct(TOK, cur_line);
+ lvalp->intn = yasm_intnum_create_oct(TOK);
RETURN(INTNUM);
}
/* 0AAh form of hexidecimal number */
digit hexdigit* 'h' {
s->tok[TOKLEN-1] = '\0'; /* strip off 'h' */
- lvalp->intn = yasm_intnum_create_hex(TOK, cur_line);
+ lvalp->intn = yasm_intnum_create_hex(TOK);
RETURN(INTNUM);
}
s->tok[TOKLEN] = '\0';
if (s->tok[1] == 'x')
/* skip 0 and x */
- lvalp->intn = yasm_intnum_create_hex(TOK+2, cur_line);
+ lvalp->intn = yasm_intnum_create_hex(TOK+2);
else
/* don't skip 0 */
- lvalp->intn = yasm_intnum_create_hex(TOK+1, cur_line);
+ lvalp->intn = yasm_intnum_create_hex(TOK+1);
s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
RETURN(ID);
} else if (!parser_nasm->locallabel_base) {
lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
- yasm__warning(YASM_WARN_GENERAL, cur_line,
+ yasm_warn_set(YASM_WARN_GENERAL,
N_("no non-local label before `%s'"),
lvalp->str_val);
} else {
s->tok[TOKLEN] = '\0';
if (parser_nasm->state != INSTRUCTION)
switch (yasm_arch_parse_check_insnprefix
- (parser_nasm->arch, lvalp->arch_data, TOK, TOKLEN,
- cur_line)) {
+ (parser_nasm->arch, lvalp->arch_data, TOK, TOKLEN)) {
case YASM_ARCH_INSN:
parser_nasm->state = INSTRUCTION;
s->tok[TOKLEN] = savech;
break;
}
switch (yasm_arch_parse_check_regtmod
- (parser_nasm->arch, lvalp->arch_data, TOK, TOKLEN,
- cur_line)) {
+ (parser_nasm->arch, lvalp->arch_data, TOK, TOKLEN)) {
case YASM_ARCH_REG:
s->tok[TOKLEN] = savech;
RETURN(REG);
}
any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
+ yasm_warn_set(YASM_WARN_UNREC_CHAR,
N_("ignoring unrecognized character `%s'"),
yasm__conv_unprint(s->tok[0]));
goto scan;
linechg_numcount++;
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
- lvalp->intn = yasm_intnum_create_dec(TOK, cur_line);
+ lvalp->intn = yasm_intnum_create_dec(TOK);
s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
}
any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
+ yasm_warn_set(YASM_WARN_UNREC_CHAR,
N_("ignoring unrecognized character `%s'"),
yasm__conv_unprint(s->tok[0]));
goto linechg;
}
any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
+ yasm_warn_set(YASM_WARN_UNREC_CHAR,
N_("ignoring unrecognized character `%s'"),
yasm__conv_unprint(s->tok[0]));
goto directive;
/*!re2c
"\n" {
if (cursor == s->eof)
- yasm__error(cur_line,
- N_("unexpected end of file in string"));
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("unexpected end of file in string"));
else
- yasm__error(cur_line, N_("unterminated string"));
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("unterminated string"));
strbuf[count] = '\0';
lvalp->str.contents = (char *)strbuf;
lvalp->str.len = count;
int lineinc;
} yasm_preproc_nasm;
static yasm_linemap *cur_lm;
+static yasm_errwarns *cur_errwarns;
int tasm_compatible_mode = 0;
typedef struct preproc_dep {
va_start(va, fmt);
switch (severity & ERR_MASK) {
case ERR_WARNING:
- yasm__warning_va(YASM_WARN_PREPROC,
- yasm_linemap_get_current(cur_lm), fmt, va);
+ yasm_warn_set_va(YASM_WARN_PREPROC, fmt, va);
break;
case ERR_NONFATAL:
- yasm__error_va(yasm_linemap_get_current(cur_lm), fmt, va);
+ yasm_error_set_va(YASM_ERROR_GENERAL, fmt, va);
break;
case ERR_FATAL:
yasm_fatal(fmt, va);
break;
}
va_end(va);
+ yasm_errwarn_propagate(cur_errwarns, yasm_linemap_get_current(cur_lm));
}
static yasm_preproc *
-nasm_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm)
+nasm_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm,
+ yasm_errwarns *errwarns)
{
yasm_preproc_nasm *preproc_nasm = yasm_xmalloc(sizeof(yasm_preproc_nasm));
preproc_nasm->in = f;
cur_lm = lm;
+ cur_errwarns = errwarns;
preproc_deps = NULL;
done_dep_preproc = 0;
preproc_nasm->line = NULL;
*q = '\0';
switch (radix) {
case 2:
- intn = yasm_intnum_create_bin(r, 0);
+ intn = yasm_intnum_create_bin(r);
break;
case 8:
- intn = yasm_intnum_create_oct(r, 0);
+ intn = yasm_intnum_create_oct(r);
break;
case 10:
- intn = yasm_intnum_create_dec(r, 0);
+ intn = yasm_intnum_create_dec(r);
break;
case 16:
- intn = yasm_intnum_create_hex(r, 0);
+ intn = yasm_intnum_create_hex(r);
break;
default:
*error = TRUE;
*q = save;
if (sign)
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, 0);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
return intn;
}
save = str[length];
str[length] = '\0';
- intn = yasm_intnum_create_charconst_nasm(str, 0);
+ intn = yasm_intnum_create_charconst_nasm(str);
str[length] = save;
return intn;
int is_interactive;
FILE *in;
yasm_linemap *cur_lm;
+ yasm_errwarns *errwarns;
} yasm_preproc_raw;
yasm_preproc_module yasm_raw_LTX_preproc;
int isatty(int);
static yasm_preproc *
-raw_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm)
+raw_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm,
+ yasm_errwarns *errwarns)
{
yasm_preproc_raw *preproc_raw = yasm_xmalloc(sizeof(yasm_preproc_raw));
preproc_raw->preproc.module = &yasm_raw_LTX_preproc;
preproc_raw->in = f;
preproc_raw->cur_lm = lm;
+ preproc_raw->errwarns = errwarns;
/*@-unrecog@*/
preproc_raw->is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
/*@=unrecog@*/
buf[n] = (char)c;
if (c == '\n')
buf[n++] = (char)c;
- if (c == EOF && ferror(preproc_raw->in))
- yasm__error(yasm_linemap_get_current(preproc_raw->cur_lm),
- N_("error when reading from file"));
+ if (c == EOF && ferror(preproc_raw->in)) {
+ yasm_error_set(YASM_ERROR_IO, N_("error when reading from file"));
+ yasm_errwarn_propagate(preproc_raw->errwarns,
+ yasm_linemap_get_current(preproc_raw->cur_lm));
+ }
} else if (((n = fread(buf, 1, max_size, preproc_raw->in)) == 0) &&
- ferror(preproc_raw->in))
- yasm__error(yasm_linemap_get_current(preproc_raw->cur_lm),
- N_("error when reading from file"));
+ ferror(preproc_raw->in)) {
+ yasm_error_set(YASM_ERROR_IO, N_("error when reading from file"));
+ yasm_errwarn_propagate(preproc_raw->errwarns,
+ yasm_linemap_get_current(preproc_raw->cur_lm));
+ }
return n;
}
PYBINDING_DEPS = tools/python-yasm/bytecode.pxi
PYBINDING_DEPS += tools/python-yasm/coretype.pxi
+PYBINDING_DEPS += tools/python-yasm/errwarn.pxi
PYBINDING_DEPS += tools/python-yasm/expr.pxi
PYBINDING_DEPS += tools/python-yasm/floatnum.pxi
PYBINDING_DEPS += tools/python-yasm/intnum.pxi
cdef struct yasm_effaddr_callback:
void (*destroy) (yasm_effaddr *ea)
- void (*c_print "print") (yasm_effaddr *ea, FILE *f, int indent_level)
+ void (*print_ "print") (yasm_effaddr *ea, FILE *f, int indent_level)
cdef struct yasm_effaddr:
yasm_effaddr_callback *callback
cdef void yasm_ea_set_len(yasm_effaddr *ea, unsigned int len)
cdef void yasm_ea_set_nosplit(yasm_effaddr *ea, unsigned int nosplit)
cdef void yasm_ea_set_strong(yasm_effaddr *ea, unsigned int strong)
- cdef void yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg,
- unsigned long line)
+ cdef void yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg)
cdef void yasm_ea_destroy(yasm_effaddr *ea)
cdef void yasm_ea_print(yasm_effaddr *ea, FILE *f, int indent_level)
cdef class Bytecode:
cdef yasm_bytecode *bc
+ property len:
+ def __get__(self): return self.bc.len
+ def __set__(self, value): self.bc.len = value
+ property line:
+ def __get__(self): return self.bc.line
+ def __set__(self, value): self.bc.line = value
+ property offset:
+ def __get__(self): return self.bc.offset
+ def __set__(self, value): self.bc.offset = value
+ property opt_flags:
+ def __get__(self): return self.bc.opt_flags
+ def __set__(self, value): self.bc.opt_flags = value
+ property symbols:
+ # Someday extend this to do something modifiable, e.g. return a
+ # list-like object.
+ def __get__(self):
+ cdef yasm_symrec *sym
+ cdef int i
+ s = []
+ i = 0
+ sym = self.bc.symrecs[i]
+ while sym != NULL:
+ s.append(__make_symbol(sym))
+ i = i+1
+ sym = self.bc.symrecs[i]
+ return s
ctypedef unsigned long size_t
+cdef extern struct va_list:
+ int arglist
+
cdef extern from "libyasm/coretype.h":
cdef struct yasm_arch
cdef struct yasm_preproc
void (*destroy) (void *data)
void (*print_ "print") (void *data, FILE *f, int indent_level)
+ cdef struct yasm_errwarns
+
cdef struct yasm_bytecode
cdef struct yasm_object
cdef struct yasm_section
--- /dev/null
+# Python bindings for Yasm: Pyrex input file for errwarn.h
+#
+# Copyright (C) 2006 Peter Johnson
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+cdef extern from "libyasm/errwarn.h":
+ cdef enum yasm_warn_class:
+ YASM_WARN_NONE
+ YASM_WARN_GENERAL
+ YASM_WARN_UNREC_CHAR
+ YASM_WARN_PREPROC
+ YASM_WARN_ORPHAN_LABEL
+ YASM_WARN_UNINIT_CONTENTS
+
+ cdef enum yasm_error_class:
+ YASM_ERROR_NONE
+ YASM_ERROR_GENERAL
+ YASM_ERROR_ARITHMETIC
+ YASM_ERROR_OVERFLOW
+ YASM_ERROR_FLOATING_POINT
+ YASM_ERROR_ZERO_DIVISION
+ YASM_ERROR_ASSERTION
+ YASM_ERROR_VALUE
+ YASM_ERROR_NOT_ABSOLUTE
+ YASM_ERROR_TOO_COMPLEX
+ YASM_ERROR_NOT_CONSTANT
+ YASM_ERROR_IO
+ YASM_ERROR_NOT_IMPLEMENTED
+ YASM_ERROR_TYPE
+ YASM_ERROR_SYNTAX
+ YASM_ERROR_PARSE
+
+ void yasm_errwarn_initialize()
+ void yasm_errwarn_cleanup()
+ extern void (*yasm_internal_error_) (char *file, unsigned int line,
+ char *message)
+ void yasm_internal_error(char *message)
+ extern void (*yasm_fatal) (char *message, va_list va)
+ void yasm__fatal(char *message, ...)
+
+ void yasm_error_clear()
+ yasm_error_class yasm_error_occurred()
+ int yasm_error_matches(yasm_error_class eclass)
+
+ void yasm_error_set_va(yasm_error_class eclass, char *format, va_list va)
+ void yasm_error_set(yasm_error_class eclass, char *format, ...)
+ void yasm_error_set_xref_va(unsigned long xrefline, char *format,
+ va_list va)
+ void yasm_error_set_xref(unsigned long xrefline, char *format, ...)
+ void yasm_error_fetch(yasm_error_class *eclass, char **str,
+ unsigned long *xrefline, char **xrefstr)
+
+ void yasm_warn_clear()
+ void yasm_warn_set_va(yasm_warn_class wclass, char *format, va_list va)
+ void yasm_warn_set(yasm_warn_class wclass, char *format, ...)
+ void yasm_warn_fetch(yasm_warn_class *wclass, char **str)
+
+ void yasm_warn_enable(yasm_warn_class wclass)
+ void yasm_warn_disable(yasm_warn_class wclass)
+
+ void yasm_warn_disable_all()
+
+ yasm_errwarns *yasm_errwarns_create()
+ void yasm_errwarns_destroy(yasm_errwarns *errwarns)
+ void yasm_errwarn_propagate(yasm_errwarns *errwarns, unsigned long line)
+ unsigned int yasm_errwarns_num_errors(yasm_errwarns *errwarns,
+ int warning_as_error)
+
+ ctypedef void (*yasm_print_error_func) (char *fn, unsigned long line,
+ char *msg, unsigned long xrefline,
+ char *xrefmsg)
+ ctypedef void (*yasm_print_warning_func) (char *fn, unsigned long line,
+ char *msg)
+ void yasm_errwarns_output_all(yasm_errwarns *errwarns, yasm_linemap *lm,
+ int warning_as_error,
+ yasm_print_error_func print_error,
+ yasm_print_warning_func print_warning)
+
+ char *yasm__conv_unprint(int ch)
+
+ extern char * (*yasm_gettext_hook) (char *msgid)
+
cdef yasm_floatnum* yasm_floatnum_copy(yasm_floatnum *flt)
cdef void yasm_floatnum_destroy(yasm_floatnum *flt)
cdef void yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
- yasm_floatnum *operand, size_t line)
+ yasm_floatnum *operand)
cdef int yasm_floatnum_get_int(yasm_floatnum *flt, size_t *ret_val)
cdef int yasm_floatnum_get_sized(yasm_floatnum *flt, unsigned char *ptr,
size_t destsize, size_t valsize, size_t shift, int
- bigendian, int warn, size_t line)
+ bigendian, int warn)
cdef int yasm_floatnum_check_size(yasm_floatnum *flt, size_t size)
cdef void yasm_floatnum_print(yasm_floatnum *flt, FILE *f)
def __neg__(self):
result = FloatNum(self)
- yasm_floatnum_calc((<FloatNum>result).flt, YASM_EXPR_NEG, NULL, 0)
+ yasm_floatnum_calc((<FloatNum>result).flt, YASM_EXPR_NEG, NULL)
return result
def __pos__(self): return self
cdef extern from "libyasm/intnum.h":
cdef void yasm_intnum_initialize()
cdef void yasm_intnum_cleanup()
- cdef yasm_intnum *yasm_intnum_create_dec(char *str, unsigned long line)
- cdef yasm_intnum *yasm_intnum_create_bin(char *str, unsigned long line)
- cdef yasm_intnum *yasm_intnum_create_oct(char *str, unsigned long line)
- cdef yasm_intnum *yasm_intnum_create_hex(char *str, unsigned long line)
- cdef yasm_intnum *yasm_intnum_create_charconst_nasm(char *str,
- unsigned long line)
+ cdef yasm_intnum *yasm_intnum_create_dec(char *str)
+ cdef yasm_intnum *yasm_intnum_create_bin(char *str)
+ cdef yasm_intnum *yasm_intnum_create_oct(char *str)
+ cdef yasm_intnum *yasm_intnum_create_hex(char *str)
+ cdef yasm_intnum *yasm_intnum_create_charconst_nasm(char *str)
cdef yasm_intnum *yasm_intnum_create_uint(unsigned long i)
cdef yasm_intnum *yasm_intnum_create_int(long i)
cdef yasm_intnum *yasm_intnum_create_leb128(unsigned char *ptr,
- int sign, unsigned long *size, unsigned long line)
+ int sign, unsigned long *size)
cdef yasm_intnum *yasm_intnum_create_sized(unsigned char *ptr, int sign,
- size_t srcsize, int bigendian, unsigned long line)
+ size_t srcsize, int bigendian)
cdef yasm_intnum *yasm_intnum_copy(yasm_intnum *intn)
cdef void yasm_intnum_destroy(yasm_intnum *intn)
cdef void yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op,
- yasm_intnum *operand, unsigned long line)
+ yasm_intnum *operand)
cdef void yasm_intnum_zero(yasm_intnum *intn)
cdef void yasm_intnum_set_uint(yasm_intnum *intn, unsigned long val)
cdef int yasm_intnum_is_zero(yasm_intnum *acc)
cdef unsigned long yasm_intnum_get_uint(yasm_intnum *intn)
cdef long yasm_intnum_get_int(yasm_intnum *intn)
cdef void yasm_intnum_get_sized(yasm_intnum *intn, unsigned char *ptr,
- size_t destsize, size_t valsize, int shift, int bigendian, int warn,
- unsigned long line)
+ size_t destsize, size_t valsize, int shift, int bigendian, int warn)
cdef int yasm_intnum_check_size(yasm_intnum *intn, size_t size,
size_t rshift, int rangetype)
cdef unsigned long yasm_intnum_get_leb128(yasm_intnum *intn,
if isinstance(x, IntNum):
result = IntNum(x)
if y is None:
- yasm_intnum_calc((<IntNum>result).intn, op, NULL, 0)
+ yasm_intnum_calc((<IntNum>result).intn, op, NULL)
else:
# Coerce to intnum if not already
if isinstance(y, IntNum):
rhs = y
else:
rhs = IntNum(y)
- yasm_intnum_calc((<IntNum>result).intn, op, (<IntNum>rhs).intn, 0)
+ yasm_intnum_calc((<IntNum>result).intn, op, (<IntNum>rhs).intn)
return result
elif isinstance(y, IntNum):
# Reversed operation - x OP y still, just y is intnum, x isn't.
result = IntNum(x)
- yasm_intnum_calc((<IntNum>result).intn, op, (<IntNum>y).intn, 0)
+ yasm_intnum_calc((<IntNum>result).intn, op, (<IntNum>y).intn)
return result
else:
raise NotImplementedError
raise ValueError
_PyLong_AsByteArray(val, buf, 16, 1, 1)
- self.intn = yasm_intnum_create_sized(buf, 1, 16, 0, 0)
+ self.intn = yasm_intnum_create_sized(buf, 1, 16, 0)
def __dealloc__(self):
if self.intn != NULL: yasm_intnum_destroy(self.intn)
def __long__(self):
cdef unsigned char buf[16]
- yasm_intnum_get_sized(self.intn, buf, 16, 128, 0, 0, 0, 0)
+ yasm_intnum_get_sized(self.intn, buf, 16, 128, 0, 0, 0)
return _PyLong_FromByteArray(buf, 16, 1, 1)
def __repr__(self):
rhs = x
else:
rhs = IntNum(x)
- yasm_intnum_calc(self.intn, op, (<IntNum>rhs).intn, 0)
+ yasm_intnum_calc(self.intn, op, (<IntNum>rhs).intn)
return self
def __iadd__(self, x): return self.__op(YASM_EXPR_ADD, x)
rhs = x
else:
rhs = IntNum(x)
- yasm_intnum_calc(t, YASM_EXPR_SUB, (<IntNum>rhs).intn, 0)
+ yasm_intnum_calc(t, YASM_EXPR_SUB, (<IntNum>rhs).intn)
result = yasm_intnum_sign(t)
yasm_intnum_destroy(t)
return result
include "coretype.pxi"
+include "errwarn.pxi"
include "intnum.pxi"
include "floatnum.pxi"
include "expr.pxi"
BitVector_Boot()
yasm_intnum_initialize()
yasm_floatnum_initialize()
+ yasm_errwarn_initialize()
def __cleanup():
yasm_floatnum_cleanup()
yasm_intnum_cleanup()
+ yasm_errwarn_cleanup()
BitVector_Shutdown()
__initialize()