src/expr-int.h \
src/symrec.c \
src/symrec.h \
- src/globals.c \
- src/globals.h \
+ src/linemgr.h \
src/util.h \
src/coretype.h \
src/file.c \
src/objfmt.c \
src/parser.c \
src/module.h \
- src/module.c
+ src/module.c \
+ src/linemgr.c
EXTRA_DIST += \
#include "ltdl.h"
#include "module.h"
-#include "globals.h"
typedef struct module {
#include "bitvect.h"
#include "file.h"
-#include "globals.h"
#include "options.h"
+#include "linemgr.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
#include "arch.h"
+/* YASM's line manager (for parse stage). */
+extern linemgr yasm_linemgr;
+
/* Extra path to search for our modules. */
#ifndef YASM_MODULE_PATH_ENV
# define YASM_MODULE_PATH_ENV "YASM_MODULE_PATH"
in_filename = xstrdup("-");
}
- /* Initialize line info */
- line_set(in_filename, 1, 1);
+ /* Initialize line manager */
+ yasm_linemgr.initialize();
+ yasm_linemgr.set(in_filename, 1, 1);
/* handle preproc-only case here */
if (preproc_only) {
/* Pre-process until done */
cur_preproc->initialize(in, in_filename);
- while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0)
+ while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE,
+ &yasm_linemgr)) != 0)
fwrite(preproc_buf, got, 1, obj);
if (in != stdin)
fclose(obj);
if (GetNumErrors() > 0) {
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
if (obj != stdout)
remove(obj_filename);
xfree(preproc_buf);
}
/* Parse! */
- sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt, in,
- in_filename);
+ sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt,
+ &yasm_linemgr, in, in_filename);
/* Close input file */
if (in != stdin)
fclose(in);
if (GetNumErrors() > 0) {
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
cleanup(sections);
return EXIT_FAILURE;
}
cur_optimizer->optimize(sections);
if (GetNumErrors() > 0) {
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
cleanup(sections);
return EXIT_FAILURE;
}
* object file (to make sure it's not left newer than the source).
*/
if (GetNumErrors() > 0) {
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
remove(obj_filename);
cleanup(sections);
return EXIT_FAILURE;
}
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
cleanup(sections);
return EXIT_SUCCESS;
if (sections)
sections_delete(sections);
symrec_delete_all();
- line_shutdown();
+ yasm_linemgr.cleanup();
floatnum_shutdown();
intnum_shutdown();
src/expr-int.h \
src/symrec.c \
src/symrec.h \
- src/globals.c \
- src/globals.h \
+ src/linemgr.h \
src/util.h \
src/coretype.h \
src/file.c \
src/objfmt.c \
src/parser.c \
src/module.h \
- src/module.c
+ src/module.c \
+ src/linemgr.c
EXTRA_DIST += \
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
-#include "globals.h"
#include "expr.h"
#include "bytecode.h"
* parse functions! The bytecode and output functions should be able
* to handle any CPU.
*/
- void (*switch_cpu) (const char *cpuid);
+ void (*switch_cpu) (const char *cpuid, unsigned long lindex);
/* Checks an generic identifier to see if it matches architecture
* specific names for instructions, registers, etc (see the
* used for TARGETMOD, REG, and SEGREG return values.
*/
arch_check_id_retval (*check_identifier) (unsigned long data[4],
- const char *id);
+ const char *id,
+ unsigned long lindex);
/* Architecture-specific directive support. Returns 1 if directive was
* not recognized. Returns 0 if directive was recognized, even if it
*/
int (*directive) (const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams,
- sectionhead *headp);
+ sectionhead *headp, unsigned long lindex);
/* Creates an instruction. Creates a bytecode by matching the
* instruction data and the parameters given with a valid instruction.
int num_operands, /*@null@*/
insn_operandhead *operands,
section *cur_section,
- /*@null@*/ bytecode *prev_bc);
+ /*@null@*/ bytecode *prev_bc,
+ unsigned long lindex);
/* Handle an instruction prefix by modifying bc as necessary. */
- void (*handle_prefix) (bytecode *bc, const unsigned long data[4]);
+ void (*handle_prefix) (bytecode *bc, const unsigned long data[4],
+ unsigned long lindex);
/* Handle an segment register instruction prefix by modifying bc as
* necessary.
*/
- void (*handle_seg_prefix) (bytecode *bc, unsigned long segreg);
+ void (*handle_seg_prefix) (bytecode *bc, unsigned long segreg,
+ unsigned long lindex);
/* Handle memory expression segment overrides by modifying ea as
* necessary.
*/
- void (*handle_seg_override) (effaddr *ea, unsigned long segreg);
+ void (*handle_seg_override) (effaddr *ea, unsigned long segreg,
+ unsigned long lindex);
/* Convert an expression into an effective address. */
effaddr * (*ea_new_expr) (/*@keep@*/ expr *e);
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
}
immval *
-imm_new_int(unsigned long int_val)
+imm_new_int(unsigned long int_val, unsigned long lindex)
{
- return imm_new_expr(expr_new_ident(ExprInt(intnum_new_uint(int_val))));
+ return imm_new_expr(expr_new_ident(ExprInt(intnum_new_uint(int_val)),
+ lindex));
}
immval *
bc_set_multiple(bytecode *bc, expr *e)
{
if (bc->multiple)
- bc->multiple = expr_new_tree(bc->multiple, EXPR_MUL, e);
+ bc->multiple = expr_new_tree(bc->multiple, EXPR_MUL, e, e->line);
else
bc->multiple = e;
}
bytecode *
-bc_new_common(bytecode_type type, size_t size)
+bc_new_common(bytecode_type type, size_t size, unsigned long lindex)
{
bytecode *bc = xmalloc(size);
bc->multiple = (expr *)NULL;
bc->len = 0;
- bc->line = line_index;
+ bc->line = lindex;
bc->offset = 0;
}
bytecode *
-bc_new_data(datavalhead *datahead, unsigned char size)
+bc_new_data(datavalhead *datahead, unsigned char size, unsigned long lindex)
{
bytecode_data *data;
- data = (bytecode_data *)bc_new_common(BC_DATA, sizeof(bytecode_data));
+ data = (bytecode_data *)bc_new_common(BC_DATA, sizeof(bytecode_data),
+ lindex);
data->datahead = *datahead;
data->size = size;
}
bytecode *
-bc_new_reserve(expr *numitems, unsigned char itemsize)
+bc_new_reserve(expr *numitems, unsigned char itemsize, unsigned long lindex)
{
bytecode_reserve *reserve;
reserve = (bytecode_reserve *)bc_new_common(BC_RESERVE,
- sizeof(bytecode_reserve));
+ sizeof(bytecode_reserve),
+ lindex);
/*@-mustfree@*/
reserve->numitems = numitems;
}
bytecode *
-bc_new_incbin(char *filename, expr *start, expr *maxlen)
+bc_new_incbin(char *filename, expr *start, expr *maxlen, unsigned long lindex)
{
bytecode_incbin *incbin;
incbin = (bytecode_incbin *)bc_new_common(BC_INCBIN,
- sizeof(bytecode_incbin));
+ sizeof(bytecode_incbin),
+ lindex);
/*@-mustfree@*/
incbin->filename = filename;
}
bytecode *
-bc_new_align(unsigned long boundary)
+bc_new_align(unsigned long boundary, unsigned long lindex)
{
bytecode_align *align;
- align = (bytecode_align *)bc_new_common(BC_ALIGN, sizeof(bytecode_align));
+ align = (bytecode_align *)bc_new_common(BC_ALIGN, sizeof(bytecode_align),
+ lindex);
align->boundary = boundary;
bytecode *
bc_new_objfmt_data(unsigned int type, unsigned long len, objfmt *of,
- void *data)
+ void *data, unsigned long lindex)
{
bytecode_objfmt_data *objfmt_data;
objfmt_data =
(bytecode_objfmt_data *)bc_new_common(BC_ALIGN,
- sizeof(bytecode_objfmt_data));
+ sizeof(bytecode_objfmt_data),
+ lindex);
objfmt_data->type = type;
objfmt_data->of = of;
const bytecode_incbin *incbin;
const bytecode_align *align;
const bytecode_objfmt_data *objfmt_data;
- const char *filename;
- unsigned long line;
switch (bc->type) {
case BC_EMPTY:
else
expr_print(f, bc->multiple);
fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
- line_lookup(bc->line, &filename, &line);
- fprintf(f, "%*sFilename=\"%s\" Line Number=%lu\n", indent_level, "",
- filename, line);
+ fprintf(f, "%*sLine Index=%lu\n", indent_level, "", bc->line);
fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
}
* the circular reference error to filter through.
*/
if (temp && expr_contains(temp, EXPR_FLOAT))
- ErrorAt(line,
- _("expression must not contain floating point value"));
+ Error(line, _("expression must not contain floating point value"));
else
- ErrorAt(line,
- _("attempt to reserve non-constant quantity of space"));
+ Error(line,
+ _("attempt to reserve non-constant quantity of space"));
retval = BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
} else
*len += intnum_get_uint(num)*reserve->itemsize;
/* Open file and determine its length */
f = fopen(incbin->filename, "rb");
if (!f) {
- ErrorAt(line, _("`incbin': unable to open file `%s'"),
- incbin->filename);
+ Error(line, _("`incbin': unable to open file `%s'"), incbin->filename);
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
if (fseek(f, 0L, SEEK_END) < 0) {
- ErrorAt(line, _("`incbin': unable to seek on file `%s'"),
- incbin->filename);
+ Error(line, _("`incbin': unable to seek on file `%s'"),
+ incbin->filename);
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
flen = (unsigned long)ftell(f);
/* Compute length of incbin from start, maxlen, and len */
if (start > flen) {
- WarningAt(line, _("`incbin': start past end of file `%s'"),
- incbin->filename);
+ Warning(line, _("`incbin': start past end of file `%s'"),
+ incbin->filename);
start = flen;
}
flen -= start;
if (!num) {
retval = BC_RESOLVE_UNKNOWN_LEN;
if (temp && expr_contains(temp, EXPR_FLOAT)) {
- ErrorAt(bc->line,
- _("expression must not contain floating point value"));
+ Error(bc->line,
+ _("expression must not contain floating point value"));
retval |= BC_RESOLVE_ERROR;
}
} else
/* Open file */
f = fopen(incbin->filename, "rb");
if (!f) {
- ErrorAt(line, _("`incbin': unable to open file `%s'"),
- incbin->filename);
+ Error(line, _("`incbin': unable to open file `%s'"), incbin->filename);
return 1;
}
/* Seek to start of data */
if (fseek(f, (long)start, SEEK_SET) < 0) {
- ErrorAt(line, _("`incbin': unable to seek on file `%s'"),
- incbin->filename);
+ Error(line, _("`incbin': unable to seek on file `%s'"),
+ incbin->filename);
fclose(f);
return 1;
}
/* Read len bytes */
if (fread(*bufp, (size_t)len, 1, f) < (size_t)len) {
- ErrorAt(line, _("`incbin': unable to read %lu bytes from file `%s'"),
- len, incbin->filename);
+ Error(line, _("`incbin': unable to read %lu bytes from file `%s'"),
+ len, incbin->filename);
fclose(f);
return 1;
}
void bc_initialize(arch *a);
-/*@only@*/ immval *imm_new_int(unsigned long int_val);
+/*@only@*/ immval *imm_new_int(unsigned long int_val, unsigned long lindex);
/*@only@*/ immval *imm_new_expr(/*@keep@*/ expr *e);
/*@observer@*/ const expr *ea_get_disp(const effaddr *ea);
void bc_set_multiple(bytecode *bc, /*@keep@*/ expr *e);
-/*@only@*/ bytecode *bc_new_common(bytecode_type type, size_t datasize);
-/*@only@*/ bytecode *bc_new_data(datavalhead *datahead, unsigned char size);
+/*@only@*/ bytecode *bc_new_common(bytecode_type type, size_t datasize,
+ unsigned long lindex);
+/*@only@*/ bytecode *bc_new_data(datavalhead *datahead, unsigned char size,
+ unsigned long lindex);
/*@only@*/ bytecode *bc_new_reserve(/*@only@*/ expr *numitems,
- unsigned char itemsize);
+ unsigned char itemsize,
+ unsigned long lindex);
/*@only@*/ bytecode *bc_new_incbin(/*@only@*/ char *filename,
/*@only@*/ /*@null@*/ expr *start,
- /*@only@*/ /*@null@*/ expr *maxlen);
-/*@only@*/ bytecode *bc_new_align(unsigned long boundary);
+ /*@only@*/ /*@null@*/ expr *maxlen,
+ unsigned long lindex);
+/*@only@*/ bytecode *bc_new_align(unsigned long boundary,
+ unsigned long lindex);
/*@only@*/ bytecode *bc_new_objfmt_data(unsigned int type, unsigned long len,
- objfmt *of, /*@only@*/ void *data);
+ objfmt *of, /*@only@*/ void *data,
+ unsigned long lindex);
void bc_delete(/*@only@*/ /*@null@*/ bytecode *bc);
typedef struct intnum intnum;
typedef struct floatnum floatnum;
+typedef struct linemgr linemgr;
+
typedef enum {
EXPR_ADD,
EXPR_SUB,
# include <stdarg.h>
#endif
-#include "globals.h"
+#include "linemgr.h"
#include "errwarn.h"
* system.
*/
void
-ParserError(const char *s)
+ParserError(unsigned long lindex, const char *s)
{
- Error("%s %s", _("parser error:"), s);
+ Error(lindex, "%s %s", _("parser error:"), s);
previous_we->type = WE_PARSERERROR;
}
-/* Register an error during the parser stage (uses global line_index). Does
- * not print the error, only stores it for OutputAllErrorWarning() to print.
- */
-void
-Error(const char *fmt, ...)
-{
- va_list va;
- va_start(va, fmt);
- error_common(line_index, fmt, va);
- va_end(va);
-}
-
/* Register an error at line lindex. Does not print the error, only stores it
* for OutputAllErrorWarning() to print.
*/
void
-ErrorAt(unsigned long lindex, const char *fmt, ...)
+Error(unsigned long lindex, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
va_end(va);
}
-/* Register a warning during the parser stage (uses global line_index). Does
- * not print the warning, only stores it for OutputAllErrorWarning() to print.
- */
-void
-Warning(const char *fmt, ...)
-{
- va_list va;
- va_start(va, fmt);
- warning_common(line_index, fmt, va);
- va_end(va);
-}
-
/* Register an warning at line lindex. Does not print the warning, only stores
* it for OutputAllErrorWarning() to print.
*/
void
-WarningAt(unsigned long lindex, const char *fmt, ...)
+Warning(unsigned long lindex, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
/* Output all previously stored errors and warnings to stderr. */
void
-OutputAllErrorWarning(void)
+OutputAllErrorWarning(linemgr *lm)
{
errwarn *we;
const char *filename;
while (!SLIST_EMPTY(&errwarns)) {
we = SLIST_FIRST(&errwarns);
/* Output error/warning */
- line_lookup(we->line, &filename, &line);
+ lm->lookup(we->line, &filename, &line);
if (we->type == WE_ERROR)
fprintf(stderr, "%s:%lu: %s\n", filename, line, we->msg);
else
/*@shared@*/ char *conv_unprint(char ch);
-void ParserError(const char *);
+void ParserError(unsigned long lindex, const char *);
/*@exits@*/ void InternalError_(const char *file, unsigned int line,
const char *message);
#define InternalError(msg) InternalError_(__FILE__, __LINE__, msg)
/*@exits@*/ void Fatal(fatal_num);
-void Error(const char *, ...) /*@printflike@*/;
-void Warning(const char *, ...) /*@printflike@*/;
-/* Use Error() and Warning() instead of ErrorAt() and WarningAt() when being
- * called in line order from a parser.
- */
-void ErrorAt(unsigned long lindex, const char *, ...) /*@printflike@*/;
-void WarningAt(unsigned long lindex, const char *, ...) /*@printflike@*/;
+void Error(unsigned long lindex, const char *, ...) /*@printflike@*/;
+void Warning(unsigned long lindex, const char *, ...) /*@printflike@*/;
/* These two functions immediately output the error or warning, with no file
* or line information. They should be used for errors and warnings outside
unsigned int GetNumErrors(void);
/* Outputs all errors/warnings to standard error. */
-void OutputAllErrorWarning(void);
+void OutputAllErrorWarning(linemgr *lm);
#endif
#include "bitvect.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
* If it's a unary operator, put the element in left and set right=NULL. */
/*@-compmempass@*/
expr *
-expr_new(ExprOp op, ExprItem *left, ExprItem *right)
+expr_new(ExprOp op, ExprItem *left, ExprItem *right, unsigned long lindex)
{
expr *ptr, *sube;
ptr = xmalloc(sizeof(expr));
}
}
- ptr->line = line_index;
+ ptr->line = lindex;
return ptr;
}
symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
section_is_absolute(sect) &&
(dist = calc_bc_dist(sect, NULL, precbc))) {
+ const expr *start = section_get_start(sect);
e->terms[i].type = EXPR_EXPR;
e->terms[i].data.expn =
- expr_new(EXPR_ADD,
- ExprExpr(expr_copy(section_get_start(sect))),
- ExprInt(dist));
+ expr_new(EXPR_ADD, ExprExpr(expr_copy(start)), ExprInt(dist),
+ start->line);
}
}
* floatnums present below; if there ARE floatnums, recurse.
*/
if (e->terms[0].type == EXPR_FLOAT)
- floatnum_calc(e->terms[0].data.flt, EXPR_NEG, NULL);
+ floatnum_calc(e->terms[0].data.flt, EXPR_NEG, NULL, e->line);
else if (e->terms[0].type == EXPR_EXPR &&
expr_contains(e->terms[0].data.expn, EXPR_FLOAT))
expr_xform_neg_helper(e->terms[0].data.expn);
/* Check for circular reference */
SLIST_FOREACH(np, eh, next) {
if (np->e == equ_expr) {
- ErrorAt(e->line, _("circular reference detected."));
+ Error(e->line, _("circular reference detected."));
return e;
}
}
void expr_initialize(arch *a);
/*@only@*/ expr *expr_new(ExprOp, /*@only@*/ ExprItem *,
- /*@only@*/ /*@null@*/ ExprItem *);
+ /*@only@*/ /*@null@*/ ExprItem *,
+ unsigned long lindex);
/*@only@*/ ExprItem *ExprSym(/*@keep@*/ symrec *);
/*@only@*/ ExprItem *ExprExpr(/*@keep@*/ expr *);
/*@only@*/ ExprItem *ExprFloat(/*@keep@*/ floatnum *);
/*@only@*/ ExprItem *ExprReg(unsigned long reg);
-#define expr_new_tree(l,o,r) \
- expr_new ((o), ExprExpr(l), ExprExpr(r))
-#define expr_new_branch(o,r) \
- expr_new ((o), ExprExpr(r), (ExprItem *)NULL)
-#define expr_new_ident(r) \
- expr_new (EXPR_IDENT, (r), (ExprItem *)NULL)
+#define expr_new_tree(l,o,r,i) \
+ expr_new ((o), ExprExpr(l), ExprExpr(r), i)
+#define expr_new_branch(o,r,i) \
+ expr_new ((o), ExprExpr(r), (ExprItem *)NULL, i)
+#define expr_new_ident(r,i) \
+ expr_new (EXPR_IDENT, (r), (ExprItem *)NULL, i)
/* allocates and makes an exact duplicate of e */
expr *expr_copy(const expr *e);
}
void
-floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand)
+floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand,
+ unsigned long lindex)
{
if (op != EXPR_NEG)
- Error(_("Unsupported floating-point arithmetic operation"));
+ Error(lindex, _("Unsupported floating-point arithmetic operation"));
else
acc->sign ^= 1;
}
void floatnum_delete(/*@only@*/ floatnum *flt);
/* calculation function: acc = acc op operand */
-void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand);
+void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand,
+ unsigned long lindex);
/* The get functions return nonzero if flt can't fit into that size format:
* -1 if underflow occurred, 1 if overflow occurred.
}
intnum *
-intnum_new_dec(char *str)
+intnum_new_dec(char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
}
if (BitVector_from_Dec_static(conv_bv,
(unsigned char *)str) == ErrCode_Ovfl)
- Warning(_("Numeric constant too large for internal format"));
+ Warning(lindex, _("Numeric constant too large for internal format"));
if (Set_Max(conv_bv) < 32) {
intn->type = INTNUM_UL;
intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
}
intnum *
-intnum_new_bin(char *str)
+intnum_new_bin(char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
intn->origsize = (unsigned char)strlen(str);
if(intn->origsize > BITVECT_ALLOC_SIZE)
- Warning(_("Numeric constant too large for internal format"));
+ Warning(lindex, _("Numeric constant too large for internal format"));
if (!conv_bv) {
conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
}
intnum *
-intnum_new_oct(char *str)
+intnum_new_oct(char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
intn->origsize = strlen(str)*3;
if(intn->origsize > BITVECT_ALLOC_SIZE)
- Warning(_("Numeric constant too large for internal format"));
+ Warning(lindex, _("Numeric constant too large for internal format"));
if (!conv_bv) {
conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
}
intnum *
-intnum_new_hex(char *str)
+intnum_new_hex(char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
intn->origsize = strlen(str)*4;
if(intn->origsize > BITVECT_ALLOC_SIZE)
- Warning(_("Numeric constant too large for internal format"));
+ Warning(lindex, _("Numeric constant too large for internal format"));
if (!conv_bv) {
conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
/*@-usedef -compdef -uniondef@*/
intnum *
-intnum_new_charconst_nasm(const char *str)
+intnum_new_charconst_nasm(const char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
size_t len = strlen(str);
if (len > 4)
- Warning(_("character constant too large, ignoring trailing characters"));
+ Warning(lindex,
+ _("character constant too large, ignoring trailing characters"));
intn->val.ul = 0;
intn->type = INTNUM_UL;
/* Clean up internal allocations */
void intnum_shutdown(void);
-/*@only@*/ intnum *intnum_new_dec(char *str);
-/*@only@*/ intnum *intnum_new_bin(char *str);
-/*@only@*/ intnum *intnum_new_oct(char *str);
-/*@only@*/ intnum *intnum_new_hex(char *str);
+/*@only@*/ intnum *intnum_new_dec(char *str, unsigned long lindex);
+/*@only@*/ intnum *intnum_new_bin(char *str, unsigned long lindex);
+/*@only@*/ intnum *intnum_new_oct(char *str, unsigned long lindex);
+/*@only@*/ intnum *intnum_new_hex(char *str, unsigned long lindex);
/* convert character constant to integer value, using NASM rules */
-/*@only@*/ intnum *intnum_new_charconst_nasm(const char *str);
+/*@only@*/ intnum *intnum_new_charconst_nasm(const char *str,
+ unsigned long lindex);
/*@only@*/ intnum *intnum_new_uint(unsigned long i);
/*@only@*/ intnum *intnum_new_int(long i);
/*@only@*/ intnum *intnum_copy(const intnum *intn);
/*
- * Global variables
+ * YASM assembler line manager (for parse stage)
*
- * Copyright (C) 2001 Peter Johnson
+ * Copyright (C) 2002 Peter Johnson
*
* This file is part of YASM.
*
#include "hamt.h"
-#include "globals.h"
+#include "linemgr.h"
/* Source lines tracking */
} line_index_mapping;
/* Shared storage for filenames */
-static /*@only@*/ /*@null@*/ HAMT *filename_table = NULL;
+static /*@only@*/ /*@null@*/ HAMT *filename_table;
/* Virtual line number. Uniquely specifies every line read by the parser. */
-unsigned long line_index = 1;
-static /*@only@*/ /*@null@*/ line_index_mapping_head *line_index_map = NULL;
-
-/* Global assembler options. */
-unsigned int asm_options = 0;
+static unsigned long line_index;
+static /*@only@*/ /*@null@*/ line_index_mapping_head *line_index_map;
static void
filename_delete_one(/*@only@*/ void *d)
xfree(d);
}
-void
-line_set(const char *filename, unsigned long line, unsigned long line_inc)
+static void
+yasm_linemgr_set(const char *filename, unsigned long line,
+ unsigned long line_inc)
{
char *copy;
int replace = 0;
line_index_mapping *mapping;
/* Create a new mapping in the map */
- if (!line_index_map) {
- /* initialize vector */
- line_index_map = xmalloc(sizeof(line_index_mapping_head));
- line_index_map->vector = xmalloc(8*sizeof(line_index_mapping));
- line_index_map->size = 0;
- line_index_map->allocated = 8;
- }
if (line_index_map->size >= line_index_map->allocated) {
/* allocate another size bins when full for 2x space */
line_index_map->vector = xrealloc(line_index_map->vector,
/* Copy the filename (via shared storage) */
copy = xstrdup(filename);
- if (!filename_table)
- filename_table = HAMT_new();
/*@-aliasunique@*/
mapping->filename = HAMT_insert(filename_table, copy, copy, &replace,
filename_delete_one);
mapping->line_inc = line_inc;
}
-void
-line_shutdown(void)
+static void
+yasm_linemgr_initialize(void)
+{
+ filename_table = HAMT_new();
+
+ line_index = 1;
+
+ /* initialize mapping vector */
+ line_index_map = xmalloc(sizeof(line_index_mapping_head));
+ line_index_map->vector = xmalloc(8*sizeof(line_index_mapping));
+ line_index_map->size = 0;
+ line_index_map->allocated = 8;
+}
+
+static void
+yasm_linemgr_cleanup(void)
{
if (line_index_map) {
xfree(line_index_map->vector);
}
}
-void
-line_lookup(unsigned long lindex, const char **filename, unsigned long *line)
+static unsigned long
+yasm_linemgr_get_current(void)
+{
+ return line_index;
+}
+
+static unsigned long
+yasm_linemgr_goto_next(void)
+{
+ return ++line_index;
+}
+
+static void
+yasm_linemgr_lookup(unsigned long lindex, const char **filename,
+ unsigned long *line)
{
line_index_mapping *mapping;
unsigned long vindex, step;
*filename = mapping->filename;
*line = mapping->line+mapping->line_inc*(lindex-mapping->index);
}
+
+linemgr yasm_linemgr = {
+ yasm_linemgr_initialize,
+ yasm_linemgr_cleanup,
+ yasm_linemgr_get_current,
+ yasm_linemgr_goto_next,
+ yasm_linemgr_set,
+ yasm_linemgr_lookup
+};
/* $IdPath$
- * Globals header file
+ * Line manager (for parse stage) header file
*
- * Copyright (C) 2001 Peter Johnson
+ * Copyright (C) 2002 Peter Johnson
*
* This file is part of YASM.
*
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef YASM_GLOBALS_H
-#define YASM_GLOBALS_H
+#ifndef YASM_LINEMGR_H
+#define YASM_LINEMGR_H
-/* Virtual line number. Uniquely specifies every line read by the parser. */
-extern unsigned long line_index;
+struct linemgr {
+ /* Initialize cur_lindex and any manager internal data structures. */
+ void (*initialize) (void);
-/* Global assembler options. */
-extern unsigned int asm_options;
+ /* Cleans up any memory allocated by initialize. */
+ void (*cleanup) (void);
-void line_set(const char *filename, unsigned long line,
- unsigned long line_inc);
-void line_shutdown(void);
-void line_lookup(unsigned long lindex, /*@out@*/ const char **filename,
- /*@out@*/ unsigned long *line);
+ /* Returns the current line index. */
+ unsigned long (*get_current) (void);
+
+ /* Goes to the next line (increments the current line index), returns
+ * the current (new) line index.
+ */
+ unsigned long (*goto_next) (void);
+
+ /* Sets a new file/line association starting point at the current line
+ * index. line_inc indicates how much the "real" line is incremented by
+ * for each line index increment (0 is perfectly legal).
+ */
+ void (*set) (const char *filename, unsigned long line,
+ unsigned long line_inc);
+
+ /* Look up the associated actual file and line for a line index. */
+ void (*lookup) (unsigned long lindex, /*@out@*/ const char **filename,
+ /*@out@*/ unsigned long *line);
+};
#endif
*/
/*@observer@*/ /*@null@*/ section *
(*sections_switch)(sectionhead *headp, valparamhead *valparams,
- /*@null@*/ valparamhead *objext_valparams);
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex);
/* Object format-specific data handling functions for sections.
* May be NULL if no data is ever allocated in sections_switch().
* May be NULL if objfmt doesn't care about such declarations.
*/
void (*extern_declare)(symrec *sym,
- /*@null@*/ valparamhead *objext_valparams);
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex);
void (*global_declare)(symrec *sym,
- /*@null@*/ valparamhead *objext_valparams);
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex);
void (*common_declare)(symrec *sym, /*@only@*/ expr *size,
- /*@null@*/ valparamhead *objext_valparams);
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex);
/* May be NULL if symrec_set_of_data() is never called. */
void (*symrec_data_delete)(/*@only@*/ void *data);
*/
int (*directive)(const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams,
- sectionhead *headp);
+ sectionhead *headp, unsigned long lindex);
/* Bytecode objfmt data (BC_OBJFMT_DATA) handling functions.
* May be NULL if no BC_OBJFMT_DATA is ever allocated by the object format.
* This function returns the starting section of a linked list of sections
* (whatever was in the file).
*/
- sectionhead *(*do_parse) (preproc *pp, arch *a, objfmt *of, FILE *f,
- const char *in_filename);
+ sectionhead *(*do_parse) (preproc *pp, arch *a, objfmt *of, linemgr *lm,
+ FILE *f, const char *in_filename);
};
/* Generic functions for all parsers - implemented in src/parser.c */
/* Gets more preprocessed source code (up to max_size bytes) into buf.
* Note that more than a single line may be returned in buf. */
- size_t (*input) (/*@out@*/ char *buf, size_t max_size);
+ size_t (*input) (/*@out@*/ char *buf, size_t max_size, linemgr *lm);
};
#endif
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
vp_new(vp, xstrdup(of->default_section_name), NULL);
vps_initialize(&vps);
vps_append(&vps, vp);
- s = of->sections_switch(headp, &vps, NULL);
+ s = of->sections_switch(headp, &vps, NULL, 0);
vps_delete(&vps);
return s;
/*@-onlytrans@*/
section *
sections_switch_general(sectionhead *headp, const char *name,
- unsigned long start, int res_only, int *isnew)
+ unsigned long start, int res_only, int *isnew,
+ unsigned long lindex)
{
section *s;
s->data.general.name = xstrdup(name);
s->data.general.of = NULL;
s->data.general.of_data = NULL;
- s->start = expr_new_ident(ExprInt(intnum_new_uint(start)));
+ s->start = expr_new_ident(ExprInt(intnum_new_uint(start)), lindex);
bcs_initialize(&s->bc);
s->opt_flags = 0;
}
void
-section_set_start(section *sect, unsigned long start)
+section_set_start(section *sect, unsigned long start, unsigned long lindex)
{
expr_delete(sect->start);
- sect->start = expr_new_ident(ExprInt(intnum_new_uint(start)));
+ sect->start = expr_new_ident(ExprInt(intnum_new_uint(start)), lindex);
}
const expr *
const char *name,
unsigned long start,
int res_only,
- /*@out@*/ int *isnew);
+ /*@out@*/ int *isnew,
+ unsigned long lindex);
/*@dependent@*/ section *sections_switch_absolute(sectionhead *headp,
/*@keep@*/ expr *start);
/*@observer@*/ /*@null@*/ const char *section_get_name(const section *sect);
-void section_set_start(section *sect, unsigned long start);
+void section_set_start(section *sect, unsigned long start,
+ unsigned long lindex);
/*@observer@*/ const expr *section_get_start(const section *sect);
void section_delete(/*@only@*/ section *sect);
#include "hamt.h"
-#include "globals.h"
#include "errwarn.h"
#include "floatnum.h"
#include "expr.h"
}
symrec *
-symrec_use(const char *name)
+symrec_use(const char *name, unsigned long lindex)
{
symrec *rec = symrec_get_or_new(name, 1);
if (rec->line == 0)
- rec->line = line_index; /* set line number of first use */
+ rec->line = lindex; /* set line number of first use */
rec->status |= SYM_USED;
return rec;
}
static /*@dependent@*/ symrec *
-symrec_define(const char *name, SymType type, int in_table)
+symrec_define(const char *name, SymType type, int in_table,
+ unsigned long lindex)
{
symrec *rec = symrec_get_or_new(name, in_table);
/* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
if ((rec->status & SYM_DEFINED) ||
(rec->visibility & (SYM_COMMON | SYM_EXTERN))) {
- Error(_("duplicate definition of `%s'; first defined on line %lu"),
+ Error(lindex,
+ _("duplicate definition of `%s'; first defined on line %lu"),
name, rec->line);
} else {
- rec->line = line_index; /* set line number of definition */
+ rec->line = lindex; /* set line number of definition */
rec->type = type;
rec->status |= SYM_DEFINED;
}
}
symrec *
-symrec_define_equ(const char *name, expr *e)
+symrec_define_equ(const char *name, expr *e, unsigned long lindex)
{
- symrec *rec = symrec_define(name, SYM_EQU, 1);
+ symrec *rec = symrec_define(name, SYM_EQU, 1, lindex);
rec->value.expn = e;
rec->status |= SYM_VALUED;
return rec;
symrec *
symrec_define_label(const char *name, section *sect, bytecode *precbc,
- int in_table)
+ int in_table, unsigned long lindex)
{
- symrec *rec = symrec_define(name, SYM_LABEL, in_table);
+ symrec *rec = symrec_define(name, SYM_LABEL, in_table, lindex);
rec->value.label.sect = sect;
rec->value.label.bc = precbc;
return rec;
}
symrec *
-symrec_declare(const char *name, SymVisibility vis)
+symrec_declare(const char *name, SymVisibility vis, unsigned long lindex)
{
symrec *rec = symrec_get_or_new(name, 1);
((rec->visibility & SYM_EXTERN) && (vis == SYM_EXTERN)))))
rec->visibility |= vis;
else
- Error(_("duplicate definition of `%s'; first defined on line %lu"),
+ Error(lindex,
+ _("duplicate definition of `%s'; first defined on line %lu"),
name, rec->line);
return rec;
}
/* error if a symbol is used but never defined or extern/common declared */
if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) &&
!(sym->visibility & (SYM_EXTERN | SYM_COMMON))) {
- ErrorAt(sym->line, _("undefined symbol `%s' (first use)"), sym->name);
+ Error(sym->line, _("undefined symbol `%s' (first use)"), sym->name);
if (sym->line < firstundef_line)
firstundef_line = sym->line;
}
firstundef_line = ULONG_MAX;
symrec_traverse(NULL, symrec_parser_finalize_checksym);
if (firstundef_line < ULONG_MAX)
- ErrorAt(firstundef_line,
- _(" (Each undefined symbol is reported only once.)"));
+ Error(firstundef_line,
+ _(" (Each undefined symbol is reported only once.)"));
}
void
void
symrec_print(FILE *f, int indent_level, const symrec *sym)
{
- const char *filename;
- unsigned long line;
-
switch (sym->type) {
case SYM_UNKNOWN:
fprintf(f, "%*s-Unknown (Common/Extern)-\n", indent_level, "");
fprintf(f, "%*sUNKNOWN\n", indent_level+1, "");
}
- line_lookup(sym->line, &filename, &line);
- fprintf(f, "%*sFilename=\"%s\" Line Number=%lu\n", indent_level, "",
- filename, line);
+ fprintf(f, "%*sLine Index=%lu\n", indent_level, "", sym->line);
}
#ifndef YASM_SYMREC_H
#define YASM_SYMREC_H
-/*@dependent@*/ symrec *symrec_use(const char *name);
-/*@dependent@*/ symrec *symrec_define_equ(const char *name,
- /*@keep@*/ expr *e);
+/*@dependent@*/ symrec *symrec_use(const char *name, unsigned long lindex);
+/*@dependent@*/ symrec *symrec_define_equ(const char *name, /*@keep@*/ expr *e,
+ unsigned long lindex);
/* in_table specifies if the label should be inserted into the symbol table.
* All labels are memory managed internally.
*/
/*@dependent@*/ /*@null@*/
section *sect,
/*@dependent@*/ /*@null@*/
- bytecode *precbc, int in_table);
-/*@dependent@*/ symrec *symrec_declare(const char *name, SymVisibility vis);
+ bytecode *precbc, int in_table,
+ unsigned long lindex);
+/*@dependent@*/ symrec *symrec_declare(const char *name, SymVisibility vis,
+ unsigned long lindex);
/*@observer@*/ const char *symrec_get_name(const symrec *sym);
SymVisibility symrec_get_visibility(const symrec *sym);
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
-#include "globals.h"
#include "expr.h"
src/expr-int.h \
src/symrec.c \
src/symrec.h \
- src/globals.c \
- src/globals.h \
+ src/linemgr.h \
src/util.h \
src/coretype.h \
src/file.c \
src/objfmt.c \
src/parser.c \
src/module.h \
- src/module.c
+ src/module.c \
+ src/linemgr.c
EXTRA_DIST += \
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
int
x86_directive(const char *name, valparamhead *valparams,
/*@unused@*/ /*@null@*/ valparamhead *objext_valparams,
- /*@unused@*/ sectionhead *headp)
+ /*@unused@*/ sectionhead *headp, unsigned long lindex)
{
valparam *vp;
const intnum *intn;
(lval = intnum_get_int(intn)) && (lval == 16 || lval == 32))
yasm_x86_LTX_mode_bits = (unsigned char)lval;
else
- Error(_("invalid argument to [%s]"), "BITS");
+ Error(lindex, _("invalid argument to [%s]"), "BITS");
return 0;
} else
return 1;
}
void
-x86_handle_prefix(bytecode *bc, const unsigned long data[4])
+x86_handle_prefix(bytecode *bc, const unsigned long data[4],
+ unsigned long lindex)
{
switch((x86_parse_insn_prefix)data[0]) {
case X86_LOCKREP:
- x86_bc_insn_set_lockrep_prefix(bc, (unsigned char)data[1]);
+ x86_bc_insn_set_lockrep_prefix(bc, (unsigned char)data[1], lindex);
break;
case X86_ADDRSIZE:
x86_bc_insn_addrsize_override(bc, (unsigned char)data[1]);
}
void
-x86_handle_seg_prefix(bytecode *bc, unsigned long segreg)
+x86_handle_seg_prefix(bytecode *bc, unsigned long segreg, unsigned long lindex)
{
- x86_ea_set_segment(x86_bc_insn_get_ea(bc), (unsigned char)(segreg>>8));
+ x86_ea_set_segment(x86_bc_insn_get_ea(bc), (unsigned char)(segreg>>8),
+ lindex);
}
void
-x86_handle_seg_override(effaddr *ea, unsigned long segreg)
+x86_handle_seg_override(effaddr *ea, unsigned long segreg,
+ unsigned long lindex)
{
- x86_ea_set_segment(ea, (unsigned char)(segreg>>8));
+ x86_ea_set_segment(ea, (unsigned char)(segreg>>8), lindex);
}
/* Define arch structure -- see arch.h for details */
JR_NEAR_FORCED
} x86_jmprel_opcode_sel;
-void x86_ea_set_segment(/*@null@*/ effaddr *ea, unsigned char segment);
+void x86_ea_set_segment(/*@null@*/ effaddr *ea, unsigned char segment,
+ unsigned long lindex);
void x86_ea_set_disponly(effaddr *ea);
effaddr *x86_ea_new_reg(unsigned char reg);
effaddr *x86_ea_new_imm(/*@keep@*/expr *imm, unsigned char im_len);
void x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize);
void x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize);
-void x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix);
-
-void x86_set_jmprel_opcode_sel(x86_jmprel_opcode_sel *old_sel,
- x86_jmprel_opcode_sel new_sel);
+void x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix,
+ unsigned long lindex);
/* Structure with *all* inputs passed to x86_bytecode_new_insn().
* IMPORTANT: ea_ptr and im_ptr cannot be reused or freed after calling the
* function (it doesn't make a copy).
*/
typedef struct x86_new_insn_data {
+ unsigned long lindex;
/*@keep@*/ /*@null@*/ effaddr *ea;
/*@keep@*/ /*@null@*/ expr *imm;
unsigned char opersize;
* Pass 0 for the opcode_len if that version of the opcode doesn't exist.
*/
typedef struct x86_new_jmprel_data {
+ unsigned long lindex;
/*@keep@*/ expr *target;
x86_jmprel_opcode_sel op_sel;
unsigned char short_op_len;
unsigned char *v_sib, unsigned char *n_sib,
calc_bc_dist_func calc_bc_dist);
-void x86_switch_cpu(const char *cpuid);
+void x86_switch_cpu(const char *cpuid, unsigned long lindex);
arch_check_id_retval x86_check_identifier(unsigned long data[2],
- const char *id);
+ const char *id,
+ unsigned long lindex);
int x86_directive(const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams,
- sectionhead *headp);
+ sectionhead *headp, unsigned long lindex);
/*@null@*/ bytecode *x86_new_insn(const unsigned long data[2],
int num_operands,
/*@null@*/ insn_operandhead *operands,
section *cur_section,
- /*@null@*/ bytecode *prev_bc);
+ /*@null@*/ bytecode *prev_bc,
+ unsigned long lindex);
-void x86_handle_prefix(bytecode *bc, const unsigned long data[4]);
+void x86_handle_prefix(bytecode *bc, const unsigned long data[4],
+ unsigned long lindex);
-void x86_handle_seg_prefix(bytecode *bc, unsigned long segreg);
+void x86_handle_seg_prefix(bytecode *bc, unsigned long segreg,
+ unsigned long lindex);
-void x86_handle_seg_override(effaddr *ea, unsigned long segreg);
+void x86_handle_seg_override(effaddr *ea, unsigned long segreg,
+ unsigned long lindex);
int x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp,
unsigned long valsize, const expr *e);
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
x86_insn *insn;
insn = (x86_insn *)bc_new_common((bytecode_type)X86_BC_INSN,
- sizeof(x86_insn));
+ sizeof(x86_insn), d->lindex);
insn->ea = (x86_effaddr *)d->ea;
if (d->ea) {
x86_jmprel *jmprel;
jmprel = (x86_jmprel *)bc_new_common((bytecode_type)X86_BC_JMPREL,
- sizeof(x86_jmprel));
+ sizeof(x86_jmprel), d->lindex);
jmprel->target = d->target;
jmprel->op_sel = d->op_sel;
if ((d->op_sel == JR_SHORT_FORCED) && (d->near_op_len == 0))
- Error(_("no SHORT form of that jump instruction exists"));
+ Error(d->lindex, _("no SHORT form of that jump instruction exists"));
if ((d->op_sel == JR_NEAR_FORCED) && (d->short_op_len == 0))
- Error(_("no NEAR form of that jump instruction exists"));
+ Error(d->lindex, _("no NEAR form of that jump instruction exists"));
jmprel->shortop.opcode[0] = d->short_op[0];
jmprel->shortop.opcode[1] = d->short_op[1];
/*@=compmempass =mustfree@*/
void
-x86_ea_set_segment(effaddr *ea, unsigned char segment)
+x86_ea_set_segment(effaddr *ea, unsigned char segment, unsigned long lindex)
{
x86_effaddr *x86_ea = (x86_effaddr *)ea;
return;
if (segment != 0 && x86_ea->segment != 0)
- Warning(_("multiple segment overrides, using leftmost"));
+ Warning(lindex, _("multiple segment overrides, using leftmost"));
x86_ea->segment = segment;
}
}
void
-x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
+x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix,
+ unsigned long lindex)
{
x86_insn *insn;
x86_jmprel *jmprel;
}
if (*lockrep_pre != 0)
- Warning(_("multiple LOCK or REP prefixes, using leftmost"));
+ Warning(lindex, _("multiple LOCK or REP prefixes, using leftmost"));
*lockrep_pre = prefix;
}
-void
-x86_set_jmprel_opcode_sel(x86_jmprel_opcode_sel *old_sel,
- x86_jmprel_opcode_sel new_sel)
-{
- if (!old_sel)
- return;
-
- if (new_sel != JR_NONE && ((*old_sel == JR_SHORT_FORCED) ||
- (*old_sel == JR_NEAR_FORCED)))
- Warning(_("multiple SHORT or NEAR specifiers, using leftmost"));
- *old_sel = new_sel;
-}
-
void
x86_bc_delete(bytecode *bc)
{
temp = expr_copy(jmprel->target);
num = expr_get_intnum(&temp, calc_bc_dist);
if (!num) {
- ErrorAt(bc->line,
- _("short jump target external or out of segment"));
+ Error(bc->line,
+ _("short jump target external or out of segment"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
} else {
rel = intnum_get_int(num);
rel -= jmprel->shortop.opcode_len+1;
/* does a short form exist? */
if (jmprel->shortop.opcode_len == 0) {
- ErrorAt(bc->line, _("short jump does not exist"));
+ Error(bc->line, _("short jump does not exist"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
/* short displacement must fit in -128 <= rel <= +127 */
if (rel < -128 || rel > 127) {
- ErrorAt(bc->line, _("short jump out of range"));
+ Error(bc->line, _("short jump out of range"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
}
jrshort = 0;
if (save) {
if (jmprel->nearop.opcode_len == 0) {
- ErrorAt(bc->line, _("near jump does not exist"));
+ Error(bc->line, _("near jump does not exist"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
}
* it to actually be within short range).
*/
if (save) {
- ErrorAt(bc->line, _("short jump out of range (near jump does not exist)"));
+ Error(bc->line,
+ _("short jump out of range (near jump does not exist)"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
jrshort = 1;
jrshort = 0;
} else {
if (save) {
- ErrorAt(bc->line,
- _("short jump out of range (near jump does not exist)"));
+ Error(bc->line,
+ _("short jump out of range (near jump does not exist)"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
jrshort = 1;
case JR_NEAR:
/* 2/4 byte relative displacement (depending on operand size) */
if (jmprel->nearop.opcode_len == 0) {
- ErrorAt(bc->line, _("near jump does not exist"));
+ Error(bc->line, _("near jump does not exist"));
return 1;
}
#include "bitvect.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
*/
if (!intnum_check_size(intn, (size_t)wordsize, 0) &&
!intnum_check_size(intn, 1, 1)) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
case 2:
case 4:
if (wordsize != *displen) {
- ErrorAt(e->line,
- _("invalid effective address (displacement size)"));
+ Error(e->line,
+ _("invalid effective address (displacement size)"));
return 0;
}
/* TODO: Add optional warning here about 2/4 not being valid
calc_bc_dist)) {
case 0:
e = *ep;
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
case 1:
return 1;
*/
for (i=0; i<8; i++) {
if (reg32mult[i] < 0) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
if (i != indexreg && reg32mult[i] == 1 && basereg == REG32_NONE)
*/
for (i=0; i<8; i++)
if (i != basereg && i != indexreg && reg32mult[i] != 0) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
if (indexreg != REG32_NONE && reg32mult[indexreg] != 1 &&
reg32mult[indexreg] != 2 && reg32mult[indexreg] != 4 &&
reg32mult[indexreg] != 8) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
* legal.
*/
if (reg32mult[REG32_ESP] > 1 || basereg == REG32_ESP) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
/* If mult==1 and basereg is not ESP, swap indexreg w/basereg. */
calc_bc_dist)) {
case 0:
e = *ep;
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
case 1:
return 1;
/* reg multipliers not 0 or 1 are illegal. */
if (reg16mult.bx & ~1 || reg16mult.si & ~1 || reg16mult.di & ~1 ||
reg16mult.bp & ~1) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
/* Check the modrm value for invalid combinations. */
if (modrm16[havereg] & 0070) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
int fltret;
if (!floatnum_check_size(flt, (size_t)valsize)) {
- ErrorAt(e->line, _("invalid floating point constant size"));
+ Error(e->line, _("invalid floating point constant size"));
return 1;
}
fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize);
if (fltret < 0) {
- ErrorAt(e->line, _("underflow in floating point expression"));
+ Error(e->line, _("underflow in floating point expression"));
return 1;
}
if (fltret > 0) {
- ErrorAt(e->line, _("overflow in floating point expression"));
+ Error(e->line, _("overflow in floating point expression"));
return 1;
}
*bufp += valsize;
#include "bitvect.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
static bytecode *
x86_new_jmprel(const unsigned long data[4], int num_operands,
insn_operandhead *operands, x86_insn_info *jrinfo,
- section *cur_section, /*@null@*/ bytecode *prev_bc)
+ section *cur_section, /*@null@*/ bytecode *prev_bc,
+ unsigned long lindex)
{
x86_new_jmprel_data d;
int num_info = (int)(data[1]&0xFF);
insn_operand *op;
static const unsigned char size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
+ d.lindex = lindex;
+
/* We know the target is in operand 0, but sanity check for Imm. */
op = ops_first(operands);
if (op->type != INSN_OPERAND_IMM)
InternalError(_("invalid operand conversion"));
d.target = expr_new(EXPR_SUB, ExprExpr(op->data.val),
ExprSym(symrec_define_label("$", cur_section, prev_bc,
- 0)));
+ 0, lindex)), lindex);
/* See if the user explicitly specified short/near. */
switch (jrinfo->operands[0] & OPTM_MASK) {
bytecode *
x86_new_insn(const unsigned long data[4], int num_operands,
insn_operandhead *operands, section *cur_section,
- /*@null@*/ bytecode *prev_bc)
+ /*@null@*/ bytecode *prev_bc, unsigned long lindex)
{
x86_new_insn_data d;
int num_info = (int)(data[1]&0xFF);
if (!found) {
/* Didn't find a matching one */
- Error(_("invalid combination of opcode and operands"));
+ Error(lindex, _("invalid combination of opcode and operands"));
return NULL;
}
case MOD_ExtErr:
switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) {
case 0:
- Error(_("mismatch in operand sizes"));
+ Error(lindex, _("mismatch in operand sizes"));
break;
case 1:
- Error(_("operand size not specified"));
+ Error(lindex, _("operand size not specified"));
break;
default:
InternalError(_("unrecognized x86 ext mod index"));
/* Shortcut to JmpRel */
if (operands && (info->operands[0] & OPA_MASK) == OPA_JmpRel)
return x86_new_jmprel(data, num_operands, operands, info, cur_section,
- prev_bc);
+ prev_bc, lindex);
/* Copy what we can from info */
+ d.lindex = lindex;
d.ea = NULL;
d.imm = NULL;
d.opersize = info->opersize;
mod_data >>= 8;
}
if (info->modifiers & MOD_Imm8) {
- d.imm = expr_new_ident(ExprInt(intnum_new_int(mod_data & 0xFF)));
+ d.imm = expr_new_ident(ExprInt(intnum_new_int(mod_data & 0xFF)),
+ lindex);
d.im_len = 1;
/*mod_data >>= 8;*/
}
*/
void
-x86_switch_cpu(const char *id)
+x86_switch_cpu(const char *id, unsigned long lindex)
{
/*const char *marker;*/
/* catchalls */
[\001-\377]+ {
- Warning(_("unrecognized CPU identifier `%s'"), id);
+ Warning(lindex, _("unrecognized CPU identifier `%s'"), id);
return;
}
[\000] {
- Warning(_("unrecognized CPU identifier `%s'"), id);
+ Warning(lindex, _("unrecognized CPU identifier `%s'"), id);
return;
}
*/
}
arch_check_id_retval
-x86_check_identifier(unsigned long data[4], const char *id)
+x86_check_identifier(unsigned long data[4], const char *id,
+ /*@unused@*/ unsigned long lindex)
{
const char *oid = id;
/*const char *marker;*/
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
if (e->terms[i].type == EXPR_SYM &&
symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
(dist = common_calc_bc_dist(sect, NULL, precbc))) {
+ const expr *start = section_get_start(sect);
e->terms[i].type = EXPR_EXPR;
e->terms[i].data.expn =
- expr_new(EXPR_ADD,
- ExprExpr(expr_copy(section_get_start(sect))),
- ExprInt(dist));
+ expr_new(EXPR_ADD, ExprExpr(expr_copy(start)), ExprInt(dist),
+ start->line);
}
}
/* Check for complex float expressions */
if (expr_contains(*ep, EXPR_FLOAT)) {
- ErrorAt((*ep)->line, _("floating point expression too complex"));
+ Error((*ep)->line, _("floating point expression too complex"));
return 1;
}
/* Couldn't output, assume it contains an external reference. */
- ErrorAt((*ep)->line,
- _("binary object format does not support external references"));
+ Error((*ep)->line,
+ _("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;
- WarningAt(bc->line,
- _("uninitialized space declared in code/data section: zeroing"));
+ Warning(bc->line,
+ _("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
left = multiple*size;
if (data) {
start = bin_objfmt_align_section(data, prevsect, start, 4,
prevsectlenptr, prevsectpadptr);
- section_set_start(data, start);
+ section_set_start(data, start, 0);
datastart = start;
prevsect = data;
prevsectlenptr = &datalen;
if (bss) {
start = bin_objfmt_align_section(bss, prevsect, start, 4,
prevsectlenptr, prevsectpadptr);
- section_set_start(bss, start);
+ section_set_start(bss, start, 0);
}
/* Output .text first. */
static /*@observer@*/ /*@null@*/ section *
bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams,
+ unsigned long lindex)
{
valparam *vp;
section *retval;
resonly = 1;
} else {
/* other section names not recognized. */
- Error(_("segment name `%s' not recognized"), sectname);
+ Error(lindex, _("segment name `%s' not recognized"), sectname);
return NULL;
}
unsigned long bitcnt;
if (strcmp(sectname, ".text") == 0) {
- Error(_("cannot specify an alignment to the `%s' section"),
+ Error(lindex,
+ _("cannot specify an alignment to the `%s' section"),
sectname);
return NULL;
}
align = expr_get_intnum(&vp->param, NULL);
if (!align) {
- Error(_("argument to `%s' is not a power of two"),
+ Error(lindex, _("argument to `%s' is not a power of two"),
vp->val);
return NULL;
}
*/
BitCount(bitcnt, alignval);
if (bitcnt > 1) {
- Error(_("argument to `%s' is not a power of two"),
+ Error(lindex, _("argument to `%s' is not a power of two"),
vp->val);
return NULL;
}
}
retval = sections_switch_general(headp, sectname, start, resonly,
- &isnew);
+ &isnew, lindex);
if (isnew) {
if (have_alignval) {
section_set_of_data(retval, &yasm_bin_LTX_objfmt, data);
}
- symrec_define_label(sectname, retval, (bytecode *)NULL, 1);
+ symrec_define_label(sectname, retval, (bytecode *)NULL, 1, lindex);
} else if (have_alignval)
- Warning(_("alignment value ignored on section redeclaration"));
+ Warning(lindex,
+ _("alignment value ignored on section redeclaration"));
return retval;
} else
static void
bin_objfmt_common_declare(/*@unused@*/ symrec *sym, /*@only@*/ expr *size,
/*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams, unsigned long lindex)
{
expr_delete(size);
- Error(_("binary object format does not support common variables"));
+ Error(lindex, _("binary object format does not support common variables"));
}
static int
bin_objfmt_directive(const char *name, valparamhead *valparams,
/*@unused@*/ /*@null@*/ valparamhead *objext_valparams,
- sectionhead *headp)
+ sectionhead *headp, unsigned long lindex)
{
section *sect;
valparam *vp;
/* ORG takes just a simple integer as param */
vp = vps_first(valparams);
if (vp->val) {
- Error(_("argument to ORG should be numeric"));
+ Error(lindex, _("argument to ORG should be numeric"));
return 0;
} else if (vp->param)
start = expr_get_intnum(&vp->param, NULL);
if (!start) {
- Error(_("argument to ORG should be numeric"));
+ Error(lindex, _("argument to ORG should be numeric"));
return 0;
}
sect = sections_find_general(headp, ".text");
if (!sect)
InternalError(_("bin objfmt: .text section does not exist before ORG is called?"));
- section_set_start(sect, intnum_get_uint(start));
+ section_set_start(sect, intnum_get_uint(start), lindex);
return 0; /* directive recognized */
} else
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
data->index = 0;
data->sclass = COFF_SCL_FILE;
data->size = NULL;
- filesym = symrec_define_label(".file", NULL, NULL, 0);
+ filesym = symrec_define_label(".file", NULL, NULL, 0, 0);
symrec_set_of_data(filesym, &yasm_coff_LTX_objfmt, data);
entry = xmalloc(sizeof(coff_symtab_entry));
SymVisibility vis;
if (valsize != 4) {
- ErrorAt((*ep)->line, _("coff: invalid relocation size"));
+ Error((*ep)->line, _("coff: invalid relocation size"));
return 1;
}
csymd = symrec_get_of_data(sym);
assert(csymd != NULL);
*ep = expr_new(EXPR_ADD, ExprExpr(*ep),
- ExprExpr(expr_copy(csymd->size)));
+ ExprExpr(expr_copy(csymd->size)),
+ csymd->size->line);
*ep = expr_simplify(*ep, common_calc_bc_dist);
} else if (!(vis & SYM_EXTERN)) {
/* Local symbols need relocation to their section's start */
reloc->sym = label_csd->sym;
if (COFF_SET_VMA)
*ep = expr_new(EXPR_ADD, ExprExpr(*ep),
- ExprInt(intnum_new_uint(label_csd->addr)));
+ ExprInt(intnum_new_uint(label_csd->addr)),
+ (*ep)->line);
}
}
/* Need to reference to start of section, so add $$ in. */
*ep = expr_new(EXPR_ADD, ExprExpr(*ep),
ExprSym(symrec_define_label("$$", info->sect, NULL,
- 0)));
+ 0, (*ep)->line)),
+ (*ep)->line);
*ep = expr_simplify(*ep, common_calc_bc_dist);
} else
reloc->type = COFF_RELOC_ADDR32;
/* Check for complex float expressions */
if (expr_contains(*ep, EXPR_FLOAT)) {
- ErrorAt((*ep)->line, _("floating point expression too complex"));
+ Error((*ep)->line, _("floating point expression too complex"));
return 1;
}
- ErrorAt((*ep)->line, _("coff: relocation too complex"));
+ Error((*ep)->line, _("coff: relocation too complex"));
return 1;
}
/* Warn that gaps are converted to 0 and write out the 0's. */
if (gap) {
unsigned long left;
- WarningAt(bc->line,
- _("uninitialized space declared in code/data section: zeroing"));
+ Warning(bc->line,
+ _("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
left = multiple*size;
const intnum *intn;
intn = expr_get_intnum(&csymd->size, common_calc_bc_dist);
if (!intn)
- ErrorAt(csymd->size->line,
- _("COMMON data size not an integer expression"));
+ Error(csymd->size->line,
+ _("COMMON data size not an integer expression"));
else
value = intnum_get_uint(intn);
scnum = 0;
static /*@observer@*/ /*@null@*/ section *
coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams,
+ unsigned long lindex)
{
valparam *vp = vps_first(valparams);
section *retval;
sectname = vp->val;
if (strlen(sectname) > 8) {
- Warning(_("COFF section names limited to 8 characters: truncating"));
+ Warning(lindex,
+ _("COFF section names limited to 8 characters: truncating"));
sectname[8] = '\0';
}
}
}
- retval = sections_switch_general(headp, sectname, 0, resonly, &isnew);
+ retval = sections_switch_general(headp, sectname, 0, resonly, &isnew,
+ lindex);
if (isnew) {
coff_section_data *data;
STAILQ_INIT(&data->relocs);
section_set_of_data(retval, &yasm_coff_LTX_objfmt, data);
- sym = symrec_define_label(sectname, retval, (bytecode *)NULL, 1);
+ sym = symrec_define_label(sectname, retval, (bytecode *)NULL, 1,
+ lindex);
coff_objfmt_symtab_append(sym, COFF_SCL_STAT, NULL, 1,
COFF_SYMTAB_AUX_SECT);
data->sym = sym;
} else if (flags_override)
- Warning(_("section flags ignored on section redeclaration"));
+ Warning(lindex, _("section flags ignored on section redeclaration"));
return retval;
}
static void
coff_objfmt_extglob_declare(symrec *sym, /*@unused@*/
- /*@null@*/ valparamhead *objext_valparams)
+ /*@null@*/ valparamhead *objext_valparams,
+ /*@unused@*/ unsigned long lindex)
{
coff_objfmt_symtab_append(sym, COFF_SCL_EXT, NULL, 0,
COFF_SYMTAB_AUX_NONE);
static void
coff_objfmt_common_declare(symrec *sym, /*@only@*/ expr *size, /*@unused@*/
- /*@null@*/ valparamhead *objext_valparams)
+ /*@null@*/ valparamhead *objext_valparams,
+ /*@unused@*/ unsigned long lindex)
{
coff_objfmt_symtab_append(sym, COFF_SCL_EXT, size, 0,
COFF_SYMTAB_AUX_NONE);
coff_objfmt_directive(/*@unused@*/ const char *name,
/*@unused@*/ valparamhead *valparams,
/*@unused@*/ /*@null@*/ valparamhead *objext_valparams,
- /*@unused@*/ sectionhead *headp)
+ /*@unused@*/ sectionhead *headp,
+ /*@unused@*/ unsigned long lindex)
{
return 1; /* no objfmt directives */
}
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
-#include "globals.h"
#include "errwarn.h"
#include "expr.h"
#include "symrec.h"
static /*@observer@*/ /*@null@*/ section *
dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams,
+ unsigned long lindex)
{
valparam *vp;
section *retval;
vps_print(dbg_objfmt_file, valparams);
fprintf(dbg_objfmt_file, ", ");
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), returning ");
+ fprintf(dbg_objfmt_file, ", %lu), returning ", lindex);
if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
- retval = sections_switch_general(headp, vp->val, 200, 0, &isnew);
+ retval = sections_switch_general(headp, vp->val, 200, 0, &isnew,
+ lindex);
if (isnew) {
fprintf(dbg_objfmt_file, "(new) ");
- symrec_define_label(vp->val, retval, (bytecode *)NULL, 1);
+ symrec_define_label(vp->val, retval, (bytecode *)NULL, 1, lindex);
}
fprintf(dbg_objfmt_file, "\"%s\" section\n", vp->val);
return retval;
static void
dbg_objfmt_extern_declare(symrec *sym, /*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams, unsigned long lindex)
{
fprintf(dbg_objfmt_file, "extern_declare(\"%s\", ", symrec_get_name(sym));
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), setting of_data=NULL\n");
+ fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
}
static void
dbg_objfmt_global_declare(symrec *sym, /*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams, unsigned long lindex)
{
fprintf(dbg_objfmt_file, "global_declare(\"%s\", ", symrec_get_name(sym));
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), setting of_data=NULL\n");
+ fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
}
static void
dbg_objfmt_common_declare(symrec *sym, /*@only@*/ expr *size, /*@unused@*/
- /*@null@*/ valparamhead *objext_valparams)
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex)
{
assert(dbg_objfmt_file != NULL);
fprintf(dbg_objfmt_file, "common_declare(\"%s\", ", symrec_get_name(sym));
expr_print(dbg_objfmt_file, size);
fprintf(dbg_objfmt_file, ", ");
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), setting of_data=");
+ fprintf(dbg_objfmt_file, ", %lu), setting of_data=", lindex);
expr_print(dbg_objfmt_file, size);
symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, size);
fprintf(dbg_objfmt_file, "\n");
static int
dbg_objfmt_directive(const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams,
- /*@unused@*/ sectionhead *headp)
+ /*@unused@*/ sectionhead *headp, unsigned long lindex)
{
fprintf(dbg_objfmt_file, "directive(\"%s\", ", name);
vps_print(dbg_objfmt_file, valparams);
fprintf(dbg_objfmt_file, ", ");
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), returning 0 (recognized)\n");
+ fprintf(dbg_objfmt_file, ", %lu), returning 0 (recognized)\n", lindex);
return 0; /* dbg format "recognizes" all directives */
}
bcr_retval = bc_resolve(bc, 0, data->sect, basic_optimize_calc_bc_dist_1);
if (bcr_retval & BC_RESOLVE_UNKNOWN_LEN) {
if (!(bcr_retval & BC_RESOLVE_ERROR))
- ErrorAt(bc->line, _("circular reference detected."));
+ Error(bc->line, _("circular reference detected."));
data->saw_unknown = -1;
return 0;
}
#include "bitvect.h"
-#include "globals.h"
+#include "linemgr.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
extern size_t nasm_parser_locallabel_base_len;
extern /*@dependent@*/ arch *nasm_parser_arch;
extern /*@dependent@*/ objfmt *nasm_parser_objfmt;
+extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
+
+#define p_line_index (nasm_parser_linemgr->get_current())
+
+#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,p_line_index)
+#define p_expr_new_branch(o,r) expr_new_branch(o,r,p_line_index)
+#define p_expr_new_ident(r) expr_new_ident(r,p_line_index)
static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
static bytecode *nasm_parser_temp_bc;
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
- line_index++;
+ nasm_parser_linemgr->goto_next();
}
;
/* %line indicates the line number of the *next* line, so subtract out
* the increment when setting the line number.
*/
- line_set($5, intnum_get_uint($2)-intnum_get_uint($4),
- intnum_get_uint($4));
+ nasm_parser_linemgr->set($5, intnum_get_uint($2)-intnum_get_uint($4),
+ intnum_get_uint($4));
intnum_delete($2);
intnum_delete($4);
xfree($5);
$$ = (bytecode *)NULL;
}
| error '\n' {
- Error(_("label or instruction expected at start of line"));
+ Error(p_line_index,
+ _("label or instruction expected at start of line"));
$$ = (bytecode *)NULL;
yyerrok;
}
| label exp { $$ = $2; }
| label TIMES expr exp { $$ = $4; bc_set_multiple($$, $3); }
| label_id_equ EQU expr {
- symrec_define_equ($1, $3);
+ symrec_define_equ($1, $3, p_line_index);
xfree($1);
$$ = (bytecode *)NULL;
}
;
exp: instr
- | DECLARE_DATA datavals { $$ = bc_new_data(&$2, $1); }
- | RESERVE_SPACE expr { $$ = bc_new_reserve($2, $1); }
- | INCBIN STRING { $$ = bc_new_incbin($2, NULL, NULL); }
- | INCBIN STRING ',' expr { $$ = bc_new_incbin($2, $4, NULL); }
- | INCBIN STRING ',' expr ',' expr { $$ = bc_new_incbin($2, $4, $6); }
+ | DECLARE_DATA datavals {
+ $$ = bc_new_data(&$2, $1, p_line_index);
+ }
+ | RESERVE_SPACE expr {
+ $$ = bc_new_reserve($2, $1, p_line_index);
+ }
+ | INCBIN STRING {
+ $$ = bc_new_incbin($2, NULL, NULL, p_line_index);
+ }
+ | INCBIN STRING ',' expr {
+ $$ = bc_new_incbin($2, $4, NULL, p_line_index);
+ }
+ | INCBIN STRING ',' expr ',' expr {
+ $$ = bc_new_incbin($2, $4, $6, p_line_index);
+ }
;
instr: INSN {
$$ = nasm_parser_arch->parse.new_insn($1, 0, NULL,
nasm_parser_cur_section,
- nasm_parser_prev_bc);
+ nasm_parser_prev_bc,
+ p_line_index);
}
| INSN operands {
$$ = nasm_parser_arch->parse.new_insn($1, $2.num_operands,
&$2.operands,
nasm_parser_cur_section,
- nasm_parser_prev_bc);
+ nasm_parser_prev_bc,
+ p_line_index);
ops_delete(&$2.operands, 0);
}
| INSN error {
- Error(_("expression syntax error"));
+ Error(p_line_index, _("expression syntax error"));
$$ = NULL;
}
| PREFIX instr {
$$ = $2;
- nasm_parser_arch->parse.handle_prefix($$, $1);
+ nasm_parser_arch->parse.handle_prefix($$, $1, p_line_index);
}
| SEGREG instr {
$$ = $2;
- nasm_parser_arch->parse.handle_seg_prefix($$, $1[0]);
+ nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], p_line_index);
}
;
dataval: dvexpr { $$ = dv_new_expr($1); }
| STRING { $$ = dv_new_string($1); }
| error {
- Error(_("expression syntax error"));
+ Error(p_line_index, _("expression syntax error"));
$$ = (dataval *)NULL;
}
;
label: label_id {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
- 1);
+ 1, p_line_index);
xfree($1);
}
| label_id ':' {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
- 1);
+ 1, p_line_index);
xfree($1);
}
;
xfree($1);
}
| DIRECTIVE_NAME error {
- Error(_("invalid arguments to [%s]"), $1);
+ Error(p_line_index, _("invalid arguments to [%s]"), $1);
xfree($1);
}
;
}
| SEGREG ':' memaddr {
$$ = $3;
- nasm_parser_arch->parse.handle_seg_override($$, $1[0]);
+ nasm_parser_arch->parse.handle_seg_override($$, $1[0], p_line_index);
}
| BYTE memaddr { $$ = $2; ea_set_len($$, 1); }
| WORD memaddr { $$ = $2; ea_set_len($$, 2); }
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 1)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 1;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 2)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 2;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 4)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 4;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 8)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 8;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 10)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 10;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 16)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 16;
}
/* expression trees */
/* expr w/o FLTNUM and unary + and -, for use in directives */
-direxpr: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
+direxpr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); }
| ID {
- $$ = expr_new_ident(ExprSym(symrec_define_label($1, NULL, NULL, 0)));
+ $$ = p_expr_new_ident(ExprSym(symrec_define_label($1, NULL, NULL, 0,
+ p_line_index)));
xfree($1);
}
- | direxpr '|' direxpr { $$ = expr_new_tree($1, EXPR_OR, $3); }
- | direxpr '^' direxpr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
- | direxpr '&' direxpr { $$ = expr_new_tree($1, EXPR_AND, $3); }
- | direxpr LEFT_OP direxpr { $$ = expr_new_tree($1, EXPR_SHL, $3); }
- | direxpr RIGHT_OP direxpr { $$ = expr_new_tree($1, EXPR_SHR, $3); }
- | direxpr '+' direxpr { $$ = expr_new_tree($1, EXPR_ADD, $3); }
- | direxpr '-' direxpr { $$ = expr_new_tree($1, EXPR_SUB, $3); }
- | direxpr '*' direxpr { $$ = expr_new_tree($1, EXPR_MUL, $3); }
- | direxpr '/' direxpr { $$ = expr_new_tree($1, EXPR_DIV, $3); }
- | direxpr SIGNDIV direxpr { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
- | direxpr '%' direxpr { $$ = expr_new_tree($1, EXPR_MOD, $3); }
- | direxpr SIGNMOD direxpr { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
- /*| '!' expr { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
- | '~' direxpr %prec UNARYOP { $$ = expr_new_branch(EXPR_NOT, $2); }
+ | direxpr '|' direxpr { $$ = p_expr_new_tree($1, EXPR_OR, $3); }
+ | direxpr '^' direxpr { $$ = p_expr_new_tree($1, EXPR_XOR, $3); }
+ | direxpr '&' direxpr { $$ = p_expr_new_tree($1, EXPR_AND, $3); }
+ | direxpr LEFT_OP direxpr { $$ = p_expr_new_tree($1, EXPR_SHL, $3); }
+ | direxpr RIGHT_OP direxpr { $$ = p_expr_new_tree($1, EXPR_SHR, $3); }
+ | direxpr '+' direxpr { $$ = p_expr_new_tree($1, EXPR_ADD, $3); }
+ | direxpr '-' direxpr { $$ = p_expr_new_tree($1, EXPR_SUB, $3); }
+ | direxpr '*' direxpr { $$ = p_expr_new_tree($1, EXPR_MUL, $3); }
+ | direxpr '/' direxpr { $$ = p_expr_new_tree($1, EXPR_DIV, $3); }
+ | direxpr SIGNDIV direxpr { $$ = p_expr_new_tree($1, EXPR_SIGNDIV, $3); }
+ | direxpr '%' direxpr { $$ = p_expr_new_tree($1, EXPR_MOD, $3); }
+ | direxpr SIGNMOD direxpr { $$ = p_expr_new_tree($1, EXPR_SIGNMOD, $3); }
+ /*| '!' expr { $$ = p_expr_new_branch(EXPR_LNOT, $2); }*/
+ | '~' direxpr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NOT, $2); }
| '(' direxpr ')' { $$ = $2; }
;
-dvexpr: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
- | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); }
- | explabel { $$ = expr_new_ident(ExprSym($1)); }
- /*| dvexpr '||' dvexpr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
- | dvexpr '|' dvexpr { $$ = expr_new_tree($1, EXPR_OR, $3); }
- | dvexpr '^' dvexpr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
- /*| dvexpr '&&' dvexpr { $$ = expr_new_tree($1, EXPR_LAND, $3); }*/
- | dvexpr '&' dvexpr { $$ = expr_new_tree($1, EXPR_AND, $3); }
- /*| dvexpr '==' dvexpr { $$ = expr_new_tree($1, EXPR_EQUALS, $3); }*/
- /*| dvexpr '>' dvexpr { $$ = expr_new_tree($1, EXPR_GT, $3); }*/
- /*| dvexpr '<' dvexpr { $$ = expr_new_tree($1, EXPR_GT, $3); }*/
- /*| dvexpr '>=' dvexpr { $$ = expr_new_tree($1, EXPR_GE, $3); }*/
- /*| dvexpr '<=' dvexpr { $$ = expr_new_tree($1, EXPR_GE, $3); }*/
- /*| dvexpr '!=' dvexpr { $$ = expr_new_tree($1, EXPR_NE, $3); }*/
- | dvexpr LEFT_OP dvexpr { $$ = expr_new_tree($1, EXPR_SHL, $3); }
- | dvexpr RIGHT_OP dvexpr { $$ = expr_new_tree($1, EXPR_SHR, $3); }
- | dvexpr '+' dvexpr { $$ = expr_new_tree($1, EXPR_ADD, $3); }
- | dvexpr '-' dvexpr { $$ = expr_new_tree($1, EXPR_SUB, $3); }
- | dvexpr '*' dvexpr { $$ = expr_new_tree($1, EXPR_MUL, $3); }
- | dvexpr '/' dvexpr { $$ = expr_new_tree($1, EXPR_DIV, $3); }
- | dvexpr SIGNDIV dvexpr { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
- | dvexpr '%' dvexpr { $$ = expr_new_tree($1, EXPR_MOD, $3); }
- | dvexpr SIGNMOD dvexpr { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
+dvexpr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); }
+ | FLTNUM { $$ = p_expr_new_ident(ExprFloat($1)); }
+ | explabel { $$ = p_expr_new_ident(ExprSym($1)); }
+ /*| dvexpr '||' dvexpr { $$ = p_expr_new_tree($1, EXPR_LOR, $3); }*/
+ | dvexpr '|' dvexpr { $$ = p_expr_new_tree($1, EXPR_OR, $3); }
+ | dvexpr '^' dvexpr { $$ = p_expr_new_tree($1, EXPR_XOR, $3); }
+ /*| dvexpr '&&' dvexpr { $$ = p_expr_new_tree($1, EXPR_LAND, $3); }*/
+ | dvexpr '&' dvexpr { $$ = p_expr_new_tree($1, EXPR_AND, $3); }
+ /*| dvexpr '==' dvexpr { $$ = p_expr_new_tree($1, EXPR_EQUALS, $3); }*/
+ /*| dvexpr '>' dvexpr { $$ = p_expr_new_tree($1, EXPR_GT, $3); }*/
+ /*| dvexpr '<' dvexpr { $$ = p_expr_new_tree($1, EXPR_GT, $3); }*/
+ /*| dvexpr '>=' dvexpr { $$ = p_expr_new_tree($1, EXPR_GE, $3); }*/
+ /*| dvexpr '<=' dvexpr { $$ = p_expr_new_tree($1, EXPR_GE, $3); }*/
+ /*| dvexpr '!=' dvexpr { $$ = p_expr_new_tree($1, EXPR_NE, $3); }*/
+ | dvexpr LEFT_OP dvexpr { $$ = p_expr_new_tree($1, EXPR_SHL, $3); }
+ | dvexpr RIGHT_OP dvexpr { $$ = p_expr_new_tree($1, EXPR_SHR, $3); }
+ | dvexpr '+' dvexpr { $$ = p_expr_new_tree($1, EXPR_ADD, $3); }
+ | dvexpr '-' dvexpr { $$ = p_expr_new_tree($1, EXPR_SUB, $3); }
+ | dvexpr '*' dvexpr { $$ = p_expr_new_tree($1, EXPR_MUL, $3); }
+ | dvexpr '/' dvexpr { $$ = p_expr_new_tree($1, EXPR_DIV, $3); }
+ | dvexpr SIGNDIV dvexpr { $$ = p_expr_new_tree($1, EXPR_SIGNDIV, $3); }
+ | dvexpr '%' dvexpr { $$ = p_expr_new_tree($1, EXPR_MOD, $3); }
+ | dvexpr SIGNMOD dvexpr { $$ = p_expr_new_tree($1, EXPR_SIGNMOD, $3); }
| '+' dvexpr %prec UNARYOP { $$ = $2; }
- | '-' dvexpr %prec UNARYOP { $$ = expr_new_branch(EXPR_NEG, $2); }
- /*| '!' dvexpr { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
- | '~' dvexpr %prec UNARYOP { $$ = expr_new_branch(EXPR_NOT, $2); }
- | SEG dvexpr { $$ = expr_new_branch(EXPR_SEG, $2); }
- | WRT dvexpr { $$ = expr_new_branch(EXPR_WRT, $2); }
+ | '-' dvexpr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NEG, $2); }
+ /*| '!' dvexpr { $$ = p_expr_new_branch(EXPR_LNOT, $2); }*/
+ | '~' dvexpr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NOT, $2); }
+ | SEG dvexpr { $$ = p_expr_new_branch(EXPR_SEG, $2); }
+ | WRT dvexpr { $$ = p_expr_new_branch(EXPR_WRT, $2); }
| '(' dvexpr ')' { $$ = $2; }
;
* We don't attempt to check memory expressions for validity here.
* Essentially the same as expr_no_string above but adds REG and STRING.
*/
-expr: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
- | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); }
- | REG { $$ = expr_new_ident(ExprReg($1[0])); }
+expr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); }
+ | FLTNUM { $$ = p_expr_new_ident(ExprFloat($1)); }
+ | REG { $$ = p_expr_new_ident(ExprReg($1[0])); }
| STRING {
- $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ $$ = p_expr_new_ident(ExprInt(intnum_new_charconst_nasm($1,
+ p_line_index)));
xfree($1);
}
- | explabel { $$ = expr_new_ident(ExprSym($1)); }
- /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
- | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); }
- | expr '^' expr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
- /*| expr '&&' expr { $$ = expr_new_tree($1, EXPR_LAND, $3); }*/
- | expr '&' expr { $$ = expr_new_tree($1, EXPR_AND, $3); }
- /*| expr '==' expr { $$ = expr_new_tree($1, EXPR_EQUALS, $3); }*/
- /*| expr '>' expr { $$ = expr_new_tree($1, EXPR_GT, $3); }*/
- /*| expr '<' expr { $$ = expr_new_tree($1, EXPR_GT, $3); }*/
- /*| expr '>=' expr { $$ = expr_new_tree($1, EXPR_GE, $3); }*/
- /*| expr '<=' expr { $$ = expr_new_tree($1, EXPR_GE, $3); }*/
- /*| expr '!=' expr { $$ = expr_new_tree($1, EXPR_NE, $3); }*/
- | expr LEFT_OP expr { $$ = expr_new_tree($1, EXPR_SHL, $3); }
- | expr RIGHT_OP expr { $$ = expr_new_tree($1, EXPR_SHR, $3); }
- | expr '+' expr { $$ = expr_new_tree($1, EXPR_ADD, $3); }
- | expr '-' expr { $$ = expr_new_tree($1, EXPR_SUB, $3); }
- | expr '*' expr { $$ = expr_new_tree($1, EXPR_MUL, $3); }
- | expr '/' expr { $$ = expr_new_tree($1, EXPR_DIV, $3); }
- | expr SIGNDIV expr { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
- | expr '%' expr { $$ = expr_new_tree($1, EXPR_MOD, $3); }
- | expr SIGNMOD expr { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
+ | explabel { $$ = p_expr_new_ident(ExprSym($1)); }
+ /*| expr '||' expr { $$ = p_expr_new_tree($1, EXPR_LOR, $3); }*/
+ | expr '|' expr { $$ = p_expr_new_tree($1, EXPR_OR, $3); }
+ | expr '^' expr { $$ = p_expr_new_tree($1, EXPR_XOR, $3); }
+ /*| expr '&&' expr { $$ = p_expr_new_tree($1, EXPR_LAND, $3); }*/
+ | expr '&' expr { $$ = p_expr_new_tree($1, EXPR_AND, $3); }
+ /*| expr '==' expr { $$ = p_expr_new_tree($1, EXPR_EQUALS, $3); }*/
+ /*| expr '>' expr { $$ = p_expr_new_tree($1, EXPR_GT, $3); }*/
+ /*| expr '<' expr { $$ = p_expr_new_tree($1, EXPR_GT, $3); }*/
+ /*| expr '>=' expr { $$ = p_expr_new_tree($1, EXPR_GE, $3); }*/
+ /*| expr '<=' expr { $$ = p_expr_new_tree($1, EXPR_GE, $3); }*/
+ /*| expr '!=' expr { $$ = p_expr_new_tree($1, EXPR_NE, $3); }*/
+ | expr LEFT_OP expr { $$ = p_expr_new_tree($1, EXPR_SHL, $3); }
+ | expr RIGHT_OP expr { $$ = p_expr_new_tree($1, EXPR_SHR, $3); }
+ | expr '+' expr { $$ = p_expr_new_tree($1, EXPR_ADD, $3); }
+ | expr '-' expr { $$ = p_expr_new_tree($1, EXPR_SUB, $3); }
+ | expr '*' expr { $$ = p_expr_new_tree($1, EXPR_MUL, $3); }
+ | expr '/' expr { $$ = p_expr_new_tree($1, EXPR_DIV, $3); }
+ | expr SIGNDIV expr { $$ = p_expr_new_tree($1, EXPR_SIGNDIV, $3); }
+ | expr '%' expr { $$ = p_expr_new_tree($1, EXPR_MOD, $3); }
+ | expr SIGNMOD expr { $$ = p_expr_new_tree($1, EXPR_SIGNMOD, $3); }
| '+' expr %prec UNARYOP { $$ = $2; }
- | '-' expr %prec UNARYOP { $$ = expr_new_branch(EXPR_NEG, $2); }
- /*| '!' expr { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
- | '~' expr %prec UNARYOP { $$ = expr_new_branch(EXPR_NOT, $2); }
- | SEG expr { $$ = expr_new_branch(EXPR_SEG, $2); }
- | WRT expr { $$ = expr_new_branch(EXPR_WRT, $2); }
- | expr ':' expr { $$ = expr_new_tree($1, EXPR_SEGOFF, $3); }
+ | '-' expr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NEG, $2); }
+ /*| '!' expr { $$ = p_expr_new_branch(EXPR_LNOT, $2); }*/
+ | '~' expr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NOT, $2); }
+ | SEG expr { $$ = p_expr_new_branch(EXPR_SEG, $2); }
+ | WRT expr { $$ = p_expr_new_branch(EXPR_WRT, $2); }
+ | expr ':' expr { $$ = p_expr_new_tree($1, EXPR_SEGOFF, $3); }
| '(' expr ')' { $$ = $2; }
;
explabel: ID {
- $$ = symrec_use($1);
+ $$ = symrec_use($1, p_line_index);
xfree($1);
}
| SPECIAL_ID {
- $$ = symrec_use($1);
+ $$ = symrec_use($1, p_line_index);
xfree($1);
}
| LOCAL_ID {
- $$ = symrec_use($1);
+ $$ = symrec_use($1, p_line_index);
xfree($1);
}
| '$' {
/* "$" references the current assembly position */
$$ = symrec_define_label("$", nasm_parser_cur_section,
- nasm_parser_prev_bc, 0);
+ nasm_parser_prev_bc, 0, p_line_index);
}
| START_SECTION_ID {
/* "$$" references the start of the current section */
- $$ = symrec_define_label("$$", nasm_parser_cur_section, NULL, 0);
+ $$ = symrec_define_label("$$", nasm_parser_cur_section, NULL, 0,
+ p_line_index);
}
;
{
valparam *vp, *vp2;
symrec *sym;
+ unsigned long lindex = p_line_index;
/* Handle (mostly) output-format independent directives here */
if (strcasecmp(name, "extern") == 0) {
vp = vps_first(valparams);
if (vp->val) {
- sym = symrec_declare(vp->val, SYM_EXTERN);
+ sym = symrec_declare(vp->val, SYM_EXTERN, lindex);
if (nasm_parser_objfmt->extern_declare)
- nasm_parser_objfmt->extern_declare(sym, objext_valparams);
+ nasm_parser_objfmt->extern_declare(sym, objext_valparams,
+ lindex);
} else
- Error(_("invalid argument to [%s]"), "EXTERN");
+ Error(lindex, _("invalid argument to [%s]"), "EXTERN");
} else if (strcasecmp(name, "global") == 0) {
vp = vps_first(valparams);
if (vp->val) {
- sym = symrec_declare(vp->val, SYM_GLOBAL);
+ sym = symrec_declare(vp->val, SYM_GLOBAL, lindex);
if (nasm_parser_objfmt->global_declare)
- nasm_parser_objfmt->global_declare(sym, objext_valparams);
+ nasm_parser_objfmt->global_declare(sym, objext_valparams,
+ lindex);
} else
- Error(_("invalid argument to [%s]"), "GLOBAL");
+ Error(lindex, _("invalid argument to [%s]"), "GLOBAL");
} else if (strcasecmp(name, "common") == 0) {
vp = vps_first(valparams);
if (vp->val) {
vp2 = vps_next(vp);
if (!vp2 || (!vp2->val && !vp2->param))
- Error(_("no size specified in %s declaration"), "COMMON");
+ Error(lindex, _("no size specified in %s declaration"),
+ "COMMON");
else {
if (vp2->val) {
- sym = symrec_declare(vp->val, SYM_COMMON);
+ sym = symrec_declare(vp->val, SYM_COMMON, lindex);
if (nasm_parser_objfmt->common_declare)
nasm_parser_objfmt->common_declare(sym,
- expr_new_ident(ExprSym(symrec_use(vp2->val))),
- objext_valparams);
+ p_expr_new_ident(ExprSym(symrec_use(vp2->val,
+ lindex))),
+ objext_valparams, lindex);
} else if (vp2->param) {
- sym = symrec_declare(vp->val, SYM_COMMON);
+ sym = symrec_declare(vp->val, SYM_COMMON, lindex);
if (nasm_parser_objfmt->common_declare)
nasm_parser_objfmt->common_declare(sym, vp2->param,
- objext_valparams);
+ objext_valparams,
+ lindex);
vp2->param = NULL;
}
}
} else
- Error(_("invalid argument to [%s]"), "COMMON");
+ Error(lindex, _("invalid argument to [%s]"), "COMMON");
} else if (strcasecmp(name, "section") == 0 ||
strcasecmp(name, "segment") == 0) {
section *new_section =
nasm_parser_objfmt->sections_switch(&nasm_parser_sections,
- valparams, objext_valparams);
+ valparams, objext_valparams,
+ lindex);
if (new_section) {
nasm_parser_cur_section = new_section;
nasm_parser_prev_bc = bcs_last(section_get_bytecodes(new_section));
} else
- Error(_("invalid argument to [%s]"), "SECTION");
+ Error(lindex, _("invalid argument to [%s]"), "SECTION");
} else if (strcasecmp(name, "absolute") == 0) {
/* it can be just an ID or a complete expression, so handle both. */
vp = vps_first(valparams);
if (vp->val)
nasm_parser_cur_section =
sections_switch_absolute(&nasm_parser_sections,
- expr_new_ident(ExprSym(symrec_use(vp->val))));
+ p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex))));
else if (vp->param) {
nasm_parser_cur_section =
sections_switch_absolute(&nasm_parser_sections, vp->param);
} else if (strcasecmp(name, "cpu") == 0) {
vps_foreach(vp, valparams) {
if (vp->val)
- nasm_parser_arch->parse.switch_cpu(vp->val);
+ nasm_parser_arch->parse.switch_cpu(vp->val, lindex);
else if (vp->param) {
const intnum *intcpu;
intcpu = expr_get_intnum(&vp->param, NULL);
if (!intcpu)
- Error(_("invalid argument to [%s]"), "CPU");
+ Error(lindex, _("invalid argument to [%s]"), "CPU");
else {
char strcpu[16];
sprintf(strcpu, "%lu", intnum_get_uint(intcpu));
- nasm_parser_arch->parse.switch_cpu(strcpu);
+ nasm_parser_arch->parse.switch_cpu(strcpu, lindex);
}
}
}
} else if (!nasm_parser_arch->parse.directive(name, valparams,
objext_valparams,
- &nasm_parser_sections)) {
+ &nasm_parser_sections,
+ lindex)) {
;
} else if (nasm_parser_objfmt->directive(name, valparams, objext_valparams,
- &nasm_parser_sections)) {
- Error(_("unrecognized directive [%s]"), name);
+ &nasm_parser_sections, lindex)) {
+ Error(lindex, _("unrecognized directive [%s]"), name);
}
vps_delete(valparams);
void
nasm_parser_error(const char *s)
{
- ParserError(s);
+ ParserError(p_line_index, s);
}
extern int nasm_parser_parse(void);
extern void nasm_parser_cleanup(void);
-size_t (*nasm_parser_input) (char *buf, size_t max_size);
+size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm);
sectionhead nasm_parser_sections;
/*@dependent@*/ section *nasm_parser_cur_section;
/*@dependent@*/ arch *nasm_parser_arch;
/*@dependent@*/ objfmt *nasm_parser_objfmt;
+/*@dependent@*/ linemgr *nasm_parser_linemgr;
static /*@dependent@*/ sectionhead *
-nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, FILE *f,
+nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm, FILE *f,
const char *in_filename)
/*@globals killed nasm_parser_locallabel_base @*/
{
nasm_parser_input = pp->input;
nasm_parser_arch = a;
nasm_parser_objfmt = of;
+ nasm_parser_linemgr = lm;
/* Initialize section list */
nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of);
#include "bitvect.h"
+#include "linemgr.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
void nasm_parser_set_directive_state(void);
int nasm_parser_lex(void);
-extern size_t (*nasm_parser_input) (char *buf, size_t max_size);
+extern size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm);
extern /*@dependent@*/ arch *nasm_parser_arch;
+extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
+
+#define p_line_index (nasm_parser_linemgr->get_current())
typedef struct Scanner {
xfree(s.bot);
s.bot = buf;
}
- if((cnt = nasm_parser_input(s.lim, BSIZE)) != BSIZE){
+ if((cnt = nasm_parser_input(s.lim, BSIZE,
+ nasm_parser_linemgr)) != BSIZE){
s.eof = &s.lim[cnt]; *s.eof++ = '\n';
}
s.lim += cnt;
digit+ {
savech = s.tok[TOKLEN];
s.tok[TOKLEN] = '\0';
- yylval.intn = intnum_new_dec(s.tok);
+ yylval.intn = intnum_new_dec(s.tok, p_line_index);
s.tok[TOKLEN] = savech;
RETURN(INTNUM);
}
bindigit+ "b" {
s.tok[TOKLEN-1] = '\0'; /* strip off 'b' */
- yylval.intn = intnum_new_bin(s.tok);
+ yylval.intn = intnum_new_bin(s.tok, p_line_index);
RETURN(INTNUM);
}
/* 777q - octal number */
octdigit+ "q" {
s.tok[TOKLEN-1] = '\0'; /* strip off 'q' */
- yylval.intn = intnum_new_oct(s.tok);
+ yylval.intn = intnum_new_oct(s.tok, p_line_index);
RETURN(INTNUM);
}
/* 0AAh form of hexidecimal number */
digit hexdigit* "h" {
s.tok[TOKLEN-1] = '\0'; /* strip off 'h' */
- yylval.intn = intnum_new_hex(s.tok);
+ yylval.intn = intnum_new_hex(s.tok, p_line_index);
RETURN(INTNUM);
}
savech = s.tok[TOKLEN];
s.tok[TOKLEN] = '\0';
if (s.tok[1] == 'x')
- yylval.intn = intnum_new_hex(s.tok+2); /* skip 0 and x */
+ /* skip 0 and x */
+ yylval.intn = intnum_new_hex(s.tok+2, p_line_index);
else
- yylval.intn = intnum_new_hex(s.tok+1); /* don't skip 0 */
+ /* don't skip 0 */
+ yylval.intn = intnum_new_hex(s.tok+1, p_line_index);
s.tok[TOKLEN] = savech;
RETURN(INTNUM);
}
yylval.str_val = xstrndup(s.tok, TOKLEN);
RETURN(ID);
} else if (!nasm_parser_locallabel_base) {
- Warning(_("no non-local label before `%s'"), s.tok[0]);
+ Warning(p_line_index, _("no non-local label before `%s'"),
+ s.tok[0]);
yylval.str_val = xstrndup(s.tok, TOKLEN);
} else {
len = TOKLEN + nasm_parser_locallabel_base_len;
savech = s.tok[TOKLEN];
s.tok[TOKLEN] = '\0';
check_id_ret = nasm_parser_arch->parse.check_identifier(
- yylval.arch_data, s.tok);
+ yylval.arch_data, s.tok, p_line_index);
s.tok[TOKLEN] = savech;
switch (check_id_ret) {
case ARCH_CHECK_ID_NONE:
case ARCH_CHECK_ID_TARGETMOD:
RETURN(TARGETMOD);
default:
- Warning(_("Arch feature not supported, treating as identifier"));
+ Warning(p_line_index,
+ _("Arch feature not supported, treating as identifier"));
yylval.str_val = xstrndup(s.tok, TOKLEN);
RETURN(ID);
}
any {
if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
- Warning(_("ignoring unrecognized character `%s'"),
+ Warning(p_line_index,
+ _("ignoring unrecognized character `%s'"),
conv_unprint(s.tok[0]));
goto scan;
}
linechg_numcount++;
savech = s.tok[TOKLEN];
s.tok[TOKLEN] = '\0';
- yylval.intn = intnum_new_dec(s.tok);
+ yylval.intn = intnum_new_dec(s.tok, p_line_index);
s.tok[TOKLEN] = savech;
RETURN(INTNUM);
}
any {
if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
- Warning(_("ignoring unrecognized character `%s'"),
+ Warning(p_line_index,
+ _("ignoring unrecognized character `%s'"),
conv_unprint(s.tok[0]));
goto linechg;
}
any {
if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
- Warning(_("ignoring unrecognized character `%s'"),
+ Warning(p_line_index,
+ _("ignoring unrecognized character `%s'"),
conv_unprint(s.tok[0]));
goto directive;
}
/*!re2c
"\n" {
if (cursor == s.eof)
- Error(_("unexpected end of file in string"));
+ Error(p_line_index, _("unexpected end of file in string"));
else
- Error(_("unterminated string"));
+ Error(p_line_index, _("unterminated string"));
strbuf[count] = '\0';
yylval.str_val = strbuf;
RETURN(STRING);
}
static size_t
-raw_preproc_input(char *buf, size_t max_size)
+raw_preproc_input(char *buf, size_t max_size, unsigned long lindex)
{
int c = '*';
size_t n;
if (c == '\n')
buf[n++] = (char)c;
if (c == EOF && ferror(in))
- Error(_("error when reading from file"));
+ Error(lindex, _("error when reading from file"));
} else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in))
- Error(_("error when reading from file"));
+ Error(lindex, _("error when reading from file"));
return n;
}
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "linemgr.h"
#include "errwarn.h"
#include "preproc.h"
#include "hamt.h"
static HAMT *macro_table;
-YAPP_Output current_output;
+static YAPP_Output current_output;
YYSTYPE yapp_preproc_lval;
+/*@dependent@*/ linemgr *yapp_preproc_linemgr;
+#define p_line_index (yapp_preproc_linemgr->get_current())
+
int isatty(int);
/* Build source and macro representations */
void
yapp_macro_error_exists (YAPP_Macro *v)
{
- if (v) Error(_("Redefining macro of the same name %d:%d"), v->type, v->args);
+ if (v) Error(p_line_index, _("Redefining macro of the same name %d:%d"), v->type, v->args);
}
void
yapp_macro_error_sameargname (YAPP_Macro *v)
{
- if (v) Error(_("Duplicate argument names in macro"));
+ if (v) Error(p_line_index, _("Duplicate argument names in macro"));
}
YAPP_Macro *
if ((argc >= 0 && ym->args < 0)
|| (argc < 0 && ym->args >= 0))
{
- Warning(_("Attempted %%define both with and without parameters"));
+ Warning(p_line_index, _("Attempted %%define both with and without parameters"));
return NULL;
}
}
yapp_preproc_initialize(FILE *f, const char *in_filename)
{
is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
- current_file = xstrdup(in_filename);
- line_number = 1;
+ yapp_preproc_current_file = xstrdup(in_filename);
+ yapp_preproc_line_number = 1;
yapp_lex_initialize(f);
SLIST_INIT(&output_head);
SLIST_INIT(&source_head);
&& (token == '\n' || token == LINE))
{
free ((*to_tail)->token.str);
- (*to_tail)->token.str = xmalloc(23+strlen(current_file));
- sprintf((*to_tail)->token.str, "%%line %d+1 %s\n", line_number, current_file);
+ (*to_tail)->token.str = xmalloc(23+strlen(yapp_preproc_current_file));
+ sprintf((*to_tail)->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file);
}
else {
src = xmalloc(sizeof(source));
case LINE:
/* TODO: consider removing any trailing newline or LINE tokens */
- src->token.str = xmalloc(23+strlen(current_file));
- sprintf(src->token.str, "%%line %d+1 %s\n", line_number, current_file);
+ src->token.str = xmalloc(23+strlen(yapp_preproc_current_file));
+ sprintf(src->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file);
break;
default:
while ((token = yapp_preproc_lex()) != '\n') {
if (token == 0)
return 0;
- Error(_("Skipping possibly valid %%define stuff"));
+ Error(p_line_index, _("Skipping possibly valid %%define stuff"));
}
append_token('\n', to_head, to_tail);
return '\n';
if (token == WHITESPACE)
token = yapp_preproc_lex();
if (token != IDENT) {
- Error(_("Identifier expected after %%%s"), synlvl);
+ Error(p_line_index, _("Identifier expected after %%%s"), synlvl);
}
return token;
}
if (token < 256)
InternalError(_("Unexpected character token in parameter expansion"));
else
- Error(_("Cannot handle preprocessor items inside possible macro invocation"));
+ Error(p_line_index, _("Cannot handle preprocessor items inside possible macro invocation"));
}
}
}
static size_t
-yapp_preproc_input(char *buf, size_t max_size)
+yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
{
static YAPP_State state = YAPP_STATE_INITIAL;
int n = 0;
int token;
int need_line_directive = 0;
+ yapp_preproc_linemgr = lm;
+
while (saved_length < max_size && state != YAPP_STATE_EOF)
{
token = yapp_preproc_lex();
append_token(token, &source_head, &source_tail);
/*if (append_to_return()==0) state=YAPP_STATE_EOF;*/
ydebug(("YAPP: default: '%c' \"%s\"\n", token, yapp_preproc_lval.str_val));
- /*Error(_("YAPP got an unhandled token."));*/
+ /*Error(p_line_index, _("YAPP got an unhandled token."));*/
break;
case IDENT:
break;
}
else if (last_token == ',' || token != ',')
- Error(_("Unexpected token in %%define parameters"));
+ Error(p_line_index, _("Unexpected token in %%define parameters"));
last_token = token;
}
if (token == ')') {
}
break;
default:
- Error(_("YAPP got into a bad state"));
+ Error(p_line_index, _("YAPP got into a bad state"));
}
if (need_line_directive) {
append_token(LINE, &source_head, &source_tail);
extern YYSTYPE yapp_preproc_lval;
-extern char *current_file;
-extern int line_number;
+extern char *yapp_preproc_current_file;
+extern int yapp_preproc_line_number;
+extern /*@dependent@*/ linemgr *yapp_preproc_linemgr;
+#define p_line_index (yapp_preproc_linemgr->get_current())
int yapp_preproc_lex(void);
#include <errno.h>
+#include "linemgr.h"
#include "errwarn.h"
#include "src/preprocs/yapp/yapp-preproc.h"
};
typedef struct include_s include;
-char *current_file;
-int line_number;
+char *yapp_preproc_current_file;
+int yapp_preproc_line_number;
%}
%option noyywrap
}
if(inch == '\n')
- Error(_("unterminated string"));
+ Error(p_line_index, _("unterminated string"));
else if(inch == EOF)
- Error(_("unexpected end of file in string"));
+ Error(p_line_index, _("unexpected end of file in string"));
strbuf[count] = '\0';
/* FIXME: handle includes that aren't relative */
incfile = fopen (yytext, "r");
if(!incfile) {
- Error(_("include file `%s': %s"),
+ Error(p_line_index, _("include file `%s': %s"),
yytext, strerror(errno));
free(inc);
}
else {
yyin = incfile;
- inc->filename = current_file;
- inc->line_number = line_number;
+ inc->filename = yapp_preproc_current_file;
+ inc->line_number = yapp_preproc_line_number;
SLIST_INSERT_HEAD(&includes_head, inc, next);
- line_number = 1;
- current_file = xstrdup(yytext);
+ yapp_preproc_line_number = 1;
+ yapp_preproc_current_file = xstrdup(yytext);
BEGIN(INITIAL);
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
}
inc = SLIST_FIRST(&includes_head);
yy_delete_buffer (YY_CURRENT_BUFFER);
yy_switch_to_buffer (inc->include_state);
- free(current_file);
- current_file = inc->filename;
- line_number = inc->line_number + 1;
+ free(yapp_preproc_current_file);
+ yapp_preproc_current_file = inc->filename;
+ yapp_preproc_line_number = inc->line_number + 1;
SLIST_REMOVE_HEAD(&includes_head, next);
free(inc);
<inhibit>{DIR}line[^\n] ;
{DIR}line BEGIN(line);
-<line>{DIGIT}+ line_number = strtoul(yytext, (char **)NULL, 10);
+<line>{DIGIT}+ yapp_preproc_line_number = strtoul(yytext, (char **)NULL, 10);
<line>{DIGIT}+{WS}*\n {
- line_number = strtoul(yytext, (char **)NULL, 10);
+ yapp_preproc_line_number = strtoul(yytext, (char **)NULL, 10);
BEGIN(INITIAL);
return LINE;
}
<line>{WS}+["] ; /* eat space before file */
<line>[^ \t\n"]* { /* have the filename */
- free(current_file);
- current_file = xstrdup(yytext);
+ free(yapp_preproc_current_file);
+ yapp_preproc_current_file = xstrdup(yytext);
}
<line>["]{WS}*\n {
BEGIN(INITIAL);
<inhibit>{DIR}pop[^\n]* ;
<inhibit>{DIR}repl[^\n]* ;
-<inhibit>[^%\n]*\n { line_number++; return '\n'; }
+<inhibit>[^%\n]*\n { yapp_preproc_line_number++; return '\n'; }
-;.*\n { line_number++; return '\n'; }
+;.*\n { yapp_preproc_line_number++; return '\n'; }
{WS}+ { yylval.str_val = yytext; return WHITESPACE; }
-{WS}*\n { line_number++; return '\n'; }
+{WS}*\n { yapp_preproc_line_number++; return '\n'; }
[][+*/,()-] { return yytext[0]; }
<inhibit>. {
- Warning(_("Unhandled character in <inhibit> `%s'"), conv_unprint(yytext[0]));
+ Warning(p_line_index, _("Unhandled character in <inhibit> `%s'"), conv_unprint(yytext[0]));
}
. {
- Warning(_("ignoring unrecognized character `%s'"),
+ Warning(p_line_index, _("ignoring unrecognized character `%s'"),
conv_unprint(yytext[0]));
}
src/expr-int.h \
src/symrec.c \
src/symrec.h \
- src/globals.c \
- src/globals.h \
+ src/linemgr.h \
src/util.h \
src/coretype.h \
src/file.c \
src/objfmt.c \
src/parser.c \
src/module.h \
- src/module.c
+ src/module.c \
+ src/linemgr.c
EXTRA_DIST += \
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
-#include "globals.h"
#include "expr.h"
#include "bytecode.h"
* parse functions! The bytecode and output functions should be able
* to handle any CPU.
*/
- void (*switch_cpu) (const char *cpuid);
+ void (*switch_cpu) (const char *cpuid, unsigned long lindex);
/* Checks an generic identifier to see if it matches architecture
* specific names for instructions, registers, etc (see the
* used for TARGETMOD, REG, and SEGREG return values.
*/
arch_check_id_retval (*check_identifier) (unsigned long data[4],
- const char *id);
+ const char *id,
+ unsigned long lindex);
/* Architecture-specific directive support. Returns 1 if directive was
* not recognized. Returns 0 if directive was recognized, even if it
*/
int (*directive) (const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams,
- sectionhead *headp);
+ sectionhead *headp, unsigned long lindex);
/* Creates an instruction. Creates a bytecode by matching the
* instruction data and the parameters given with a valid instruction.
int num_operands, /*@null@*/
insn_operandhead *operands,
section *cur_section,
- /*@null@*/ bytecode *prev_bc);
+ /*@null@*/ bytecode *prev_bc,
+ unsigned long lindex);
/* Handle an instruction prefix by modifying bc as necessary. */
- void (*handle_prefix) (bytecode *bc, const unsigned long data[4]);
+ void (*handle_prefix) (bytecode *bc, const unsigned long data[4],
+ unsigned long lindex);
/* Handle an segment register instruction prefix by modifying bc as
* necessary.
*/
- void (*handle_seg_prefix) (bytecode *bc, unsigned long segreg);
+ void (*handle_seg_prefix) (bytecode *bc, unsigned long segreg,
+ unsigned long lindex);
/* Handle memory expression segment overrides by modifying ea as
* necessary.
*/
- void (*handle_seg_override) (effaddr *ea, unsigned long segreg);
+ void (*handle_seg_override) (effaddr *ea, unsigned long segreg,
+ unsigned long lindex);
/* Convert an expression into an effective address. */
effaddr * (*ea_new_expr) (/*@keep@*/ expr *e);
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
int
x86_directive(const char *name, valparamhead *valparams,
/*@unused@*/ /*@null@*/ valparamhead *objext_valparams,
- /*@unused@*/ sectionhead *headp)
+ /*@unused@*/ sectionhead *headp, unsigned long lindex)
{
valparam *vp;
const intnum *intn;
(lval = intnum_get_int(intn)) && (lval == 16 || lval == 32))
yasm_x86_LTX_mode_bits = (unsigned char)lval;
else
- Error(_("invalid argument to [%s]"), "BITS");
+ Error(lindex, _("invalid argument to [%s]"), "BITS");
return 0;
} else
return 1;
}
void
-x86_handle_prefix(bytecode *bc, const unsigned long data[4])
+x86_handle_prefix(bytecode *bc, const unsigned long data[4],
+ unsigned long lindex)
{
switch((x86_parse_insn_prefix)data[0]) {
case X86_LOCKREP:
- x86_bc_insn_set_lockrep_prefix(bc, (unsigned char)data[1]);
+ x86_bc_insn_set_lockrep_prefix(bc, (unsigned char)data[1], lindex);
break;
case X86_ADDRSIZE:
x86_bc_insn_addrsize_override(bc, (unsigned char)data[1]);
}
void
-x86_handle_seg_prefix(bytecode *bc, unsigned long segreg)
+x86_handle_seg_prefix(bytecode *bc, unsigned long segreg, unsigned long lindex)
{
- x86_ea_set_segment(x86_bc_insn_get_ea(bc), (unsigned char)(segreg>>8));
+ x86_ea_set_segment(x86_bc_insn_get_ea(bc), (unsigned char)(segreg>>8),
+ lindex);
}
void
-x86_handle_seg_override(effaddr *ea, unsigned long segreg)
+x86_handle_seg_override(effaddr *ea, unsigned long segreg,
+ unsigned long lindex)
{
- x86_ea_set_segment(ea, (unsigned char)(segreg>>8));
+ x86_ea_set_segment(ea, (unsigned char)(segreg>>8), lindex);
}
/* Define arch structure -- see arch.h for details */
JR_NEAR_FORCED
} x86_jmprel_opcode_sel;
-void x86_ea_set_segment(/*@null@*/ effaddr *ea, unsigned char segment);
+void x86_ea_set_segment(/*@null@*/ effaddr *ea, unsigned char segment,
+ unsigned long lindex);
void x86_ea_set_disponly(effaddr *ea);
effaddr *x86_ea_new_reg(unsigned char reg);
effaddr *x86_ea_new_imm(/*@keep@*/expr *imm, unsigned char im_len);
void x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize);
void x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize);
-void x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix);
-
-void x86_set_jmprel_opcode_sel(x86_jmprel_opcode_sel *old_sel,
- x86_jmprel_opcode_sel new_sel);
+void x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix,
+ unsigned long lindex);
/* Structure with *all* inputs passed to x86_bytecode_new_insn().
* IMPORTANT: ea_ptr and im_ptr cannot be reused or freed after calling the
* function (it doesn't make a copy).
*/
typedef struct x86_new_insn_data {
+ unsigned long lindex;
/*@keep@*/ /*@null@*/ effaddr *ea;
/*@keep@*/ /*@null@*/ expr *imm;
unsigned char opersize;
* Pass 0 for the opcode_len if that version of the opcode doesn't exist.
*/
typedef struct x86_new_jmprel_data {
+ unsigned long lindex;
/*@keep@*/ expr *target;
x86_jmprel_opcode_sel op_sel;
unsigned char short_op_len;
unsigned char *v_sib, unsigned char *n_sib,
calc_bc_dist_func calc_bc_dist);
-void x86_switch_cpu(const char *cpuid);
+void x86_switch_cpu(const char *cpuid, unsigned long lindex);
arch_check_id_retval x86_check_identifier(unsigned long data[2],
- const char *id);
+ const char *id,
+ unsigned long lindex);
int x86_directive(const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams,
- sectionhead *headp);
+ sectionhead *headp, unsigned long lindex);
/*@null@*/ bytecode *x86_new_insn(const unsigned long data[2],
int num_operands,
/*@null@*/ insn_operandhead *operands,
section *cur_section,
- /*@null@*/ bytecode *prev_bc);
+ /*@null@*/ bytecode *prev_bc,
+ unsigned long lindex);
-void x86_handle_prefix(bytecode *bc, const unsigned long data[4]);
+void x86_handle_prefix(bytecode *bc, const unsigned long data[4],
+ unsigned long lindex);
-void x86_handle_seg_prefix(bytecode *bc, unsigned long segreg);
+void x86_handle_seg_prefix(bytecode *bc, unsigned long segreg,
+ unsigned long lindex);
-void x86_handle_seg_override(effaddr *ea, unsigned long segreg);
+void x86_handle_seg_override(effaddr *ea, unsigned long segreg,
+ unsigned long lindex);
int x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp,
unsigned long valsize, const expr *e);
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
x86_insn *insn;
insn = (x86_insn *)bc_new_common((bytecode_type)X86_BC_INSN,
- sizeof(x86_insn));
+ sizeof(x86_insn), d->lindex);
insn->ea = (x86_effaddr *)d->ea;
if (d->ea) {
x86_jmprel *jmprel;
jmprel = (x86_jmprel *)bc_new_common((bytecode_type)X86_BC_JMPREL,
- sizeof(x86_jmprel));
+ sizeof(x86_jmprel), d->lindex);
jmprel->target = d->target;
jmprel->op_sel = d->op_sel;
if ((d->op_sel == JR_SHORT_FORCED) && (d->near_op_len == 0))
- Error(_("no SHORT form of that jump instruction exists"));
+ Error(d->lindex, _("no SHORT form of that jump instruction exists"));
if ((d->op_sel == JR_NEAR_FORCED) && (d->short_op_len == 0))
- Error(_("no NEAR form of that jump instruction exists"));
+ Error(d->lindex, _("no NEAR form of that jump instruction exists"));
jmprel->shortop.opcode[0] = d->short_op[0];
jmprel->shortop.opcode[1] = d->short_op[1];
/*@=compmempass =mustfree@*/
void
-x86_ea_set_segment(effaddr *ea, unsigned char segment)
+x86_ea_set_segment(effaddr *ea, unsigned char segment, unsigned long lindex)
{
x86_effaddr *x86_ea = (x86_effaddr *)ea;
return;
if (segment != 0 && x86_ea->segment != 0)
- Warning(_("multiple segment overrides, using leftmost"));
+ Warning(lindex, _("multiple segment overrides, using leftmost"));
x86_ea->segment = segment;
}
}
void
-x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
+x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix,
+ unsigned long lindex)
{
x86_insn *insn;
x86_jmprel *jmprel;
}
if (*lockrep_pre != 0)
- Warning(_("multiple LOCK or REP prefixes, using leftmost"));
+ Warning(lindex, _("multiple LOCK or REP prefixes, using leftmost"));
*lockrep_pre = prefix;
}
-void
-x86_set_jmprel_opcode_sel(x86_jmprel_opcode_sel *old_sel,
- x86_jmprel_opcode_sel new_sel)
-{
- if (!old_sel)
- return;
-
- if (new_sel != JR_NONE && ((*old_sel == JR_SHORT_FORCED) ||
- (*old_sel == JR_NEAR_FORCED)))
- Warning(_("multiple SHORT or NEAR specifiers, using leftmost"));
- *old_sel = new_sel;
-}
-
void
x86_bc_delete(bytecode *bc)
{
temp = expr_copy(jmprel->target);
num = expr_get_intnum(&temp, calc_bc_dist);
if (!num) {
- ErrorAt(bc->line,
- _("short jump target external or out of segment"));
+ Error(bc->line,
+ _("short jump target external or out of segment"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
} else {
rel = intnum_get_int(num);
rel -= jmprel->shortop.opcode_len+1;
/* does a short form exist? */
if (jmprel->shortop.opcode_len == 0) {
- ErrorAt(bc->line, _("short jump does not exist"));
+ Error(bc->line, _("short jump does not exist"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
/* short displacement must fit in -128 <= rel <= +127 */
if (rel < -128 || rel > 127) {
- ErrorAt(bc->line, _("short jump out of range"));
+ Error(bc->line, _("short jump out of range"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
}
jrshort = 0;
if (save) {
if (jmprel->nearop.opcode_len == 0) {
- ErrorAt(bc->line, _("near jump does not exist"));
+ Error(bc->line, _("near jump does not exist"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
}
* it to actually be within short range).
*/
if (save) {
- ErrorAt(bc->line, _("short jump out of range (near jump does not exist)"));
+ Error(bc->line,
+ _("short jump out of range (near jump does not exist)"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
jrshort = 1;
jrshort = 0;
} else {
if (save) {
- ErrorAt(bc->line,
- _("short jump out of range (near jump does not exist)"));
+ Error(bc->line,
+ _("short jump out of range (near jump does not exist)"));
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
jrshort = 1;
case JR_NEAR:
/* 2/4 byte relative displacement (depending on operand size) */
if (jmprel->nearop.opcode_len == 0) {
- ErrorAt(bc->line, _("near jump does not exist"));
+ Error(bc->line, _("near jump does not exist"));
return 1;
}
#include "bitvect.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
*/
if (!intnum_check_size(intn, (size_t)wordsize, 0) &&
!intnum_check_size(intn, 1, 1)) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
case 2:
case 4:
if (wordsize != *displen) {
- ErrorAt(e->line,
- _("invalid effective address (displacement size)"));
+ Error(e->line,
+ _("invalid effective address (displacement size)"));
return 0;
}
/* TODO: Add optional warning here about 2/4 not being valid
calc_bc_dist)) {
case 0:
e = *ep;
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
case 1:
return 1;
*/
for (i=0; i<8; i++) {
if (reg32mult[i] < 0) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
if (i != indexreg && reg32mult[i] == 1 && basereg == REG32_NONE)
*/
for (i=0; i<8; i++)
if (i != basereg && i != indexreg && reg32mult[i] != 0) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
if (indexreg != REG32_NONE && reg32mult[indexreg] != 1 &&
reg32mult[indexreg] != 2 && reg32mult[indexreg] != 4 &&
reg32mult[indexreg] != 8) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
* legal.
*/
if (reg32mult[REG32_ESP] > 1 || basereg == REG32_ESP) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
/* If mult==1 and basereg is not ESP, swap indexreg w/basereg. */
calc_bc_dist)) {
case 0:
e = *ep;
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
case 1:
return 1;
/* reg multipliers not 0 or 1 are illegal. */
if (reg16mult.bx & ~1 || reg16mult.si & ~1 || reg16mult.di & ~1 ||
reg16mult.bp & ~1) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
/* Check the modrm value for invalid combinations. */
if (modrm16[havereg] & 0070) {
- ErrorAt(e->line, _("invalid effective address"));
+ Error(e->line, _("invalid effective address"));
return 0;
}
int fltret;
if (!floatnum_check_size(flt, (size_t)valsize)) {
- ErrorAt(e->line, _("invalid floating point constant size"));
+ Error(e->line, _("invalid floating point constant size"));
return 1;
}
fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize);
if (fltret < 0) {
- ErrorAt(e->line, _("underflow in floating point expression"));
+ Error(e->line, _("underflow in floating point expression"));
return 1;
}
if (fltret > 0) {
- ErrorAt(e->line, _("overflow in floating point expression"));
+ Error(e->line, _("overflow in floating point expression"));
return 1;
}
*bufp += valsize;
#include "bitvect.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
static bytecode *
x86_new_jmprel(const unsigned long data[4], int num_operands,
insn_operandhead *operands, x86_insn_info *jrinfo,
- section *cur_section, /*@null@*/ bytecode *prev_bc)
+ section *cur_section, /*@null@*/ bytecode *prev_bc,
+ unsigned long lindex)
{
x86_new_jmprel_data d;
int num_info = (int)(data[1]&0xFF);
insn_operand *op;
static const unsigned char size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
+ d.lindex = lindex;
+
/* We know the target is in operand 0, but sanity check for Imm. */
op = ops_first(operands);
if (op->type != INSN_OPERAND_IMM)
InternalError(_("invalid operand conversion"));
d.target = expr_new(EXPR_SUB, ExprExpr(op->data.val),
ExprSym(symrec_define_label("$", cur_section, prev_bc,
- 0)));
+ 0, lindex)), lindex);
/* See if the user explicitly specified short/near. */
switch (jrinfo->operands[0] & OPTM_MASK) {
bytecode *
x86_new_insn(const unsigned long data[4], int num_operands,
insn_operandhead *operands, section *cur_section,
- /*@null@*/ bytecode *prev_bc)
+ /*@null@*/ bytecode *prev_bc, unsigned long lindex)
{
x86_new_insn_data d;
int num_info = (int)(data[1]&0xFF);
if (!found) {
/* Didn't find a matching one */
- Error(_("invalid combination of opcode and operands"));
+ Error(lindex, _("invalid combination of opcode and operands"));
return NULL;
}
case MOD_ExtErr:
switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) {
case 0:
- Error(_("mismatch in operand sizes"));
+ Error(lindex, _("mismatch in operand sizes"));
break;
case 1:
- Error(_("operand size not specified"));
+ Error(lindex, _("operand size not specified"));
break;
default:
InternalError(_("unrecognized x86 ext mod index"));
/* Shortcut to JmpRel */
if (operands && (info->operands[0] & OPA_MASK) == OPA_JmpRel)
return x86_new_jmprel(data, num_operands, operands, info, cur_section,
- prev_bc);
+ prev_bc, lindex);
/* Copy what we can from info */
+ d.lindex = lindex;
d.ea = NULL;
d.imm = NULL;
d.opersize = info->opersize;
mod_data >>= 8;
}
if (info->modifiers & MOD_Imm8) {
- d.imm = expr_new_ident(ExprInt(intnum_new_int(mod_data & 0xFF)));
+ d.imm = expr_new_ident(ExprInt(intnum_new_int(mod_data & 0xFF)),
+ lindex);
d.im_len = 1;
/*mod_data >>= 8;*/
}
*/
void
-x86_switch_cpu(const char *id)
+x86_switch_cpu(const char *id, unsigned long lindex)
{
/*const char *marker;*/
/* catchalls */
[\001-\377]+ {
- Warning(_("unrecognized CPU identifier `%s'"), id);
+ Warning(lindex, _("unrecognized CPU identifier `%s'"), id);
return;
}
[\000] {
- Warning(_("unrecognized CPU identifier `%s'"), id);
+ Warning(lindex, _("unrecognized CPU identifier `%s'"), id);
return;
}
*/
}
arch_check_id_retval
-x86_check_identifier(unsigned long data[4], const char *id)
+x86_check_identifier(unsigned long data[4], const char *id,
+ /*@unused@*/ unsigned long lindex)
{
const char *oid = id;
/*const char *marker;*/
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
}
immval *
-imm_new_int(unsigned long int_val)
+imm_new_int(unsigned long int_val, unsigned long lindex)
{
- return imm_new_expr(expr_new_ident(ExprInt(intnum_new_uint(int_val))));
+ return imm_new_expr(expr_new_ident(ExprInt(intnum_new_uint(int_val)),
+ lindex));
}
immval *
bc_set_multiple(bytecode *bc, expr *e)
{
if (bc->multiple)
- bc->multiple = expr_new_tree(bc->multiple, EXPR_MUL, e);
+ bc->multiple = expr_new_tree(bc->multiple, EXPR_MUL, e, e->line);
else
bc->multiple = e;
}
bytecode *
-bc_new_common(bytecode_type type, size_t size)
+bc_new_common(bytecode_type type, size_t size, unsigned long lindex)
{
bytecode *bc = xmalloc(size);
bc->multiple = (expr *)NULL;
bc->len = 0;
- bc->line = line_index;
+ bc->line = lindex;
bc->offset = 0;
}
bytecode *
-bc_new_data(datavalhead *datahead, unsigned char size)
+bc_new_data(datavalhead *datahead, unsigned char size, unsigned long lindex)
{
bytecode_data *data;
- data = (bytecode_data *)bc_new_common(BC_DATA, sizeof(bytecode_data));
+ data = (bytecode_data *)bc_new_common(BC_DATA, sizeof(bytecode_data),
+ lindex);
data->datahead = *datahead;
data->size = size;
}
bytecode *
-bc_new_reserve(expr *numitems, unsigned char itemsize)
+bc_new_reserve(expr *numitems, unsigned char itemsize, unsigned long lindex)
{
bytecode_reserve *reserve;
reserve = (bytecode_reserve *)bc_new_common(BC_RESERVE,
- sizeof(bytecode_reserve));
+ sizeof(bytecode_reserve),
+ lindex);
/*@-mustfree@*/
reserve->numitems = numitems;
}
bytecode *
-bc_new_incbin(char *filename, expr *start, expr *maxlen)
+bc_new_incbin(char *filename, expr *start, expr *maxlen, unsigned long lindex)
{
bytecode_incbin *incbin;
incbin = (bytecode_incbin *)bc_new_common(BC_INCBIN,
- sizeof(bytecode_incbin));
+ sizeof(bytecode_incbin),
+ lindex);
/*@-mustfree@*/
incbin->filename = filename;
}
bytecode *
-bc_new_align(unsigned long boundary)
+bc_new_align(unsigned long boundary, unsigned long lindex)
{
bytecode_align *align;
- align = (bytecode_align *)bc_new_common(BC_ALIGN, sizeof(bytecode_align));
+ align = (bytecode_align *)bc_new_common(BC_ALIGN, sizeof(bytecode_align),
+ lindex);
align->boundary = boundary;
bytecode *
bc_new_objfmt_data(unsigned int type, unsigned long len, objfmt *of,
- void *data)
+ void *data, unsigned long lindex)
{
bytecode_objfmt_data *objfmt_data;
objfmt_data =
(bytecode_objfmt_data *)bc_new_common(BC_ALIGN,
- sizeof(bytecode_objfmt_data));
+ sizeof(bytecode_objfmt_data),
+ lindex);
objfmt_data->type = type;
objfmt_data->of = of;
const bytecode_incbin *incbin;
const bytecode_align *align;
const bytecode_objfmt_data *objfmt_data;
- const char *filename;
- unsigned long line;
switch (bc->type) {
case BC_EMPTY:
else
expr_print(f, bc->multiple);
fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
- line_lookup(bc->line, &filename, &line);
- fprintf(f, "%*sFilename=\"%s\" Line Number=%lu\n", indent_level, "",
- filename, line);
+ fprintf(f, "%*sLine Index=%lu\n", indent_level, "", bc->line);
fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
}
* the circular reference error to filter through.
*/
if (temp && expr_contains(temp, EXPR_FLOAT))
- ErrorAt(line,
- _("expression must not contain floating point value"));
+ Error(line, _("expression must not contain floating point value"));
else
- ErrorAt(line,
- _("attempt to reserve non-constant quantity of space"));
+ Error(line,
+ _("attempt to reserve non-constant quantity of space"));
retval = BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
} else
*len += intnum_get_uint(num)*reserve->itemsize;
/* Open file and determine its length */
f = fopen(incbin->filename, "rb");
if (!f) {
- ErrorAt(line, _("`incbin': unable to open file `%s'"),
- incbin->filename);
+ Error(line, _("`incbin': unable to open file `%s'"), incbin->filename);
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
if (fseek(f, 0L, SEEK_END) < 0) {
- ErrorAt(line, _("`incbin': unable to seek on file `%s'"),
- incbin->filename);
+ Error(line, _("`incbin': unable to seek on file `%s'"),
+ incbin->filename);
return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN;
}
flen = (unsigned long)ftell(f);
/* Compute length of incbin from start, maxlen, and len */
if (start > flen) {
- WarningAt(line, _("`incbin': start past end of file `%s'"),
- incbin->filename);
+ Warning(line, _("`incbin': start past end of file `%s'"),
+ incbin->filename);
start = flen;
}
flen -= start;
if (!num) {
retval = BC_RESOLVE_UNKNOWN_LEN;
if (temp && expr_contains(temp, EXPR_FLOAT)) {
- ErrorAt(bc->line,
- _("expression must not contain floating point value"));
+ Error(bc->line,
+ _("expression must not contain floating point value"));
retval |= BC_RESOLVE_ERROR;
}
} else
/* Open file */
f = fopen(incbin->filename, "rb");
if (!f) {
- ErrorAt(line, _("`incbin': unable to open file `%s'"),
- incbin->filename);
+ Error(line, _("`incbin': unable to open file `%s'"), incbin->filename);
return 1;
}
/* Seek to start of data */
if (fseek(f, (long)start, SEEK_SET) < 0) {
- ErrorAt(line, _("`incbin': unable to seek on file `%s'"),
- incbin->filename);
+ Error(line, _("`incbin': unable to seek on file `%s'"),
+ incbin->filename);
fclose(f);
return 1;
}
/* Read len bytes */
if (fread(*bufp, (size_t)len, 1, f) < (size_t)len) {
- ErrorAt(line, _("`incbin': unable to read %lu bytes from file `%s'"),
- len, incbin->filename);
+ Error(line, _("`incbin': unable to read %lu bytes from file `%s'"),
+ len, incbin->filename);
fclose(f);
return 1;
}
void bc_initialize(arch *a);
-/*@only@*/ immval *imm_new_int(unsigned long int_val);
+/*@only@*/ immval *imm_new_int(unsigned long int_val, unsigned long lindex);
/*@only@*/ immval *imm_new_expr(/*@keep@*/ expr *e);
/*@observer@*/ const expr *ea_get_disp(const effaddr *ea);
void bc_set_multiple(bytecode *bc, /*@keep@*/ expr *e);
-/*@only@*/ bytecode *bc_new_common(bytecode_type type, size_t datasize);
-/*@only@*/ bytecode *bc_new_data(datavalhead *datahead, unsigned char size);
+/*@only@*/ bytecode *bc_new_common(bytecode_type type, size_t datasize,
+ unsigned long lindex);
+/*@only@*/ bytecode *bc_new_data(datavalhead *datahead, unsigned char size,
+ unsigned long lindex);
/*@only@*/ bytecode *bc_new_reserve(/*@only@*/ expr *numitems,
- unsigned char itemsize);
+ unsigned char itemsize,
+ unsigned long lindex);
/*@only@*/ bytecode *bc_new_incbin(/*@only@*/ char *filename,
/*@only@*/ /*@null@*/ expr *start,
- /*@only@*/ /*@null@*/ expr *maxlen);
-/*@only@*/ bytecode *bc_new_align(unsigned long boundary);
+ /*@only@*/ /*@null@*/ expr *maxlen,
+ unsigned long lindex);
+/*@only@*/ bytecode *bc_new_align(unsigned long boundary,
+ unsigned long lindex);
/*@only@*/ bytecode *bc_new_objfmt_data(unsigned int type, unsigned long len,
- objfmt *of, /*@only@*/ void *data);
+ objfmt *of, /*@only@*/ void *data,
+ unsigned long lindex);
void bc_delete(/*@only@*/ /*@null@*/ bytecode *bc);
typedef struct intnum intnum;
typedef struct floatnum floatnum;
+typedef struct linemgr linemgr;
+
typedef enum {
EXPR_ADD,
EXPR_SUB,
# include <stdarg.h>
#endif
-#include "globals.h"
+#include "linemgr.h"
#include "errwarn.h"
* system.
*/
void
-ParserError(const char *s)
+ParserError(unsigned long lindex, const char *s)
{
- Error("%s %s", _("parser error:"), s);
+ Error(lindex, "%s %s", _("parser error:"), s);
previous_we->type = WE_PARSERERROR;
}
-/* Register an error during the parser stage (uses global line_index). Does
- * not print the error, only stores it for OutputAllErrorWarning() to print.
- */
-void
-Error(const char *fmt, ...)
-{
- va_list va;
- va_start(va, fmt);
- error_common(line_index, fmt, va);
- va_end(va);
-}
-
/* Register an error at line lindex. Does not print the error, only stores it
* for OutputAllErrorWarning() to print.
*/
void
-ErrorAt(unsigned long lindex, const char *fmt, ...)
+Error(unsigned long lindex, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
va_end(va);
}
-/* Register a warning during the parser stage (uses global line_index). Does
- * not print the warning, only stores it for OutputAllErrorWarning() to print.
- */
-void
-Warning(const char *fmt, ...)
-{
- va_list va;
- va_start(va, fmt);
- warning_common(line_index, fmt, va);
- va_end(va);
-}
-
/* Register an warning at line lindex. Does not print the warning, only stores
* it for OutputAllErrorWarning() to print.
*/
void
-WarningAt(unsigned long lindex, const char *fmt, ...)
+Warning(unsigned long lindex, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
/* Output all previously stored errors and warnings to stderr. */
void
-OutputAllErrorWarning(void)
+OutputAllErrorWarning(linemgr *lm)
{
errwarn *we;
const char *filename;
while (!SLIST_EMPTY(&errwarns)) {
we = SLIST_FIRST(&errwarns);
/* Output error/warning */
- line_lookup(we->line, &filename, &line);
+ lm->lookup(we->line, &filename, &line);
if (we->type == WE_ERROR)
fprintf(stderr, "%s:%lu: %s\n", filename, line, we->msg);
else
/*@shared@*/ char *conv_unprint(char ch);
-void ParserError(const char *);
+void ParserError(unsigned long lindex, const char *);
/*@exits@*/ void InternalError_(const char *file, unsigned int line,
const char *message);
#define InternalError(msg) InternalError_(__FILE__, __LINE__, msg)
/*@exits@*/ void Fatal(fatal_num);
-void Error(const char *, ...) /*@printflike@*/;
-void Warning(const char *, ...) /*@printflike@*/;
-/* Use Error() and Warning() instead of ErrorAt() and WarningAt() when being
- * called in line order from a parser.
- */
-void ErrorAt(unsigned long lindex, const char *, ...) /*@printflike@*/;
-void WarningAt(unsigned long lindex, const char *, ...) /*@printflike@*/;
+void Error(unsigned long lindex, const char *, ...) /*@printflike@*/;
+void Warning(unsigned long lindex, const char *, ...) /*@printflike@*/;
/* These two functions immediately output the error or warning, with no file
* or line information. They should be used for errors and warnings outside
unsigned int GetNumErrors(void);
/* Outputs all errors/warnings to standard error. */
-void OutputAllErrorWarning(void);
+void OutputAllErrorWarning(linemgr *lm);
#endif
#include "bitvect.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
* If it's a unary operator, put the element in left and set right=NULL. */
/*@-compmempass@*/
expr *
-expr_new(ExprOp op, ExprItem *left, ExprItem *right)
+expr_new(ExprOp op, ExprItem *left, ExprItem *right, unsigned long lindex)
{
expr *ptr, *sube;
ptr = xmalloc(sizeof(expr));
}
}
- ptr->line = line_index;
+ ptr->line = lindex;
return ptr;
}
symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
section_is_absolute(sect) &&
(dist = calc_bc_dist(sect, NULL, precbc))) {
+ const expr *start = section_get_start(sect);
e->terms[i].type = EXPR_EXPR;
e->terms[i].data.expn =
- expr_new(EXPR_ADD,
- ExprExpr(expr_copy(section_get_start(sect))),
- ExprInt(dist));
+ expr_new(EXPR_ADD, ExprExpr(expr_copy(start)), ExprInt(dist),
+ start->line);
}
}
* floatnums present below; if there ARE floatnums, recurse.
*/
if (e->terms[0].type == EXPR_FLOAT)
- floatnum_calc(e->terms[0].data.flt, EXPR_NEG, NULL);
+ floatnum_calc(e->terms[0].data.flt, EXPR_NEG, NULL, e->line);
else if (e->terms[0].type == EXPR_EXPR &&
expr_contains(e->terms[0].data.expn, EXPR_FLOAT))
expr_xform_neg_helper(e->terms[0].data.expn);
/* Check for circular reference */
SLIST_FOREACH(np, eh, next) {
if (np->e == equ_expr) {
- ErrorAt(e->line, _("circular reference detected."));
+ Error(e->line, _("circular reference detected."));
return e;
}
}
void expr_initialize(arch *a);
/*@only@*/ expr *expr_new(ExprOp, /*@only@*/ ExprItem *,
- /*@only@*/ /*@null@*/ ExprItem *);
+ /*@only@*/ /*@null@*/ ExprItem *,
+ unsigned long lindex);
/*@only@*/ ExprItem *ExprSym(/*@keep@*/ symrec *);
/*@only@*/ ExprItem *ExprExpr(/*@keep@*/ expr *);
/*@only@*/ ExprItem *ExprFloat(/*@keep@*/ floatnum *);
/*@only@*/ ExprItem *ExprReg(unsigned long reg);
-#define expr_new_tree(l,o,r) \
- expr_new ((o), ExprExpr(l), ExprExpr(r))
-#define expr_new_branch(o,r) \
- expr_new ((o), ExprExpr(r), (ExprItem *)NULL)
-#define expr_new_ident(r) \
- expr_new (EXPR_IDENT, (r), (ExprItem *)NULL)
+#define expr_new_tree(l,o,r,i) \
+ expr_new ((o), ExprExpr(l), ExprExpr(r), i)
+#define expr_new_branch(o,r,i) \
+ expr_new ((o), ExprExpr(r), (ExprItem *)NULL, i)
+#define expr_new_ident(r,i) \
+ expr_new (EXPR_IDENT, (r), (ExprItem *)NULL, i)
/* allocates and makes an exact duplicate of e */
expr *expr_copy(const expr *e);
}
void
-floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand)
+floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand,
+ unsigned long lindex)
{
if (op != EXPR_NEG)
- Error(_("Unsupported floating-point arithmetic operation"));
+ Error(lindex, _("Unsupported floating-point arithmetic operation"));
else
acc->sign ^= 1;
}
void floatnum_delete(/*@only@*/ floatnum *flt);
/* calculation function: acc = acc op operand */
-void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand);
+void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand,
+ unsigned long lindex);
/* The get functions return nonzero if flt can't fit into that size format:
* -1 if underflow occurred, 1 if overflow occurred.
+++ /dev/null
-/*
- * Global variables
- *
- * Copyright (C) 2001 Peter Johnson
- *
- * This file is part of YASM.
- *
- * YASM is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * YASM is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "util.h"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "hamt.h"
-
-#include "globals.h"
-
-
-/* Source lines tracking */
-typedef struct {
- struct line_index_mapping *vector;
- unsigned long size;
- unsigned long allocated;
-} line_index_mapping_head;
-
-typedef struct line_index_mapping {
- /* monotonically increasing line index */
- unsigned long index;
-
- /* related info */
- /* "original" source filename */
- /*@null@*/ /*@dependent@*/ const char *filename;
- /* "original" source base line number */
- unsigned long line;
- /* "original" source line number increment (for following lines) */
- unsigned long line_inc;
-} line_index_mapping;
-
-/* Shared storage for filenames */
-static /*@only@*/ /*@null@*/ HAMT *filename_table = NULL;
-
-/* Virtual line number. Uniquely specifies every line read by the parser. */
-unsigned long line_index = 1;
-static /*@only@*/ /*@null@*/ line_index_mapping_head *line_index_map = NULL;
-
-/* Global assembler options. */
-unsigned int asm_options = 0;
-
-static void
-filename_delete_one(/*@only@*/ void *d)
-{
- xfree(d);
-}
-
-void
-line_set(const char *filename, unsigned long line, unsigned long line_inc)
-{
- char *copy;
- int replace = 0;
- line_index_mapping *mapping;
-
- /* Create a new mapping in the map */
- if (!line_index_map) {
- /* initialize vector */
- line_index_map = xmalloc(sizeof(line_index_mapping_head));
- line_index_map->vector = xmalloc(8*sizeof(line_index_mapping));
- line_index_map->size = 0;
- line_index_map->allocated = 8;
- }
- if (line_index_map->size >= line_index_map->allocated) {
- /* allocate another size bins when full for 2x space */
- line_index_map->vector = xrealloc(line_index_map->vector,
- 2*line_index_map->allocated*sizeof(line_index_mapping));
- line_index_map->allocated *= 2;
- }
- mapping = &line_index_map->vector[line_index_map->size];
- line_index_map->size++;
-
- /* Fill it */
-
- /* Copy the filename (via shared storage) */
- copy = xstrdup(filename);
- if (!filename_table)
- filename_table = HAMT_new();
- /*@-aliasunique@*/
- mapping->filename = HAMT_insert(filename_table, copy, copy, &replace,
- filename_delete_one);
- /*@=aliasunique@*/
-
- mapping->index = line_index;
- mapping->line = line;
- mapping->line_inc = line_inc;
-}
-
-void
-line_shutdown(void)
-{
- if (line_index_map) {
- xfree(line_index_map->vector);
- xfree(line_index_map);
- line_index_map = NULL;
- }
-
- if (filename_table) {
- HAMT_delete(filename_table, filename_delete_one);
- filename_table = NULL;
- }
-}
-
-void
-line_lookup(unsigned long lindex, const char **filename, unsigned long *line)
-{
- line_index_mapping *mapping;
- unsigned long vindex, step;
-
- assert(lindex <= line_index);
-
- /* Binary search through map to find highest line_index <= index */
- assert(line_index_map != NULL);
- vindex = 0;
- /* start step as the greatest power of 2 <= size */
- step = 1;
- while (step*2<=line_index_map->size)
- step*=2;
- while (step>0) {
- if (vindex+step < line_index_map->size
- && line_index_map->vector[vindex+step].index <= lindex)
- vindex += step;
- step /= 2;
- }
- mapping = &line_index_map->vector[vindex];
-
- *filename = mapping->filename;
- *line = mapping->line+mapping->line_inc*(lindex-mapping->index);
-}
+++ /dev/null
-/* $IdPath$
- * Globals header file
- *
- * Copyright (C) 2001 Peter Johnson
- *
- * This file is part of YASM.
- *
- * YASM is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * YASM is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef YASM_GLOBALS_H
-#define YASM_GLOBALS_H
-
-/* Virtual line number. Uniquely specifies every line read by the parser. */
-extern unsigned long line_index;
-
-/* Global assembler options. */
-extern unsigned int asm_options;
-
-void line_set(const char *filename, unsigned long line,
- unsigned long line_inc);
-void line_shutdown(void);
-void line_lookup(unsigned long lindex, /*@out@*/ const char **filename,
- /*@out@*/ unsigned long *line);
-
-#endif
}
intnum *
-intnum_new_dec(char *str)
+intnum_new_dec(char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
}
if (BitVector_from_Dec_static(conv_bv,
(unsigned char *)str) == ErrCode_Ovfl)
- Warning(_("Numeric constant too large for internal format"));
+ Warning(lindex, _("Numeric constant too large for internal format"));
if (Set_Max(conv_bv) < 32) {
intn->type = INTNUM_UL;
intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
}
intnum *
-intnum_new_bin(char *str)
+intnum_new_bin(char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
intn->origsize = (unsigned char)strlen(str);
if(intn->origsize > BITVECT_ALLOC_SIZE)
- Warning(_("Numeric constant too large for internal format"));
+ Warning(lindex, _("Numeric constant too large for internal format"));
if (!conv_bv) {
conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
}
intnum *
-intnum_new_oct(char *str)
+intnum_new_oct(char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
intn->origsize = strlen(str)*3;
if(intn->origsize > BITVECT_ALLOC_SIZE)
- Warning(_("Numeric constant too large for internal format"));
+ Warning(lindex, _("Numeric constant too large for internal format"));
if (!conv_bv) {
conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
}
intnum *
-intnum_new_hex(char *str)
+intnum_new_hex(char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
intn->origsize = strlen(str)*4;
if(intn->origsize > BITVECT_ALLOC_SIZE)
- Warning(_("Numeric constant too large for internal format"));
+ Warning(lindex, _("Numeric constant too large for internal format"));
if (!conv_bv) {
conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
/*@-usedef -compdef -uniondef@*/
intnum *
-intnum_new_charconst_nasm(const char *str)
+intnum_new_charconst_nasm(const char *str, unsigned long lindex)
{
intnum *intn = xmalloc(sizeof(intnum));
size_t len = strlen(str);
if (len > 4)
- Warning(_("character constant too large, ignoring trailing characters"));
+ Warning(lindex,
+ _("character constant too large, ignoring trailing characters"));
intn->val.ul = 0;
intn->type = INTNUM_UL;
/* Clean up internal allocations */
void intnum_shutdown(void);
-/*@only@*/ intnum *intnum_new_dec(char *str);
-/*@only@*/ intnum *intnum_new_bin(char *str);
-/*@only@*/ intnum *intnum_new_oct(char *str);
-/*@only@*/ intnum *intnum_new_hex(char *str);
+/*@only@*/ intnum *intnum_new_dec(char *str, unsigned long lindex);
+/*@only@*/ intnum *intnum_new_bin(char *str, unsigned long lindex);
+/*@only@*/ intnum *intnum_new_oct(char *str, unsigned long lindex);
+/*@only@*/ intnum *intnum_new_hex(char *str, unsigned long lindex);
/* convert character constant to integer value, using NASM rules */
-/*@only@*/ intnum *intnum_new_charconst_nasm(const char *str);
+/*@only@*/ intnum *intnum_new_charconst_nasm(const char *str,
+ unsigned long lindex);
/*@only@*/ intnum *intnum_new_uint(unsigned long i);
/*@only@*/ intnum *intnum_new_int(long i);
/*@only@*/ intnum *intnum_copy(const intnum *intn);
/*
- * Global variables
+ * YASM assembler line manager (for parse stage)
*
- * Copyright (C) 2001 Peter Johnson
+ * Copyright (C) 2002 Peter Johnson
*
* This file is part of YASM.
*
#include "hamt.h"
-#include "globals.h"
+#include "linemgr.h"
/* Source lines tracking */
} line_index_mapping;
/* Shared storage for filenames */
-static /*@only@*/ /*@null@*/ HAMT *filename_table = NULL;
+static /*@only@*/ /*@null@*/ HAMT *filename_table;
/* Virtual line number. Uniquely specifies every line read by the parser. */
-unsigned long line_index = 1;
-static /*@only@*/ /*@null@*/ line_index_mapping_head *line_index_map = NULL;
-
-/* Global assembler options. */
-unsigned int asm_options = 0;
+static unsigned long line_index;
+static /*@only@*/ /*@null@*/ line_index_mapping_head *line_index_map;
static void
filename_delete_one(/*@only@*/ void *d)
xfree(d);
}
-void
-line_set(const char *filename, unsigned long line, unsigned long line_inc)
+static void
+yasm_linemgr_set(const char *filename, unsigned long line,
+ unsigned long line_inc)
{
char *copy;
int replace = 0;
line_index_mapping *mapping;
/* Create a new mapping in the map */
- if (!line_index_map) {
- /* initialize vector */
- line_index_map = xmalloc(sizeof(line_index_mapping_head));
- line_index_map->vector = xmalloc(8*sizeof(line_index_mapping));
- line_index_map->size = 0;
- line_index_map->allocated = 8;
- }
if (line_index_map->size >= line_index_map->allocated) {
/* allocate another size bins when full for 2x space */
line_index_map->vector = xrealloc(line_index_map->vector,
/* Copy the filename (via shared storage) */
copy = xstrdup(filename);
- if (!filename_table)
- filename_table = HAMT_new();
/*@-aliasunique@*/
mapping->filename = HAMT_insert(filename_table, copy, copy, &replace,
filename_delete_one);
mapping->line_inc = line_inc;
}
-void
-line_shutdown(void)
+static void
+yasm_linemgr_initialize(void)
+{
+ filename_table = HAMT_new();
+
+ line_index = 1;
+
+ /* initialize mapping vector */
+ line_index_map = xmalloc(sizeof(line_index_mapping_head));
+ line_index_map->vector = xmalloc(8*sizeof(line_index_mapping));
+ line_index_map->size = 0;
+ line_index_map->allocated = 8;
+}
+
+static void
+yasm_linemgr_cleanup(void)
{
if (line_index_map) {
xfree(line_index_map->vector);
}
}
-void
-line_lookup(unsigned long lindex, const char **filename, unsigned long *line)
+static unsigned long
+yasm_linemgr_get_current(void)
+{
+ return line_index;
+}
+
+static unsigned long
+yasm_linemgr_goto_next(void)
+{
+ return ++line_index;
+}
+
+static void
+yasm_linemgr_lookup(unsigned long lindex, const char **filename,
+ unsigned long *line)
{
line_index_mapping *mapping;
unsigned long vindex, step;
*filename = mapping->filename;
*line = mapping->line+mapping->line_inc*(lindex-mapping->index);
}
+
+linemgr yasm_linemgr = {
+ yasm_linemgr_initialize,
+ yasm_linemgr_cleanup,
+ yasm_linemgr_get_current,
+ yasm_linemgr_goto_next,
+ yasm_linemgr_set,
+ yasm_linemgr_lookup
+};
/* $IdPath$
- * Globals header file
+ * Line manager (for parse stage) header file
*
- * Copyright (C) 2001 Peter Johnson
+ * Copyright (C) 2002 Peter Johnson
*
* This file is part of YASM.
*
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef YASM_GLOBALS_H
-#define YASM_GLOBALS_H
+#ifndef YASM_LINEMGR_H
+#define YASM_LINEMGR_H
-/* Virtual line number. Uniquely specifies every line read by the parser. */
-extern unsigned long line_index;
+struct linemgr {
+ /* Initialize cur_lindex and any manager internal data structures. */
+ void (*initialize) (void);
-/* Global assembler options. */
-extern unsigned int asm_options;
+ /* Cleans up any memory allocated by initialize. */
+ void (*cleanup) (void);
-void line_set(const char *filename, unsigned long line,
- unsigned long line_inc);
-void line_shutdown(void);
-void line_lookup(unsigned long lindex, /*@out@*/ const char **filename,
- /*@out@*/ unsigned long *line);
+ /* Returns the current line index. */
+ unsigned long (*get_current) (void);
+
+ /* Goes to the next line (increments the current line index), returns
+ * the current (new) line index.
+ */
+ unsigned long (*goto_next) (void);
+
+ /* Sets a new file/line association starting point at the current line
+ * index. line_inc indicates how much the "real" line is incremented by
+ * for each line index increment (0 is perfectly legal).
+ */
+ void (*set) (const char *filename, unsigned long line,
+ unsigned long line_inc);
+
+ /* Look up the associated actual file and line for a line index. */
+ void (*lookup) (unsigned long lindex, /*@out@*/ const char **filename,
+ /*@out@*/ unsigned long *line);
+};
#endif
#include "bitvect.h"
#include "file.h"
-#include "globals.h"
#include "options.h"
+#include "linemgr.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
#include "arch.h"
+/* YASM's line manager (for parse stage). */
+extern linemgr yasm_linemgr;
+
/* Extra path to search for our modules. */
#ifndef YASM_MODULE_PATH_ENV
# define YASM_MODULE_PATH_ENV "YASM_MODULE_PATH"
in_filename = xstrdup("-");
}
- /* Initialize line info */
- line_set(in_filename, 1, 1);
+ /* Initialize line manager */
+ yasm_linemgr.initialize();
+ yasm_linemgr.set(in_filename, 1, 1);
/* handle preproc-only case here */
if (preproc_only) {
/* Pre-process until done */
cur_preproc->initialize(in, in_filename);
- while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0)
+ while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE,
+ &yasm_linemgr)) != 0)
fwrite(preproc_buf, got, 1, obj);
if (in != stdin)
fclose(obj);
if (GetNumErrors() > 0) {
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
if (obj != stdout)
remove(obj_filename);
xfree(preproc_buf);
}
/* Parse! */
- sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt, in,
- in_filename);
+ sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt,
+ &yasm_linemgr, in, in_filename);
/* Close input file */
if (in != stdin)
fclose(in);
if (GetNumErrors() > 0) {
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
cleanup(sections);
return EXIT_FAILURE;
}
cur_optimizer->optimize(sections);
if (GetNumErrors() > 0) {
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
cleanup(sections);
return EXIT_FAILURE;
}
* object file (to make sure it's not left newer than the source).
*/
if (GetNumErrors() > 0) {
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
remove(obj_filename);
cleanup(sections);
return EXIT_FAILURE;
}
- OutputAllErrorWarning();
+ OutputAllErrorWarning(&yasm_linemgr);
cleanup(sections);
return EXIT_SUCCESS;
if (sections)
sections_delete(sections);
symrec_delete_all();
- line_shutdown();
+ yasm_linemgr.cleanup();
floatnum_shutdown();
intnum_shutdown();
#include "ltdl.h"
#include "module.h"
-#include "globals.h"
typedef struct module {
*/
/*@observer@*/ /*@null@*/ section *
(*sections_switch)(sectionhead *headp, valparamhead *valparams,
- /*@null@*/ valparamhead *objext_valparams);
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex);
/* Object format-specific data handling functions for sections.
* May be NULL if no data is ever allocated in sections_switch().
* May be NULL if objfmt doesn't care about such declarations.
*/
void (*extern_declare)(symrec *sym,
- /*@null@*/ valparamhead *objext_valparams);
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex);
void (*global_declare)(symrec *sym,
- /*@null@*/ valparamhead *objext_valparams);
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex);
void (*common_declare)(symrec *sym, /*@only@*/ expr *size,
- /*@null@*/ valparamhead *objext_valparams);
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex);
/* May be NULL if symrec_set_of_data() is never called. */
void (*symrec_data_delete)(/*@only@*/ void *data);
*/
int (*directive)(const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams,
- sectionhead *headp);
+ sectionhead *headp, unsigned long lindex);
/* Bytecode objfmt data (BC_OBJFMT_DATA) handling functions.
* May be NULL if no BC_OBJFMT_DATA is ever allocated by the object format.
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
if (e->terms[i].type == EXPR_SYM &&
symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
(dist = common_calc_bc_dist(sect, NULL, precbc))) {
+ const expr *start = section_get_start(sect);
e->terms[i].type = EXPR_EXPR;
e->terms[i].data.expn =
- expr_new(EXPR_ADD,
- ExprExpr(expr_copy(section_get_start(sect))),
- ExprInt(dist));
+ expr_new(EXPR_ADD, ExprExpr(expr_copy(start)), ExprInt(dist),
+ start->line);
}
}
/* Check for complex float expressions */
if (expr_contains(*ep, EXPR_FLOAT)) {
- ErrorAt((*ep)->line, _("floating point expression too complex"));
+ Error((*ep)->line, _("floating point expression too complex"));
return 1;
}
/* Couldn't output, assume it contains an external reference. */
- ErrorAt((*ep)->line,
- _("binary object format does not support external references"));
+ Error((*ep)->line,
+ _("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;
- WarningAt(bc->line,
- _("uninitialized space declared in code/data section: zeroing"));
+ Warning(bc->line,
+ _("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
left = multiple*size;
if (data) {
start = bin_objfmt_align_section(data, prevsect, start, 4,
prevsectlenptr, prevsectpadptr);
- section_set_start(data, start);
+ section_set_start(data, start, 0);
datastart = start;
prevsect = data;
prevsectlenptr = &datalen;
if (bss) {
start = bin_objfmt_align_section(bss, prevsect, start, 4,
prevsectlenptr, prevsectpadptr);
- section_set_start(bss, start);
+ section_set_start(bss, start, 0);
}
/* Output .text first. */
static /*@observer@*/ /*@null@*/ section *
bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams,
+ unsigned long lindex)
{
valparam *vp;
section *retval;
resonly = 1;
} else {
/* other section names not recognized. */
- Error(_("segment name `%s' not recognized"), sectname);
+ Error(lindex, _("segment name `%s' not recognized"), sectname);
return NULL;
}
unsigned long bitcnt;
if (strcmp(sectname, ".text") == 0) {
- Error(_("cannot specify an alignment to the `%s' section"),
+ Error(lindex,
+ _("cannot specify an alignment to the `%s' section"),
sectname);
return NULL;
}
align = expr_get_intnum(&vp->param, NULL);
if (!align) {
- Error(_("argument to `%s' is not a power of two"),
+ Error(lindex, _("argument to `%s' is not a power of two"),
vp->val);
return NULL;
}
*/
BitCount(bitcnt, alignval);
if (bitcnt > 1) {
- Error(_("argument to `%s' is not a power of two"),
+ Error(lindex, _("argument to `%s' is not a power of two"),
vp->val);
return NULL;
}
}
retval = sections_switch_general(headp, sectname, start, resonly,
- &isnew);
+ &isnew, lindex);
if (isnew) {
if (have_alignval) {
section_set_of_data(retval, &yasm_bin_LTX_objfmt, data);
}
- symrec_define_label(sectname, retval, (bytecode *)NULL, 1);
+ symrec_define_label(sectname, retval, (bytecode *)NULL, 1, lindex);
} else if (have_alignval)
- Warning(_("alignment value ignored on section redeclaration"));
+ Warning(lindex,
+ _("alignment value ignored on section redeclaration"));
return retval;
} else
static void
bin_objfmt_common_declare(/*@unused@*/ symrec *sym, /*@only@*/ expr *size,
/*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams, unsigned long lindex)
{
expr_delete(size);
- Error(_("binary object format does not support common variables"));
+ Error(lindex, _("binary object format does not support common variables"));
}
static int
bin_objfmt_directive(const char *name, valparamhead *valparams,
/*@unused@*/ /*@null@*/ valparamhead *objext_valparams,
- sectionhead *headp)
+ sectionhead *headp, unsigned long lindex)
{
section *sect;
valparam *vp;
/* ORG takes just a simple integer as param */
vp = vps_first(valparams);
if (vp->val) {
- Error(_("argument to ORG should be numeric"));
+ Error(lindex, _("argument to ORG should be numeric"));
return 0;
} else if (vp->param)
start = expr_get_intnum(&vp->param, NULL);
if (!start) {
- Error(_("argument to ORG should be numeric"));
+ Error(lindex, _("argument to ORG should be numeric"));
return 0;
}
sect = sections_find_general(headp, ".text");
if (!sect)
InternalError(_("bin objfmt: .text section does not exist before ORG is called?"));
- section_set_start(sect, intnum_get_uint(start));
+ section_set_start(sect, intnum_get_uint(start), lindex);
return 0; /* directive recognized */
} else
#include "file.h"
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
data->index = 0;
data->sclass = COFF_SCL_FILE;
data->size = NULL;
- filesym = symrec_define_label(".file", NULL, NULL, 0);
+ filesym = symrec_define_label(".file", NULL, NULL, 0, 0);
symrec_set_of_data(filesym, &yasm_coff_LTX_objfmt, data);
entry = xmalloc(sizeof(coff_symtab_entry));
SymVisibility vis;
if (valsize != 4) {
- ErrorAt((*ep)->line, _("coff: invalid relocation size"));
+ Error((*ep)->line, _("coff: invalid relocation size"));
return 1;
}
csymd = symrec_get_of_data(sym);
assert(csymd != NULL);
*ep = expr_new(EXPR_ADD, ExprExpr(*ep),
- ExprExpr(expr_copy(csymd->size)));
+ ExprExpr(expr_copy(csymd->size)),
+ csymd->size->line);
*ep = expr_simplify(*ep, common_calc_bc_dist);
} else if (!(vis & SYM_EXTERN)) {
/* Local symbols need relocation to their section's start */
reloc->sym = label_csd->sym;
if (COFF_SET_VMA)
*ep = expr_new(EXPR_ADD, ExprExpr(*ep),
- ExprInt(intnum_new_uint(label_csd->addr)));
+ ExprInt(intnum_new_uint(label_csd->addr)),
+ (*ep)->line);
}
}
/* Need to reference to start of section, so add $$ in. */
*ep = expr_new(EXPR_ADD, ExprExpr(*ep),
ExprSym(symrec_define_label("$$", info->sect, NULL,
- 0)));
+ 0, (*ep)->line)),
+ (*ep)->line);
*ep = expr_simplify(*ep, common_calc_bc_dist);
} else
reloc->type = COFF_RELOC_ADDR32;
/* Check for complex float expressions */
if (expr_contains(*ep, EXPR_FLOAT)) {
- ErrorAt((*ep)->line, _("floating point expression too complex"));
+ Error((*ep)->line, _("floating point expression too complex"));
return 1;
}
- ErrorAt((*ep)->line, _("coff: relocation too complex"));
+ Error((*ep)->line, _("coff: relocation too complex"));
return 1;
}
/* Warn that gaps are converted to 0 and write out the 0's. */
if (gap) {
unsigned long left;
- WarningAt(bc->line,
- _("uninitialized space declared in code/data section: zeroing"));
+ Warning(bc->line,
+ _("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
left = multiple*size;
const intnum *intn;
intn = expr_get_intnum(&csymd->size, common_calc_bc_dist);
if (!intn)
- ErrorAt(csymd->size->line,
- _("COMMON data size not an integer expression"));
+ Error(csymd->size->line,
+ _("COMMON data size not an integer expression"));
else
value = intnum_get_uint(intn);
scnum = 0;
static /*@observer@*/ /*@null@*/ section *
coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams,
+ unsigned long lindex)
{
valparam *vp = vps_first(valparams);
section *retval;
sectname = vp->val;
if (strlen(sectname) > 8) {
- Warning(_("COFF section names limited to 8 characters: truncating"));
+ Warning(lindex,
+ _("COFF section names limited to 8 characters: truncating"));
sectname[8] = '\0';
}
}
}
- retval = sections_switch_general(headp, sectname, 0, resonly, &isnew);
+ retval = sections_switch_general(headp, sectname, 0, resonly, &isnew,
+ lindex);
if (isnew) {
coff_section_data *data;
STAILQ_INIT(&data->relocs);
section_set_of_data(retval, &yasm_coff_LTX_objfmt, data);
- sym = symrec_define_label(sectname, retval, (bytecode *)NULL, 1);
+ sym = symrec_define_label(sectname, retval, (bytecode *)NULL, 1,
+ lindex);
coff_objfmt_symtab_append(sym, COFF_SCL_STAT, NULL, 1,
COFF_SYMTAB_AUX_SECT);
data->sym = sym;
} else if (flags_override)
- Warning(_("section flags ignored on section redeclaration"));
+ Warning(lindex, _("section flags ignored on section redeclaration"));
return retval;
}
static void
coff_objfmt_extglob_declare(symrec *sym, /*@unused@*/
- /*@null@*/ valparamhead *objext_valparams)
+ /*@null@*/ valparamhead *objext_valparams,
+ /*@unused@*/ unsigned long lindex)
{
coff_objfmt_symtab_append(sym, COFF_SCL_EXT, NULL, 0,
COFF_SYMTAB_AUX_NONE);
static void
coff_objfmt_common_declare(symrec *sym, /*@only@*/ expr *size, /*@unused@*/
- /*@null@*/ valparamhead *objext_valparams)
+ /*@null@*/ valparamhead *objext_valparams,
+ /*@unused@*/ unsigned long lindex)
{
coff_objfmt_symtab_append(sym, COFF_SCL_EXT, size, 0,
COFF_SYMTAB_AUX_NONE);
coff_objfmt_directive(/*@unused@*/ const char *name,
/*@unused@*/ valparamhead *valparams,
/*@unused@*/ /*@null@*/ valparamhead *objext_valparams,
- /*@unused@*/ sectionhead *headp)
+ /*@unused@*/ sectionhead *headp,
+ /*@unused@*/ unsigned long lindex)
{
return 1; /* no objfmt directives */
}
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
-#include "globals.h"
#include "errwarn.h"
#include "expr.h"
#include "symrec.h"
static /*@observer@*/ /*@null@*/ section *
dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams,
+ unsigned long lindex)
{
valparam *vp;
section *retval;
vps_print(dbg_objfmt_file, valparams);
fprintf(dbg_objfmt_file, ", ");
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), returning ");
+ fprintf(dbg_objfmt_file, ", %lu), returning ", lindex);
if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
- retval = sections_switch_general(headp, vp->val, 200, 0, &isnew);
+ retval = sections_switch_general(headp, vp->val, 200, 0, &isnew,
+ lindex);
if (isnew) {
fprintf(dbg_objfmt_file, "(new) ");
- symrec_define_label(vp->val, retval, (bytecode *)NULL, 1);
+ symrec_define_label(vp->val, retval, (bytecode *)NULL, 1, lindex);
}
fprintf(dbg_objfmt_file, "\"%s\" section\n", vp->val);
return retval;
static void
dbg_objfmt_extern_declare(symrec *sym, /*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams, unsigned long lindex)
{
fprintf(dbg_objfmt_file, "extern_declare(\"%s\", ", symrec_get_name(sym));
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), setting of_data=NULL\n");
+ fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
}
static void
dbg_objfmt_global_declare(symrec *sym, /*@unused@*/ /*@null@*/
- valparamhead *objext_valparams)
+ valparamhead *objext_valparams, unsigned long lindex)
{
fprintf(dbg_objfmt_file, "global_declare(\"%s\", ", symrec_get_name(sym));
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), setting of_data=NULL\n");
+ fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
}
static void
dbg_objfmt_common_declare(symrec *sym, /*@only@*/ expr *size, /*@unused@*/
- /*@null@*/ valparamhead *objext_valparams)
+ /*@null@*/ valparamhead *objext_valparams,
+ unsigned long lindex)
{
assert(dbg_objfmt_file != NULL);
fprintf(dbg_objfmt_file, "common_declare(\"%s\", ", symrec_get_name(sym));
expr_print(dbg_objfmt_file, size);
fprintf(dbg_objfmt_file, ", ");
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), setting of_data=");
+ fprintf(dbg_objfmt_file, ", %lu), setting of_data=", lindex);
expr_print(dbg_objfmt_file, size);
symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, size);
fprintf(dbg_objfmt_file, "\n");
static int
dbg_objfmt_directive(const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams,
- /*@unused@*/ sectionhead *headp)
+ /*@unused@*/ sectionhead *headp, unsigned long lindex)
{
fprintf(dbg_objfmt_file, "directive(\"%s\", ", name);
vps_print(dbg_objfmt_file, valparams);
fprintf(dbg_objfmt_file, ", ");
vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, "), returning 0 (recognized)\n");
+ fprintf(dbg_objfmt_file, ", %lu), returning 0 (recognized)\n", lindex);
return 0; /* dbg format "recognizes" all directives */
}
bcr_retval = bc_resolve(bc, 0, data->sect, basic_optimize_calc_bc_dist_1);
if (bcr_retval & BC_RESOLVE_UNKNOWN_LEN) {
if (!(bcr_retval & BC_RESOLVE_ERROR))
- ErrorAt(bc->line, _("circular reference detected."));
+ Error(bc->line, _("circular reference detected."));
data->saw_unknown = -1;
return 0;
}
* This function returns the starting section of a linked list of sections
* (whatever was in the file).
*/
- sectionhead *(*do_parse) (preproc *pp, arch *a, objfmt *of, FILE *f,
- const char *in_filename);
+ sectionhead *(*do_parse) (preproc *pp, arch *a, objfmt *of, linemgr *lm,
+ FILE *f, const char *in_filename);
};
/* Generic functions for all parsers - implemented in src/parser.c */
#include "bitvect.h"
-#include "globals.h"
+#include "linemgr.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
extern size_t nasm_parser_locallabel_base_len;
extern /*@dependent@*/ arch *nasm_parser_arch;
extern /*@dependent@*/ objfmt *nasm_parser_objfmt;
+extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
+
+#define p_line_index (nasm_parser_linemgr->get_current())
+
+#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,p_line_index)
+#define p_expr_new_branch(o,r) expr_new_branch(o,r,p_line_index)
+#define p_expr_new_ident(r) expr_new_ident(r,p_line_index)
static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
static bytecode *nasm_parser_temp_bc;
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
- line_index++;
+ nasm_parser_linemgr->goto_next();
}
;
/* %line indicates the line number of the *next* line, so subtract out
* the increment when setting the line number.
*/
- line_set($5, intnum_get_uint($2)-intnum_get_uint($4),
- intnum_get_uint($4));
+ nasm_parser_linemgr->set($5, intnum_get_uint($2)-intnum_get_uint($4),
+ intnum_get_uint($4));
intnum_delete($2);
intnum_delete($4);
xfree($5);
$$ = (bytecode *)NULL;
}
| error '\n' {
- Error(_("label or instruction expected at start of line"));
+ Error(p_line_index,
+ _("label or instruction expected at start of line"));
$$ = (bytecode *)NULL;
yyerrok;
}
| label exp { $$ = $2; }
| label TIMES expr exp { $$ = $4; bc_set_multiple($$, $3); }
| label_id_equ EQU expr {
- symrec_define_equ($1, $3);
+ symrec_define_equ($1, $3, p_line_index);
xfree($1);
$$ = (bytecode *)NULL;
}
;
exp: instr
- | DECLARE_DATA datavals { $$ = bc_new_data(&$2, $1); }
- | RESERVE_SPACE expr { $$ = bc_new_reserve($2, $1); }
- | INCBIN STRING { $$ = bc_new_incbin($2, NULL, NULL); }
- | INCBIN STRING ',' expr { $$ = bc_new_incbin($2, $4, NULL); }
- | INCBIN STRING ',' expr ',' expr { $$ = bc_new_incbin($2, $4, $6); }
+ | DECLARE_DATA datavals {
+ $$ = bc_new_data(&$2, $1, p_line_index);
+ }
+ | RESERVE_SPACE expr {
+ $$ = bc_new_reserve($2, $1, p_line_index);
+ }
+ | INCBIN STRING {
+ $$ = bc_new_incbin($2, NULL, NULL, p_line_index);
+ }
+ | INCBIN STRING ',' expr {
+ $$ = bc_new_incbin($2, $4, NULL, p_line_index);
+ }
+ | INCBIN STRING ',' expr ',' expr {
+ $$ = bc_new_incbin($2, $4, $6, p_line_index);
+ }
;
instr: INSN {
$$ = nasm_parser_arch->parse.new_insn($1, 0, NULL,
nasm_parser_cur_section,
- nasm_parser_prev_bc);
+ nasm_parser_prev_bc,
+ p_line_index);
}
| INSN operands {
$$ = nasm_parser_arch->parse.new_insn($1, $2.num_operands,
&$2.operands,
nasm_parser_cur_section,
- nasm_parser_prev_bc);
+ nasm_parser_prev_bc,
+ p_line_index);
ops_delete(&$2.operands, 0);
}
| INSN error {
- Error(_("expression syntax error"));
+ Error(p_line_index, _("expression syntax error"));
$$ = NULL;
}
| PREFIX instr {
$$ = $2;
- nasm_parser_arch->parse.handle_prefix($$, $1);
+ nasm_parser_arch->parse.handle_prefix($$, $1, p_line_index);
}
| SEGREG instr {
$$ = $2;
- nasm_parser_arch->parse.handle_seg_prefix($$, $1[0]);
+ nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], p_line_index);
}
;
dataval: dvexpr { $$ = dv_new_expr($1); }
| STRING { $$ = dv_new_string($1); }
| error {
- Error(_("expression syntax error"));
+ Error(p_line_index, _("expression syntax error"));
$$ = (dataval *)NULL;
}
;
label: label_id {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
- 1);
+ 1, p_line_index);
xfree($1);
}
| label_id ':' {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
- 1);
+ 1, p_line_index);
xfree($1);
}
;
xfree($1);
}
| DIRECTIVE_NAME error {
- Error(_("invalid arguments to [%s]"), $1);
+ Error(p_line_index, _("invalid arguments to [%s]"), $1);
xfree($1);
}
;
}
| SEGREG ':' memaddr {
$$ = $3;
- nasm_parser_arch->parse.handle_seg_override($$, $1[0]);
+ nasm_parser_arch->parse.handle_seg_override($$, $1[0], p_line_index);
}
| BYTE memaddr { $$ = $2; ea_set_len($$, 1); }
| WORD memaddr { $$ = $2; ea_set_len($$, 2); }
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 1)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 1;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 2)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 2;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 4)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 4;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 8)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 8;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 10)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 10;
}
$$ = $2;
if ($$->type == INSN_OPERAND_REG &&
nasm_parser_arch->get_reg_size($$->data.reg) != 16)
- Error(_("cannot override register size"));
+ Error(p_line_index, _("cannot override register size"));
else
$$->size = 16;
}
/* expression trees */
/* expr w/o FLTNUM and unary + and -, for use in directives */
-direxpr: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
+direxpr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); }
| ID {
- $$ = expr_new_ident(ExprSym(symrec_define_label($1, NULL, NULL, 0)));
+ $$ = p_expr_new_ident(ExprSym(symrec_define_label($1, NULL, NULL, 0,
+ p_line_index)));
xfree($1);
}
- | direxpr '|' direxpr { $$ = expr_new_tree($1, EXPR_OR, $3); }
- | direxpr '^' direxpr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
- | direxpr '&' direxpr { $$ = expr_new_tree($1, EXPR_AND, $3); }
- | direxpr LEFT_OP direxpr { $$ = expr_new_tree($1, EXPR_SHL, $3); }
- | direxpr RIGHT_OP direxpr { $$ = expr_new_tree($1, EXPR_SHR, $3); }
- | direxpr '+' direxpr { $$ = expr_new_tree($1, EXPR_ADD, $3); }
- | direxpr '-' direxpr { $$ = expr_new_tree($1, EXPR_SUB, $3); }
- | direxpr '*' direxpr { $$ = expr_new_tree($1, EXPR_MUL, $3); }
- | direxpr '/' direxpr { $$ = expr_new_tree($1, EXPR_DIV, $3); }
- | direxpr SIGNDIV direxpr { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
- | direxpr '%' direxpr { $$ = expr_new_tree($1, EXPR_MOD, $3); }
- | direxpr SIGNMOD direxpr { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
- /*| '!' expr { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
- | '~' direxpr %prec UNARYOP { $$ = expr_new_branch(EXPR_NOT, $2); }
+ | direxpr '|' direxpr { $$ = p_expr_new_tree($1, EXPR_OR, $3); }
+ | direxpr '^' direxpr { $$ = p_expr_new_tree($1, EXPR_XOR, $3); }
+ | direxpr '&' direxpr { $$ = p_expr_new_tree($1, EXPR_AND, $3); }
+ | direxpr LEFT_OP direxpr { $$ = p_expr_new_tree($1, EXPR_SHL, $3); }
+ | direxpr RIGHT_OP direxpr { $$ = p_expr_new_tree($1, EXPR_SHR, $3); }
+ | direxpr '+' direxpr { $$ = p_expr_new_tree($1, EXPR_ADD, $3); }
+ | direxpr '-' direxpr { $$ = p_expr_new_tree($1, EXPR_SUB, $3); }
+ | direxpr '*' direxpr { $$ = p_expr_new_tree($1, EXPR_MUL, $3); }
+ | direxpr '/' direxpr { $$ = p_expr_new_tree($1, EXPR_DIV, $3); }
+ | direxpr SIGNDIV direxpr { $$ = p_expr_new_tree($1, EXPR_SIGNDIV, $3); }
+ | direxpr '%' direxpr { $$ = p_expr_new_tree($1, EXPR_MOD, $3); }
+ | direxpr SIGNMOD direxpr { $$ = p_expr_new_tree($1, EXPR_SIGNMOD, $3); }
+ /*| '!' expr { $$ = p_expr_new_branch(EXPR_LNOT, $2); }*/
+ | '~' direxpr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NOT, $2); }
| '(' direxpr ')' { $$ = $2; }
;
-dvexpr: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
- | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); }
- | explabel { $$ = expr_new_ident(ExprSym($1)); }
- /*| dvexpr '||' dvexpr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
- | dvexpr '|' dvexpr { $$ = expr_new_tree($1, EXPR_OR, $3); }
- | dvexpr '^' dvexpr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
- /*| dvexpr '&&' dvexpr { $$ = expr_new_tree($1, EXPR_LAND, $3); }*/
- | dvexpr '&' dvexpr { $$ = expr_new_tree($1, EXPR_AND, $3); }
- /*| dvexpr '==' dvexpr { $$ = expr_new_tree($1, EXPR_EQUALS, $3); }*/
- /*| dvexpr '>' dvexpr { $$ = expr_new_tree($1, EXPR_GT, $3); }*/
- /*| dvexpr '<' dvexpr { $$ = expr_new_tree($1, EXPR_GT, $3); }*/
- /*| dvexpr '>=' dvexpr { $$ = expr_new_tree($1, EXPR_GE, $3); }*/
- /*| dvexpr '<=' dvexpr { $$ = expr_new_tree($1, EXPR_GE, $3); }*/
- /*| dvexpr '!=' dvexpr { $$ = expr_new_tree($1, EXPR_NE, $3); }*/
- | dvexpr LEFT_OP dvexpr { $$ = expr_new_tree($1, EXPR_SHL, $3); }
- | dvexpr RIGHT_OP dvexpr { $$ = expr_new_tree($1, EXPR_SHR, $3); }
- | dvexpr '+' dvexpr { $$ = expr_new_tree($1, EXPR_ADD, $3); }
- | dvexpr '-' dvexpr { $$ = expr_new_tree($1, EXPR_SUB, $3); }
- | dvexpr '*' dvexpr { $$ = expr_new_tree($1, EXPR_MUL, $3); }
- | dvexpr '/' dvexpr { $$ = expr_new_tree($1, EXPR_DIV, $3); }
- | dvexpr SIGNDIV dvexpr { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
- | dvexpr '%' dvexpr { $$ = expr_new_tree($1, EXPR_MOD, $3); }
- | dvexpr SIGNMOD dvexpr { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
+dvexpr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); }
+ | FLTNUM { $$ = p_expr_new_ident(ExprFloat($1)); }
+ | explabel { $$ = p_expr_new_ident(ExprSym($1)); }
+ /*| dvexpr '||' dvexpr { $$ = p_expr_new_tree($1, EXPR_LOR, $3); }*/
+ | dvexpr '|' dvexpr { $$ = p_expr_new_tree($1, EXPR_OR, $3); }
+ | dvexpr '^' dvexpr { $$ = p_expr_new_tree($1, EXPR_XOR, $3); }
+ /*| dvexpr '&&' dvexpr { $$ = p_expr_new_tree($1, EXPR_LAND, $3); }*/
+ | dvexpr '&' dvexpr { $$ = p_expr_new_tree($1, EXPR_AND, $3); }
+ /*| dvexpr '==' dvexpr { $$ = p_expr_new_tree($1, EXPR_EQUALS, $3); }*/
+ /*| dvexpr '>' dvexpr { $$ = p_expr_new_tree($1, EXPR_GT, $3); }*/
+ /*| dvexpr '<' dvexpr { $$ = p_expr_new_tree($1, EXPR_GT, $3); }*/
+ /*| dvexpr '>=' dvexpr { $$ = p_expr_new_tree($1, EXPR_GE, $3); }*/
+ /*| dvexpr '<=' dvexpr { $$ = p_expr_new_tree($1, EXPR_GE, $3); }*/
+ /*| dvexpr '!=' dvexpr { $$ = p_expr_new_tree($1, EXPR_NE, $3); }*/
+ | dvexpr LEFT_OP dvexpr { $$ = p_expr_new_tree($1, EXPR_SHL, $3); }
+ | dvexpr RIGHT_OP dvexpr { $$ = p_expr_new_tree($1, EXPR_SHR, $3); }
+ | dvexpr '+' dvexpr { $$ = p_expr_new_tree($1, EXPR_ADD, $3); }
+ | dvexpr '-' dvexpr { $$ = p_expr_new_tree($1, EXPR_SUB, $3); }
+ | dvexpr '*' dvexpr { $$ = p_expr_new_tree($1, EXPR_MUL, $3); }
+ | dvexpr '/' dvexpr { $$ = p_expr_new_tree($1, EXPR_DIV, $3); }
+ | dvexpr SIGNDIV dvexpr { $$ = p_expr_new_tree($1, EXPR_SIGNDIV, $3); }
+ | dvexpr '%' dvexpr { $$ = p_expr_new_tree($1, EXPR_MOD, $3); }
+ | dvexpr SIGNMOD dvexpr { $$ = p_expr_new_tree($1, EXPR_SIGNMOD, $3); }
| '+' dvexpr %prec UNARYOP { $$ = $2; }
- | '-' dvexpr %prec UNARYOP { $$ = expr_new_branch(EXPR_NEG, $2); }
- /*| '!' dvexpr { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
- | '~' dvexpr %prec UNARYOP { $$ = expr_new_branch(EXPR_NOT, $2); }
- | SEG dvexpr { $$ = expr_new_branch(EXPR_SEG, $2); }
- | WRT dvexpr { $$ = expr_new_branch(EXPR_WRT, $2); }
+ | '-' dvexpr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NEG, $2); }
+ /*| '!' dvexpr { $$ = p_expr_new_branch(EXPR_LNOT, $2); }*/
+ | '~' dvexpr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NOT, $2); }
+ | SEG dvexpr { $$ = p_expr_new_branch(EXPR_SEG, $2); }
+ | WRT dvexpr { $$ = p_expr_new_branch(EXPR_WRT, $2); }
| '(' dvexpr ')' { $$ = $2; }
;
* We don't attempt to check memory expressions for validity here.
* Essentially the same as expr_no_string above but adds REG and STRING.
*/
-expr: INTNUM { $$ = expr_new_ident(ExprInt($1)); }
- | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); }
- | REG { $$ = expr_new_ident(ExprReg($1[0])); }
+expr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); }
+ | FLTNUM { $$ = p_expr_new_ident(ExprFloat($1)); }
+ | REG { $$ = p_expr_new_ident(ExprReg($1[0])); }
| STRING {
- $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ $$ = p_expr_new_ident(ExprInt(intnum_new_charconst_nasm($1,
+ p_line_index)));
xfree($1);
}
- | explabel { $$ = expr_new_ident(ExprSym($1)); }
- /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
- | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); }
- | expr '^' expr { $$ = expr_new_tree($1, EXPR_XOR, $3); }
- /*| expr '&&' expr { $$ = expr_new_tree($1, EXPR_LAND, $3); }*/
- | expr '&' expr { $$ = expr_new_tree($1, EXPR_AND, $3); }
- /*| expr '==' expr { $$ = expr_new_tree($1, EXPR_EQUALS, $3); }*/
- /*| expr '>' expr { $$ = expr_new_tree($1, EXPR_GT, $3); }*/
- /*| expr '<' expr { $$ = expr_new_tree($1, EXPR_GT, $3); }*/
- /*| expr '>=' expr { $$ = expr_new_tree($1, EXPR_GE, $3); }*/
- /*| expr '<=' expr { $$ = expr_new_tree($1, EXPR_GE, $3); }*/
- /*| expr '!=' expr { $$ = expr_new_tree($1, EXPR_NE, $3); }*/
- | expr LEFT_OP expr { $$ = expr_new_tree($1, EXPR_SHL, $3); }
- | expr RIGHT_OP expr { $$ = expr_new_tree($1, EXPR_SHR, $3); }
- | expr '+' expr { $$ = expr_new_tree($1, EXPR_ADD, $3); }
- | expr '-' expr { $$ = expr_new_tree($1, EXPR_SUB, $3); }
- | expr '*' expr { $$ = expr_new_tree($1, EXPR_MUL, $3); }
- | expr '/' expr { $$ = expr_new_tree($1, EXPR_DIV, $3); }
- | expr SIGNDIV expr { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
- | expr '%' expr { $$ = expr_new_tree($1, EXPR_MOD, $3); }
- | expr SIGNMOD expr { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
+ | explabel { $$ = p_expr_new_ident(ExprSym($1)); }
+ /*| expr '||' expr { $$ = p_expr_new_tree($1, EXPR_LOR, $3); }*/
+ | expr '|' expr { $$ = p_expr_new_tree($1, EXPR_OR, $3); }
+ | expr '^' expr { $$ = p_expr_new_tree($1, EXPR_XOR, $3); }
+ /*| expr '&&' expr { $$ = p_expr_new_tree($1, EXPR_LAND, $3); }*/
+ | expr '&' expr { $$ = p_expr_new_tree($1, EXPR_AND, $3); }
+ /*| expr '==' expr { $$ = p_expr_new_tree($1, EXPR_EQUALS, $3); }*/
+ /*| expr '>' expr { $$ = p_expr_new_tree($1, EXPR_GT, $3); }*/
+ /*| expr '<' expr { $$ = p_expr_new_tree($1, EXPR_GT, $3); }*/
+ /*| expr '>=' expr { $$ = p_expr_new_tree($1, EXPR_GE, $3); }*/
+ /*| expr '<=' expr { $$ = p_expr_new_tree($1, EXPR_GE, $3); }*/
+ /*| expr '!=' expr { $$ = p_expr_new_tree($1, EXPR_NE, $3); }*/
+ | expr LEFT_OP expr { $$ = p_expr_new_tree($1, EXPR_SHL, $3); }
+ | expr RIGHT_OP expr { $$ = p_expr_new_tree($1, EXPR_SHR, $3); }
+ | expr '+' expr { $$ = p_expr_new_tree($1, EXPR_ADD, $3); }
+ | expr '-' expr { $$ = p_expr_new_tree($1, EXPR_SUB, $3); }
+ | expr '*' expr { $$ = p_expr_new_tree($1, EXPR_MUL, $3); }
+ | expr '/' expr { $$ = p_expr_new_tree($1, EXPR_DIV, $3); }
+ | expr SIGNDIV expr { $$ = p_expr_new_tree($1, EXPR_SIGNDIV, $3); }
+ | expr '%' expr { $$ = p_expr_new_tree($1, EXPR_MOD, $3); }
+ | expr SIGNMOD expr { $$ = p_expr_new_tree($1, EXPR_SIGNMOD, $3); }
| '+' expr %prec UNARYOP { $$ = $2; }
- | '-' expr %prec UNARYOP { $$ = expr_new_branch(EXPR_NEG, $2); }
- /*| '!' expr { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
- | '~' expr %prec UNARYOP { $$ = expr_new_branch(EXPR_NOT, $2); }
- | SEG expr { $$ = expr_new_branch(EXPR_SEG, $2); }
- | WRT expr { $$ = expr_new_branch(EXPR_WRT, $2); }
- | expr ':' expr { $$ = expr_new_tree($1, EXPR_SEGOFF, $3); }
+ | '-' expr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NEG, $2); }
+ /*| '!' expr { $$ = p_expr_new_branch(EXPR_LNOT, $2); }*/
+ | '~' expr %prec UNARYOP { $$ = p_expr_new_branch(EXPR_NOT, $2); }
+ | SEG expr { $$ = p_expr_new_branch(EXPR_SEG, $2); }
+ | WRT expr { $$ = p_expr_new_branch(EXPR_WRT, $2); }
+ | expr ':' expr { $$ = p_expr_new_tree($1, EXPR_SEGOFF, $3); }
| '(' expr ')' { $$ = $2; }
;
explabel: ID {
- $$ = symrec_use($1);
+ $$ = symrec_use($1, p_line_index);
xfree($1);
}
| SPECIAL_ID {
- $$ = symrec_use($1);
+ $$ = symrec_use($1, p_line_index);
xfree($1);
}
| LOCAL_ID {
- $$ = symrec_use($1);
+ $$ = symrec_use($1, p_line_index);
xfree($1);
}
| '$' {
/* "$" references the current assembly position */
$$ = symrec_define_label("$", nasm_parser_cur_section,
- nasm_parser_prev_bc, 0);
+ nasm_parser_prev_bc, 0, p_line_index);
}
| START_SECTION_ID {
/* "$$" references the start of the current section */
- $$ = symrec_define_label("$$", nasm_parser_cur_section, NULL, 0);
+ $$ = symrec_define_label("$$", nasm_parser_cur_section, NULL, 0,
+ p_line_index);
}
;
{
valparam *vp, *vp2;
symrec *sym;
+ unsigned long lindex = p_line_index;
/* Handle (mostly) output-format independent directives here */
if (strcasecmp(name, "extern") == 0) {
vp = vps_first(valparams);
if (vp->val) {
- sym = symrec_declare(vp->val, SYM_EXTERN);
+ sym = symrec_declare(vp->val, SYM_EXTERN, lindex);
if (nasm_parser_objfmt->extern_declare)
- nasm_parser_objfmt->extern_declare(sym, objext_valparams);
+ nasm_parser_objfmt->extern_declare(sym, objext_valparams,
+ lindex);
} else
- Error(_("invalid argument to [%s]"), "EXTERN");
+ Error(lindex, _("invalid argument to [%s]"), "EXTERN");
} else if (strcasecmp(name, "global") == 0) {
vp = vps_first(valparams);
if (vp->val) {
- sym = symrec_declare(vp->val, SYM_GLOBAL);
+ sym = symrec_declare(vp->val, SYM_GLOBAL, lindex);
if (nasm_parser_objfmt->global_declare)
- nasm_parser_objfmt->global_declare(sym, objext_valparams);
+ nasm_parser_objfmt->global_declare(sym, objext_valparams,
+ lindex);
} else
- Error(_("invalid argument to [%s]"), "GLOBAL");
+ Error(lindex, _("invalid argument to [%s]"), "GLOBAL");
} else if (strcasecmp(name, "common") == 0) {
vp = vps_first(valparams);
if (vp->val) {
vp2 = vps_next(vp);
if (!vp2 || (!vp2->val && !vp2->param))
- Error(_("no size specified in %s declaration"), "COMMON");
+ Error(lindex, _("no size specified in %s declaration"),
+ "COMMON");
else {
if (vp2->val) {
- sym = symrec_declare(vp->val, SYM_COMMON);
+ sym = symrec_declare(vp->val, SYM_COMMON, lindex);
if (nasm_parser_objfmt->common_declare)
nasm_parser_objfmt->common_declare(sym,
- expr_new_ident(ExprSym(symrec_use(vp2->val))),
- objext_valparams);
+ p_expr_new_ident(ExprSym(symrec_use(vp2->val,
+ lindex))),
+ objext_valparams, lindex);
} else if (vp2->param) {
- sym = symrec_declare(vp->val, SYM_COMMON);
+ sym = symrec_declare(vp->val, SYM_COMMON, lindex);
if (nasm_parser_objfmt->common_declare)
nasm_parser_objfmt->common_declare(sym, vp2->param,
- objext_valparams);
+ objext_valparams,
+ lindex);
vp2->param = NULL;
}
}
} else
- Error(_("invalid argument to [%s]"), "COMMON");
+ Error(lindex, _("invalid argument to [%s]"), "COMMON");
} else if (strcasecmp(name, "section") == 0 ||
strcasecmp(name, "segment") == 0) {
section *new_section =
nasm_parser_objfmt->sections_switch(&nasm_parser_sections,
- valparams, objext_valparams);
+ valparams, objext_valparams,
+ lindex);
if (new_section) {
nasm_parser_cur_section = new_section;
nasm_parser_prev_bc = bcs_last(section_get_bytecodes(new_section));
} else
- Error(_("invalid argument to [%s]"), "SECTION");
+ Error(lindex, _("invalid argument to [%s]"), "SECTION");
} else if (strcasecmp(name, "absolute") == 0) {
/* it can be just an ID or a complete expression, so handle both. */
vp = vps_first(valparams);
if (vp->val)
nasm_parser_cur_section =
sections_switch_absolute(&nasm_parser_sections,
- expr_new_ident(ExprSym(symrec_use(vp->val))));
+ p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex))));
else if (vp->param) {
nasm_parser_cur_section =
sections_switch_absolute(&nasm_parser_sections, vp->param);
} else if (strcasecmp(name, "cpu") == 0) {
vps_foreach(vp, valparams) {
if (vp->val)
- nasm_parser_arch->parse.switch_cpu(vp->val);
+ nasm_parser_arch->parse.switch_cpu(vp->val, lindex);
else if (vp->param) {
const intnum *intcpu;
intcpu = expr_get_intnum(&vp->param, NULL);
if (!intcpu)
- Error(_("invalid argument to [%s]"), "CPU");
+ Error(lindex, _("invalid argument to [%s]"), "CPU");
else {
char strcpu[16];
sprintf(strcpu, "%lu", intnum_get_uint(intcpu));
- nasm_parser_arch->parse.switch_cpu(strcpu);
+ nasm_parser_arch->parse.switch_cpu(strcpu, lindex);
}
}
}
} else if (!nasm_parser_arch->parse.directive(name, valparams,
objext_valparams,
- &nasm_parser_sections)) {
+ &nasm_parser_sections,
+ lindex)) {
;
} else if (nasm_parser_objfmt->directive(name, valparams, objext_valparams,
- &nasm_parser_sections)) {
- Error(_("unrecognized directive [%s]"), name);
+ &nasm_parser_sections, lindex)) {
+ Error(lindex, _("unrecognized directive [%s]"), name);
}
vps_delete(valparams);
void
nasm_parser_error(const char *s)
{
- ParserError(s);
+ ParserError(p_line_index, s);
}
extern int nasm_parser_parse(void);
extern void nasm_parser_cleanup(void);
-size_t (*nasm_parser_input) (char *buf, size_t max_size);
+size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm);
sectionhead nasm_parser_sections;
/*@dependent@*/ section *nasm_parser_cur_section;
/*@dependent@*/ arch *nasm_parser_arch;
/*@dependent@*/ objfmt *nasm_parser_objfmt;
+/*@dependent@*/ linemgr *nasm_parser_linemgr;
static /*@dependent@*/ sectionhead *
-nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, FILE *f,
+nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm, FILE *f,
const char *in_filename)
/*@globals killed nasm_parser_locallabel_base @*/
{
nasm_parser_input = pp->input;
nasm_parser_arch = a;
nasm_parser_objfmt = of;
+ nasm_parser_linemgr = lm;
/* Initialize section list */
nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of);
#include "bitvect.h"
+#include "linemgr.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
void nasm_parser_set_directive_state(void);
int nasm_parser_lex(void);
-extern size_t (*nasm_parser_input) (char *buf, size_t max_size);
+extern size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm);
extern /*@dependent@*/ arch *nasm_parser_arch;
+extern /*@dependent@*/ linemgr *nasm_parser_linemgr;
+
+#define p_line_index (nasm_parser_linemgr->get_current())
typedef struct Scanner {
xfree(s.bot);
s.bot = buf;
}
- if((cnt = nasm_parser_input(s.lim, BSIZE)) != BSIZE){
+ if((cnt = nasm_parser_input(s.lim, BSIZE,
+ nasm_parser_linemgr)) != BSIZE){
s.eof = &s.lim[cnt]; *s.eof++ = '\n';
}
s.lim += cnt;
digit+ {
savech = s.tok[TOKLEN];
s.tok[TOKLEN] = '\0';
- yylval.intn = intnum_new_dec(s.tok);
+ yylval.intn = intnum_new_dec(s.tok, p_line_index);
s.tok[TOKLEN] = savech;
RETURN(INTNUM);
}
bindigit+ "b" {
s.tok[TOKLEN-1] = '\0'; /* strip off 'b' */
- yylval.intn = intnum_new_bin(s.tok);
+ yylval.intn = intnum_new_bin(s.tok, p_line_index);
RETURN(INTNUM);
}
/* 777q - octal number */
octdigit+ "q" {
s.tok[TOKLEN-1] = '\0'; /* strip off 'q' */
- yylval.intn = intnum_new_oct(s.tok);
+ yylval.intn = intnum_new_oct(s.tok, p_line_index);
RETURN(INTNUM);
}
/* 0AAh form of hexidecimal number */
digit hexdigit* "h" {
s.tok[TOKLEN-1] = '\0'; /* strip off 'h' */
- yylval.intn = intnum_new_hex(s.tok);
+ yylval.intn = intnum_new_hex(s.tok, p_line_index);
RETURN(INTNUM);
}
savech = s.tok[TOKLEN];
s.tok[TOKLEN] = '\0';
if (s.tok[1] == 'x')
- yylval.intn = intnum_new_hex(s.tok+2); /* skip 0 and x */
+ /* skip 0 and x */
+ yylval.intn = intnum_new_hex(s.tok+2, p_line_index);
else
- yylval.intn = intnum_new_hex(s.tok+1); /* don't skip 0 */
+ /* don't skip 0 */
+ yylval.intn = intnum_new_hex(s.tok+1, p_line_index);
s.tok[TOKLEN] = savech;
RETURN(INTNUM);
}
yylval.str_val = xstrndup(s.tok, TOKLEN);
RETURN(ID);
} else if (!nasm_parser_locallabel_base) {
- Warning(_("no non-local label before `%s'"), s.tok[0]);
+ Warning(p_line_index, _("no non-local label before `%s'"),
+ s.tok[0]);
yylval.str_val = xstrndup(s.tok, TOKLEN);
} else {
len = TOKLEN + nasm_parser_locallabel_base_len;
savech = s.tok[TOKLEN];
s.tok[TOKLEN] = '\0';
check_id_ret = nasm_parser_arch->parse.check_identifier(
- yylval.arch_data, s.tok);
+ yylval.arch_data, s.tok, p_line_index);
s.tok[TOKLEN] = savech;
switch (check_id_ret) {
case ARCH_CHECK_ID_NONE:
case ARCH_CHECK_ID_TARGETMOD:
RETURN(TARGETMOD);
default:
- Warning(_("Arch feature not supported, treating as identifier"));
+ Warning(p_line_index,
+ _("Arch feature not supported, treating as identifier"));
yylval.str_val = xstrndup(s.tok, TOKLEN);
RETURN(ID);
}
any {
if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
- Warning(_("ignoring unrecognized character `%s'"),
+ Warning(p_line_index,
+ _("ignoring unrecognized character `%s'"),
conv_unprint(s.tok[0]));
goto scan;
}
linechg_numcount++;
savech = s.tok[TOKLEN];
s.tok[TOKLEN] = '\0';
- yylval.intn = intnum_new_dec(s.tok);
+ yylval.intn = intnum_new_dec(s.tok, p_line_index);
s.tok[TOKLEN] = savech;
RETURN(INTNUM);
}
any {
if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
- Warning(_("ignoring unrecognized character `%s'"),
+ Warning(p_line_index,
+ _("ignoring unrecognized character `%s'"),
conv_unprint(s.tok[0]));
goto linechg;
}
any {
if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR))
- Warning(_("ignoring unrecognized character `%s'"),
+ Warning(p_line_index,
+ _("ignoring unrecognized character `%s'"),
conv_unprint(s.tok[0]));
goto directive;
}
/*!re2c
"\n" {
if (cursor == s.eof)
- Error(_("unexpected end of file in string"));
+ Error(p_line_index, _("unexpected end of file in string"));
else
- Error(_("unterminated string"));
+ Error(p_line_index, _("unterminated string"));
strbuf[count] = '\0';
yylval.str_val = strbuf;
RETURN(STRING);
/* Gets more preprocessed source code (up to max_size bytes) into buf.
* Note that more than a single line may be returned in buf. */
- size_t (*input) (/*@out@*/ char *buf, size_t max_size);
+ size_t (*input) (/*@out@*/ char *buf, size_t max_size, linemgr *lm);
};
#endif
}
static size_t
-raw_preproc_input(char *buf, size_t max_size)
+raw_preproc_input(char *buf, size_t max_size, unsigned long lindex)
{
int c = '*';
size_t n;
if (c == '\n')
buf[n++] = (char)c;
if (c == EOF && ferror(in))
- Error(_("error when reading from file"));
+ Error(lindex, _("error when reading from file"));
} else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in))
- Error(_("error when reading from file"));
+ Error(lindex, _("error when reading from file"));
return n;
}
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "linemgr.h"
#include "errwarn.h"
#include "preproc.h"
#include "hamt.h"
static HAMT *macro_table;
-YAPP_Output current_output;
+static YAPP_Output current_output;
YYSTYPE yapp_preproc_lval;
+/*@dependent@*/ linemgr *yapp_preproc_linemgr;
+#define p_line_index (yapp_preproc_linemgr->get_current())
+
int isatty(int);
/* Build source and macro representations */
void
yapp_macro_error_exists (YAPP_Macro *v)
{
- if (v) Error(_("Redefining macro of the same name %d:%d"), v->type, v->args);
+ if (v) Error(p_line_index, _("Redefining macro of the same name %d:%d"), v->type, v->args);
}
void
yapp_macro_error_sameargname (YAPP_Macro *v)
{
- if (v) Error(_("Duplicate argument names in macro"));
+ if (v) Error(p_line_index, _("Duplicate argument names in macro"));
}
YAPP_Macro *
if ((argc >= 0 && ym->args < 0)
|| (argc < 0 && ym->args >= 0))
{
- Warning(_("Attempted %%define both with and without parameters"));
+ Warning(p_line_index, _("Attempted %%define both with and without parameters"));
return NULL;
}
}
yapp_preproc_initialize(FILE *f, const char *in_filename)
{
is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
- current_file = xstrdup(in_filename);
- line_number = 1;
+ yapp_preproc_current_file = xstrdup(in_filename);
+ yapp_preproc_line_number = 1;
yapp_lex_initialize(f);
SLIST_INIT(&output_head);
SLIST_INIT(&source_head);
&& (token == '\n' || token == LINE))
{
free ((*to_tail)->token.str);
- (*to_tail)->token.str = xmalloc(23+strlen(current_file));
- sprintf((*to_tail)->token.str, "%%line %d+1 %s\n", line_number, current_file);
+ (*to_tail)->token.str = xmalloc(23+strlen(yapp_preproc_current_file));
+ sprintf((*to_tail)->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file);
}
else {
src = xmalloc(sizeof(source));
case LINE:
/* TODO: consider removing any trailing newline or LINE tokens */
- src->token.str = xmalloc(23+strlen(current_file));
- sprintf(src->token.str, "%%line %d+1 %s\n", line_number, current_file);
+ src->token.str = xmalloc(23+strlen(yapp_preproc_current_file));
+ sprintf(src->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file);
break;
default:
while ((token = yapp_preproc_lex()) != '\n') {
if (token == 0)
return 0;
- Error(_("Skipping possibly valid %%define stuff"));
+ Error(p_line_index, _("Skipping possibly valid %%define stuff"));
}
append_token('\n', to_head, to_tail);
return '\n';
if (token == WHITESPACE)
token = yapp_preproc_lex();
if (token != IDENT) {
- Error(_("Identifier expected after %%%s"), synlvl);
+ Error(p_line_index, _("Identifier expected after %%%s"), synlvl);
}
return token;
}
if (token < 256)
InternalError(_("Unexpected character token in parameter expansion"));
else
- Error(_("Cannot handle preprocessor items inside possible macro invocation"));
+ Error(p_line_index, _("Cannot handle preprocessor items inside possible macro invocation"));
}
}
}
static size_t
-yapp_preproc_input(char *buf, size_t max_size)
+yapp_preproc_input(char *buf, size_t max_size, linemgr *lm)
{
static YAPP_State state = YAPP_STATE_INITIAL;
int n = 0;
int token;
int need_line_directive = 0;
+ yapp_preproc_linemgr = lm;
+
while (saved_length < max_size && state != YAPP_STATE_EOF)
{
token = yapp_preproc_lex();
append_token(token, &source_head, &source_tail);
/*if (append_to_return()==0) state=YAPP_STATE_EOF;*/
ydebug(("YAPP: default: '%c' \"%s\"\n", token, yapp_preproc_lval.str_val));
- /*Error(_("YAPP got an unhandled token."));*/
+ /*Error(p_line_index, _("YAPP got an unhandled token."));*/
break;
case IDENT:
break;
}
else if (last_token == ',' || token != ',')
- Error(_("Unexpected token in %%define parameters"));
+ Error(p_line_index, _("Unexpected token in %%define parameters"));
last_token = token;
}
if (token == ')') {
}
break;
default:
- Error(_("YAPP got into a bad state"));
+ Error(p_line_index, _("YAPP got into a bad state"));
}
if (need_line_directive) {
append_token(LINE, &source_head, &source_tail);
extern YYSTYPE yapp_preproc_lval;
-extern char *current_file;
-extern int line_number;
+extern char *yapp_preproc_current_file;
+extern int yapp_preproc_line_number;
+extern /*@dependent@*/ linemgr *yapp_preproc_linemgr;
+#define p_line_index (yapp_preproc_linemgr->get_current())
int yapp_preproc_lex(void);
#include <errno.h>
+#include "linemgr.h"
#include "errwarn.h"
#include "src/preprocs/yapp/yapp-preproc.h"
};
typedef struct include_s include;
-char *current_file;
-int line_number;
+char *yapp_preproc_current_file;
+int yapp_preproc_line_number;
%}
%option noyywrap
}
if(inch == '\n')
- Error(_("unterminated string"));
+ Error(p_line_index, _("unterminated string"));
else if(inch == EOF)
- Error(_("unexpected end of file in string"));
+ Error(p_line_index, _("unexpected end of file in string"));
strbuf[count] = '\0';
/* FIXME: handle includes that aren't relative */
incfile = fopen (yytext, "r");
if(!incfile) {
- Error(_("include file `%s': %s"),
+ Error(p_line_index, _("include file `%s': %s"),
yytext, strerror(errno));
free(inc);
}
else {
yyin = incfile;
- inc->filename = current_file;
- inc->line_number = line_number;
+ inc->filename = yapp_preproc_current_file;
+ inc->line_number = yapp_preproc_line_number;
SLIST_INSERT_HEAD(&includes_head, inc, next);
- line_number = 1;
- current_file = xstrdup(yytext);
+ yapp_preproc_line_number = 1;
+ yapp_preproc_current_file = xstrdup(yytext);
BEGIN(INITIAL);
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
}
inc = SLIST_FIRST(&includes_head);
yy_delete_buffer (YY_CURRENT_BUFFER);
yy_switch_to_buffer (inc->include_state);
- free(current_file);
- current_file = inc->filename;
- line_number = inc->line_number + 1;
+ free(yapp_preproc_current_file);
+ yapp_preproc_current_file = inc->filename;
+ yapp_preproc_line_number = inc->line_number + 1;
SLIST_REMOVE_HEAD(&includes_head, next);
free(inc);
<inhibit>{DIR}line[^\n] ;
{DIR}line BEGIN(line);
-<line>{DIGIT}+ line_number = strtoul(yytext, (char **)NULL, 10);
+<line>{DIGIT}+ yapp_preproc_line_number = strtoul(yytext, (char **)NULL, 10);
<line>{DIGIT}+{WS}*\n {
- line_number = strtoul(yytext, (char **)NULL, 10);
+ yapp_preproc_line_number = strtoul(yytext, (char **)NULL, 10);
BEGIN(INITIAL);
return LINE;
}
<line>{WS}+["] ; /* eat space before file */
<line>[^ \t\n"]* { /* have the filename */
- free(current_file);
- current_file = xstrdup(yytext);
+ free(yapp_preproc_current_file);
+ yapp_preproc_current_file = xstrdup(yytext);
}
<line>["]{WS}*\n {
BEGIN(INITIAL);
<inhibit>{DIR}pop[^\n]* ;
<inhibit>{DIR}repl[^\n]* ;
-<inhibit>[^%\n]*\n { line_number++; return '\n'; }
+<inhibit>[^%\n]*\n { yapp_preproc_line_number++; return '\n'; }
-;.*\n { line_number++; return '\n'; }
+;.*\n { yapp_preproc_line_number++; return '\n'; }
{WS}+ { yylval.str_val = yytext; return WHITESPACE; }
-{WS}*\n { line_number++; return '\n'; }
+{WS}*\n { yapp_preproc_line_number++; return '\n'; }
[][+*/,()-] { return yytext[0]; }
<inhibit>. {
- Warning(_("Unhandled character in <inhibit> `%s'"), conv_unprint(yytext[0]));
+ Warning(p_line_index, _("Unhandled character in <inhibit> `%s'"), conv_unprint(yytext[0]));
}
. {
- Warning(_("ignoring unrecognized character `%s'"),
+ Warning(p_line_index, _("ignoring unrecognized character `%s'"),
conv_unprint(yytext[0]));
}
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
-#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
vp_new(vp, xstrdup(of->default_section_name), NULL);
vps_initialize(&vps);
vps_append(&vps, vp);
- s = of->sections_switch(headp, &vps, NULL);
+ s = of->sections_switch(headp, &vps, NULL, 0);
vps_delete(&vps);
return s;
/*@-onlytrans@*/
section *
sections_switch_general(sectionhead *headp, const char *name,
- unsigned long start, int res_only, int *isnew)
+ unsigned long start, int res_only, int *isnew,
+ unsigned long lindex)
{
section *s;
s->data.general.name = xstrdup(name);
s->data.general.of = NULL;
s->data.general.of_data = NULL;
- s->start = expr_new_ident(ExprInt(intnum_new_uint(start)));
+ s->start = expr_new_ident(ExprInt(intnum_new_uint(start)), lindex);
bcs_initialize(&s->bc);
s->opt_flags = 0;
}
void
-section_set_start(section *sect, unsigned long start)
+section_set_start(section *sect, unsigned long start, unsigned long lindex)
{
expr_delete(sect->start);
- sect->start = expr_new_ident(ExprInt(intnum_new_uint(start)));
+ sect->start = expr_new_ident(ExprInt(intnum_new_uint(start)), lindex);
}
const expr *
const char *name,
unsigned long start,
int res_only,
- /*@out@*/ int *isnew);
+ /*@out@*/ int *isnew,
+ unsigned long lindex);
/*@dependent@*/ section *sections_switch_absolute(sectionhead *headp,
/*@keep@*/ expr *start);
/*@observer@*/ /*@null@*/ const char *section_get_name(const section *sect);
-void section_set_start(section *sect, unsigned long start);
+void section_set_start(section *sect, unsigned long start,
+ unsigned long lindex);
/*@observer@*/ const expr *section_get_start(const section *sect);
void section_delete(/*@only@*/ section *sect);
#include "hamt.h"
-#include "globals.h"
#include "errwarn.h"
#include "floatnum.h"
#include "expr.h"
}
symrec *
-symrec_use(const char *name)
+symrec_use(const char *name, unsigned long lindex)
{
symrec *rec = symrec_get_or_new(name, 1);
if (rec->line == 0)
- rec->line = line_index; /* set line number of first use */
+ rec->line = lindex; /* set line number of first use */
rec->status |= SYM_USED;
return rec;
}
static /*@dependent@*/ symrec *
-symrec_define(const char *name, SymType type, int in_table)
+symrec_define(const char *name, SymType type, int in_table,
+ unsigned long lindex)
{
symrec *rec = symrec_get_or_new(name, in_table);
/* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
if ((rec->status & SYM_DEFINED) ||
(rec->visibility & (SYM_COMMON | SYM_EXTERN))) {
- Error(_("duplicate definition of `%s'; first defined on line %lu"),
+ Error(lindex,
+ _("duplicate definition of `%s'; first defined on line %lu"),
name, rec->line);
} else {
- rec->line = line_index; /* set line number of definition */
+ rec->line = lindex; /* set line number of definition */
rec->type = type;
rec->status |= SYM_DEFINED;
}
}
symrec *
-symrec_define_equ(const char *name, expr *e)
+symrec_define_equ(const char *name, expr *e, unsigned long lindex)
{
- symrec *rec = symrec_define(name, SYM_EQU, 1);
+ symrec *rec = symrec_define(name, SYM_EQU, 1, lindex);
rec->value.expn = e;
rec->status |= SYM_VALUED;
return rec;
symrec *
symrec_define_label(const char *name, section *sect, bytecode *precbc,
- int in_table)
+ int in_table, unsigned long lindex)
{
- symrec *rec = symrec_define(name, SYM_LABEL, in_table);
+ symrec *rec = symrec_define(name, SYM_LABEL, in_table, lindex);
rec->value.label.sect = sect;
rec->value.label.bc = precbc;
return rec;
}
symrec *
-symrec_declare(const char *name, SymVisibility vis)
+symrec_declare(const char *name, SymVisibility vis, unsigned long lindex)
{
symrec *rec = symrec_get_or_new(name, 1);
((rec->visibility & SYM_EXTERN) && (vis == SYM_EXTERN)))))
rec->visibility |= vis;
else
- Error(_("duplicate definition of `%s'; first defined on line %lu"),
+ Error(lindex,
+ _("duplicate definition of `%s'; first defined on line %lu"),
name, rec->line);
return rec;
}
/* error if a symbol is used but never defined or extern/common declared */
if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) &&
!(sym->visibility & (SYM_EXTERN | SYM_COMMON))) {
- ErrorAt(sym->line, _("undefined symbol `%s' (first use)"), sym->name);
+ Error(sym->line, _("undefined symbol `%s' (first use)"), sym->name);
if (sym->line < firstundef_line)
firstundef_line = sym->line;
}
firstundef_line = ULONG_MAX;
symrec_traverse(NULL, symrec_parser_finalize_checksym);
if (firstundef_line < ULONG_MAX)
- ErrorAt(firstundef_line,
- _(" (Each undefined symbol is reported only once.)"));
+ Error(firstundef_line,
+ _(" (Each undefined symbol is reported only once.)"));
}
void
void
symrec_print(FILE *f, int indent_level, const symrec *sym)
{
- const char *filename;
- unsigned long line;
-
switch (sym->type) {
case SYM_UNKNOWN:
fprintf(f, "%*s-Unknown (Common/Extern)-\n", indent_level, "");
fprintf(f, "%*sUNKNOWN\n", indent_level+1, "");
}
- line_lookup(sym->line, &filename, &line);
- fprintf(f, "%*sFilename=\"%s\" Line Number=%lu\n", indent_level, "",
- filename, line);
+ fprintf(f, "%*sLine Index=%lu\n", indent_level, "", sym->line);
}
#ifndef YASM_SYMREC_H
#define YASM_SYMREC_H
-/*@dependent@*/ symrec *symrec_use(const char *name);
-/*@dependent@*/ symrec *symrec_define_equ(const char *name,
- /*@keep@*/ expr *e);
+/*@dependent@*/ symrec *symrec_use(const char *name, unsigned long lindex);
+/*@dependent@*/ symrec *symrec_define_equ(const char *name, /*@keep@*/ expr *e,
+ unsigned long lindex);
/* in_table specifies if the label should be inserted into the symbol table.
* All labels are memory managed internally.
*/
/*@dependent@*/ /*@null@*/
section *sect,
/*@dependent@*/ /*@null@*/
- bytecode *precbc, int in_table);
-/*@dependent@*/ symrec *symrec_declare(const char *name, SymVisibility vis);
+ bytecode *precbc, int in_table,
+ unsigned long lindex);
+/*@dependent@*/ symrec *symrec_declare(const char *name, SymVisibility vis,
+ unsigned long lindex);
/*@observer@*/ const char *symrec_get_name(const symrec *sym);
SymVisibility symrec_get_visibility(const symrec *sym);
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
-#include "globals.h"
#include "expr.h"