Re: Bug#396291: Bug#356055: loadlin: loadlin.exe cannot be built from source
- To: Thomas Viehmann <tv@beamnet.de>, Robert Millan <rmh@aybabtu.com>, 356055@bugs.debian.org, Pierre Habouzit <madcoder@debian.org>, 396291@bugs.debian.org, 497676@bugs.debian.org, debian-release@lists.debian.org
- Subject: Re: Bug#396291: Bug#356055: loadlin: loadlin.exe cannot be built from source
- From: Samuel Thibault <samuel.thibault@ens-lyon.org>
- Date: Tue, 7 Oct 2008 11:06:23 +0200
- Message-id: <20081007090623.GB7472@const.bordeaux.inria.fr>
- Mail-followup-to: Samuel Thibault <samuel.thibault@ens-lyon.org>, Thomas Viehmann <tv@beamnet.de>, Robert Millan <rmh@aybabtu.com>, 356055@bugs.debian.org, Pierre Habouzit <madcoder@debian.org>, 396291@bugs.debian.org, 497676@bugs.debian.org, debian-release@lists.debian.org
- In-reply-to: <20080930212106.GB4623@implementation.famille.thibault.fr>
- References: <20080505150408.GA15385@thorin> <20080505151151.GM4497@implementation.uk.xensource.com> <20080728193034.GA9267@thorin> <20080729004314.GA11519@implementation> <20080829164623.GA2159@thorin> <20080829170039.GK5946@implementation.uk.xensource.com> <20080829171428.GA2823@thorin> <20080829172313.GO5946@implementation.uk.xensource.com> <48E28210.9000006@beamnet.de> <20080930212106.GB4623@implementation.famille.thibault.fr>
Hello,
Peter commited upstream my yasm patch to support tasm syntax for
loadlin, here is a backport to the debian package (just a few minor
changes). The patch is quite big, but as noted in the changelog, it
just adds extensions that are enabled only when tasm compatible mode is
requested.
Samuel
Index: libyasm/bytecode.c
===================================================================
--- libyasm/bytecode.c (révision 2128)
+++ libyasm/bytecode.c (copie de travail)
@@ -223,6 +223,18 @@
}
int
+yasm_bc_elem_size(yasm_bytecode *bc)
+{
+ if (!bc->callback) {
+ yasm_internal_error(N_("got empty bytecode in yasm_bc_elem_size"));
+ return 0;
+ } else if (!bc->callback->elem_size)
+ return 0;
+ else
+ return bc->callback->elem_size(bc);
+}
+
+int
yasm_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
void *add_span_data)
{
Index: libyasm/symrec.c
===================================================================
--- libyasm/symrec.c (révision 2128)
+++ libyasm/symrec.c (copie de travail)
@@ -28,6 +28,7 @@
/*@unused@*/ RCSID("$Id$");
#include <limits.h>
+#include <ctype.h>
#include "libyasm-stdint.h"
#include "coretype.h"
@@ -71,6 +72,8 @@
/* bytecode immediately preceding a label */
/*@dependent@*/ yasm_bytecode *precbc;
} value;
+ unsigned int size; /* 0 if not user-defined */
+ const char *segment; /* for segmented systems like DOS */
/* associated data; NULL if none */
/*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data;
@@ -87,6 +90,8 @@
/*@only@*/ HAMT *sym_table;
/* Symbols not in the table */
SLIST_HEAD(nontablesymhead_s, non_table_symrec_s) non_table_syms;
+
+ int case_sensitive;
};
static void
@@ -132,9 +137,16 @@
yasm_symtab *symtab = yasm_xmalloc(sizeof(yasm_symtab));
symtab->sym_table = HAMT_create(0, yasm_internal_error_);
SLIST_INIT(&symtab->non_table_syms);
+ symtab->case_sensitive = 1;
return symtab;
}
+void
+yasm_symtab_set_case_sensitive(yasm_symtab *symtab, int sensitive)
+{
+ symtab->case_sensitive = sensitive;
+}
+
static void
symrec_destroy_one(/*@only@*/ void *d)
{
@@ -147,15 +159,24 @@
}
static /*@partial@*/ yasm_symrec *
-symrec_new_common(/*@keep@*/ char *name)
+symrec_new_common(/*@keep@*/ char *name, int case_sensitive)
{
yasm_symrec *rec = yasm_xmalloc(sizeof(yasm_symrec));
+
+ if (!case_sensitive) {
+ char *c;
+ for (c=name; *c; c++)
+ *c = tolower(*c);
+ }
+
rec->name = name;
rec->type = SYM_UNKNOWN;
rec->def_line = 0;
rec->decl_line = 0;
rec->use_line = 0;
rec->visibility = YASM_SYM_LOCAL;
+ rec->size = 0;
+ rec->segment = NULL;
rec->assoc_data = NULL;
return rec;
}
@@ -163,11 +184,17 @@
static /*@partial@*/ /*@dependent@*/ yasm_symrec *
symtab_get_or_new_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
{
- yasm_symrec *rec = symrec_new_common(name);
+ yasm_symrec *rec = symrec_new_common(name, symtab->case_sensitive);
int replace = 0;
rec->status = YASM_SYM_NOSTATUS;
+ if (!symtab->case_sensitive) {
+ char *c;
+ for (c=name; *c; c++)
+ *c = tolower(*c);
+ }
+
return HAMT_insert(symtab->sym_table, name, rec, &replace,
symrec_destroy_one);
}
@@ -176,7 +203,7 @@
symtab_get_or_new_not_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
{
non_table_symrec *sym = yasm_xmalloc(sizeof(non_table_symrec));
- sym->rec = symrec_new_common(name);
+ sym->rec = symrec_new_common(name, symtab->case_sensitive);
sym->rec->status = YASM_SYM_NOTINTABLE;
@@ -251,7 +278,17 @@
yasm_symrec *
yasm_symtab_get(yasm_symtab *symtab, const char *name)
{
- return HAMT_search(symtab->sym_table, name);
+ if (!symtab->case_sensitive) {
+ char *_name = yasm__xstrdup(name);
+ char *c;
+ yasm_symrec *ret;
+ for (c=_name; *c; c++)
+ *c = tolower(*c);
+ ret = HAMT_search(symtab->sym_table, _name);
+ yasm_xfree(_name);
+ return ret;
+ } else
+ return HAMT_search(symtab->sym_table, name);
}
static /*@dependent@*/ yasm_symrec *
@@ -273,6 +310,8 @@
rec->def_line = line; /* set line number of definition */
rec->type = type;
rec->status |= YASM_SYM_DEFINED;
+ rec->size = 0;
+ rec->segment = NULL;
}
return rec;
}
@@ -519,7 +558,31 @@
return 1;
}
+void
+yasm_symrec_set_size(yasm_symrec *sym, int size)
+{
+ sym->size = size;
+}
+
int
+yasm_symrec_get_size(const yasm_symrec *sym)
+{
+ return sym->size;
+}
+
+void
+yasm_symrec_set_segment(yasm_symrec *sym, const char *segment)
+{
+ sym->segment = segment;
+}
+
+const char *
+yasm_symrec_get_segment(const yasm_symrec *sym)
+{
+ return sym->segment;
+}
+
+int
yasm_symrec_is_abs(const yasm_symrec *sym)
{
return (sym->def_line == 0 && sym->type == SYM_EQU &&
Index: libyasm/bytecode.h
===================================================================
--- libyasm/bytecode.h (révision 2128)
+++ libyasm/bytecode.h (copie de travail)
@@ -86,6 +86,14 @@
*/
void (*finalize) (yasm_bytecode *bc, yasm_bytecode *prev_bc);
+ /** Return elements size of a data bytecode.
+ * This function should return the size of each elements of a data
+ * bytecode, for proper dereference of symbols attached to it.
+ * \param bc bytecode
+ * \return 0 if element size is unknown.
+ */
+ int (*elem_size) (yasm_bytecode *bc);
+
/** Calculates the minimum size of a bytecode.
* Called from yasm_bc_calc_len().
* A generic fill-in for this is yasm_bc_calc_len_common(), but as this
@@ -438,6 +446,14 @@
YASM_LIB_DECL
unsigned long yasm_bc_next_offset(yasm_bytecode *precbc);
+/** Return elemens size of a data bytecode.
+ * Returns the size of each elements of a data bytecode, for proper dereference
+ * of symbols attached to it.
+ * \param bc bytecode
+ * \return 0 if element size is unknown
+ */
+int yasm_bc_elem_size(yasm_bytecode *bc);
+
/** Resolve EQUs in a bytecode and calculate its minimum size.
* Generates dependent bytecode spans for cases where, if the length spanned
* increases, it could cause the bytecode size to increase.
@@ -548,11 +565,31 @@
yasm_dataval *yasm_dv_create_raw(/*@keep@*/ unsigned char *contents,
unsigned long len);
+/** Create a new uninitialized data value.
+ * \return Newly allocated data value.
+ */
+yasm_dataval *yasm_dv_create_reserve(void);
+
#ifndef YASM_DOXYGEN
#define yasm_dv_create_string(s, l) yasm_dv_create_raw((unsigned char *)(s), \
(unsigned long)(l))
#endif
+/** Set multiple field of a data value.
+ * A data value can be repeated a number of times when output. This function
+ * sets that multiple.
+ * \param dv data value
+ * \param e multiple (kept, do not free)
+ */
+void yasm_dv_set_multiple(yasm_dataval *dv, /*@keep@*/ yasm_expr *e);
+
+/** Get the data value multiple value as an unsigned long integer.
+ * \param dv data value
+ * \param multiple multiple value (output)
+ * \return 1 on error (set with yasm_error_set), 0 on success.
+ */
+int yasm_dv_get_multiple(yasm_dataval *dv, /*@out@*/ unsigned long *multiple);
+
/** Initialize a list of data values.
* \param headp list of data values
*/
Index: libyasm/symrec.h
===================================================================
--- libyasm/symrec.h (révision 2128)
+++ libyasm/symrec.h (copie de travail)
@@ -73,6 +73,13 @@
YASM_LIB_DECL
void yasm_symtab_destroy(/*@only@*/ yasm_symtab *symtab);
+/** Set the symbol table to be case sensitive or not.
+ * Should be called before adding any symbol.
+ * \param symtab symbol table
+ * \param sensitive whether the symbol table should be case sensitive.
+ */
+void yasm_symtab_set_case_sensitive(yasm_symtab *symtab, int sensitive);
+
/** Get a reference to the symbol table's "absolute" symbol. This is
* essentially an EQU with no name and value 0, and is used for relocating
* absolute current-position-relative values.
@@ -318,6 +326,30 @@
int yasm_symrec_get_label(const yasm_symrec *sym,
/*@out@*/ yasm_symrec_get_label_bytecodep *precbc);
+/** Set the size of a symbol.
+ * \param sym symbol
+ * \param size size to be set
+ */
+void yasm_symrec_set_size(yasm_symrec *sym, int size);
+
+/** Get the size of a symbol.
+ * \param sym symbol
+ * \return size of the symbol, 0 if none specified by the user.
+ */
+int yasm_symrec_get_size(const yasm_symrec *sym);
+
+/** Set the segment of a symbol.
+ * \param sym symbol
+ * \param segment segment to be set
+ */
+void yasm_symrec_set_segment(yasm_symrec *sym, const char *segment);
+
+/** Get the segment of a symbol.
+ * \param sym symbol
+ * \return segment of the symbol, NULL if none specified by the user.
+ */
+const char *yasm_symrec_get_segment(const yasm_symrec *sym);
+
/** Determine if symbol is the "absolute" symbol created by
* yasm_symtab_abs_sym().
* \param sym symbol
Index: libyasm/insn.c
===================================================================
--- libyasm/insn.c (révision 2128)
+++ libyasm/insn.c (copie de travail)
@@ -96,6 +96,7 @@
retval->size = 0;
retval->deref = 0;
retval->strict = 0;
+ retval->size = ea->data_len * 8;
return retval;
}
Index: libyasm/insn.h
===================================================================
--- libyasm/insn.h (révision 2128)
+++ libyasm/insn.h (copie de travail)
@@ -74,6 +74,9 @@
/** 1 if effective address is forced non-PC-relative. */
unsigned int not_pc_rel:1;
+
+ /** length of pointed data (in bytes), 0 if unknown. */
+ unsigned int data_len;
};
/** An instruction operand (opaque type). */
Index: libyasm/bc-align.c
===================================================================
--- libyasm/bc-align.c (révision 2128)
+++ libyasm/bc-align.c (copie de travail)
@@ -66,6 +66,7 @@
bc_align_destroy,
bc_align_print,
bc_align_finalize,
+ NULL,
bc_align_calc_len,
bc_align_expand,
bc_align_tobytes,
Index: libyasm/bc-reserve.c
===================================================================
--- libyasm/bc-reserve.c (révision 2128)
+++ libyasm/bc-reserve.c (copie de travail)
@@ -46,6 +46,7 @@
static void bc_reserve_destroy(void *contents);
static void bc_reserve_print(const void *contents, FILE *f, int indent_level);
static void bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
+static int bc_reserve_elem_size(yasm_bytecode *bc);
static int bc_reserve_calc_len(yasm_bytecode *bc,
yasm_bc_add_span_func add_span,
void *add_span_data);
@@ -57,6 +58,7 @@
bc_reserve_destroy,
bc_reserve_print,
bc_reserve_finalize,
+ bc_reserve_elem_size,
bc_reserve_calc_len,
yasm_bc_expand_common,
bc_reserve_tobytes,
@@ -96,6 +98,13 @@
}
static int
+bc_reserve_elem_size(yasm_bytecode *bc)
+{
+ bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
+ return reserve->itemsize;
+}
+
+static int
bc_reserve_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
void *add_span_data)
{
Index: libyasm/bc-org.c
===================================================================
--- libyasm/bc-org.c (révision 2128)
+++ libyasm/bc-org.c (copie de travail)
@@ -60,6 +60,7 @@
bc_org_destroy,
bc_org_print,
bc_org_finalize,
+ NULL,
bc_org_calc_len,
bc_org_expand,
bc_org_tobytes,
Index: libyasm/intnum.c
===================================================================
--- libyasm/intnum.c (révision 2128)
+++ libyasm/intnum.c (copie de travail)
@@ -244,17 +244,65 @@
case 0:
break;
default:
- /* >32 bit conversion */
+ /* >=32 bit conversion */
while (len) {
BitVector_Move_Left(conv_bv, 8);
BitVector_Chunk_Store(conv_bv, 8, 0,
- (unsigned long)str[--len]);
+ ((unsigned long)str[--len]) & 0xff);
}
intn->val.bv = BitVector_Clone(conv_bv);
}
return intn;
}
+
+yasm_intnum *
+yasm_intnum_create_charconst_tasm(const char *str)
+{
+ yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
+ size_t len = strlen(str);
+ size_t i;
+
+ if(len*8 > BITVECT_NATIVE_SIZE)
+ yasm_error_set(YASM_ERROR_OVERFLOW,
+ N_("Character constant too large for internal format"));
+
+ /* be conservative in choosing bitvect in case MSB is set */
+ if (len > 3) {
+ BitVector_Empty(conv_bv);
+ intn->type = INTNUM_BV;
+ } else {
+ intn->val.l = 0;
+ intn->type = INTNUM_L;
+ }
+
+ /* tasm uses big endian notation */
+ i = 0;
+ switch (len) {
+ case 3:
+ intn->val.l |= ((unsigned long)str[i++]) & 0xff;
+ intn->val.l <<= 8;
+ /*@fallthrough@*/
+ case 2:
+ intn->val.l |= ((unsigned long)str[i++]) & 0xff;
+ intn->val.l <<= 8;
+ /*@fallthrough@*/
+ case 1:
+ intn->val.l |= ((unsigned long)str[i++]) & 0xff;
+ case 0:
+ break;
+ default:
+ /* >=32 bit conversion */
+ while (i < len) {
+ BitVector_Chunk_Store(conv_bv, 8, (len-i-1)*8,
+ ((unsigned long)str[i]) & 0xff);
+ i++;
+ }
+ intn->val.bv = BitVector_Clone(conv_bv);
+ }
+
+ return intn;
+}
/*@=usedef =compdef =uniondef@*/
yasm_intnum *
Index: libyasm/expr.c
===================================================================
--- libyasm/expr.c (révision 2128)
+++ libyasm/expr.c (copie de travail)
@@ -1444,3 +1444,73 @@
fprintf(f, "%s", opstr);
}
}
+
+unsigned int
+yasm_expr_size(const yasm_expr *e)
+{
+ int i;
+ int seen = 0;
+ unsigned int size = 0, newsize;
+
+ if (e->op == YASM_EXPR_IDENT) {
+ if (e->terms[0].type == YASM_EXPR_SYM)
+ return yasm_symrec_get_size(e->terms[0].data.sym);
+ return 0;
+ }
+ if (e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_SUB)
+ return 0;
+
+ for (i=0; i<e->numterms; i++) {
+ newsize = 0;
+ switch (e->terms[i].type) {
+ case YASM_EXPR_EXPR:
+ newsize = yasm_expr_size(e->terms[i].data.expn);
+ break;
+ case YASM_EXPR_SYM:
+ newsize = yasm_symrec_get_size(e->terms[i].data.sym);
+ break;
+ default:
+ break;
+ }
+ if (newsize) {
+ size = newsize;
+ if (seen)
+ /* either sum of idents (?!) or substract of idents */
+ return 0;
+ seen = 1;
+ }
+ }
+ /* exactly one offset */
+ return size;
+}
+
+const char *
+yasm_expr_segment(const yasm_expr *e)
+{
+ int i;
+ int seen = 0;
+ const char *segment = NULL;
+
+ if (e->op == YASM_EXPR_IDENT) {
+ if (e->terms[0].type == YASM_EXPR_SYM)
+ return yasm_symrec_get_segment(e->terms[0].data.sym);
+ return NULL;
+ }
+ if (e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_SUB)
+ return NULL;
+
+ for (i=0; i<e->numterms; i++) {
+ if ((e->op == YASM_EXPR_ADD || !i) &&
+ e->terms[i].type == YASM_EXPR_EXPR) {
+ if ((segment = yasm_expr_segment(e->terms[i].data.expn))) {
+ if (seen) {
+ /* either sum of idents (?!) or substract of idents */
+ return NULL;
+ }
+ seen = 1;
+ }
+ }
+ }
+ /* exactly one offset */
+ return segment;
+}
Index: libyasm/intnum.h
===================================================================
--- libyasm/intnum.h (révision 2128)
+++ libyasm/intnum.h (copie de travail)
@@ -76,12 +76,20 @@
/** Convert character constant to integer value, using NASM rules. NASM syntax
* supports automatic conversion from strings such as 'abcd' to a 32-bit
- * integer value. This function performs those conversions.
+ * integer value (little endian order). This function performs those conversions.
* \param str character constant string
* \return Newly allocated intnum.
*/
/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str);
+/** Convert character constant to integer value, using TASM rules. TASM syntax
+ * supports automatic conversion from strings such as 'abcd' to a 32-bit
+ * integer value (big endian order). This function performs those conversions.
+ * \param str character constant string
+ * \return Newly allocated intnum.
+ */
+/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_tasm(const char *str);
+
/** Create a new intnum from an unsigned integer value.
* \param i unsigned integer value
* \return Newly allocated intnum.
Index: libyasm/errwarn.c
===================================================================
--- libyasm/errwarn.c (révision 2128)
+++ libyasm/errwarn.c (copie de travail)
@@ -115,7 +115,8 @@
warn_class_enabled =
(1UL<<YASM_WARN_GENERAL) | (1UL<<YASM_WARN_UNREC_CHAR) |
(1UL<<YASM_WARN_PREPROC) | (0UL<<YASM_WARN_ORPHAN_LABEL) |
- (1UL<<YASM_WARN_UNINIT_CONTENTS);
+ (1UL<<YASM_WARN_UNINIT_CONTENTS) | (0UL<<YASM_WARN_SIZE_OVERRIDE) |
+ (1UL<<YASM_WARN_IMPLICIT_SIZE_OVERRIDE);
yasm_eclass = YASM_ERROR_NONE;
yasm_estr = NULL;
Index: libyasm/expr.h
===================================================================
--- libyasm/expr.h (révision 2128)
+++ libyasm/expr.h (copie de travail)
@@ -297,6 +297,16 @@
YASM_LIB_DECL
void yasm_expr_print(/*@null@*/ const yasm_expr *e, FILE *f);
+/** Return the size of an expression, if the user provided it
+ * \param e expression
+ */
+unsigned int yasm_expr_size(const yasm_expr *e);
+
+/** Return the segment of an expression, if the user provided it
+ * \param e expression
+ */
+const char *yasm_expr_segment(const yasm_expr *e);
+
/** Traverse over expression tree in order (const version).
* Calls func for each leaf (non-operation).
* \param e expression
Index: libyasm/bc-incbin.c
===================================================================
--- libyasm/bc-incbin.c (révision 2128)
+++ libyasm/bc-incbin.c (copie de travail)
@@ -66,6 +66,7 @@
bc_incbin_destroy,
bc_incbin_print,
bc_incbin_finalize,
+ NULL,
bc_incbin_calc_len,
yasm_bc_expand_common,
bc_incbin_tobytes,
Index: libyasm/errwarn.h
===================================================================
--- libyasm/errwarn.h (révision 2128)
+++ libyasm/errwarn.h (copie de travail)
@@ -46,7 +46,8 @@
YASM_WARN_PREPROC, /**< Preprocessor warnings */
YASM_WARN_ORPHAN_LABEL, /**< Label alone on a line without a colon */
YASM_WARN_UNINIT_CONTENTS, /**< Uninitialized space in code/data section */
- YASM_WARN_SIZE_OVERRIDE /**< Double size override */
+ YASM_WARN_SIZE_OVERRIDE,/**< Double size override */
+ YASM_WARN_IMPLICIT_SIZE_OVERRIDE /**< Implicit size override */
} yasm_warn_class;
/** Error classes. Bitmask-based to support limited subclassing. */
Index: libyasm/bc-data.c
===================================================================
--- libyasm/bc-data.c (révision 2128)
+++ libyasm/bc-data.c (copie de travail)
@@ -42,7 +42,8 @@
struct yasm_dataval {
/*@reldef@*/ STAILQ_ENTRY(yasm_dataval) link;
- enum { DV_EMPTY, DV_VALUE, DV_RAW, DV_ULEB128, DV_SLEB128 } type;
+ enum { DV_EMPTY, DV_VALUE, DV_RAW, DV_ULEB128, DV_SLEB128, DV_RESERVE }
+ type;
union {
yasm_value val;
@@ -51,16 +52,22 @@
unsigned long len;
} raw;
} data;
+
+ /* number of times data is repeated, NULL=1. */
+ /*@only@*/ /*@null@*/ yasm_expr *multiple;
};
typedef struct bytecode_data {
/* converted data (linked list) */
yasm_datavalhead datahead;
+
+ int item_size;
} bytecode_data;
static void bc_data_destroy(void *contents);
static void bc_data_print(const void *contents, FILE *f, int indent_level);
static void bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
+static int bc_data_item_size(yasm_bytecode *bc);
static int bc_data_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
void *add_span_data);
static int bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
@@ -71,6 +78,7 @@
bc_data_destroy,
bc_data_print,
bc_data_finalize,
+ bc_data_item_size,
bc_data_calc_len,
yasm_bc_expand_common,
bc_data_tobytes,
@@ -131,37 +139,64 @@
default:
break;
}
+ if (dv->multiple) {
+ yasm_value val;
+ if (yasm_value_finalize_expr(&val, dv->multiple, prev_bc, 0))
+ yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+ N_("multiple expression too complex"));
+ else if (val.rel)
+ yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
+ N_("multiple expression not absolute"));
+ dv->multiple = val.abs;
+ }
}
}
static int
+bc_data_item_size(yasm_bytecode *bc)
+{
+ bytecode_data *bc_data = (bytecode_data *)bc->contents;
+ return bc_data->item_size;
+}
+
+static int
bc_data_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
void *add_span_data)
{
bytecode_data *bc_data = (bytecode_data *)bc->contents;
yasm_dataval *dv;
yasm_intnum *intn;
+ int len;
+ unsigned long multiple;
/* Count up element sizes, rounding up string length. */
STAILQ_FOREACH(dv, &bc_data->datahead, link) {
switch (dv->type) {
case DV_EMPTY:
+ len = 0;
break;
case DV_VALUE:
- bc->len += dv->data.val.size/8;
+ len = dv->data.val.size/8;
break;
case DV_RAW:
- bc->len += dv->data.raw.len;
+ len = dv->data.raw.len;
break;
case DV_ULEB128:
case DV_SLEB128:
intn = yasm_expr_get_intnum(&dv->data.val.abs, 0);
if (!intn)
yasm_internal_error(N_("non-constant in data_tobytes"));
- bc->len +=
- yasm_intnum_size_leb128(intn, dv->type == DV_SLEB128);
+ len = yasm_intnum_size_leb128(intn, dv->type == DV_SLEB128);
break;
+ case DV_RESERVE:
+ len = dv->data.val.size/8;
+ break;
}
+
+ if (!yasm_dv_get_multiple(dv, &multiple))
+ len *= multiple;
+
+ bc->len += len;
}
return 0;
@@ -177,29 +212,47 @@
unsigned char *bufp_orig = *bufp;
yasm_intnum *intn;
unsigned int val_len;
+ unsigned long multiple, i;
STAILQ_FOREACH(dv, &bc_data->datahead, link) {
+ if (yasm_dv_get_multiple(dv, &multiple) || multiple == 0)
+ continue;
switch (dv->type) {
case DV_EMPTY:
break;
case DV_VALUE:
val_len = dv->data.val.size/8;
- if (output_value(&dv->data.val, *bufp, val_len,
- (unsigned long)(*bufp-bufp_orig), bc, 1, d))
- return 1;
- *bufp += val_len;
+ for (i=0; i<multiple; i++) {
+ if (output_value(&dv->data.val, *bufp, val_len,
+ (unsigned long)(*bufp-bufp_orig), bc, 1,
+ d))
+ return 1;
+ *bufp += val_len;
+ }
break;
case DV_RAW:
- memcpy(*bufp, dv->data.raw.contents, dv->data.raw.len);
- *bufp += dv->data.raw.len;
+ for (i=0; i<multiple; i++) {
+ memcpy(*bufp, dv->data.raw.contents, dv->data.raw.len);
+ *bufp += dv->data.raw.len;
+ }
break;
case DV_ULEB128:
case DV_SLEB128:
intn = yasm_expr_get_intnum(&dv->data.val.abs, 234);
if (!intn)
yasm_internal_error(N_("non-constant in data_tobytes"));
- *bufp +=
- yasm_intnum_get_leb128(intn, *bufp, dv->type == DV_SLEB128);
+ for (i=0; i<multiple; i++) {
+ *bufp +=
+ yasm_intnum_get_leb128(intn, *bufp,
+ dv->type == DV_SLEB128);
+ }
+ case DV_RESERVE:
+ val_len = dv->data.val.size/8;
+ for (i=0; i<multiple; i++) {
+ memset(*bufp, 0, val_len);
+ *bufp += val_len;
+ }
+ break;
}
}
@@ -218,11 +271,18 @@
yasm_dvs_initialize(&data->datahead);
+ data->item_size = size;
/* Prescan input data for length, etc. Careful: this needs to be
* precisely paired with the second loop.
*/
STAILQ_FOREACH(dv, datahead, link) {
+ if (dv->multiple && dv->type != DV_EMPTY && len > 0) {
+ /* Flush previous data */
+ dvo = yasm_dv_create_raw(yasm_xmalloc(len), len);
+ STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
+ len = 0;
+ }
switch (dv->type) {
case DV_EMPTY:
break;
@@ -247,6 +307,7 @@
/* Create bytecode for this value */
dvo = yasm_xmalloc(sizeof(yasm_dataval));
STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
+ dvo->multiple = dv->multiple;
}
break;
case DV_RAW:
@@ -255,7 +316,19 @@
rlen = (rlen + size - 1) / size;
len += rlen*size;
break;
+ case DV_RESERVE:
+ len += size;
+ break;
}
+
+ if (dv->multiple && dv->type != DV_EMPTY && len > 0) {
+ /* Flush this data */
+ dvo = yasm_dv_create_raw(yasm_xmalloc(len), len);
+ STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
+ dvo->multiple = dv->multiple;
+ len = 0;
+ }
+
if (append_zero)
len++;
}
@@ -271,6 +344,10 @@
dvo = STAILQ_FIRST(&data->datahead);
len = 0;
while (dv && dvo) {
+ if (dv->multiple && dv->type != DV_EMPTY && len > 0) {
+ dvo = STAILQ_NEXT(dvo, link);
+ len = 0;
+ }
switch (dv->type) {
case DV_EMPTY:
break;
@@ -323,7 +400,17 @@
dvo->data.raw.contents[len++] = 0;
}
break;
+ case DV_RESERVE:
+ memset(&dvo->data.raw.contents[len], 0, size);
+ len += size;
+ break;
}
+
+ if (dv->multiple && dv->type != DV_EMPTY && len > 0) {
+ dvo = STAILQ_NEXT(dvo, link);
+ len = 0;
+ }
+
if (append_zero)
dvo->data.raw.contents[len++] = 0;
dv2 = STAILQ_NEXT(dv, link);
@@ -364,6 +451,7 @@
retval->type = DV_VALUE;
yasm_value_initialize(&retval->data.val, e, 0);
+ retval->multiple = NULL;
return retval;
}
@@ -376,11 +464,55 @@
retval->type = DV_RAW;
retval->data.raw.contents = contents;
retval->data.raw.len = len;
+ retval->multiple = NULL;
return retval;
}
+yasm_dataval *
+yasm_dv_create_reserve(void)
+{
+ yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
+
+ retval->type = DV_RESERVE;
+ retval->multiple = NULL;
+
+ return retval;
+}
+
void
+yasm_dv_set_multiple(yasm_dataval *dv, yasm_expr *e)
+{
+ if (dv->multiple)
+ dv->multiple = yasm_expr_create_tree( dv->multiple, YASM_EXPR_MUL, e,
+ e->line);
+ else
+ dv->multiple = e;
+}
+
+int
+yasm_dv_get_multiple(yasm_dataval *dv, unsigned long *multiple)
+{
+ /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
+
+ *multiple = 1;
+ if (dv->multiple) {
+ num = yasm_expr_get_intnum(&dv->multiple, 0);
+ if (!num) {
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("could not determine multiple"));
+ return 1;
+ }
+ if (yasm_intnum_sign(num) < 0) {
+ yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
+ return 1;
+ }
+ *multiple = yasm_intnum_get_uint(num);
+ }
+ return 0;
+}
+
+void
yasm_dvs_delete(yasm_datavalhead *headp)
{
yasm_dataval *cur, *next;
@@ -398,6 +530,8 @@
default:
break;
}
+ if (cur->multiple)
+ yasm_expr_destroy(cur->multiple);
yasm_xfree(cur);
cur = next;
}
@@ -421,6 +555,11 @@
unsigned long i;
STAILQ_FOREACH(cur, head, link) {
+ fprintf(f, "%*sMultiple=", indent_level, "");
+ if (!cur->multiple)
+ fprintf(f, "nil (1)");
+ else
+ yasm_expr_print(cur->multiple, f);
switch (cur->type) {
case DV_EMPTY:
fprintf(f, "%*sEmpty\n", indent_level, "");
@@ -445,6 +584,9 @@
fprintf(f, "%*sSLEB128 value:\n", indent_level, "");
yasm_value_print(&cur->data.val, f, indent_level+1);
break;
+ case DV_RESERVE:
+ fprintf(f, "%*sReserved\n", indent_level, "");
+ break;
}
}
}
Index: configure.ac
===================================================================
--- configure.ac (révision 2129)
+++ configure.ac (révision 2137)
@@ -125,7 +125,7 @@
#
AC_CHECK_FUNCS([abort toascii vsnprintf])
AC_CHECK_FUNCS([strsep mergesort getcwd])
-AC_CHECK_FUNCS([popen])
+AC_CHECK_FUNCS([popen ftruncate])
# Look for the case-insensitive comparison functions
AC_CHECK_FUNCS([strcasecmp strncasecmp stricmp _stricmp strcmpi])
Index: COPYING
===================================================================
--- COPYING (révision 2129)
+++ COPYING (révision 2137)
@@ -10,6 +10,7 @@
Stephen Polkowski (x86 instruction patches)
Henryk Richter (Mach-O object format)
Ben Skeggs (patches, bug reports)
+ Samuel Thibault (TASM parser and frontend)
-----------------------------------
Yasm licensing overview and summary
Index: modules/parsers/tasm/tests/lidt.hex
===================================================================
--- modules/parsers/tasm/tests/lidt.hex (révision 0)
+++ modules/parsers/tasm/tests/lidt.hex (révision 0)
@@ -0,0 +1,11 @@
+00
+00
+00
+00
+00
+00
+0f
+01
+1e
+00
+00
Index: modules/parsers/tasm/tests/macro.asm
===================================================================
--- modules/parsers/tasm/tests/macro.asm (révision 0)
+++ modules/parsers/tasm/tests/macro.asm (révision 0)
@@ -0,0 +1,6 @@
+a macro reg,i
+ mov reg,i
+ endm
+
+a ax,0
+a bx,1
Index: modules/parsers/tasm/tests/segment.asm
===================================================================
--- modules/parsers/tasm/tests/segment.asm (révision 0)
+++ modules/parsers/tasm/tests/segment.asm (révision 0)
@@ -0,0 +1,8 @@
+data segment
+ a db 0
+data ends
+
+assume es:data
+code segment
+ mov byte ptr [a],1
+code ends
Index: modules/parsers/tasm/tests/exe/exe.asm
===================================================================
--- modules/parsers/tasm/tests/exe/exe.asm (révision 0)
+++ modules/parsers/tasm/tests/exe/exe.asm (révision 0)
@@ -0,0 +1,4 @@
+a db 1
+start proc
+int 22
+start endp
Index: modules/parsers/tasm/tests/exe/exe.hex
===================================================================
--- modules/parsers/tasm/tests/exe/exe.hex (révision 0)
+++ modules/parsers/tasm/tests/exe/exe.hex (révision 0)
@@ -0,0 +1,515 @@
+4d
+5a
+03
+00
+02
+00
+00
+00
+20
+00
+00
+00
+ff
+ff
+00
+00
+00
+00
+00
+00
+01
+00
+00
+00
+22
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+01
+cd
+16
Index: modules/parsers/tasm/tests/exe/Makefile.inc
===================================================================
--- modules/parsers/tasm/tests/exe/Makefile.inc (révision 0)
+++ modules/parsers/tasm/tests/exe/Makefile.inc (révision 0)
@@ -0,0 +1,8 @@
+# $Id: Makefile.inc 2063 2008-04-12 08:30:22Z peter $
+
+TESTS += modules/parsers/tasm/tests/exe/tasm_exe_test.sh
+
+EXTRA_DIST += modules/parsers/tasm/tests/exe/tasm_exe_test.sh
+EXTRA_DIST += modules/parsers/tasm/tests/exe/exe.asm
+EXTRA_DIST += modules/parsers/tasm/tests/exe/exe.hex
+
Index: modules/parsers/tasm/tests/exe/tasm_exe_test.sh
===================================================================
--- modules/parsers/tasm/tests/exe/tasm_exe_test.sh (révision 0)
+++ modules/parsers/tasm/tests/exe/tasm_exe_test.sh (révision 0)
@@ -0,0 +1,4 @@
+#! /bin/sh
+# $Id: tasm_test.sh 1137 2004-09-04 01:24:57Z peter $
+${srcdir}/out_test.sh tasm_test modules/parsers/tasm/tests/exe "tasm-compat parser" "-f dosexe -p tasm" ""
+exit $?
Modification de propriétés sur modules/parsers/tasm/tests/exe/tasm_exe_test.sh
___________________________________________________________________
Ajouté : svn:mergeinfo
Index: modules/parsers/tasm/tests/macro.hex
===================================================================
--- modules/parsers/tasm/tests/macro.hex (révision 0)
+++ modules/parsers/tasm/tests/macro.hex (révision 0)
@@ -0,0 +1,6 @@
+b8
+00
+00
+bb
+01
+00
Index: modules/parsers/tasm/tests/Makefile.inc
===================================================================
--- modules/parsers/tasm/tests/Makefile.inc (révision 0)
+++ modules/parsers/tasm/tests/Makefile.inc (révision 0)
@@ -0,0 +1,44 @@
+# $Id: Makefile.inc 2063 2008-04-12 08:30:22Z peter $
+
+TESTS += modules/parsers/tasm/tests/tasm_test.sh
+
+EXTRA_DIST += modules/parsers/tasm/tests/tasm_test.sh
+EXTRA_DIST += modules/parsers/tasm/tests/array.asm
+EXTRA_DIST += modules/parsers/tasm/tests/array.hex
+EXTRA_DIST += modules/parsers/tasm/tests/case.asm
+EXTRA_DIST += modules/parsers/tasm/tests/case.hex
+EXTRA_DIST += modules/parsers/tasm/tests/charstr.asm
+EXTRA_DIST += modules/parsers/tasm/tests/charstr.hex
+EXTRA_DIST += modules/parsers/tasm/tests/dup.asm
+EXTRA_DIST += modules/parsers/tasm/tests/dup.hex
+EXTRA_DIST += modules/parsers/tasm/tests/equal.asm
+EXTRA_DIST += modules/parsers/tasm/tests/equal.hex
+EXTRA_DIST += modules/parsers/tasm/tests/expr.asm
+EXTRA_DIST += modules/parsers/tasm/tests/expr.hex
+EXTRA_DIST += modules/parsers/tasm/tests/irp.asm
+EXTRA_DIST += modules/parsers/tasm/tests/irp.hex
+EXTRA_DIST += modules/parsers/tasm/tests/label.asm
+EXTRA_DIST += modules/parsers/tasm/tests/label.hex
+EXTRA_DIST += modules/parsers/tasm/tests/les.asm
+EXTRA_DIST += modules/parsers/tasm/tests/les.hex
+EXTRA_DIST += modules/parsers/tasm/tests/lidt.asm
+EXTRA_DIST += modules/parsers/tasm/tests/lidt.hex
+EXTRA_DIST += modules/parsers/tasm/tests/macro.asm
+EXTRA_DIST += modules/parsers/tasm/tests/macro.hex
+EXTRA_DIST += modules/parsers/tasm/tests/offset.asm
+EXTRA_DIST += modules/parsers/tasm/tests/offset.hex
+EXTRA_DIST += modules/parsers/tasm/tests/quote.asm
+EXTRA_DIST += modules/parsers/tasm/tests/quote.hex
+EXTRA_DIST += modules/parsers/tasm/tests/res.asm
+EXTRA_DIST += modules/parsers/tasm/tests/res.hex
+EXTRA_DIST += modules/parsers/tasm/tests/segment.asm
+EXTRA_DIST += modules/parsers/tasm/tests/segment.hex
+EXTRA_DIST += modules/parsers/tasm/tests/size.asm
+EXTRA_DIST += modules/parsers/tasm/tests/size.hex
+EXTRA_DIST += modules/parsers/tasm/tests/struc.asm
+EXTRA_DIST += modules/parsers/tasm/tests/struc.hex
+EXTRA_DIST += modules/parsers/tasm/tests/
+
+EXTRA_DIST += modules/parsers/nasm/test/exe/Makefile.inc
+
+include modules/parsers/nasm/test/exe/Makefile.inc
Index: modules/parsers/tasm/tests/segment.hex
===================================================================
--- modules/parsers/tasm/tests/segment.hex (révision 0)
+++ modules/parsers/tasm/tests/segment.hex (révision 0)
@@ -0,0 +1,7 @@
+00
+26
+c6
+06
+00
+00
+01
Index: modules/parsers/tasm/tests/charstr.asm
===================================================================
--- modules/parsers/tasm/tests/charstr.asm (révision 0)
+++ modules/parsers/tasm/tests/charstr.asm (révision 0)
@@ -0,0 +1 @@
+mov eax,"1234"
Index: modules/parsers/tasm/tests/charstr.hex
===================================================================
--- modules/parsers/tasm/tests/charstr.hex (révision 0)
+++ modules/parsers/tasm/tests/charstr.hex (révision 0)
@@ -0,0 +1,6 @@
+66
+b8
+34
+33
+32
+31
Index: modules/parsers/tasm/tests/array.asm
===================================================================
--- modules/parsers/tasm/tests/array.asm (révision 0)
+++ modules/parsers/tasm/tests/array.asm (révision 0)
@@ -0,0 +1,2 @@
+t db 0,1,2
+mov al,t[1]
Index: modules/parsers/tasm/tests/label.asm
===================================================================
--- modules/parsers/tasm/tests/label.asm (révision 0)
+++ modules/parsers/tasm/tests/label.asm (révision 0)
@@ -0,0 +1,2 @@
+a label byte
+mov ax,offset a
Index: modules/parsers/tasm/tests/array.hex
===================================================================
--- modules/parsers/tasm/tests/array.hex (révision 0)
+++ modules/parsers/tasm/tests/array.hex (révision 0)
@@ -0,0 +1,6 @@
+00
+01
+02
+a0
+01
+00
Index: modules/parsers/tasm/tests/label.hex
===================================================================
--- modules/parsers/tasm/tests/label.hex (révision 0)
+++ modules/parsers/tasm/tests/label.hex (révision 0)
@@ -0,0 +1,3 @@
+b8
+00
+00
Index: modules/parsers/tasm/tests/offset.asm
===================================================================
--- modules/parsers/tasm/tests/offset.asm (révision 0)
+++ modules/parsers/tasm/tests/offset.asm (révision 0)
@@ -0,0 +1,3 @@
+a db 1
+mov ax,offset a
+mov ax,offset[a]
Index: modules/parsers/tasm/tests/offset.hex
===================================================================
--- modules/parsers/tasm/tests/offset.hex (révision 0)
+++ modules/parsers/tasm/tests/offset.hex (révision 0)
@@ -0,0 +1,7 @@
+01
+b8
+00
+00
+b8
+00
+00
Index: modules/parsers/tasm/tests/irp.asm
===================================================================
--- modules/parsers/tasm/tests/irp.asm (révision 0)
+++ modules/parsers/tasm/tests/irp.asm (révision 0)
@@ -0,0 +1,3 @@
+irp i,<1,2,3>
+ mov ax,i
+endm
Index: modules/parsers/tasm/tests/quote.asm
===================================================================
--- modules/parsers/tasm/tests/quote.asm (révision 0)
+++ modules/parsers/tasm/tests/quote.asm (révision 0)
@@ -0,0 +1,2 @@
+a db 'don''t'
+b db """"
Index: modules/parsers/tasm/tests/tasm_test.sh
===================================================================
--- modules/parsers/tasm/tests/tasm_test.sh (révision 0)
+++ modules/parsers/tasm/tests/tasm_test.sh (révision 0)
@@ -0,0 +1,5 @@
+#! /bin/sh
+# $Id: tasm_test.sh 1137 2004-09-04 01:24:57Z peter $
+${srcdir}/out_test.sh tasm_test modules/parsers/tasm/tests "tasm-compat parser" "-f bin -p tasm" ""
+${srcdir}/out_test.sh tasm_test modules/parsers/tasm/tests/exe "tasm-compat parser" "-f dosexe -p tasm" ""
+exit $?
Modification de propriétés sur modules/parsers/tasm/tests/tasm_test.sh
___________________________________________________________________
Ajouté : svn:executable
+ *
Index: modules/parsers/tasm/tests/irp.hex
===================================================================
--- modules/parsers/tasm/tests/irp.hex (révision 0)
+++ modules/parsers/tasm/tests/irp.hex (révision 0)
@@ -0,0 +1,9 @@
+b8
+01
+00
+b8
+02
+00
+b8
+03
+00
Index: modules/parsers/tasm/tests/struc.asm
===================================================================
--- modules/parsers/tasm/tests/struc.asm (révision 0)
+++ modules/parsers/tasm/tests/struc.asm (révision 0)
@@ -0,0 +1,8 @@
+s struc
+ a db ?
+ b db ?
+s ends
+
+v s <1,?>
+
+mov al,[v].b
Index: modules/parsers/tasm/tests/struc.errwarn
===================================================================
--- modules/parsers/tasm/tests/struc.errwarn (révision 0)
+++ modules/parsers/tasm/tests/struc.errwarn (révision 0)
@@ -0,0 +1 @@
+-:6: warning: uninitialized space declared in code/data section: zeroing
Index: modules/parsers/tasm/tests/quote.hex
===================================================================
--- modules/parsers/tasm/tests/quote.hex (révision 0)
+++ modules/parsers/tasm/tests/quote.hex (révision 0)
@@ -0,0 +1,6 @@
+64
+6f
+6e
+27
+74
+22
Index: modules/parsers/tasm/tests/struc.hex
===================================================================
--- modules/parsers/tasm/tests/struc.hex (révision 0)
+++ modules/parsers/tasm/tests/struc.hex (révision 0)
@@ -0,0 +1,5 @@
+01
+00
+a0
+01
+00
Index: modules/parsers/tasm/tests/equal.asm
===================================================================
--- modules/parsers/tasm/tests/equal.asm (révision 0)
+++ modules/parsers/tasm/tests/equal.asm (révision 0)
@@ -0,0 +1 @@
+a = byte 1
Index: modules/parsers/tasm/tests/size.asm
===================================================================
--- modules/parsers/tasm/tests/size.asm (révision 0)
+++ modules/parsers/tasm/tests/size.asm (révision 0)
@@ -0,0 +1,2 @@
+a db 0
+mov a,1
Index: modules/parsers/tasm/tests/equal.hex
===================================================================
Index: modules/parsers/tasm/tests/case.asm
===================================================================
--- modules/parsers/tasm/tests/case.asm (révision 0)
+++ modules/parsers/tasm/tests/case.asm (révision 0)
@@ -0,0 +1,3 @@
+a db 0
+B dw A
+c dw b
Index: modules/parsers/tasm/tests/size.hex
===================================================================
--- modules/parsers/tasm/tests/size.hex (révision 0)
+++ modules/parsers/tasm/tests/size.hex (révision 0)
@@ -0,0 +1,6 @@
+00
+c6
+06
+00
+00
+01
Index: modules/parsers/tasm/tests/expr.asm
===================================================================
--- modules/parsers/tasm/tests/expr.asm (révision 0)
+++ modules/parsers/tasm/tests/expr.asm (révision 0)
@@ -0,0 +1 @@
+a db low ((1 shl 2) and (16 shr 2) or (high 0x5034))
Index: modules/parsers/tasm/tests/case.hex
===================================================================
--- modules/parsers/tasm/tests/case.hex (révision 0)
+++ modules/parsers/tasm/tests/case.hex (révision 0)
@@ -0,0 +1,5 @@
+00
+00
+00
+01
+00
Index: modules/parsers/tasm/tests/expr.hex
===================================================================
--- modules/parsers/tasm/tests/expr.hex (révision 0)
+++ modules/parsers/tasm/tests/expr.hex (révision 0)
@@ -0,0 +1 @@
+54
Index: modules/parsers/tasm/tests/les.asm
===================================================================
--- modules/parsers/tasm/tests/les.asm (révision 0)
+++ modules/parsers/tasm/tests/les.asm (révision 0)
@@ -0,0 +1,2 @@
+a db 1
+les ax,a
Index: modules/parsers/tasm/tests/les.hex
===================================================================
--- modules/parsers/tasm/tests/les.hex (révision 0)
+++ modules/parsers/tasm/tests/les.hex (révision 0)
@@ -0,0 +1,5 @@
+01
+c4
+06
+00
+00
Index: modules/parsers/tasm/tests/dup.asm
===================================================================
--- modules/parsers/tasm/tests/dup.asm (révision 0)
+++ modules/parsers/tasm/tests/dup.asm (révision 0)
@@ -0,0 +1 @@
+a db 10 dup(1)
Index: modules/parsers/tasm/tests/res.errwarn
===================================================================
--- modules/parsers/tasm/tests/res.errwarn (révision 0)
+++ modules/parsers/tasm/tests/res.errwarn (révision 0)
@@ -0,0 +1,2 @@
+-:1: warning: uninitialized space declared in code/data section: zeroing
+-:2: warning: uninitialized space declared in code/data section: zeroing
Index: modules/parsers/tasm/tests/res.asm
===================================================================
--- modules/parsers/tasm/tests/res.asm (révision 0)
+++ modules/parsers/tasm/tests/res.asm (révision 0)
@@ -0,0 +1,2 @@
+a db ?
+b db 2 dup (?)
Index: modules/parsers/tasm/tests/lidt.asm
===================================================================
--- modules/parsers/tasm/tests/lidt.asm (révision 0)
+++ modules/parsers/tasm/tests/lidt.asm (révision 0)
@@ -0,0 +1,3 @@
+idtr dw 0
+ dd 0
+lidt fword ptr idtr
Index: modules/parsers/tasm/tests/dup.hex
===================================================================
--- modules/parsers/tasm/tests/dup.hex (révision 0)
+++ modules/parsers/tasm/tests/dup.hex (révision 0)
@@ -0,0 +1,10 @@
+01
+01
+01
+01
+01
+01
+01
+01
+01
+01
Index: modules/parsers/tasm/tests/res.hex
===================================================================
--- modules/parsers/tasm/tests/res.hex (révision 0)
+++ modules/parsers/tasm/tests/res.hex (révision 0)
@@ -0,0 +1,3 @@
+00
+00
+00
Index: modules/parsers/tasm/Makefile.inc
===================================================================
--- modules/parsers/tasm/Makefile.inc (révision 0)
+++ modules/parsers/tasm/Makefile.inc (révision 0)
@@ -0,0 +1,5 @@
+# $Id: Makefile.inc 2082 2008-05-09 06:46:02Z peter $
+
+EXTRA_DIST += modules/parsers/tasm/tests/Makefile.inc
+
+include modules/parsers/tasm/tests/Makefile.inc
Index: modules/parsers/Makefile.inc
===================================================================
--- modules/parsers/Makefile.inc (révision 2128)
+++ modules/parsers/Makefile.inc (copie de travail)
@@ -5,6 +5,7 @@
include modules/parsers/gas/Makefile.inc
include modules/parsers/nasm/Makefile.inc
+include modules/parsers/tasm/Makefile.inc
dist_man_MANS += yasm_parsers.7
Index: modules/parsers/nasm/nasm-token.re
===================================================================
--- modules/parsers/nasm/nasm-token.re (révision 2128)
+++ modules/parsers/nasm/nasm-token.re (copie de travail)
@@ -32,6 +32,7 @@
#include <libyasm.h>
#include "modules/parsers/nasm/nasm-parser.h"
+#include "modules/preprocs/nasm/nasm.h"
#define YYCURSOR cursor
@@ -76,13 +77,22 @@
{
/* check for special non-local labels like ..start */
if (tok[zeropos+1] == '.') {
- lvalp->str_val = yasm__xstrndup(tok+zeropos, toklen-zeropos);
+ lvalp->str_val = yasm__xstrndup(tok+zeropos+(parser_nasm->tasm?2:0),
+ toklen-zeropos-(parser_nasm->tasm?2:0));
/* check for special non-local ..@label */
if (lvalp->str_val[zeropos+2] == '@')
return NONLOCAL_ID;
return SPECIAL_ID;
}
-
+ if (parser_nasm->tasm && (!tasm_locals ||
+ (tok[zeropos] == '.' &&
+ tok[zeropos+1] != '@' && tok[zeropos+2] != '@'))) {
+ /* no locals on Tasm without the 'locals' directive */
+ /* .foo is never local either, but .@@foo may be (local structure
+ * members) */
+ lvalp->str_val = yasm__xstrndup(tok + zeropos, toklen - zeropos);
+ return SPECIAL_ID;
+ }
if (!parser_nasm->locallabel_base) {
lvalp->str_val = yasm__xstrndup(tok+zeropos, toklen-zeropos);
yasm_warn_set(YASM_WARN_GENERAL,
@@ -242,65 +252,95 @@
}
/* pseudo-instructions */
- 'db' { lvalp->int_info = 8; RETURN(DECLARE_DATA); }
+ 'db' {
+ lvalp->int_info = 8;
+ parser_nasm->state = INSTRUCTION;
+ RETURN(DECLARE_DATA);
+ }
'dhw' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)/2;
+ parser_nasm->state = INSTRUCTION;
RETURN(DECLARE_DATA);
}
'dw' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch);
+ parser_nasm->state = INSTRUCTION;
RETURN(DECLARE_DATA);
}
'dd' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)*2;
+ parser_nasm->state = INSTRUCTION;
RETURN(DECLARE_DATA);
}
'dq' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)*4;
+ parser_nasm->state = INSTRUCTION;
RETURN(DECLARE_DATA);
}
- 'dt' { lvalp->int_info = 80; RETURN(DECLARE_DATA); }
+ 'dt' {
+ lvalp->int_info = 80;
+ parser_nasm->state = INSTRUCTION;
+ RETURN(DECLARE_DATA);
+ }
'ddq' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
+ parser_nasm->state = INSTRUCTION;
RETURN(DECLARE_DATA);
}
'do' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
+ parser_nasm->state = INSTRUCTION;
RETURN(DECLARE_DATA);
}
'dy' {
lvalp->int_info = 256;
+ parser_nasm->state = INSTRUCTION;
RETURN(DECLARE_DATA);
}
- 'resb' { lvalp->int_info = 8; RETURN(RESERVE_SPACE); }
+ 'resb' {
+ lvalp->int_info = 8;
+ parser_nasm->state = INSTRUCTION;
+ RETURN(RESERVE_SPACE);
+ }
'reshw' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)/2;
+ parser_nasm->state = INSTRUCTION;
RETURN(RESERVE_SPACE);
}
'resw' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch);
+ parser_nasm->state = INSTRUCTION;
RETURN(RESERVE_SPACE);
}
'resd' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)*2;
+ parser_nasm->state = INSTRUCTION;
RETURN(RESERVE_SPACE);
}
'resq' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)*4;
+ parser_nasm->state = INSTRUCTION;
RETURN(RESERVE_SPACE);
}
- 'rest' { lvalp->int_info = 80; RETURN(RESERVE_SPACE); }
+ 'rest' {
+ lvalp->int_info = 80;
+ parser_nasm->state = INSTRUCTION;
+ RETURN(RESERVE_SPACE);
+ }
'resdq' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
+ parser_nasm->state = INSTRUCTION;
RETURN(RESERVE_SPACE);
}
'reso' {
lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
+ parser_nasm->state = INSTRUCTION;
RETURN(RESERVE_SPACE);
}
'resy' {
lvalp->int_info = 256;
+ parser_nasm->state = INSTRUCTION;
RETURN(RESERVE_SPACE);
}
@@ -325,17 +365,18 @@
"//" { RETURN(SIGNDIV); }
"%%" { RETURN(SIGNMOD); }
"$$" { RETURN(START_SECTION_ID); }
- [-+|^*&/%~$():=,\[] { RETURN(s->tok[0]); }
+ [-+|^*&/%~$():=,\[?] { RETURN(s->tok[0]); }
"]" { RETURN(s->tok[0]); }
/* local label (.label) */
- "." [a-zA-Z0-9_$#@~.?]+ {
+ ("." | "@@") [a-zA-Z0-9_$#@~.?]+ {
RETURN(handle_dot_label(lvalp, TOK, TOKLEN, 0, parser_nasm));
}
/* forced identifier */
"$" [a-zA-Z0-9_$#@~.?]+ {
- if (TOK[1] == '.') {
+ if (TOK[1] == '.' ||
+ (parser_nasm->tasm && TOK[1] == '@' && TOK[2] == '@')) {
/* handle like .label */
RETURN(handle_dot_label(lvalp, TOK, TOKLEN, 1, parser_nasm));
}
@@ -376,11 +417,61 @@
s->tok[TOKLEN] = savech;
RETURN(TARGETMOD);
default:
+ break;
+ }
+ if (parser_nasm->tasm) {
+ if (!strcasecmp(TOK, "shl")) {
s->tok[TOKLEN] = savech;
+ RETURN(LEFT_OP);
+ }
+ if (!strcasecmp(TOK, "shr")) {
+ s->tok[TOKLEN] = savech;
+ RETURN(RIGHT_OP);
+ }
+ if (!strcasecmp(TOK, "and")) {
+ s->tok[TOKLEN] = savech;
+ RETURN('&');
+ }
+ if (!strcasecmp(TOK, "or")) {
+ s->tok[TOKLEN] = savech;
+ RETURN('|');
+ }
+ if (!strcasecmp(TOK, "low")) {
+ s->tok[TOKLEN] = savech;
+ RETURN(LOW);
+ }
+ if (!strcasecmp(TOK, "high")) {
+ s->tok[TOKLEN] = savech;
+ RETURN(HIGH);
+ }
+ if (!strcasecmp(TOK, "offset")) {
+ s->tok[TOKLEN] = savech;
+ RETURN(OFFSET);
+ }
+ if (!strcasecmp(TOK, "fword")) {
+ s->tok[TOKLEN] = savech;
+ lvalp->int_info = yasm_arch_wordsize(p_object->arch)*2;
+ RETURN(SIZE_OVERRIDE);
+ }
+ if (!strcasecmp(TOK, "df")) {
+ s->tok[TOKLEN] = savech;
+ lvalp->int_info = yasm_arch_wordsize(p_object->arch)*3;
+ parser_nasm->state = INSTRUCTION;
+ RETURN(DECLARE_DATA);
+ }
+ if (!strcasecmp(TOK, "label")) {
+ s->tok[TOKLEN] = savech;
+ RETURN(LABEL);
+ }
+ if (!strcasecmp(TOK, "dup")) {
+ s->tok[TOKLEN] = savech;
+ RETURN(DUP);
+ }
}
/* Propagate errors in case we got a warning from the arch */
yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
/* Just an identifier, return as such. */
+ s->tok[TOKLEN] = savech;
lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
RETURN(ID);
}
@@ -638,6 +729,26 @@
/*!re2c
[\000] { goto stringconst_error; }
+ "''" | '""' {
+ if (endch != s->tok[0]) {
+ strbuf[count++] = s->tok[0];
+ if (count >= strbuf_size) {
+ strbuf = yasm_xrealloc(strbuf,
+ strbuf_size + STRBUF_ALLOC_SIZE);
+ strbuf_size += STRBUF_ALLOC_SIZE;
+ }
+ } else if (!parser_nasm->tasm) {
+ YYCURSOR--;
+ goto scan;
+ }
+ strbuf[count++] = s->tok[0];
+ if (count >= strbuf_size) {
+ strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
+ strbuf_size += STRBUF_ALLOC_SIZE;
+ }
+ goto stringconst_scan;
+ }
+
any {
if (s->tok[0] == endch)
goto stringconst_end;
Index: modules/parsers/nasm/Makefile.inc
===================================================================
--- modules/parsers/nasm/Makefile.inc (révision 2128)
+++ modules/parsers/nasm/Makefile.inc (copie de travail)
@@ -5,7 +5,7 @@
libyasm_a_SOURCES += modules/parsers/nasm/nasm-parse.c
nodist_libyasm_a_SOURCES += nasm-token.c
-YASM_MODULES += parser_nasm
+YASM_MODULES += parser_nasm parser_tasm
nasm-token.c: $(srcdir)/modules/parsers/nasm/nasm-token.re re2c$(EXEEXT)
$(top_builddir)/re2c$(EXEEXT) -b -o $@ $(srcdir)/modules/parsers/nasm/nasm-token.re
Index: modules/parsers/nasm/nasm-parse.c
===================================================================
--- modules/parsers/nasm/nasm-parse.c (révision 2128)
+++ modules/parsers/nasm/nasm-parse.c (copie de travail)
@@ -32,6 +32,7 @@
#include <math.h>
#include "modules/parsers/nasm/nasm-parser.h"
+#include "modules/preprocs/nasm/nasm.h"
typedef enum {
NORM_EXPR,
@@ -62,8 +63,24 @@
/*@null@*/ yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams);
static void define_label(yasm_parser_nasm *parser_nasm, /*@only@*/ char *name,
- int local);
+ unsigned int size, int local);
+static void yasm_ea_set_implicit_size_segment(yasm_parser_nasm *parser_nasm,
+ yasm_effaddr *ea, yasm_expr *e)
+{
+ if (parser_nasm->tasm) {
+ const char *segment = yasm_expr_segment(e);
+ ea->data_len = yasm_expr_size(e);
+ if (segment) {
+ const char *segreg = tasm_get_segment_register(segment);
+ if (segreg)
+ yasm_arch_parse_check_regtmod(p_object->arch, segreg,
+ strlen(segreg), &ea->segreg);
+ }
+ }
+}
+
+
#define is_eol_tok(tok) ((tok) == 0)
#define is_eol() is_eol_tok(curtok)
@@ -242,11 +259,12 @@
yasm_bc_destroy(bc);
}
temp_bc = NULL;
- } else {
+ } else if (bc) {
temp_bc = yasm_section_bcs_append(cursect, bc);
if (temp_bc)
parser_nasm->prev_bc = temp_bc;
- }
+ } else
+ temp_bc = NULL;
yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
if (parser_nasm->save_input)
@@ -355,23 +373,33 @@
case LOCAL_ID:
{
char *name = ID_val;
- int local = (curtok != ID);
+ int local = parser_nasm->tasm
+ ? (curtok == ID || curtok == LOCAL_ID ||
+ (curtok == SPECIAL_ID && name[0] == '@'))
+ : (curtok != ID);
+ unsigned int size = 0;
get_next_token();
if (is_eol()) {
/* label alone on the line */
yasm_warn_set(YASM_WARN_ORPHAN_LABEL,
N_("label alone on a line without a colon might be in error"));
- define_label(parser_nasm, name, local);
+ define_label(parser_nasm, name, 0, local);
return NULL;
}
if (curtok == ':')
get_next_token();
- if (curtok == EQU) {
+ if (curtok == EQU || (parser_nasm->tasm && curtok == '=')) {
/* label EQU expr */
yasm_expr *e;
get_next_token();
+
+ if (parser_nasm->tasm && curtok == SIZE_OVERRIDE) {
+ size = SIZE_OVERRIDE_val;
+ get_next_token();
+ }
+
e = parse_expr(parser_nasm, NORM_EXPR);
if (!e) {
yasm_error_set(YASM_ERROR_SYNTAX,
@@ -384,17 +412,30 @@
return NULL;
}
- define_label(parser_nasm, name, local);
- if (is_eol())
+ if (parser_nasm->tasm && curtok == LABEL)
+ get_next_token();
+
+ if (parser_nasm->tasm && curtok == SIZE_OVERRIDE) {
+ size = SIZE_OVERRIDE_val;
+ get_next_token();
+ }
+
+ if (is_eol()) {
+ define_label(parser_nasm, name, size, local);
return NULL;
+ }
if (curtok == TIMES) {
+ define_label(parser_nasm, name, size, local);
get_next_token();
return parse_times(parser_nasm);
}
bc = parse_exp(parser_nasm);
- if (!bc)
+ if (!parser_nasm->tasm && !bc)
yasm_error_set(YASM_ERROR_SYNTAX,
N_("instruction expected after label"));
+ if (parser_nasm->tasm && bc && !size)
+ size = yasm_bc_elem_size(bc);
+ define_label(parser_nasm, name, size, local);
return bc;
}
default:
@@ -510,7 +551,7 @@
unsigned int size = DECLARE_DATA_val/8;
yasm_datavalhead dvs;
yasm_dataval *dv;
- yasm_expr *e;
+ yasm_expr *e, *e2;
get_next_token();
@@ -529,14 +570,68 @@
goto dv_done;
}
}
- if ((e = parse_bexpr(parser_nasm, DV_EXPR)))
- dv = yasm_dv_create_expr(e);
- else {
+ if (curtok == '?') {
+ yasm_dvs_delete(&dvs);
+ get_next_token();
+ if (! is_eol_tok(curtok)) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("can not handle more than one '?'"));
+ return NULL;
+ }
+ return yasm_bc_create_reserve(
+ p_expr_new_ident(yasm_expr_int(
+ yasm_intnum_create_uint(1))),
+ size, cur_line);
+ }
+ if (!(e = parse_bexpr(parser_nasm, DV_EXPR))) {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("expression or string expected"));
yasm_dvs_delete(&dvs);
return NULL;
}
+ if (curtok == DUP) {
+ get_next_token();
+ if (curtok != '(') {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expected ( after DUP"));
+ goto error;
+ }
+ get_next_token();
+ if (curtok == '?') {
+ get_next_token();
+ if (curtok != ')') {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expected ) after DUPlicated expression"));
+ goto error;
+ }
+ get_next_token();
+ if (! is_eol_tok(curtok)) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("can not handle more than one '?'"));
+ goto error;
+ }
+ yasm_dvs_delete(&dvs);
+ return yasm_bc_create_reserve(e, size, cur_line);
+ } else if ((e2 = parse_bexpr(parser_nasm, DV_EXPR))) {
+ if (curtok != ')') {
+ yasm_expr_destroy(e2);
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expected ) after DUPlicated expression"));
+ goto error;
+ }
+ get_next_token();
+ dv = yasm_dv_create_expr(e2);
+ yasm_dv_set_multiple(dv, e);
+ } else {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression or string expected"));
+error:
+ yasm_expr_destroy(e);
+ yasm_dvs_delete(&dvs);
+ return NULL;
+ }
+ } else
+ dv = yasm_dv_create_expr(e);
dv_done:
yasm_dvs_append(&dvs, dv);
if (is_eol())
@@ -699,12 +794,106 @@
N_("memory address expected"));
return NULL;
}
+
+ if (parser_nasm->tasm && !is_eol() && curtok != ',') {
+ yasm_expr *e = NULL, *f;
+ yasm_effaddr *ea;
+
+ switch (op->type) {
+ case YASM_INSN__OPERAND_IMM:
+ e = op->data.val;
+ break;
+ case YASM_INSN__OPERAND_MEMORY:
+ if (op->data.ea->disp.rel) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("relative adressing not supported\n"));
+ return NULL;
+ }
+ e = yasm_expr_copy(op->data.ea->disp.abs);
+ yasm_arch_ea_destroy(p_object->arch, op->data.ea);
+ break;
+ case YASM_INSN__OPERAND_REG:
+ case YASM_INSN__OPERAND_SEGREG:
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("register adressing not supported\n"));
+ return NULL;
+ }
+ yasm_xfree(op);
+ f = parse_bexpr(parser_nasm, NORM_EXPR);
+ if (!f) {
+ yasm_expr_destroy(e);
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expected expression after ]"));
+ return NULL;
+ }
+ e = p_expr_new_tree(e, YASM_EXPR_ADD, f);
+ ea = yasm_arch_ea_create(p_object->arch, e);
+ yasm_ea_set_implicit_size_segment(parser_nasm, ea, e);
+ op = yasm_operand_create_mem(ea);
+ }
return op;
}
+ case OFFSET:
+ {
+ yasm_insn_operand *op2;
+ get_next_token();
+ op = parse_operand(parser_nasm);
+ if (!op) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("memory address expected"));
+ return NULL;
+ }
+ if (op->type == YASM_INSN__OPERAND_IMM)
+ return op;
+ if (op->type != YASM_INSN__OPERAND_MEMORY) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("OFFSET applied to non-memory operand"));
+ return NULL;
+ }
+ if (op->data.ea->disp.rel) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("OFFSET applied to non-absolute memory operand"));
+ return NULL;
+ }
+ if (op->data.ea->disp.abs)
+ op2 = yasm_operand_create_imm(op->data.ea->disp.abs);
+ else
+ op2 = yasm_operand_create_imm(p_expr_new_ident(
+ yasm_expr_int(yasm_intnum_create_uint(0))));
+ yasm_xfree(op);
+ return op2;
+ }
case SEGREG:
- op = yasm_operand_create_segreg(SEGREG_val);
+ {
+ uintptr_t segreg = SEGREG_val;
get_next_token();
+ if (parser_nasm->tasm && curtok == ':') {
+ get_next_token();
+ op = parse_operand(parser_nasm);
+ if (!op)
+ return NULL;
+ if (op->type == YASM_INSN__OPERAND_IMM) {
+ yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch,
+ op->data.val);
+ yasm_insn_operand *op2;
+ yasm_ea_set_implicit_size_segment(parser_nasm, ea,
+ op->data.val);
+ op2 = yasm_operand_create_mem(ea);
+ op2->size = op->size;
+ yasm_xfree(op);
+ op = op2;
+ }
+ if (op->type != YASM_INSN__OPERAND_MEMORY) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("segment applied to non-memory operand"));
+ return NULL;
+ }
+ yasm_ea_set_segreg(op->data.ea, segreg);
+ return op;
+ }
+ op = yasm_operand_create_segreg(segreg);
return op;
+ }
case REG:
op = yasm_operand_create_reg(REG_val);
get_next_token();
@@ -756,13 +945,51 @@
op->targetmod = tmod;
return op;
}
+ case ID:
+ case LOCAL_ID:
+ case NONLOCAL_ID:
+ if (parser_nasm->tasm) {
+ get_peek_token(parser_nasm);
+ if (parser_nasm->peek_token == '[') {
+ yasm_symrec *sym = yasm_symtab_use(p_symtab, ID_val,
+ cur_line);
+ yasm_expr *e = p_expr_new_ident(yasm_expr_sym(sym)), *f;
+ yasm_effaddr *ea;
+ yasm_xfree(ID_val);
+ get_next_token();
+ get_next_token();
+ f = parse_bexpr(parser_nasm, NORM_EXPR);
+ if (!f) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expected expression after ["));
+ return NULL;
+ }
+ e = p_expr_new_tree(e, YASM_EXPR_ADD, f);
+ if (!expect(']')) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("missing closing bracket"));
+ return NULL;
+ }
+ get_next_token();
+ ea = yasm_arch_ea_create(p_object->arch, e);
+ yasm_ea_set_implicit_size_segment(parser_nasm, ea, e);
+ op = yasm_operand_create_mem(ea);
+ return op;
+ }
+ }
+ /* Fallthrough */
default:
{
yasm_expr *e = parse_bexpr(parser_nasm, NORM_EXPR);
if (!e)
return NULL;
if (curtok != ':')
- return yasm_operand_create_imm(e);
+ if (parser_nasm->tasm && yasm_expr_size(e)) {
+ yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch, e);
+ yasm_ea_set_implicit_size_segment(parser_nasm, ea, e);
+ op = yasm_operand_create_mem(ea);
+ return op;
+ } else
+ return yasm_operand_create_imm(e);
else {
yasm_expr *off;
get_next_token();
@@ -836,10 +1061,12 @@
yasm_expr *e = parse_bexpr(parser_nasm, NORM_EXPR);
if (!e)
return NULL;
- if (curtok != ':')
- return yasm_operand_create_mem(
- yasm_arch_ea_create(p_object->arch, e));
- else {
+ if (curtok != ':') {
+ yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch, e);
+ yasm_ea_set_implicit_size_segment(parser_nasm, ea, e);
+ return yasm_operand_create_mem(ea);
+ } else {
+ yasm_effaddr *ea;
yasm_expr *off;
get_next_token();
off = parse_bexpr(parser_nasm, NORM_EXPR);
@@ -847,8 +1074,9 @@
yasm_expr_destroy(e);
return NULL;
}
- op = yasm_operand_create_mem(
- yasm_arch_ea_create(p_object->arch, off));
+ ea = yasm_arch_ea_create(p_object->arch, off);
+ yasm_ea_set_implicit_size_segment(parser_nasm, ea, off);
+ op = yasm_operand_create_mem(ea);
op->seg = e;
return op;
}
@@ -1094,6 +1322,30 @@
return NULL;
}
return p_expr_new_branch(YASM_EXPR_NOT, e);
+ case LOW:
+ get_next_token();
+ e = parse_expr6(parser_nasm, type);
+ if (!e) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expected expression after %s"), "LOW");
+ return NULL;
+ }
+ return p_expr_new_tree(e, YASM_EXPR_AND,
+ p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0xff))));
+ case HIGH:
+ get_next_token();
+ e = parse_expr6(parser_nasm, type);
+ if (!e) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expected expression after %s"), "HIGH");
+ return NULL;
+ }
+ return p_expr_new_tree(
+ p_expr_new_tree(e, YASM_EXPR_SHR,
+ p_expr_new_ident(yasm_expr_int(
+ yasm_intnum_create_uint(8)))),
+ YASM_EXPR_AND,
+ p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0xff))));
case SEG:
get_next_token();
e = parse_expr6(parser_nasm, type);
@@ -1132,10 +1384,16 @@
e = p_expr_new_ident(yasm_expr_reg(REG_val));
break;
case STRING:
- e = p_expr_new_ident(yasm_expr_int(
- yasm_intnum_create_charconst_nasm(STRING_val.contents)));
+ {
+ yasm_intnum *intn;
+ if (parser_nasm->tasm)
+ intn = yasm_intnum_create_charconst_tasm(STRING_val.contents);
+ else
+ intn = yasm_intnum_create_charconst_nasm(STRING_val.contents);
+ e = p_expr_new_ident(yasm_expr_int(intn));
yasm_xfree(STRING_val.contents);
break;
+ }
case SPECIAL_ID:
sym = yasm_objfmt_get_special_sym(p_object, ID_val+2, "nasm");
if (sym) {
@@ -1179,9 +1437,12 @@
}
static void
-define_label(yasm_parser_nasm *parser_nasm, char *name, int local)
+define_label(yasm_parser_nasm *parser_nasm, char *name, unsigned int size,
+ int local)
{
- if (!local) {
+ yasm_symrec *symrec;
+
+ if ((!parser_nasm->tasm || tasm_locals) && !local) {
if (parser_nasm->locallabel_base)
yasm_xfree(parser_nasm->locallabel_base);
parser_nasm->locallabel_base_len = strlen(name);
@@ -1191,11 +1452,16 @@
}
if (parser_nasm->abspos)
- yasm_symtab_define_equ(p_symtab, name,
- yasm_expr_copy(parser_nasm->abspos), cur_line);
+ symrec = yasm_symtab_define_equ(p_symtab, name,
+ yasm_expr_copy(parser_nasm->abspos),
+ cur_line);
else
- yasm_symtab_define_label(p_symtab, name, parser_nasm->prev_bc, 1,
- cur_line);
+ symrec = yasm_symtab_define_label(p_symtab, name, parser_nasm->prev_bc,
+ 1, cur_line);
+
+ yasm_symrec_set_size(symrec, size);
+ yasm_symrec_set_segment(symrec, tasm_segment);
+
yasm_xfree(name);
}
Index: modules/parsers/nasm/nasm-parser.c
===================================================================
--- modules/parsers/nasm/nasm-parser.c (révision 2129)
+++ modules/parsers/nasm/nasm-parser.c (révision 2137)
@@ -33,12 +33,13 @@
static void
-nasm_parser_do_parse(yasm_object *object, yasm_preproc *pp,
- int save_input, yasm_linemap *linemap,
- yasm_errwarns *errwarns)
+nasm_do_parse(yasm_object *object, yasm_preproc *pp, int save_input,
+ yasm_linemap *linemap, yasm_errwarns *errwarns, int tasm)
{
yasm_parser_nasm parser_nasm;
+ parser_nasm.tasm = tasm;
+
parser_nasm.object = object;
parser_nasm.linemap = linemap;
@@ -77,6 +78,14 @@
yasm_symtab_parser_finalize(object->symtab, 0, errwarns);
}
+static void
+nasm_parser_do_parse(yasm_object *object, yasm_preproc *pp,
+ int save_input, yasm_linemap *linemap,
+ yasm_errwarns *errwarns)
+{
+ nasm_do_parse(object, pp, save_input, linemap, errwarns, 0);
+}
+
/* Define valid preprocessors to use with this parser */
static const char *nasm_parser_preproc_keywords[] = {
"raw",
@@ -100,3 +109,29 @@
nasm_parser_stdmacs,
nasm_parser_do_parse
};
+
+static void
+tasm_parser_do_parse(yasm_object *object, yasm_preproc *pp,
+ int save_input, yasm_linemap *linemap,
+ yasm_errwarns *errwarns)
+{
+ yasm_symtab_set_case_sensitive(object->symtab, 0);
+ yasm_warn_disable(YASM_WARN_IMPLICIT_SIZE_OVERRIDE);
+ nasm_do_parse(object, pp, save_input, linemap, errwarns, 1);
+}
+
+/* Define valid preprocessors to use with this parser */
+static const char *tasm_parser_preproc_keywords[] = {
+ "raw",
+ "tasm",
+ NULL
+};
+
+/* Define parser structure -- see parser.h for details */
+yasm_parser_module yasm_tasm_LTX_parser = {
+ "TASM-compatible parser",
+ "tasm",
+ tasm_parser_preproc_keywords,
+ "tasm",
+ tasm_parser_do_parse
+};
Index: modules/parsers/nasm/nasm-parser.h
===================================================================
--- modules/parsers/nasm/nasm-parser.h (révision 2128)
+++ modules/parsers/nasm/nasm-parser.h (copie de travail)
@@ -38,11 +38,14 @@
FILENAME,
STRING,
SIZE_OVERRIDE,
+ OFFSET,
DECLARE_DATA,
RESERVE_SPACE,
+ LABEL,
INCBIN,
EQU,
TIMES,
+ DUP,
SEG,
WRT,
ABS,
@@ -56,6 +59,8 @@
TARGETMOD,
LEFT_OP,
RIGHT_OP,
+ LOW,
+ HIGH,
SIGNDIV,
SIGNMOD,
START_SECTION_ID,
@@ -82,6 +87,8 @@
#define YYSTYPE yystype
typedef struct yasm_parser_nasm {
+ int tasm;
+
int debug;
/*@only@*/ yasm_object *object;
Index: modules/objfmts/win64/tests/win64-dataref.hex
===================================================================
--- modules/objfmts/win64/tests/win64-dataref.hex (révision 2128)
+++ modules/objfmts/win64/tests/win64-dataref.hex (copie de travail)
@@ -1364,7 +1364,7 @@
00
00
00
-17
+16
00
00
00
@@ -1374,7 +1374,7 @@
00
00
00
-17
+16
00
00
00
@@ -1999,39 +1999,39 @@
03
00
78
-70
-74
-72
00
00
00
00
-40
00
00
00
-02
00
00
00
+00
03
00
-78
00
00
+03
00
+78
+70
+74
+72
00
00
00
00
+40
00
00
00
+02
00
-03
00
00
-00
03
00
78
Index: modules/objfmts/bin/Makefile.inc
===================================================================
--- modules/objfmts/bin/Makefile.inc (révision 2128)
+++ modules/objfmts/bin/Makefile.inc (copie de travail)
@@ -2,7 +2,7 @@
libyasm_a_SOURCES += modules/objfmts/bin/bin-objfmt.c
-YASM_MODULES += objfmt_bin
+YASM_MODULES += objfmt_bin objfmt_dosexe
EXTRA_DIST += modules/objfmts/bin/tests/Makefile.inc
Index: modules/objfmts/bin/bin-objfmt.c
===================================================================
--- modules/objfmts/bin/bin-objfmt.c (révision 2128)
+++ modules/objfmts/bin/bin-objfmt.c (copie de travail)
@@ -27,6 +27,9 @@
#include <util.h>
/*@unused@*/ RCSID("$Id$");
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#include <libyasm.h>
@@ -1071,7 +1072,8 @@
yasm_errwarn_propagate(info->errwarns, 0);
return 0;
}
- if (fseek(info->f, yasm_intnum_get_int(info->tmp_intn), SEEK_SET) < 0)
+ if (fseek(info->f, yasm_intnum_get_int(info->tmp_intn) + info->start,
+ SEEK_SET) < 0)
yasm__fatal(N_("could not seek on output file"));
yasm_section_bcs_traverse(sect, info->errwarns,
info, bin_objfmt_output_bytecode);
@@ -1106,6 +1107,8 @@
yasm_intnum *start, *last, *vdelta;
bin_groups unsorted_groups, bss_groups;
+ info.start = ftell(f);
+
/* Set ORG to 0 unless otherwise specified */
if (objfmt_bin->org) {
info.origin = yasm_expr_get_intnum(&objfmt_bin->org, 0);
@@ -1802,3 +1806,153 @@
bin_objfmt_section_switch,
bin_objfmt_get_special_sym
};
+
+#define EXE_HEADER_SIZE 0x200
+
+/* DOS .EXE binaries are just raw binaries with a header */
+yasm_objfmt_module yasm_dosexe_LTX_objfmt;
+
+static yasm_objfmt *
+dosexe_objfmt_create(yasm_object *object)
+{
+ yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *) bin_objfmt_create(object);
+ objfmt_bin->objfmt.module = &yasm_dosexe_LTX_objfmt;
+ return (yasm_objfmt *)objfmt_bin;
+}
+
+static unsigned long
+get_sym(yasm_object *object, const char *name) {
+ yasm_symrec *symrec = yasm_symtab_get(object->symtab, name);
+ yasm_bytecode *prevbc;
+ if (!symrec)
+ return 0;
+ if (!yasm_symrec_get_label(symrec, &prevbc))
+ return 0;
+ return prevbc->offset + prevbc->len;
+}
+
+static void
+dosexe_objfmt_output(yasm_object *object, FILE *f, /*@unused@*/ int all_syms,
+ yasm_errwarns *errwarns)
+{
+ unsigned long tot_size, size, bss_size;
+ unsigned long start, bss;
+ unsigned char c;
+
+ fseek(f, EXE_HEADER_SIZE, SEEK_SET);
+
+ bin_objfmt_output(object, f, all_syms, errwarns);
+
+ tot_size = ftell(f);
+
+ /* if there is a __bss_start symbol, data after it is 0, no need to write
+ * it. */
+ bss = get_sym(object, "__bss_start");
+ if (bss)
+ size = bss;
+ else
+ size = tot_size;
+ bss_size = tot_size - size;
+#ifdef HAVE_FTRUNCATE
+ if (size != tot_size)
+ ftruncate(fileno(f), EXE_HEADER_SIZE + size);
+#endif
+ fseek(f, 0, SEEK_SET);
+
+ /* magic */
+ fwrite("MZ", 1, 2, f);
+
+ /* file size */
+ c = size & 0xff;
+ fwrite(&c, 1, 1, f);
+ c = !!(size & 0x100);
+ fwrite(&c, 1, 1, f);
+ c = ((size + 511) >> 9) & 0xff;
+ fwrite(&c, 1, 1, f);
+ c = ((size + 511) >> 17) & 0xff;
+ fwrite(&c, 1, 1, f);
+
+ /* relocation # */
+ c = 0;
+ fwrite(&c, 1, 1, f);
+ fwrite(&c, 1, 1, f);
+
+ /* header size */
+ c = EXE_HEADER_SIZE / 16;
+ fwrite(&c, 1, 1, f);
+ c = 0;
+ fwrite(&c, 1, 1, f);
+
+ /* minimum paragraph # */
+ bss_size = (bss_size + 15) >> 4;
+ c = bss_size & 0xff;
+ fwrite(&c, 1, 1, f);
+ c = (bss_size >> 8) & 0xff;
+ fwrite(&c, 1, 1, f);
+
+ /* maximum paragraph # */
+ c = 0xFF;
+ fwrite(&c, 1, 1, f);
+ fwrite(&c, 1, 1, f);
+
+ /* relative value of stack segment */
+ c = 0;
+ fwrite(&c, 1, 1, f);
+ fwrite(&c, 1, 1, f);
+
+ /* SP at start */
+ c = 0;
+ fwrite(&c, 1, 1, f);
+ fwrite(&c, 1, 1, f);
+
+ /* header checksum */
+ c = 0;
+ fwrite(&c, 1, 1, f);
+ fwrite(&c, 1, 1, f);
+
+ /* IP at start */
+ start = get_sym(object, "start");
+ if (!start) {
+ yasm_error_set(YASM_ERROR_GENERAL,
+ N_("%s: could not find symbol `start'"));
+ return;
+ }
+ c = start & 0xff;
+ fwrite(&c, 1, 1, f);
+ c = (start >> 8) & 0xff;
+ fwrite(&c, 1, 1, f);
+
+ /* CS start */
+ c = 0;
+ fwrite(&c, 1, 1, f);
+ fwrite(&c, 1, 1, f);
+
+ /* reloc start */
+ c = 0x22;
+ fwrite(&c, 1, 1, f);
+ c = 0;
+ fwrite(&c, 1, 1, f);
+
+ /* Overlay number */
+ c = 0;
+ fwrite(&c, 1, 1, f);
+ fwrite(&c, 1, 1, f);
+}
+
+
+/* Define objfmt structure -- see objfmt.h for details */
+yasm_objfmt_module yasm_dosexe_LTX_objfmt = {
+ "DOS .EXE format binary",
+ "dosexe",
+ "exe",
+ 16,
+ bin_objfmt_dbgfmt_keywords,
+ "null",
+ bin_objfmt_directives,
+ dosexe_objfmt_create,
+ dosexe_objfmt_output,
+ bin_objfmt_destroy,
+ bin_objfmt_add_default_section,
+ bin_objfmt_section_switch,
+ bin_objfmt_get_special_sym
+};
Index: modules/objfmts/coff/coff-objfmt.c
===================================================================
--- modules/objfmts/coff/coff-objfmt.c (révision 2128)
+++ modules/objfmts/coff/coff-objfmt.c (copie de travail)
@@ -234,6 +234,7 @@
win32_sxdata_bc_destroy,
win32_sxdata_bc_print,
yasm_bc_finalize_common,
+ NULL,
win32_sxdata_bc_calc_len,
yasm_bc_expand_common,
win32_sxdata_bc_tobytes,
Index: modules/objfmts/coff/win64-except.c
===================================================================
--- modules/objfmts/coff/win64-except.c (révision 2128)
+++ modules/objfmts/coff/win64-except.c (copie de travail)
@@ -72,6 +72,7 @@
win64_uwinfo_bc_destroy,
win64_uwinfo_bc_print,
win64_uwinfo_bc_finalize,
+ NULL,
win64_uwinfo_bc_calc_len,
win64_uwinfo_bc_expand,
win64_uwinfo_bc_tobytes,
@@ -82,6 +83,7 @@
win64_uwcode_bc_destroy,
win64_uwcode_bc_print,
win64_uwcode_bc_finalize,
+ NULL,
win64_uwcode_bc_calc_len,
win64_uwcode_bc_expand,
win64_uwcode_bc_tobytes,
Index: modules/dbgfmts/codeview/cv-symline.c
===================================================================
--- modules/dbgfmts/codeview/cv-symline.c (révision 2128)
+++ modules/dbgfmts/codeview/cv-symline.c (copie de travail)
@@ -201,6 +201,7 @@
cv8_symhead_bc_destroy,
cv8_symhead_bc_print,
yasm_bc_finalize_common,
+ NULL,
cv8_symhead_bc_calc_len,
yasm_bc_expand_common,
cv8_symhead_bc_tobytes,
@@ -211,6 +212,7 @@
cv8_fileinfo_bc_destroy,
cv8_fileinfo_bc_print,
yasm_bc_finalize_common,
+ NULL,
cv8_fileinfo_bc_calc_len,
yasm_bc_expand_common,
cv8_fileinfo_bc_tobytes,
@@ -221,6 +223,7 @@
cv8_lineinfo_bc_destroy,
cv8_lineinfo_bc_print,
yasm_bc_finalize_common,
+ NULL,
cv8_lineinfo_bc_calc_len,
yasm_bc_expand_common,
cv8_lineinfo_bc_tobytes,
@@ -231,6 +234,7 @@
cv_sym_bc_destroy,
cv_sym_bc_print,
yasm_bc_finalize_common,
+ NULL,
cv_sym_bc_calc_len,
yasm_bc_expand_common,
cv_sym_bc_tobytes,
Index: modules/dbgfmts/codeview/cv-type.c
===================================================================
--- modules/dbgfmts/codeview/cv-type.c (révision 2128)
+++ modules/dbgfmts/codeview/cv-type.c (copie de travail)
@@ -492,6 +492,7 @@
cv_type_bc_destroy,
cv_type_bc_print,
yasm_bc_finalize_common,
+ NULL,
cv_type_bc_calc_len,
yasm_bc_expand_common,
cv_type_bc_tobytes,
Index: modules/dbgfmts/dwarf2/dwarf2-info.c
===================================================================
--- modules/dbgfmts/dwarf2/dwarf2-info.c (révision 2128)
+++ modules/dbgfmts/dwarf2/dwarf2-info.c (copie de travail)
@@ -207,6 +207,7 @@
dwarf2_abbrev_bc_destroy,
dwarf2_abbrev_bc_print,
yasm_bc_finalize_common,
+ NULL,
dwarf2_abbrev_bc_calc_len,
yasm_bc_expand_common,
dwarf2_abbrev_bc_tobytes,
Index: modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c
===================================================================
--- modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c (révision 2128)
+++ modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c (copie de travail)
@@ -55,6 +55,7 @@
dwarf2_head_bc_destroy,
dwarf2_head_bc_print,
yasm_bc_finalize_common,
+ NULL,
dwarf2_head_bc_calc_len,
yasm_bc_expand_common,
dwarf2_head_bc_tobytes,
Index: modules/dbgfmts/dwarf2/dwarf2-line.c
===================================================================
--- modules/dbgfmts/dwarf2/dwarf2-line.c (révision 2128)
+++ modules/dbgfmts/dwarf2/dwarf2-line.c (copie de travail)
@@ -149,6 +149,7 @@
dwarf2_spp_bc_destroy,
dwarf2_spp_bc_print,
yasm_bc_finalize_common,
+ NULL,
dwarf2_spp_bc_calc_len,
yasm_bc_expand_common,
dwarf2_spp_bc_tobytes,
@@ -159,6 +160,7 @@
dwarf2_line_op_bc_destroy,
dwarf2_line_op_bc_print,
yasm_bc_finalize_common,
+ NULL,
dwarf2_line_op_bc_calc_len,
yasm_bc_expand_common,
dwarf2_line_op_bc_tobytes,
Index: modules/dbgfmts/stabs/stabs-dbgfmt.c
===================================================================
--- modules/dbgfmts/stabs/stabs-dbgfmt.c (révision 2128)
+++ modules/dbgfmts/stabs/stabs-dbgfmt.c (copie de travail)
@@ -139,6 +139,7 @@
stabs_bc_str_destroy,
stabs_bc_str_print,
yasm_bc_finalize_common,
+ NULL,
stabs_bc_str_calc_len,
yasm_bc_expand_common,
stabs_bc_str_tobytes,
@@ -149,6 +150,7 @@
stabs_bc_stab_destroy,
stabs_bc_stab_print,
yasm_bc_finalize_common,
+ NULL,
stabs_bc_stab_calc_len,
yasm_bc_expand_common,
stabs_bc_stab_tobytes,
Index: modules/arch/lc3b/lc3bid.re
===================================================================
--- modules/arch/lc3b/lc3bid.re (révision 2128)
+++ modules/arch/lc3b/lc3bid.re (copie de travail)
@@ -128,6 +128,7 @@
lc3b_id_insn_destroy,
lc3b_id_insn_print,
lc3b_id_insn_finalize,
+ NULL,
yasm_bc_calc_len_common,
yasm_bc_expand_common,
yasm_bc_tobytes_common,
Index: modules/arch/lc3b/lc3bbc.c
===================================================================
--- modules/arch/lc3b/lc3bbc.c (révision 2128)
+++ modules/arch/lc3b/lc3bbc.c (copie de travail)
@@ -53,6 +53,7 @@
lc3b_bc_insn_destroy,
lc3b_bc_insn_print,
yasm_bc_finalize_common,
+ NULL,
lc3b_bc_insn_calc_len,
lc3b_bc_insn_expand,
lc3b_bc_insn_tobytes,
Index: modules/arch/x86/tests/lds-err.errwarn
===================================================================
--- modules/arch/x86/tests/lds-err.errwarn (révision 2129)
+++ modules/arch/x86/tests/lds-err.errwarn (révision 2137)
@@ -1,4 +0,0 @@
--:2: error: invalid size for operand 2
--:3: error: invalid size for operand 2
--:5: error: invalid size for operand 2
--:6: error: invalid size for operand 2
Index: modules/arch/x86/tests/lds-err.asm
===================================================================
--- modules/arch/x86/tests/lds-err.asm (révision 2129)
+++ modules/arch/x86/tests/lds-err.asm (révision 2137)
@@ -1,6 +0,0 @@
-lds ax,[1]
-lds ax,word [1]
-lds ax,dword [1]
-lds eax,[1]
-lds eax,word [1]
-lds eax,dword [1]
Index: modules/arch/x86/tests/Makefile.inc
===================================================================
--- modules/arch/x86/tests/Makefile.inc (révision 2129)
+++ modules/arch/x86/tests/Makefile.inc (révision 2137)
@@ -84,8 +84,8 @@
EXTRA_DIST += modules/arch/x86/tests/jmp64-6.hex
EXTRA_DIST += modules/arch/x86/tests/jmpfar.asm
EXTRA_DIST += modules/arch/x86/tests/jmpfar.hex
-EXTRA_DIST += modules/arch/x86/tests/lds-err.asm
-EXTRA_DIST += modules/arch/x86/tests/lds-err.errwarn
+EXTRA_DIST += modules/arch/x86/tests/lds.asm
+EXTRA_DIST += modules/arch/x86/tests/lds.hex
EXTRA_DIST += modules/arch/x86/tests/loopadsz.asm
EXTRA_DIST += modules/arch/x86/tests/loopadsz.hex
EXTRA_DIST += modules/arch/x86/tests/lsahf.asm
Index: modules/arch/x86/tests/lds.asm
===================================================================
--- modules/arch/x86/tests/lds.asm (révision 0)
+++ modules/arch/x86/tests/lds.asm (révision 2137)
@@ -0,0 +1,6 @@
+lds ax,[1]
+lds ax,word [1]
+lds ax,dword [1]
+lds eax,[1]
+lds eax,word [1]
+lds eax,dword [1]
Index: modules/arch/x86/tests/lds.hex
===================================================================
--- modules/arch/x86/tests/lds.hex (révision 0)
+++ modules/arch/x86/tests/lds.hex (révision 2137)
@@ -0,0 +1,27 @@
+c5
+06
+01
+00
+c5
+06
+01
+00
+c5
+06
+01
+00
+66
+c5
+06
+01
+00
+66
+c5
+06
+01
+00
+66
+c5
+06
+01
+00
Index: modules/arch/x86/x86id.c
===================================================================
--- modules/arch/x86/x86id.c (révision 2128)
+++ modules/arch/x86/x86id.c (copie de travail)
@@ -350,6 +350,7 @@
x86_id_insn_destroy,
x86_id_insn_print,
x86_id_insn_finalize,
+ NULL,
yasm_bc_calc_len_common,
yasm_bc_expand_common,
yasm_bc_tobytes_common,
@@ -1733,6 +1734,9 @@
case X86_PARSER_NASM:
pdata = insnprefix_nasm_find(lcaseid, id_len);
break;
+ case X86_PARSER_TASM:
+ pdata = insnprefix_nasm_find(lcaseid, id_len);
+ break;
case X86_PARSER_GAS:
pdata = insnprefix_gas_find(lcaseid, id_len);
break;
Index: modules/arch/x86/x86arch.c
===================================================================
--- modules/arch/x86/x86arch.c (révision 2128)
+++ modules/arch/x86/x86arch.c (copie de travail)
@@ -71,6 +71,8 @@
if (yasm__strcasecmp(parser, "nasm") == 0)
arch_x86->parser = X86_PARSER_NASM;
+ else if (yasm__strcasecmp(parser, "tasm") == 0)
+ arch_x86->parser = X86_PARSER_TASM;
else if (yasm__strcasecmp(parser, "gas") == 0
|| yasm__strcasecmp(parser, "gnu") == 0)
arch_x86->parser = X86_PARSER_GAS;
Index: modules/arch/x86/x86expr.c
===================================================================
--- modules/arch/x86/x86expr.c (révision 2128)
+++ modules/arch/x86/x86expr.c (copie de travail)
@@ -422,7 +422,7 @@
* EA. With no registers, we must have a 16/32 value.
*/
if (noreg) {
- yasm_warn_set(YASM_WARN_GENERAL,
+ yasm_warn_set(YASM_WARN_IMPLICIT_SIZE_OVERRIDE,
N_("invalid displacement size; fixed"));
x86_ea->ea.disp.size = wordsize;
} else
Index: modules/arch/x86/x86arch.h
===================================================================
--- modules/arch/x86/x86arch.h (révision 2128)
+++ modules/arch/x86/x86arch.h (copie de travail)
@@ -82,7 +82,8 @@
unsigned int amd64_machine;
enum {
X86_PARSER_NASM = 0,
- X86_PARSER_GAS = 1
+ X86_PARSER_TASM = 1,
+ X86_PARSER_GAS = 2
} parser;
unsigned int mode_bits;
unsigned int force_strict;
Index: modules/arch/x86/x86bc.c
===================================================================
--- modules/arch/x86/x86bc.c (révision 2128)
+++ modules/arch/x86/x86bc.c (copie de travail)
@@ -76,6 +76,7 @@
x86_bc_insn_destroy,
x86_bc_insn_print,
yasm_bc_finalize_common,
+ NULL,
x86_bc_insn_calc_len,
x86_bc_insn_expand,
x86_bc_insn_tobytes,
@@ -86,6 +87,7 @@
x86_bc_jmp_destroy,
x86_bc_jmp_print,
yasm_bc_finalize_common,
+ NULL,
x86_bc_jmp_calc_len,
x86_bc_jmp_expand,
x86_bc_jmp_tobytes,
@@ -96,6 +98,7 @@
x86_bc_jmpfar_destroy,
x86_bc_jmpfar_print,
yasm_bc_finalize_common,
+ NULL,
x86_bc_jmpfar_calc_len,
yasm_bc_expand_common,
x86_bc_jmpfar_tobytes,
@@ -192,6 +195,7 @@
x86_ea->ea.segreg = 0;
x86_ea->ea.pc_rel = 0;
x86_ea->ea.not_pc_rel = 0;
+ x86_ea->ea.data_len = 0;
x86_ea->modrm = 0;
x86_ea->valid_modrm = 0;
x86_ea->need_modrm = 0;
@@ -254,6 +258,8 @@
*/
x86_ea->need_sib = 0xff;
+ x86_ea->ea.data_len = 0;
+
return (yasm_effaddr *)x86_ea;
}
Index: modules/arch/x86/gen_x86_insn.py
===================================================================
--- modules/arch/x86/gen_x86_insn.py (révision 2128)
+++ modules/arch/x86/gen_x86_insn.py (copie de travail)
@@ -671,7 +671,7 @@
modifiers=["SpAdd", "Op0Add", "Op1Add"],
opcode=[0x00, 0x00],
spare=0,
- operands=[Operand(type="Mem", dest="EA")])
+ operands=[Operand(type="Mem", relaxed=True, dest="EA")])
#
# mov
@@ -1666,7 +1666,7 @@
opersize=sz,
opcode=[0x8D],
operands=[Operand(type="Reg", size=sz, dest="Spare"),
- Operand(type="Mem", size=sz, relaxed=True, dest="EA")])
+ Operand(type="Mem", relaxed=True, dest="EA")])
add_insn("lea", "lea")
@@ -1681,7 +1681,7 @@
opersize=sz,
opcode=[0x00],
operands=[Operand(type="Reg", size=sz, dest="Spare"),
- Operand(type="Mem", dest="EA")])
+ Operand(type="Mem", relaxed=True, dest="EA")])
add_insn("lds", "ldes", modifiers=[0xC5])
add_insn("les", "ldes", modifiers=[0xC4])
@@ -1694,7 +1694,7 @@
opersize=sz,
opcode=[0x0F, 0x00],
operands=[Operand(type="Reg", size=sz, dest="Spare"),
- Operand(type="Mem", dest="EA")])
+ Operand(type="Mem", relaxed=True, dest="EA")])
add_insn("lfs", "lfgss", modifiers=[0xB4])
add_insn("lgs", "lfgss", modifiers=[0xB5])
Index: modules/preprocs/nasm/nasm.h
===================================================================
--- modules/preprocs/nasm/nasm.h (révision 2128)
+++ modules/preprocs/nasm/nasm.h (copie de travail)
@@ -276,5 +276,8 @@
#define elements(x) ( sizeof(x) / sizeof(*(x)) )
extern int tasm_compatible_mode;
+extern int tasm_locals;
+extern const char *tasm_segment;
+const char *tasm_get_segment_register(const char *segment);
#endif
Index: modules/preprocs/nasm/Makefile.inc
===================================================================
--- modules/preprocs/nasm/Makefile.inc (révision 2128)
+++ modules/preprocs/nasm/Makefile.inc (copie de travail)
@@ -9,7 +9,7 @@
libyasm_a_SOURCES += modules/preprocs/nasm/nasm-eval.h
libyasm_a_SOURCES += modules/preprocs/nasm/nasm-eval.c
-YASM_MODULES += preproc_nasm
+YASM_MODULES += preproc_nasm preproc_tasm
$(top_srcdir)/modules/preprocs/nasm/nasm-preproc.c: nasm-version.c
Modification de propriétés sur modules/preprocs/nasm/nasmlib.c
___________________________________________________________________
Ajouté : svn:mergeinfo
Index: modules/preprocs/nasm/nasm-preproc.c
===================================================================
--- modules/preprocs/nasm/nasm-preproc.c (révision 2128)
+++ modules/preprocs/nasm/nasm-preproc.c (copie de travail)
@@ -47,6 +47,8 @@
static yasm_linemap *cur_lm;
static yasm_errwarns *cur_errwarns;
int tasm_compatible_mode = 0;
+int tasm_locals;
+const char *tasm_segment;
#include "nasm-version.c"
@@ -314,3 +316,24 @@
nasm_preproc_define_builtin,
nasm_preproc_add_standard
};
+
+static yasm_preproc *
+tasm_preproc_create(const char *in_filename, yasm_symtab *symtab,
+ yasm_linemap *lm, yasm_errwarns *errwarns)
+{
+ tasm_compatible_mode = 1;
+ return nasm_preproc_create(in_filename, symtab, lm, errwarns);
+}
+
+yasm_preproc_module yasm_tasm_LTX_preproc = {
+ "Real TASM Preprocessor",
+ "tasm",
+ tasm_preproc_create,
+ nasm_preproc_destroy,
+ nasm_preproc_get_line,
+ nasm_preproc_get_included_file,
+ nasm_preproc_add_include_file,
+ nasm_preproc_predefine_macro,
+ nasm_preproc_undefine_macro,
+ nasm_preproc_define_builtin,
+};
Modification de propriétés sur modules/preprocs/nasm/nasmlib.h
___________________________________________________________________
Ajouté : svn:mergeinfo
Index: modules/preprocs/nasm/nasm-pp.c
===================================================================
--- modules/preprocs/nasm/nasm-pp.c (révision 2128)
+++ modules/preprocs/nasm/nasm-pp.c (copie de travail)
@@ -324,7 +324,9 @@
enum
{
TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
- TM_IFNDEF, TM_INCLUDE, TM_LOCAL
+ TM_IFNDEF, TM_INCLUDE, TM_LOCAL,
+ TM_REPT, TM_IRP, TM_MACRO,
+ TM_STRUC, TM_SEGMENT
};
static const char *tasm_directives[] = {
@@ -428,6 +473,7 @@
static Token *new_Token(Token * next, int type, const char *text,
size_t txtlen);
static Token *delete_Token(Token * t);
+static Token *tokenise(char *line);
/*
* Macros for safe checking of token pointers, avoid *(NULL)
@@ -442,69 +488,555 @@
* place to do it for the moment, and it is a hack (ideally it would
* be nice to be able to use the NASM pre-processor to do it).
*/
+
+typedef struct TMEndItem {
+ int type;
+ void *data;
+ struct TMEndItem *next;
+} TMEndItem;
+
+static TMEndItem *EndmStack = NULL, *EndsStack = NULL;
+
+char **TMParameters;
+
+struct TStrucField {
+ char *name;
+ char *type;
+ struct TStrucField *next;
+};
+struct TStruc {
+ char *name;
+ struct TStrucField *fields, *lastField;
+ struct TStruc *next;
+};
+static struct TStruc *TStrucs = NULL;
+static int inTstruc = 0;
+
+struct TSegmentAssume {
+ char *segreg;
+ char *segment;
+};
+struct TSegmentAssume *TAssumes;
+
+const char *tasm_get_segment_register(const char *segment)
+{
+ struct TSegmentAssume *assume;
+ if (!TAssumes)
+ return NULL;
+ for (assume = TAssumes; assume->segreg; assume++) {
+ if (!strcmp(assume->segment, segment))
+ break;
+ }
+ return assume->segreg;
+}
+
static char *
check_tasm_directive(char *line)
{
int i, j, k, m;
- size_t len;
- char *p = line, *oldline, oldchar;
+ size_t len, len2;
+ char *p, *oldline, oldchar, *q, oldchar2;
+ TMEndItem *end;
+ if ((p = strchr(line, ';')))
+ *p = '\0';
+
+ p = line;
+
/* Skip whitespace */
while (isspace(*p) && *p != 0)
p++;
+ /* Ignore nasm directives */
+ if (*p == '%')
+ return line;
+
/* Binary search for the directive name */
- i = -1;
- j = elements(tasm_directives);
len = 0;
while (!isspace(p[len]) && p[len] != 0)
len++;
- if (len)
+ if (!len)
+ return line;
+
+ oldchar = p[len];
+ p[len] = 0;
+ i = -1;
+ j = elements(tasm_directives);
+ while (j - i > 1)
{
- oldchar = p[len];
- p[len] = 0;
- while (j - i > 1)
+ k = (j + i) / 2;
+ m = nasm_stricmp(p, tasm_directives[k]);
+ if (m == 0)
{
- k = (j + i) / 2;
- m = nasm_stricmp(p, tasm_directives[k]);
- if (m == 0)
+ /* We have found a directive, so jam a % in front of it
+ * so that NASM will then recognise it as one if it's own.
+ */
+ p[len] = oldchar;
+ len = strlen(p);
+ oldline = line;
+ if (k == TM_IFDIFI)
{
- /* We have found a directive, so jam a % in front of it
- * so that NASM will then recognise it as one if it's own.
+ /* NASM does not recognise IFDIFI, so we convert it to
+ * %ifdef BOGUS. This is not used in NASM comaptible
+ * code, but does need to parse for the TASM macro
+ * package.
*/
- p[len] = oldchar;
+ line = nasm_malloc(13);
+ strcpy(line, "%ifdef BOGUS");
+ }
+ else if (k == TM_INCLUDE)
+ {
+ /* add double quotes around file name */
+ p += 7 + 1;
+ while (isspace(*p) && *p)
+ p++;
len = strlen(p);
- oldline = line;
+ line = nasm_malloc(1 + 7 + 1 + 1 + len + 1 + 1);
+ sprintf(line, "%%include \"%s\"", p);
+ }
+ else
+ {
line = nasm_malloc(len + 2);
line[0] = '%';
- if (k == TM_IFDIFI)
- {
- /* NASM does not recognise IFDIFI, so we convert it to
- * %ifdef BOGUS. This is not used in NASM comaptible
- * code, but does need to parse for the TASM macro
- * package.
- */
- strcpy(line + 1, "ifdef BOGUS");
+ memcpy(line + 1, p, len + 1);
+ }
+ nasm_free(oldline);
+ return line;
+ }
+ else if (m < 0)
+ {
+ j = k;
+ }
+ else
+ i = k;
+ }
+
+ /* Not a simple directive */
+
+ if (!nasm_stricmp(p, "endm")) {
+ /* handle end of endm directive */
+ char **parameter;
+ end = EndmStack;
+ /* undef parameters */
+ if (!end) {
+ error(ERR_FATAL, "ENDM: not in an endm context");
+ return line;
+ }
+ EndmStack = EndmStack->next;
+ nasm_free(line);
+ switch (end->type) {
+ case TM_MACRO:
+ len = 0;
+ for (parameter = end->data; *parameter; parameter++)
+ len += 6 + 1 + strlen(*parameter) + 1;
+ len += 5 + 1;
+ line = nasm_malloc(len);
+ p = line;
+ for (parameter = end->data; *parameter; parameter++) {
+ p += sprintf(p, "%%undef %s\n", *parameter);
+ nasm_free(*parameter);
+ }
+ nasm_free(end->data);
+ nasm_free(end);
+ sprintf(p, "%%endm");
+ return line;
+ case TM_REPT:
+ nasm_free(end);
+ return nasm_strdup("%endrep");
+ case TM_IRP: {
+ char **data;
+ const char *irp_format =
+ "%%undef %s\n"
+ "%%rotate 1\n"
+ "%%endrep\n"
+ "%%endm\n"
+ "irp %s\n"
+ "%%undef irp";
+ data = end->data;
+ line = nasm_malloc(strlen(irp_format) - 4 + strlen(data[0])
+ + strlen(data[1]));
+ sprintf(line, irp_format, data[0], data[1]);
+ nasm_free(data[0]);
+ nasm_free(data[1]);
+ nasm_free(data);
+ return line;
+ }
+ default:
+ error(ERR_FATAL, "ENDM: bogus endm context type %d\n",end->type);
+ return NULL;
+ }
+ } else if (!nasm_stricmp(p, "end")) {
+ nasm_free(line);
+ return strdup("");
+ } else if (!nasm_stricmp(p, "rept")) {
+ /* handle repeat directive */
+ end = nasm_malloc(sizeof(*end));
+ end->type = TM_REPT;
+ end->next = EndmStack;
+ EndmStack = end;
+ memcpy(p, "%rep", 4);
+ p[len] = oldchar;
+ return line;
+ } else if (!nasm_stricmp(p, "locals")) {
+ tasm_locals = 1;
+ nasm_free(line);
+ return strdup("");
+ }
+
+ if (!oldchar)
+ return line;
+
+ /* handle two-words directives */
+ q = p + len + 1;
+ /* Skip whitespaces */
+ while (isspace(*q) && *q)
+ q++;
+
+ len2 = 0;
+ while (!isspace(q[len2]) && q[len2]!=',' && q[len2] != 0)
+ len2++;
+ oldchar2 = q[len2];
+ q[len2] = '\0';
+
+ if (!nasm_stricmp(p, "irp")) {
+ /* handle indefinite repeat directive */
+ const char *irp_format =
+ "%%imacro irp 0-*\n"
+ "%%rep %%0\n"
+ "%%define %s %%1\n";
+ char **data;
+
+ data = malloc(2*sizeof(char*));
+ oldline = line;
+ line = nasm_malloc(strlen(irp_format) - 2 + len2 + 1);
+ sprintf(line,irp_format,q);
+ data[0] = nasm_strdup(q);
+
+ if (!oldchar2)
+ error(ERR_FATAL, "%s: expected <values>", q + len2);
+ p = strchr(q + len2 + 1, '<');
+ if (!p)
+ error(ERR_FATAL, "%s: expected <values>", q + len2);
+ p++;
+ q = strchr(p, '>');
+ data[1] = nasm_strndup(p, q - p);
+
+ end = nasm_malloc(sizeof(*end));
+ end->type = TM_IRP;
+ end->next = EndmStack;
+ end->data = data;
+ EndmStack = end;
+
+ nasm_free(oldline);
+ return line;
+ } else if (!nasm_stricmp(q, "macro")) {
+ char *name = p;
+ /* handle MACRO */
+ /* count parameters */
+ j = 1;
+ i = 0;
+ TMParameters = nasm_malloc(j*sizeof(*TMParameters));
+ len = 0;
+ p = q + len2 + 1;
+ /* Skip whitespaces */
+ while (isspace(*p) && *p)
+ p++;
+ while (*p) {
+ /* Get parameter name */
+ for (q = p; !isspace(*q) && *q != ',' && *q; q++);
+ len2 = q-p;
+ if (len2 == 0)
+ error(ERR_FATAL, "'%s': expected parameter name", p);
+ TMParameters[i] = nasm_malloc(len2 + 1);
+ memcpy(TMParameters[i], p, len2);
+ TMParameters[i][len2] = '\0';
+ len += len2;
+ i++;
+ if (i + 1 > j) {
+ j *= 2;
+ TMParameters = nasm_realloc(TMParameters,
+ j*sizeof(*TMParameters));
+ }
+ if (i == 1000)
+ error(ERR_FATAL, "too many parameters for macro %s", name);
+ p = q;
+ while (isspace(*p) && *p)
+ p++;
+ if (!*p)
+ break;
+ if (*p != ',')
+ error(ERR_FATAL, "expected comma");
+ p++;
+ while (isspace(*p) && *p)
+ p++;
+ }
+ TMParameters[i] = NULL;
+ TMParameters = nasm_realloc(TMParameters,
+ (i+1)*sizeof(*TMParameters));
+ len += 1 + 6 + 1 + strlen(name) + 1 + 3; /* macro definition */
+ len += i * (1 + 9 + 1 + 1 + 1 + 3 + 2); /* macro parameter definition */
+ oldline = line;
+ p = line = nasm_malloc(len + 1);
+ p += sprintf(p, "%%imacro %s 0-*", name);
+ nasm_free(oldline);
+ for (j = 0; TMParameters[j]; j++) {
+ p += sprintf(p, "\n%%idefine %s %%{%-u}", TMParameters[j], j + 1);
+ }
+ end = nasm_malloc(sizeof(*end));
+ end->type = TM_MACRO;
+ end->next = EndmStack;
+ end->data = TMParameters;
+ EndmStack = end;
+ return line;
+ } else if (!nasm_stricmp(q, "proc")) {
+ /* handle PROC */
+ oldline = line;
+ line = nasm_malloc(2 + len + 1);
+ sprintf(line, "..%s",p);
+ nasm_free(oldline);
+ return line;
+ } else if (!nasm_stricmp(q, "struc")) {
+ /* handle struc */
+ struct TStruc *struc;
+ if (inTstruc) {
+ error(ERR_FATAL, "STRUC: already in a struc context");
+ return line;
+ }
+ oldline = line;
+ line = nasm_malloc(5 + 1 + len + 1);
+ sprintf(line, "struc %s", p);
+ struc = malloc(sizeof(*struc));
+ struc->name = strdup(p);
+ struc->fields = NULL;
+ struc->lastField = NULL;
+ struc->next = TStrucs;
+ TStrucs = struc;
+ inTstruc = 1;
+ nasm_free(oldline);
+ end = nasm_malloc(sizeof(*end));
+ end->type = TM_STRUC;
+ end->next = EndsStack;
+ EndsStack = end;
+ return line;
+ } else if (!nasm_stricmp(q, "segment")) {
+ /* handle SEGMENT */
+ oldline = line;
+ line = strdup(oldchar2?q+len2+1:"");
+ if (tasm_segment) {
+ error(ERR_FATAL, "SEGMENT: already in a segment context");
+ return line;
+ }
+ tasm_segment = strdup(p);
+ nasm_free(oldline);
+ end = nasm_malloc(sizeof(*end));
+ end->type = TM_SEGMENT;
+ end->next = EndsStack;
+ EndsStack = end;
+ return line;
+ } else if (!nasm_stricmp(p, "ends") || !nasm_stricmp(q, "ends")) {
+ /* handle end of ends directive */
+ end = EndsStack;
+ /* undef parameters */
+ if (!end) {
+ error(ERR_FATAL, "ENDS: not in an ends context");
+ return line;
+ }
+ EndsStack = EndsStack->next;
+ nasm_free(line);
+ switch (end->type) {
+ case TM_STRUC:
+ inTstruc = 0;
+ return strdup("endstruc");
+ case TM_SEGMENT:
+ /* XXX: yes, we leak memory here, but that permits labels
+ * to avoid strduping... */
+ tasm_segment = NULL;
+ return strdup("");
+ default:
+ error(ERR_FATAL, "ENDS: bogus ends context type %d",end->type);
+ return NULL;
+ }
+ } else if (!nasm_stricmp(p, "endp") || !nasm_stricmp(q, "endp")) {
+ nasm_free(line);
+ return strdup("");
+ } else if (!nasm_stricmp(p, "assume")) {
+ struct TSegmentAssume *assume;
+ /* handle ASSUME */
+ if (!TAssumes) {
+ TAssumes = nasm_malloc(sizeof(*TAssumes));
+ TAssumes[0].segreg = NULL;
+ }
+ i = 0;
+ q[len2] = oldchar2;
+ /* Skip whitespaces */
+ while (isspace(*q) && *q)
+ q++;
+ while (*q) {
+ p = q;
+ for (; *q && *q != ':' && !isspace(*q); q++);
+ if (!*q)
+ break;
+ /* segment register name */
+ for (assume = TAssumes; assume->segreg; assume++)
+ if (strlen(assume->segreg) == (size_t)(q-p) &&
+ !strncasecmp(assume->segreg, p, q-p))
+ break;
+ if (!assume->segreg) {
+ i = assume - TAssumes + 1;
+ TAssumes = nasm_realloc(TAssumes, (i+1)*sizeof(*TAssumes));
+ assume = TAssumes + i - 1;
+ assume->segreg = nasm_strndup(p, q-p);
+ assume[1].segreg = NULL;
+ }
+ for (; *q && *q != ':' && isspace(*q); q++);
+ if (*q != ':')
+ error(ERR_FATAL, "expected `:' instead of `%c'", *q);
+ for (q++; *q && isspace(*q); q++);
+
+ /* segment name */
+ p = q;
+ for (; *q && *q != ',' && !isspace(*q); q++);
+ assume->segment = nasm_strndup(p, q-p);
+ for (; *q && isspace(*q); q++);
+ if (*q && *q != ',')
+ error(ERR_FATAL, "expected `,' instead of `%c'", *q);
+
+ for (q++; *q && isspace(*q); q++);
+ }
+ TAssumes[i].segreg = NULL;
+ TAssumes = nasm_realloc(TAssumes, (i+1)*sizeof(*TAssumes));
+ nasm_free(line);
+ return strdup("");
+ } else if (inTstruc) {
+ struct TStrucField *field;
+ /* TODO: handle unnamed data */
+ field = nasm_malloc(sizeof(*field));
+ field->name = strdup(p);
+ /* TODO: type struc ! */
+ field->type = strdup(q);
+ field->next = NULL;
+ if (!TStrucs->fields)
+ TStrucs->fields = field;
+ else if (TStrucs->lastField)
+ TStrucs->lastField->next = field;
+ TStrucs->lastField = field;
+ if (!oldchar2) {
+ error(ERR_FATAL, "Expected struc field initializer after %s %s", p, q);
+ return line;
+ }
+ oldline = line;
+ line = nasm_malloc(1 + len + 1 + len2 + 1 + strlen(q+len2+1) + 1);
+ sprintf(line, ".%s %s %s", p, q, q+len2+1);
+ nasm_free(oldline);
+ return line;
+ }
+ {
+ struct TStruc *struc;
+ for (struc = TStrucs; struc; struc = struc->next) {
+ if (!strcasecmp(q, struc->name)) {
+ char *r = q + len2 + 1, *s, *t, tasm_param[6];
+ struct TStrucField *field = struc->fields;
+ int size, n;
+ if (!oldchar2) {
+ error(ERR_FATAL, "Expected struc field initializer after %s %s", p, q);
+ return line;
}
- else
- {
- memcpy(line + 1, p, len + 1);
+ r = strchr(r, '<');
+ if (!r) {
+ error(ERR_FATAL, "Expected < for struc field initializer in %s %s %s", p, q, r);
+ return line;
}
+ t = strchr(r + 1, '>');
+ if (!t) {
+ error(ERR_FATAL, "Expected > for struc field initializer in %s %s %s", p, q, r);
+ return line;
+ }
+ *t = 0;
+ oldline = line;
+ size = len + len2 + 128;
+ line = nasm_malloc(size);
+ if (defining)
+ for (n=0;TMParameters[n];n++)
+ if (!strcmp(TMParameters[n],p)) {
+ sprintf(tasm_param,"%%{%d}",n+1);
+ p = tasm_param;
+ break;
+ }
+ n = sprintf(line, "%s: istruc %s\n", p, q);
+ /* use initialisers */
+ while ((s = strchr(r + 1, ','))) {
+ if (!field) {
+ error(ERR_FATAL, "Too many initializers in structure %s %s", p, q);
+ return oldline;
+ }
+ *s = 0;
+ while (1) {
+ m = snprintf(line + n, size - n, "%s.%s: at .%s, %s %s\n", p, field->name, field->name, field->type, r + 1);
+ if (m + 1 <= size - n)
+ break;
+ size *= 2;
+ line = nasm_realloc(line, size);
+ }
+ n += m;
+ r = s;
+ field = field->next;
+ }
+ /* complete with last initializer and '?' */
+ while(field) {
+ while (1) {
+ m = snprintf(line + n, size - n, "%s.%s: at .%s, %s %s\n", p, field->name, field->name, field->type, r ? r + 1: "?");
+ if (m + 1 <= size - n)
+ break;
+ size *= 2;
+ line = nasm_realloc(line, size);
+ }
+ n += m;
+ r = NULL;
+ field = field->next;
+ }
+ line = nasm_realloc(line, n + 5);
+ sprintf(line + n, "iend");
nasm_free(oldline);
return line;
}
- else if (m < 0)
- {
- j = k;
- }
- else
- i = k;
}
- p[len] = oldchar;
}
+
+ q[len2] = oldchar2;
+ p[len] = oldchar;
+
return line;
}
+static Token * tasm_join_tokens(Token *tline)
+{
+ Token *t, *prev, *next;
+ for (prev = NULL, t = tline; t; prev = t, t = next) {
+ next = t->next;
+ if (t->type == TOK_OTHER && !strcmp(t->text,"&")) {
+ if (!prev)
+ error(ERR_FATAL, "no token before &");
+ else if (!next)
+ error(ERR_FATAL, "no token after &");
+ else if (prev->type != next->type)
+ error(ERR_FATAL, "can't handle different types of token around &");
+ else if (!prev->text || !next->text)
+ error(ERR_FATAL, "can't handle empty token around &");
+ else {
+ int lenp = strlen(prev->text);
+ int lenn = strlen(next->text);
+ prev->text = nasm_realloc(prev->text, lenp + lenn + 1);
+ strncpy(prev->text + lenp, next->text, lenn + 1);
+ (void) delete_Token(t);
+ prev->next = delete_Token(next);
+ t = prev;
+ next = t->next;
+ }
+ }
+ }
+ return tline;
+}
+
/*
* The pre-preprocessing stage... This function translates line
* number indications as they emerge from GNU cpp (`# lineno "file"
@@ -517,6 +1049,8 @@
int lineno;
size_t fnlen;
char *fname, *oldline;
+ char *c, *d, *ret;
+ Line *l, **lp;
if (line[0] == '#' && line[1] == ' ')
{
@@ -532,8 +1066,30 @@
nasm_free(oldline);
}
if (tasm_compatible_mode)
- return check_tasm_directive(line);
- return line;
+ line = check_tasm_directive(line);
+
+ if (!(c = strchr(line, '\n')))
+ return line;
+
+ /* Turn multiline macros into several lines */
+ *c = '\0';
+ ret = nasm_strdup(line);
+
+ lp = &istk->expansion;
+ do {
+ d = strchr(c+1, '\n');
+ if (d)
+ *d = '\0';
+ l = malloc(sizeof(*l));
+ l -> first = tokenise(c+1);
+ l -> finishes = NULL;
+ l -> next = *lp;
+ *lp = l;
+ c = d;
+ lp = &l -> next;
+ } while (c);
+ nasm_free(line);
+ return ret;
}
/*
@@ -1231,7 +1787,7 @@
inc_fopen(char *file, char **newname)
{
FILE *fp;
- char *combine = NULL;
+ char *combine = NULL, *c;
char *pb, *p1, *p2, *file2 = NULL;
/* Try to expand all %ENVVAR% in filename. Warn, and leave %string%
@@ -1281,6 +1837,27 @@
fp = yasm_fopen_include(file2 ? file2 : file, nasm_src_get_fname(), "r",
&combine);
+ if (!fp && tasm_compatible_mode)
+ {
+ char *thefile = file2 ? file2 : file;
+ /* try a few case combinations */
+ do {
+ for (c = thefile; *c; c++)
+ *c = toupper(*c);
+ fp = yasm_fopen_include(thefile, nasm_src_get_fname(), "r", &combine);
+ if (fp) break;
+ *thefile = tolower(*thefile);
+ fp = yasm_fopen_include(thefile, nasm_src_get_fname(), "r", &combine);
+ if (fp) break;
+ for (c = thefile; *c; c++)
+ *c = tolower(*c);
+ fp = yasm_fopen_include(thefile, nasm_src_get_fname(), "r", &combine);
+ if (fp) break;
+ *thefile = toupper(*thefile);
+ fp = yasm_fopen_include(thefile, nasm_src_get_fname(), "r", &combine);
+ if (fp) break;
+ } while (0);
+ }
if (!fp)
error(ERR_FATAL, "unable to open include file `%s'",
file2 ? file2 : file);
@@ -4420,6 +4997,9 @@
/*
* De-tokenise the line again, and emit it.
*/
+ if (tasm_compatible_mode)
+ tline = tasm_join_tokens(tline);
+
line = detoken(tline, TRUE);
free_tlist(tline);
break;
Index: frontends/tasm/tasm-options.h
===================================================================
--- frontends/tasm/tasm-options.h (révision 0)
+++ frontends/tasm/tasm-options.h (révision 0)
@@ -0,0 +1,69 @@
+/* $Id: tasm-options.h 1137 2004-09-04 01:24:57Z peter $
+ * Generic Options Support Header File
+ *
+ * Copyright (c) 2001 Stanislav Karchebny <berk@madfire.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TASM_OPTIONS_H
+#define TASM_OPTIONS_H
+
+/* an option structure
+ * operate on either -sopt, --lopt, -sopt <val> or --lopt=<val>
+ */
+typedef struct opt_option_s
+{
+ /* option */
+ const char *opt;
+
+ /* !=0 if option requires parameter, 0 if not */
+ int takes_param;
+
+ int (*handler) (char *cmd, /*@null@*/ char *param, int extra);
+ int extra; /* extra value for handler */
+
+ /* description to use in help_msg() */
+ /*@observer@*/ const char *description;
+
+ /* optional description for the param taken (NULL if not present) */
+ /* (short - will be printed after option sopt/lopt) */
+ /*@observer@*/ /*@null@*/ const char *param_desc;
+} opt_option;
+
+/* handle everything that is not an option */
+int not_an_option_handler(char *param);
+
+/* parse command line calling handlers when appropriate
+ * argc, argv - pass directly from main(argc,argv)
+ * options - array of options
+ * nopts - options count
+ */
+int parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts,
+ void (*print_error) (const char *fmt, ...));
+
+/* display help message msg followed by list of options in options and followed
+ * by tail
+ */
+void help_msg(const char *msg, const char *tail, opt_option *options,
+ size_t nopts);
+
+#endif
Index: frontends/tasm/Makefile.inc
===================================================================
--- frontends/tasm/Makefile.inc (révision 0)
+++ frontends/tasm/Makefile.inc (révision 0)
@@ -0,0 +1,9 @@
+# $Id: Makefile.inc 1463 2006-04-05 05:39:23Z peter $
+
+bin_PROGRAMS += tasm
+
+tasm_SOURCES = frontends/tasm/tasm.c
+tasm_SOURCES += frontends/tasm/tasm-options.c
+tasm_SOURCES += frontends/tasm/tasm-options.h
+
+tasm_LDADD = libyasm.a $(INTLLIBS)
Index: frontends/tasm/tasm.c
===================================================================
--- frontends/tasm/tasm.c (révision 0)
+++ frontends/tasm/tasm.c (révision 0)
@@ -0,0 +1,1003 @@
+/*
+ * Program entry point, command line parsing
+ *
+ * Copyright (C) 2001-2008 Peter Johnson
+ * Copyright (C) 2007-2008 Samuel Thibault
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <util.h>
+/*@unused@*/ RCSID("$Id: tasm.c 1523 2006-05-06 16:11:56Z peter $");
+
+#include <ctype.h>
+#include <unistd.h>
+#include <libyasm/compat-queue.h>
+#include <libyasm/bitvect.h>
+#include <libyasm.h>
+
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+
+#include "tasm-options.h"
+
+#ifdef CMAKE_BUILD
+#include "yasm-plugin.h"
+#endif
+
+#include "license.c"
+
+#define DEFAULT_OBJFMT_MODULE "bin"
+
+/*@null@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL;
+/*@null@*/ /*@only@*/ static char *list_filename = NULL, *xref_filename = NULL;
+/*@null@*/ /*@only@*/ static char *machine_name = NULL;
+static int special_options = 0;
+static int segment_ordering = 0;
+static int cross_reference = 0;
+static int floating_point = 0;
+static int listing = 0;
+static int expanded_listing = 0;
+static int case_sensitivity = 0;
+static int valid_length = -1;
+/*@null@*/ /*@dependent@*/ static yasm_arch *cur_arch = NULL;
+/*@null@*/ /*@dependent@*/ static const yasm_arch_module *
+ cur_arch_module = NULL;
+/*@null@*/ /*@dependent@*/ static const yasm_parser_module *
+ cur_parser_module = NULL;
+/*@null@*/ /*@dependent@*/ static yasm_preproc *cur_preproc = NULL;
+/*@null@*/ /*@dependent@*/ static const yasm_preproc_module *
+ cur_preproc_module = NULL;
+/*@null@*/ static char *objfmt_keyword = NULL;
+/*@null@*/ /*@dependent@*/ static const yasm_objfmt_module *
+ cur_objfmt_module = NULL;
+/*@null@*/ /*@dependent@*/ static const yasm_dbgfmt_module *
+ cur_dbgfmt_module = NULL;
+/*@null@*/ /*@dependent@*/ static yasm_listfmt *cur_listfmt = NULL;
+/*@null@*/ /*@dependent@*/ static const yasm_listfmt_module *
+ cur_listfmt_module = NULL;
+static int warning_error = 0; /* warnings being treated as errors */
+static FILE *errfile;
+/*@null@*/ /*@only@*/ static char *error_filename = NULL;
+
+/*@null@*/ /*@dependent@*/ static FILE *open_file(const char *filename,
+ const char *mode);
+static void check_errors(/*@only@*/ yasm_errwarns *errwarns,
+ /*@only@*/ yasm_object *object,
+ /*@only@*/ yasm_linemap *linemap);
+static void cleanup(/*@null@*/ /*@only@*/ yasm_object *object);
+
+/* Forward declarations: cmd line parser handlers */
+static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_segment_ordering_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_cross_reference_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_floating_point_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_ignore(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_listing_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_case_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_valid_length_handler(char *cmd, /*@null@*/ char *param, int extra);
+
+static int opt_warning_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_preproc_option(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_exe_handler(char *cmd, /*@null@*/ char *param, int extra);
+
+static /*@only@*/ char *replace_extension(const char *orig, /*@null@*/
+ const char *ext, const char *def);
+static void print_error(const char *fmt, ...);
+
+static /*@exits@*/ void handle_yasm_int_error(const char *file,
+ unsigned int line,
+ const char *message);
+static /*@exits@*/ void handle_yasm_fatal(const char *message, va_list va);
+static const char *handle_yasm_gettext(const char *msgid);
+static void print_yasm_error(const char *filename, unsigned long line,
+ const char *msg, /*@null@*/ const char *xref_fn,
+ unsigned long xref_line,
+ /*@null@*/ const char *xref_msg);
+static void print_yasm_warning(const char *filename, unsigned long line,
+ const char *msg);
+
+static void apply_preproc_builtins(void);
+static void apply_preproc_standard_macros(const yasm_stdmac *stdmacs);
+static void apply_preproc_saved_options(void);
+static void print_list_keyword_desc(const char *name, const char *keyword);
+
+/* values for special_options */
+#define SPECIAL_SHOW_HELP 0x01
+#define SPECIAL_SHOW_VERSION 0x02
+#define SPECIAL_SHOW_LICENSE 0x04
+
+#define SEGMENT_ORDERING_ALPHABETIC 0x01
+#define SEGMENT_ORDERING_SOURCE 0x02
+
+#define FP_EMULATED 0x01
+#define FP_REAL 0x02
+
+#define CASE_ALL 0x01
+#define CASE_GLOBALS 0x02
+#define CASE_NONE 0x04
+
+#define DEBUG_FULL 0x01
+#define DEBUG_LINES 0x02
+#define DEBUG_NONE 0x04
+
+/* command line options */
+static opt_option options[] =
+{
+ { "version", 0, opt_special_handler, SPECIAL_SHOW_VERSION,
+ N_("show version text"), NULL },
+ { "license", 0, opt_special_handler, SPECIAL_SHOW_LICENSE,
+ N_("show license text"), NULL },
+ { "a", 0, opt_segment_ordering_handler, SEGMENT_ORDERING_ALPHABETIC,
+ N_("Alphabetic segment ordering"), NULL },
+ { "s", 0, opt_segment_ordering_handler, SEGMENT_ORDERING_SOURCE,
+ N_("Source segment ordering"), NULL },
+
+ { "c", 0, opt_cross_reference_handler, 0,
+ N_("Generate cross-reference in listing"), NULL },
+
+ { "d", 1, opt_preproc_option, 2,
+ N_("pre-define a macro, optionally to value"), N_("macro[=value]") },
+
+ { "e", 0, opt_floating_point_handler, FP_EMULATED,
+ N_("Emulated floating-point instructions (not supported)"), NULL },
+ { "r", 0, opt_floating_point_handler, FP_REAL,
+ N_("Real floating-point instructions"), NULL },
+
+ { "h", 0, opt_special_handler, SPECIAL_SHOW_HELP,
+ N_("show help text"), NULL },
+ { "?", 0, opt_special_handler, SPECIAL_SHOW_HELP,
+ N_("show help text"), NULL },
+
+ { "i", 1, opt_preproc_option, 0,
+ N_("add include path"), N_("path") },
+
+ { "j", 1, opt_ignore, 0,
+ N_("Jam in an assemble directive CMD (eg. /jIDEAL) (not supported)"), NULL },
+
+ { "k", 1, opt_ignore, 0,
+ N_("Hash table capacity (ignored)"), N_("# symbols") },
+
+ { "l", 0, opt_listing_handler, 0,
+ N_("Generate listing"), N_("l=normal listing, la=expanded listing") },
+
+ { "ml", 0, opt_case_handler, CASE_ALL,
+ N_("Case sensitivity on all symbols"), NULL },
+ { "mx", 0, opt_case_handler, CASE_GLOBALS,
+ N_("Case sensitivity on global symbols"), NULL },
+ { "mu", 0, opt_case_handler, CASE_NONE,
+ N_("No case sensitivity on symbols"), NULL },
+ { "mv", 0, opt_valid_length_handler, 0,
+ N_("Set maximum valid length for symbols"), N_("length") },
+
+ { "m", 1, opt_ignore, 0,
+ N_("Allow multiple passes to resolve forward reference (ignored)"), N_("number of passes") },
+
+ { "n", 0, opt_ignore, 0,
+ N_("Suppress symbol tables in listing"), NULL },
+
+ { "o", 0, opt_ignore, 0,
+ N_("Object code"), N_("os: standard, o: standard w/overlays, op: Phar Lap, oi: IBM") },
+
+ { "p", 0, opt_ignore, 0,
+ N_("Check for code segment overrides in protected mode"), NULL },
+ { "q", 0, opt_ignore, 0,
+ N_("Suppress OBJ records not needed for linking (ignored)"), NULL },
+ { "t", 0, opt_ignore, 0,
+ N_("Suppress messages if successful assembly"), NULL },
+ { "u", 0, opt_ignore, 0,
+ N_("Set version emulation"), N_("Version") },
+ { "w", 1, opt_warning_handler, 0,
+ N_("Set warning level"), N_("w0=none, w1=w2=warnings on, w-xxx/w+xxx=disable/enable warning xxx") },
+ { "x", 0, opt_ignore, 0,
+ N_("Include false conditionals in listing"), NULL },
+ { "zi", 0, opt_ignore, DEBUG_FULL,
+ N_("Full debug info"), NULL },
+ { "zd", 0, opt_ignore, DEBUG_LINES,
+ N_("Line numbers debug info"), NULL },
+ { "zn", 0, opt_ignore, DEBUG_NONE,
+ N_("No debug info"), NULL },
+ { "z", 0, opt_ignore, 0,
+ N_("Display source line with error message (ignored)"), NULL },
+
+ { "b", 0, opt_exe_handler, 0,
+ N_("Build a (very) basic .exe file"), NULL },
+};
+
+/* version message */
+/*@observer@*/ static const char *version_msg[] = {
+ PACKAGE_NAME " " PACKAGE_INTVER "." PACKAGE_BUILD,
+ "Compiled on " __DATE__ ".",
+ "Copyright (c) 2001-2008 Peter Johnson and other Yasm developers.",
+ "Run yasm --license for licensing overview and summary."
+};
+
+/* help messages */
+/*@observer@*/ static const char *help_head = N_(
+ "usage: tasm [option]* source [,object] [,listing] [,xref] \n"
+ "Options:\n");
+/*@observer@*/ static const char *help_tail = N_(
+ "\n"
+ "source is asm source to be assembled.\n"
+ "\n"
+ "Sample invocation:\n"
+ " tasm /zi source.asm\n"
+ "\n"
+ "Report bugs to bug-yasm@tortall.net\n");
+
+/* parsed command line storage until appropriate modules have been loaded */
+typedef STAILQ_HEAD(constcharparam_head, constcharparam) constcharparam_head;
+
+typedef struct constcharparam {
+ STAILQ_ENTRY(constcharparam) link;
+ const char *param;
+ int id;
+} constcharparam;
+
+static constcharparam_head preproc_options;
+
+static int
+do_assemble(void)
+{
+ yasm_object *object;
+ const char *base_filename;
+ /*@null@*/ FILE *obj = NULL;
+ yasm_arch_create_error arch_error;
+ yasm_linemap *linemap;
+ yasm_errwarns *errwarns = yasm_errwarns_create();
+ int i, matched;
+
+ /* Initialize line map */
+ linemap = yasm_linemap_create();
+ yasm_linemap_set(linemap, in_filename, 1, 1);
+
+ /* determine the object filename if not specified */
+ if (!obj_filename) {
+ if (in_filename == NULL)
+ /* Default to yasm.out if no obj filename specified */
+ obj_filename = yasm__xstrdup("yasm.out");
+ else {
+ /* replace (or add) extension to base filename */
+ yasm__splitpath(in_filename, &base_filename);
+ if (base_filename[0] == '\0')
+ obj_filename = yasm__xstrdup("yasm.out");
+ else
+ obj_filename = replace_extension(base_filename,
+ "obj",
+ "yasm.out");
+ }
+ }
+
+ cur_arch = yasm_arch_create(cur_arch_module, machine_name,
+ cur_parser_module->keyword, &arch_error);
+ if (!cur_arch) {
+ switch (arch_error) {
+ case YASM_ARCH_CREATE_BAD_MACHINE:
+ print_error(_("%s: `%s' is not a valid %s for %s `%s'"),
+ _("FATAL"), machine_name, _("machine"),
+ _("architecture"), cur_arch_module->keyword);
+ break;
+ case YASM_ARCH_CREATE_BAD_PARSER:
+ print_error(_("%s: `%s' is not a valid %s for %s `%s'"),
+ _("FATAL"), cur_parser_module->keyword,
+ _("parser"), _("architecture"),
+ cur_arch_module->keyword);
+ break;
+ default:
+ print_error(_("%s: unknown architecture error"), _("FATAL"));
+ }
+
+ return EXIT_FAILURE;
+ }
+
+ /* Create object */
+ object = yasm_object_create(in_filename, obj_filename, cur_arch,
+ cur_objfmt_module, cur_dbgfmt_module);
+ if (!object) {
+ yasm_error_class eclass;
+ unsigned long xrefline;
+ /*@only@*/ /*@null@*/ char *estr, *xrefstr;
+
+ yasm_error_fetch(&eclass, &estr, &xrefline, &xrefstr);
+ print_error("%s: %s", _("FATAL"), estr);
+ yasm_xfree(estr);
+ yasm_xfree(xrefstr);
+
+ cleanup(object);
+ return EXIT_FAILURE;
+ }
+
+ /* Get a fresh copy of objfmt_module as it may have changed. */
+ cur_objfmt_module = ((yasm_objfmt_base *)object->objfmt)->module;
+
+ /* Check to see if the requested preprocessor is in the allowed list
+ * for the active parser.
+ */
+ matched = 0;
+ for (i=0; cur_parser_module->preproc_keywords[i]; i++)
+ if (yasm__strcasecmp(cur_parser_module->preproc_keywords[i],
+ cur_preproc_module->keyword) == 0)
+ matched = 1;
+ if (!matched) {
+ print_error(_("%s: `%s' is not a valid %s for %s `%s'"), _("FATAL"),
+ cur_preproc_module->keyword, _("preprocessor"),
+ _("parser"), cur_parser_module->keyword);
+ cleanup(object);
+ return EXIT_FAILURE;
+ }
+
+ cur_preproc = yasm_preproc_create(cur_preproc_module, in_filename,
+ object->symtab, linemap, errwarns);
+
+ apply_preproc_builtins();
+ apply_preproc_standard_macros(cur_parser_module->stdmacs);
+ apply_preproc_standard_macros(cur_objfmt_module->stdmacs);
+ apply_preproc_saved_options();
+
+ /* Get initial x86 BITS setting from object format */
+ if (strcmp(cur_arch_module->keyword, "x86") == 0) {
+ yasm_arch_set_var(cur_arch, "mode_bits",
+ cur_objfmt_module->default_x86_mode_bits);
+ }
+
+ /* Parse! */
+ cur_parser_module->do_parse(object, cur_preproc, list_filename != NULL,
+ linemap, errwarns);
+
+ check_errors(errwarns, object, linemap);
+
+ /* Finalize parse */
+ yasm_object_finalize(object, errwarns);
+ check_errors(errwarns, object, linemap);
+
+ /* Optimize */
+ yasm_object_optimize(object, errwarns);
+ check_errors(errwarns, object, linemap);
+
+ /* generate any debugging information */
+ yasm_dbgfmt_generate(object, linemap, errwarns);
+ check_errors(errwarns, object, linemap);
+
+ /* open the object file for output (if not already opened by dbg objfmt) */
+ if (!obj && strcmp(cur_objfmt_module->keyword, "dbg") != 0) {
+ obj = open_file(obj_filename, "wb");
+ if (!obj) {
+ cleanup(object);
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* Write the object file */
+ yasm_objfmt_output(object, obj?obj:stderr,
+ strcmp(cur_dbgfmt_module->keyword, "null"), errwarns);
+
+ /* Close object file */
+ if (obj)
+ fclose(obj);
+
+ /* If we had an error at this point, we also need to delete the output
+ * object file (to make sure it's not left newer than the source).
+ */
+ if (yasm_errwarns_num_errors(errwarns, warning_error) > 0)
+ remove(obj_filename);
+ check_errors(errwarns, object, linemap);
+
+ /* Open and write the list file */
+ if (list_filename) {
+ FILE *list = open_file(list_filename, "wt");
+ if (!list) {
+ cleanup(object);
+ return EXIT_FAILURE;
+ }
+ /* Initialize the list format */
+ cur_listfmt = yasm_listfmt_create(cur_listfmt_module, in_filename,
+ obj_filename);
+ yasm_listfmt_output(cur_listfmt, list, linemap, cur_arch);
+ fclose(list);
+ }
+
+ yasm_errwarns_output_all(errwarns, linemap, warning_error,
+ print_yasm_error, print_yasm_warning);
+
+ yasm_linemap_destroy(linemap);
+ yasm_errwarns_destroy(errwarns);
+ cleanup(object);
+ return EXIT_SUCCESS;
+}
+
+/* main function */
+/*@-globstate -unrecog@*/
+int
+main(int argc, char *argv[])
+{
+ size_t i;
+
+ errfile = stderr;
+
+#if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES)
+ setlocale(LC_MESSAGES, "");
+#endif
+#if defined(LOCALEDIR)
+ bindtextdomain(PACKAGE, LOCALEDIR);
+#endif
+ textdomain(PACKAGE);
+
+ /* Initialize errwarn handling */
+ yasm_internal_error_ = handle_yasm_int_error;
+ yasm_fatal = handle_yasm_fatal;
+ yasm_gettext_hook = handle_yasm_gettext;
+ yasm_errwarn_initialize();
+
+ /* Initialize BitVector (needed for intnum/floatnum). */
+ if (BitVector_Boot() != ErrCode_Ok) {
+ print_error(_("%s: could not initialize BitVector"), _("FATAL"));
+ return EXIT_FAILURE;
+ }
+
+ /* Initialize intnum and floatnum */
+ yasm_intnum_initialize();
+ yasm_floatnum_initialize();
+
+#ifdef CMAKE_BUILD
+ /* Load standard modules */
+ if (!load_plugin("yasmstd")) {
+ print_error(_("%s: could not load standard modules"), _("FATAL"));
+ return EXIT_FAILURE;
+ }
+#endif
+
+ /* Initialize parameter storage */
+ STAILQ_INIT(&preproc_options);
+
+ if (parse_cmdline(argc, argv, options, NELEMS(options), print_error))
+ return EXIT_FAILURE;
+
+ switch (special_options) {
+ case SPECIAL_SHOW_HELP:
+ /* Does gettext calls internally */
+ help_msg(help_head, help_tail, options, NELEMS(options));
+ return EXIT_SUCCESS;
+ case SPECIAL_SHOW_VERSION:
+ for (i=0; i<NELEMS(version_msg); i++)
+ printf("%s\n", version_msg[i]);
+ return EXIT_SUCCESS;
+ case SPECIAL_SHOW_LICENSE:
+ for (i=0; i<NELEMS(license_msg); i++)
+ printf("%s\n", license_msg[i]);
+ return EXIT_SUCCESS;
+ }
+
+ /* Open error file if specified. */
+ if (error_filename) {
+ errfile = open_file(error_filename, "wt");
+ if (!errfile)
+ return EXIT_FAILURE;
+ }
+
+ /* If not already specified, default to bin as the object format. */
+ if (!cur_objfmt_module) {
+ if (!objfmt_keyword)
+ objfmt_keyword = yasm__xstrdup(DEFAULT_OBJFMT_MODULE);
+ cur_objfmt_module = yasm_load_objfmt(objfmt_keyword);
+ if (!cur_objfmt_module) {
+ print_error(_("%s: could not load default %s"), _("FATAL"),
+ _("object format"));
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* TASM's architecture is x86 */
+ cur_arch_module = yasm_load_arch("x86");
+ if (!cur_arch_module) {
+ print_error(_("%s: could not load %s"), _("FATAL"),
+ _("architecture"));
+ return EXIT_FAILURE;
+ }
+ machine_name =
+ yasm__xstrdup(cur_arch_module->default_machine_keyword);
+
+ /* Check for arch help */
+ if (machine_name && strcmp(machine_name, "help") == 0) {
+ const yasm_arch_machine *m = cur_arch_module->machines;
+ printf(_("Available %s for %s `%s':\n"), _("machines"),
+ _("architecture"), cur_arch_module->keyword);
+ while (m->keyword && m->name) {
+ print_list_keyword_desc(m->name, m->keyword);
+ m++;
+ }
+ return EXIT_SUCCESS;
+ }
+
+ cur_parser_module = yasm_load_parser("tasm");
+ if (!cur_parser_module) {
+ print_error(_("%s: could not load %s"), _("FATAL"),
+ _("parser"));
+ cleanup(NULL);
+ return EXIT_FAILURE;
+ }
+
+ /* If not already specified, default to the parser's default preproc. */
+ if (!cur_preproc_module) {
+ cur_preproc_module =
+ yasm_load_preproc(cur_parser_module->default_preproc_keyword);
+ if (!cur_preproc_module) {
+ print_error(_("%s: could not load default %s"), _("FATAL"),
+ _("preprocessor"));
+ cleanup(NULL);
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* Determine input filename and open input file. */
+ if (!in_filename) {
+ print_error(_("No input files specified"));
+ return EXIT_FAILURE;
+ }
+
+ /* If list file enabled, make sure we have a list format loaded. */
+ if (list_filename) {
+ /* use nasm as the list format. */
+ cur_listfmt_module = yasm_load_listfmt("nasm");
+ }
+
+ /* If not already specified, default to null as the debug format. */
+ if (!cur_dbgfmt_module) {
+ cur_dbgfmt_module = yasm_load_dbgfmt("null");
+ if (!cur_dbgfmt_module) {
+ print_error(_("%s: could not load default %s"), _("FATAL"),
+ _("debug format"));
+ return EXIT_FAILURE;
+ }
+ }
+
+ return do_assemble();
+}
+/*@=globstate =unrecog@*/
+
+/* Open the object file. Returns 0 on failure. */
+static FILE *
+open_file(const char *filename, const char *mode)
+{
+ FILE *f;
+
+ f = fopen(filename, mode);
+ if (!f)
+ print_error(_("could not open file `%s'"), filename);
+ return f;
+}
+
+static void
+check_errors(yasm_errwarns *errwarns, yasm_object *object,
+ yasm_linemap *linemap)
+{
+ if (yasm_errwarns_num_errors(errwarns, warning_error) > 0) {
+ yasm_errwarns_output_all(errwarns, linemap, warning_error,
+ print_yasm_error, print_yasm_warning);
+ yasm_linemap_destroy(linemap);
+ yasm_errwarns_destroy(errwarns);
+ cleanup(object);
+ exit(EXIT_FAILURE);
+ }
+}
+
+/* Define DO_FREE to 1 to enable deallocation of all data structures.
+ * Useful for detecting memory leaks, but slows down execution unnecessarily
+ * (as the OS will free everything we miss here).
+ */
+#define DO_FREE 1
+
+/* Cleans up all allocated structures. */
+static void
+cleanup(yasm_object *object)
+{
+ if (DO_FREE) {
+ if (cur_listfmt)
+ yasm_listfmt_destroy(cur_listfmt);
+ if (cur_preproc)
+ yasm_preproc_destroy(cur_preproc);
+ if (object)
+ yasm_object_destroy(object);
+
+ yasm_floatnum_cleanup();
+ yasm_intnum_cleanup();
+
+ yasm_errwarn_cleanup();
+
+ BitVector_Shutdown();
+ }
+
+ if (DO_FREE) {
+ if (in_filename)
+ yasm_xfree(in_filename);
+ if (obj_filename)
+ yasm_xfree(obj_filename);
+ if (list_filename)
+ yasm_xfree(list_filename);
+ if (xref_filename)
+ yasm_xfree(xref_filename);
+ if (machine_name)
+ yasm_xfree(machine_name);
+ if (objfmt_keyword)
+ yasm_xfree(objfmt_keyword);
+ }
+
+ if (errfile != stderr && errfile != stdout)
+ fclose(errfile);
+#ifdef CMAKE_BUILD
+ unload_plugins();
+#endif
+}
+
+/*
+ * Command line options handlers
+ */
+static char ** const filenames[] = {
+ &in_filename, &obj_filename, &list_filename, &xref_filename, NULL
+}, ** const * cur_filename = &filenames[0];
+
+static int filename_handler(char *param) {
+ if (!*cur_filename) {
+ print_error(_("error: too many files on command line."));
+ return 1;
+ }
+
+ if (*param)
+ **cur_filename = yasm__xstrdup(param);
+
+ return 0;
+}
+int
+not_an_option_handler(char *param) {
+ char *c, *d = param;
+
+ while ((c = strchr(d, ','))) {
+ *c = '\0';
+ if (filename_handler(d))
+ return 1;
+ d = c + 1;
+ cur_filename++;
+ }
+ filename_handler(d);
+ return 0;
+}
+
+static int
+opt_special_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
+{
+ if (special_options == 0)
+ special_options = extra;
+ return 0;
+}
+
+static int
+opt_segment_ordering_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
+{
+ segment_ordering = extra;
+ return 0;
+}
+
+static int
+opt_cross_reference_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
+{
+ cross_reference = 1;
+ return 0;
+}
+
+static int
+opt_floating_point_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
+{
+ floating_point = extra;
+ return 0;
+}
+
+static int
+opt_ignore(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
+{
+ return 0;
+}
+
+static int
+opt_listing_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
+{
+ if (param && param[0]) {
+ if (param[0] != 'a')
+ return 1;
+ expanded_listing = 1;
+ }
+ listing = 1;
+ return 0;
+}
+
+static int
+opt_case_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
+{
+ case_sensitivity = extra;
+ return 0;
+}
+
+static int
+opt_valid_length_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
+{
+ valid_length = atoi(param);
+ return 0;
+}
+
+static int
+opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra)
+{
+ /* is it disabling the warning instead of enabling? */
+ void (*action)(yasm_warn_class wclass) = NULL;
+
+ if (cmd[0] == '0') {
+ /* /w0, disable warnings */
+ yasm_warn_disable_all();
+ return 0;
+ }
+
+ if (cmd[0] == '1' || cmd[0] == '2') {
+ /* /w[12], enable warnings */
+ yasm_warn_enable(YASM_WARN_UNREC_CHAR);
+ yasm_warn_enable(YASM_WARN_ORPHAN_LABEL);
+ yasm_warn_enable(YASM_WARN_UNINIT_CONTENTS);
+ return 0;
+ }
+
+ /* detect no- prefix to disable the warning */
+ if (cmd[0] == '-') {
+ action = yasm_warn_disable;
+ } else if (cmd[0] == '+') {
+ action = yasm_warn_enable;
+ } else return 1;
+
+ /* skip past '+/-' */
+ cmd++;
+
+ if (cmd[0] == '\0')
+ /* just /w- or /w+, so definitely not valid */
+ return 1;
+ else if (strcmp(cmd, "error") == 0)
+ warning_error = (action == yasm_warn_enable);
+ else if (strcmp(cmd, "unrecognized-char") == 0)
+ action(YASM_WARN_UNREC_CHAR);
+ else if (strcmp(cmd, "orphan-labels") == 0)
+ action(YASM_WARN_ORPHAN_LABEL);
+ else if (strcmp(cmd, "uninit-contents") == 0)
+ action(YASM_WARN_UNINIT_CONTENTS);
+ else if (strcmp(cmd, "size-override") == 0)
+ action(YASM_WARN_SIZE_OVERRIDE);
+ else
+ return 1;
+
+ return 0;
+}
+
+static int
+opt_preproc_option(/*@unused@*/ char *cmd, char *param, int extra)
+{
+ constcharparam *cp;
+ cp = yasm_xmalloc(sizeof(constcharparam));
+ cp->param = param;
+ cp->id = extra;
+ STAILQ_INSERT_TAIL(&preproc_options, cp, link);
+ return 0;
+}
+
+static int
+opt_exe_handler(char *cmd, /*@unused@*/ char *param, int extra)
+{
+ objfmt_keyword = yasm__xstrdup("dosexe");
+ return 0;
+}
+
+static void
+apply_preproc_builtins()
+{
+ char *predef;
+
+ if (!objfmt_keyword)
+ objfmt_keyword = yasm__xstrdup(DEFAULT_OBJFMT_MODULE);
+
+ /* Define standard YASM assembly-time macro constants */
+ predef = yasm_xmalloc(strlen("__YASM_OBJFMT__=")
+ + strlen(objfmt_keyword) + 1);
+ strcpy(predef, "__YASM_OBJFMT__=");
+ strcat(predef, objfmt_keyword);
+ yasm_preproc_define_builtin(cur_preproc, predef);
+ yasm_xfree(predef);
+}
+
+static void
+apply_preproc_standard_macros(const yasm_stdmac *stdmacs)
+{
+ int i, matched;
+
+ if (!stdmacs)
+ return;
+
+ matched = -1;
+ for (i=0; stdmacs[i].parser; i++)
+ if (yasm__strcasecmp(stdmacs[i].parser,
+ cur_parser_module->keyword) == 0 &&
+ yasm__strcasecmp(stdmacs[i].preproc,
+ cur_preproc_module->keyword) == 0)
+ matched = i;
+ if (matched >= 0 && stdmacs[matched].macros)
+ yasm_preproc_add_standard(cur_preproc, stdmacs[matched].macros);
+}
+
+static void
+apply_preproc_saved_options()
+{
+ constcharparam *cp, *cpnext;
+
+ void (*funcs[3])(yasm_preproc *, const char *);
+ funcs[0] = cur_preproc_module->add_include_file;
+ funcs[1] = cur_preproc_module->predefine_macro;
+ funcs[2] = cur_preproc_module->undefine_macro;
+
+ STAILQ_FOREACH(cp, &preproc_options, link) {
+ if (0 <= cp->id && cp->id < 3 && funcs[cp->id])
+ funcs[cp->id](cur_preproc, cp->param);
+ }
+
+ cp = STAILQ_FIRST(&preproc_options);
+ while (cp != NULL) {
+ cpnext = STAILQ_NEXT(cp, link);
+ yasm_xfree(cp);
+ cp = cpnext;
+ }
+ STAILQ_INIT(&preproc_options);
+}
+
+/* Replace extension on a filename (or append one if none is present).
+ * If output filename would be identical to input (same extension out as in),
+ * returns (copy of) def.
+ * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext
+ * means the trailing '.' should be included.
+ */
+static char *
+replace_extension(const char *orig, /*@null@*/ const char *ext,
+ const char *def)
+{
+ char *out, *outext;
+ size_t deflen, outlen;
+
+ /* allocate enough space for full existing name + extension */
+ outlen = strlen(orig) + 2;
+ if (ext)
+ outlen += strlen(ext) + 1;
+ deflen = strlen(def) + 1;
+ if (outlen < deflen)
+ outlen = deflen;
+ out = yasm_xmalloc(outlen);
+
+ strcpy(out, orig);
+ outext = strrchr(out, '.');
+ if (outext) {
+ /* Existing extension: make sure it's not the same as the replacement
+ * (as we don't want to overwrite the source file).
+ */
+ outext++; /* advance past '.' */
+ if (ext && strcmp(outext, ext) == 0) {
+ outext = NULL; /* indicate default should be used */
+ print_error(
+ _("file name already ends in `.%s': output will be in `%s'"),
+ ext, def);
+ }
+ } else {
+ /* No extension: make sure the output extension is not empty
+ * (again, we don't want to overwrite the source file).
+ */
+ if (!ext)
+ print_error(
+ _("file name already has no extension: output will be in `%s'"),
+ def);
+ else {
+ outext = strrchr(out, '\0'); /* point to end of the string */
+ *outext++ = '.'; /* append '.' */
+ }
+ }
+
+ /* replace extension or use default name */
+ if (outext) {
+ if (!ext) {
+ /* Back up and replace '.' with string terminator */
+ outext--;
+ *outext = '\0';
+ } else
+ strcpy(outext, ext);
+ } else
+ strcpy(out, def);
+
+ return out;
+}
+
+void
+print_list_keyword_desc(const char *name, const char *keyword)
+{
+ printf("%4s%-12s%s\n", "", keyword, name);
+}
+
+static void
+print_error(const char *fmt, ...)
+{
+ va_list va;
+ fprintf(errfile, "tasm: ");
+ va_start(va, fmt);
+ vfprintf(errfile, fmt, va);
+ va_end(va);
+ fputc('\n', errfile);
+}
+
+static /*@exits@*/ void
+handle_yasm_int_error(const char *file, unsigned int line, const char *message)
+{
+ fprintf(stderr, _("INTERNAL ERROR at %s, line %u: %s\n"), file, line,
+ gettext(message));
+#ifdef HAVE_ABORT
+ abort();
+#else
+ exit(EXIT_FAILURE);
+#endif
+}
+
+static /*@exits@*/ void
+handle_yasm_fatal(const char *fmt, va_list va)
+{
+ fprintf(errfile, "**%s**: ", _("Fatal"));
+ vfprintf(errfile, gettext(fmt), va);
+ fputc('\n', errfile);
+ exit(EXIT_FAILURE);
+}
+
+static const char *
+handle_yasm_gettext(const char *msgid)
+{
+ return gettext(msgid);
+}
+
+static void
+print_yasm_error(const char *filename, unsigned long line, const char *msg,
+ const char *xref_fn, unsigned long xref_line,
+ const char *xref_msg)
+{
+ if (line)
+ fprintf(errfile, "**%s** %s(%lu) %s\n", _("Error"), filename, line, msg);
+ else
+ fprintf(errfile, "**%s** %s %s\n", _("Error"), filename, msg);
+
+ if (/* xref_fn && */ xref_msg) {
+ if (xref_line)
+ fprintf(errfile, "**%s** %s(%lu) %s\n", _("Error"), filename, xref_line, xref_msg);
+ else
+ fprintf(errfile, "**%s** %s %s\n", _("Error"), filename, xref_msg);
+ }
+}
+
+static void
+print_yasm_warning(const char *filename, unsigned long line, const char *msg)
+{
+ if (line)
+ fprintf(errfile, "*%s* %s(%lu) %s\n", _("Warning"), filename, line, msg);
+ else
+ fprintf(errfile, "*%s* %s %s\n", _("Warning"), filename, msg);
+}
Index: frontends/tasm/tasm-options.c
===================================================================
--- frontends/tasm/tasm-options.c (révision 0)
+++ frontends/tasm/tasm-options.c (révision 2137)
@@ -0,0 +1,129 @@
+/*
+ * Generic Options Support Header File
+ *
+ * Copyright (c) 2001 Stanislav Karchebny <berk@madfire.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of other contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <util.h>
+#include <ctype.h>
+/*@unused@*/ RCSID("$Id: tasm-options.c 1197 2005-01-24 06:44:25Z peter $");
+
+#include "tasm-options.h"
+
+
+#ifdef __DEBUG__
+#define DEBUG(x) fprintf ## x ;
+#else
+#define DEBUG(x)
+#endif
+
+
+/* Options Parser */
+int
+parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts,
+ void (*print_error) (const char *fmt, ...))
+{
+ int errors = 0, warnings = 0;
+ size_t i;
+ int got_it;
+
+ DEBUG((stderr, "parse_cmdline: entered\n"));
+
+ fail:
+ while (--argc) {
+ argv++;
+
+ if (argv[0][0] == '/' && argv[0][1]) { /* opt */
+ got_it = 0;
+ for (i = 0; i < nopts; i++) {
+ char *cmd = &argv[0][1];
+ size_t len = strlen(options[i].opt);
+ if (yasm__strncasecmp(cmd, options[i].opt, len) == 0) {
+ char *param;
+
+ param = &argv[0][1+len];
+ if (options[i].takes_param) {
+ if (param[0] == '\0') {
+ print_error(
+ _("option `-%c' needs an argument!"),
+ options[i].opt);
+ errors++;
+ goto fail;
+ } else {
+ argc--;
+ argv++;
+ }
+ } else
+ param = NULL;
+
+ if (!options[i].handler(cmd, param, options[i].extra))
+ got_it = 1;
+ break;
+ }
+ }
+ if (!got_it) {
+ print_error(_("warning: unrecognized option `%s'"),
+ argv[0]);
+ warnings++;
+ }
+ } else { /* not an option, then it should be a file or something */
+
+ if (not_an_option_handler(argv[0]))
+ errors++;
+ }
+ }
+
+ DEBUG((stderr, "parse_cmdline: finished\n"));
+ return errors;
+}
+
+void
+help_msg(const char *msg, const char *tail, opt_option *options, size_t nopts)
+{
+ char optbuf[100], optopt[100];
+ size_t i;
+
+ printf("%s", gettext(msg));
+
+ for (i = 0; i < nopts; i++) {
+ optbuf[0] = 0;
+ optopt[0] = 0;
+
+ if (options[i].takes_param) {
+ if (options[i].opt)
+ sprintf(optbuf, "/%s <%s>", options[i].opt,
+ options[i].param_desc ? options[i].
+ param_desc : _("param"));
+ } else {
+ if (options[i].opt)
+ sprintf(optbuf, "/%s", options[i].opt);
+ }
+
+ printf(" %-22s %s\n", optbuf, gettext(options[i].description));
+ }
+
+ printf("%s", gettext(tail));
+}
Index: frontends/Makefile.inc
===================================================================
--- frontends/Makefile.inc (révision 2128)
+++ frontends/Makefile.inc (copie de travail)
@@ -1,5 +1,7 @@
# $Id$
EXTRA_DIST += frontends/yasm/Makefile.inc
+EXTRA_DIST += frontends/tasm/Makefile.inc
include frontends/yasm/Makefile.inc
+include frontends/tasm/Makefile.inc
--- modules/preprocs/nasm/standard.mac 2008-04-16 05:29:59.000000000 +0200
+++ modules/preprocs/nasm/standard.mac 2008-10-06 19:21:36.000000000 +0200
@@ -5,10 +5,53 @@
%idefine IDEAL
%idefine JUMPS
- %idefine P386
- %idefine P486
- %idefine P586
%idefine END
+ %idefine P8086 CPU 8086
+ %idefine P186 CPU 186
+ %idefine P286 CPU 286
+ %idefine P286N CPU 286
+ %idefine P286P CPU 286 Priv
+ %idefine P386 CPU 386
+ %idefine P386N CPU 386
+ %idefine P386P CPU 386 Priv
+ %idefine P486 CPU 486
+ %idefine P586 CPU 586
+ %idefine .8086 CPU 8086
+ %idefine .186 CPU 186
+ %idefine .286 CPU 286
+ %idefine .286C CPU 286
+ %idefine .286P CPU 286
+ %idefine .386 CPU 386
+ %idefine .386C CPU 386
+ %idefine .386P CPU 386
+ %idefine .486 CPU 486
+ %idefine .486C CPU 486
+ %idefine .486P CPU 486
+ %idefine .586 CPU 586
+ %idefine .586C CPU 586
+ %idefine .586P CPU 586
+
+ %imacro TITLE 1
+ %endm
+ %imacro NAME 1
+ %endm
+
+ %imacro EXTRN 1-*.nolist
+ %rep %0
+ [extern %1]
+ %rotate 1
+ %endrep
+ %endmacro
+
+ %imacro PUBLIC 1-*.nolist
+ %rep %0
+ [global %1]
+ %rotate 1
+ %endrep
+ %endmacro
+
+ ; this is not needed
+ %idefine PTR
; This is a magic token which indicates the end of the TASM macros
*END*TASM*MACROS*
Reply to: