Yasm Assembler mainline development tree (ffmpeg 依赖)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1455 lines
39 KiB

/*
* Expression handling
*
* Copyright (C) 2001 Michael Urman, Peter Johnson
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define YASM_LIB_INTERNAL
#include "util.h"
/*@unused@*/ RCSID("$Id$");
#include "coretype.h"
#include "bitvect.h"
#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
#include "expr.h"
#include "symrec.h"
#include "bytecode.h"
#include "section.h"
#include "arch.h"
#include "expr-int.h"
static int expr_traverse_nodes_post(/*@null@*/ yasm_expr *e,
/*@null@*/ void *d,
int (*func) (/*@null@*/ yasm_expr *e,
/*@null@*/ void *d));
static void expr_delete_term(yasm_expr__item *term, int recurse);
/* Bitmap of used items. We should really never need more than 2 at a time,
* so 31 is pretty much overkill.
*/
static unsigned long itempool_used = 0;
static yasm_expr__item itempool[31];
/* allocate a new expression node, with children as defined.
* If it's a unary operator, put the element in left and set right=NULL. */
/*@-compmempass@*/
yasm_expr *
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
yasm_expr_create(yasm_expr_op op, yasm_expr__item *left,
yasm_expr__item *right, unsigned long line)
{
yasm_expr *ptr, *sube;
unsigned long z;
ptr = yasm_xmalloc(sizeof(yasm_expr));
ptr->op = op;
ptr->numterms = 0;
ptr->terms[0].type = YASM_EXPR_NONE;
ptr->terms[1].type = YASM_EXPR_NONE;
if (left) {
ptr->terms[0] = *left; /* structure copy */
z = left-itempool;
if (z>=31)
yasm_internal_error(N_("could not find expritem in pool"));
itempool_used &= ~(1<<z);
ptr->numterms++;
/* Search downward until we find something *other* than an
* IDENT, then bring it up to the current level.
*/
while (ptr->terms[0].type == YASM_EXPR_EXPR &&
ptr->terms[0].data.expn->op == YASM_EXPR_IDENT) {
sube = ptr->terms[0].data.expn;
ptr->terms[0] = sube->terms[0]; /* structure copy */
/*@-usereleased@*/
yasm_xfree(sube);
/*@=usereleased@*/
}
} else {
yasm_internal_error(N_("Right side of expression must exist"));
}
if (right) {
ptr->terms[1] = *right; /* structure copy */
z = right-itempool;
if (z>=31)
yasm_internal_error(N_("could not find expritem in pool"));
itempool_used &= ~(1<<z);
ptr->numterms++;
/* Search downward until we find something *other* than an
* IDENT, then bring it up to the current level.
*/
while (ptr->terms[1].type == YASM_EXPR_EXPR &&
ptr->terms[1].data.expn->op == YASM_EXPR_IDENT) {
sube = ptr->terms[1].data.expn;
ptr->terms[1] = sube->terms[0]; /* structure copy */
/*@-usereleased@*/
yasm_xfree(sube);
/*@=usereleased@*/
}
}
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
ptr->line = line;
return ptr;
}
/*@=compmempass@*/
/* helpers */
static yasm_expr__item *
expr_get_item(void)
{
int z = 0;
unsigned long v = itempool_used & 0x7fffffff;
while (v & 1) {
v >>= 1;
z++;
}
if (z>=31)
yasm_internal_error(N_("too many expritems"));
itempool_used |= 1<<z;
return &itempool[z];
}
yasm_expr__item *
yasm_expr_precbc(yasm_bytecode *precbc)
{
yasm_expr__item *e = expr_get_item();
e->type = YASM_EXPR_PRECBC;
e->data.precbc = precbc;
return e;
}
yasm_expr__item *
yasm_expr_sym(yasm_symrec *s)
{
yasm_expr__item *e = expr_get_item();
e->type = YASM_EXPR_SYM;
e->data.sym = s;
return e;
}
yasm_expr__item *
yasm_expr_expr(yasm_expr *x)
{
yasm_expr__item *e = expr_get_item();
e->type = YASM_EXPR_EXPR;
e->data.expn = x;
return e;
}
yasm_expr__item *
yasm_expr_int(yasm_intnum *i)
{
yasm_expr__item *e = expr_get_item();
e->type = YASM_EXPR_INT;
e->data.intn = i;
return e;
}
yasm_expr__item *
yasm_expr_float(yasm_floatnum *f)
{
yasm_expr__item *e = expr_get_item();
e->type = YASM_EXPR_FLOAT;
e->data.flt = f;
return e;
}
yasm_expr__item *
yasm_expr_reg(unsigned long reg)
{
yasm_expr__item *e = expr_get_item();
e->type = YASM_EXPR_REG;
e->data.reg = reg;
return e;
}
/* Transforms instances of symrec-symrec [symrec+(-1*symrec)] into single
* expritems if possible. Uses a simple n^2 algorithm because n is usually
* quite small. Also works for precbc-precbc (or symrec-precbc,
* precbc-symrec).
*/
static /*@only@*/ yasm_expr *
expr_xform_bc_dist_base(/*@returned@*/ /*@only@*/ yasm_expr *e,
/*@null@*/ void *cbd,
int (*callback) (yasm_expr__item *ei,
yasm_bytecode *precbc,
yasm_bytecode *precbc2,
void *cbd))
{
int i;
/*@dependent@*/ yasm_section *sect;
/*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
int numterms;
/* Handle symrec-symrec in ADD exprs by looking for (-1*symrec) and
* symrec term pairs (where both symrecs are in the same segment).
*/
if (e->op != YASM_EXPR_ADD)
return e;
for (i=0; i<e->numterms; i++) {
int j;
yasm_expr *sube;
yasm_intnum *intn;
yasm_symrec *sym = NULL;
/*@dependent@*/ yasm_section *sect2;
/*@dependent@*/ /*@null@*/ yasm_bytecode *precbc2;
/* First look for an (-1*symrec) term */
if (e->terms[i].type != YASM_EXPR_EXPR)
continue;
sube = e->terms[i].data.expn;
if (sube->op != YASM_EXPR_MUL || sube->numterms != 2)
continue;
if (sube->terms[0].type == YASM_EXPR_INT &&
More gracefully handle absolute section refernce expansion, and allow for correct detection of absolute section reference loops (fixing a crash case). This is also needed for an ongoing rewrite of reloc/value handling. * expr.c (expr_xform_bc_dist): Remove transformation of absolute section references; move in changed form into... (yasm_expr__level_tree): Here. The new code doesn't immediately calculate the distance from the start of the absolute section to the referenced symbol; rather it generates an expression for this quantity. As this actually adds new absolute section refs to the tree, we can't expand with YASM_EXPR_SYMs, otherwise we would expand multiple times. Thus we need a new YASM_EXPR_SYMEXP type that thus does not get expanded. Unfortunately this ripples changes a bit because everywhere *else* we look for YASM_EXPR_SYM, we now need to look for YASM_EXPR_SYMEXP as well... (expr_xform_bc_dist): Here. (yasm_expr__copy_except): Here. (yasm_expr_extract_symrec): Here. (yasm_expr_get_symrec): Here. (yasm_expr_print): Here. * bin-objfmt.c (bin_objfmt_expr_xform): And here. * expr-int.h (yasm_expr__type): Define new YASM_EXPR_SYMEXP. * section.h (yasm_section_abs_get_sym): To implement above, we need to get a symbol referencing the first bytecode in the absolute section. To avoid creating redundant symrecs, one is generated for us now. This function lets us get it in yasm_expr__level_tree(). * section.c (yasm_section_abs_get_sym): Implement. (yasm_section): Add necessary SECTION_ABSOLUTE data. (yasm_section_create_absolute): Create the symrec here. * absloop-err.asm: New test for absolute section reference loops. svn path=/trunk/yasm/; revision=1417
19 years ago
(sube->terms[1].type == YASM_EXPR_SYM ||
sube->terms[1].type == YASM_EXPR_SYMEXP ||
sube->terms[1].type == YASM_EXPR_PRECBC)) {
intn = sube->terms[0].data.intn;
if (sube->terms[1].type == YASM_EXPR_PRECBC)
precbc = sube->terms[1].data.precbc;
else
sym = sube->terms[1].data.sym;
More gracefully handle absolute section refernce expansion, and allow for correct detection of absolute section reference loops (fixing a crash case). This is also needed for an ongoing rewrite of reloc/value handling. * expr.c (expr_xform_bc_dist): Remove transformation of absolute section references; move in changed form into... (yasm_expr__level_tree): Here. The new code doesn't immediately calculate the distance from the start of the absolute section to the referenced symbol; rather it generates an expression for this quantity. As this actually adds new absolute section refs to the tree, we can't expand with YASM_EXPR_SYMs, otherwise we would expand multiple times. Thus we need a new YASM_EXPR_SYMEXP type that thus does not get expanded. Unfortunately this ripples changes a bit because everywhere *else* we look for YASM_EXPR_SYM, we now need to look for YASM_EXPR_SYMEXP as well... (expr_xform_bc_dist): Here. (yasm_expr__copy_except): Here. (yasm_expr_extract_symrec): Here. (yasm_expr_get_symrec): Here. (yasm_expr_print): Here. * bin-objfmt.c (bin_objfmt_expr_xform): And here. * expr-int.h (yasm_expr__type): Define new YASM_EXPR_SYMEXP. * section.h (yasm_section_abs_get_sym): To implement above, we need to get a symbol referencing the first bytecode in the absolute section. To avoid creating redundant symrecs, one is generated for us now. This function lets us get it in yasm_expr__level_tree(). * section.c (yasm_section_abs_get_sym): Implement. (yasm_section): Add necessary SECTION_ABSOLUTE data. (yasm_section_create_absolute): Create the symrec here. * absloop-err.asm: New test for absolute section reference loops. svn path=/trunk/yasm/; revision=1417
19 years ago
} else if ((sube->terms[0].type == YASM_EXPR_SYM ||
sube->terms[0].type == YASM_EXPR_SYMEXP ||
sube->terms[0].type == YASM_EXPR_PRECBC) &&
sube->terms[1].type == YASM_EXPR_INT) {
if (sube->terms[0].type == YASM_EXPR_PRECBC)
precbc = sube->terms[0].data.precbc;
else
sym = sube->terms[0].data.sym;
intn = sube->terms[1].data.intn;
} else
continue;
if (!yasm_intnum_is_neg1(intn))
continue;
if (sym && !yasm_symrec_get_label(sym, &precbc))
continue;
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
sect2 = yasm_bc_get_section(precbc);
/* Now look for a symrec term in the same segment */
for (j=0; j<e->numterms; j++) {
if ((((e->terms[j].type == YASM_EXPR_SYM ||
e->terms[j].type == YASM_EXPR_SYMEXP) &&
yasm_symrec_get_label(e->terms[j].data.sym, &precbc2)) ||
(e->terms[j].type == YASM_EXPR_PRECBC &&
(precbc2 = e->terms[j].data.precbc))) &&
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
(sect = yasm_bc_get_section(precbc2)) &&
sect == sect2 &&
callback(&e->terms[j], precbc, precbc2, cbd)) {
/* Delete the matching (-1*symrec) term */
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
yasm_expr_destroy(sube);
e->terms[i].type = YASM_EXPR_NONE;
break; /* stop looking for matching symrec term */
}
}
}
/* Clean up any deleted (EXPR_NONE) terms */
numterms = 0;
for (i=0; i<e->numterms; i++) {
if (e->terms[i].type != YASM_EXPR_NONE)
e->terms[numterms++] = e->terms[i]; /* structure copy */
}
if (e->numterms != numterms) {
e->numterms = numterms;
e = yasm_xrealloc(e, sizeof(yasm_expr)+((numterms<2) ? 0 :
sizeof(yasm_expr__item)*(numterms-2)));
if (numterms == 1)
e->op = YASM_EXPR_IDENT;
}
return e;
}
static int
expr_xform_bc_dist_cb(yasm_expr__item *ei, yasm_bytecode *precbc,
yasm_bytecode *precbc2, /*@null@*/ void *d)
{
yasm_intnum *dist = yasm_calc_bc_dist(precbc, precbc2);
if (!dist)
return 0;
/* Change the term to an integer */
ei->type = YASM_EXPR_INT;
ei->data.intn = dist;
return 1;
}
/* Transforms instances of symrec-symrec [symrec+(-1*symrec)] into integers if
* possible.
*/
static /*@only@*/ yasm_expr *
expr_xform_bc_dist(/*@returned@*/ /*@only@*/ yasm_expr *e)
{
return expr_xform_bc_dist_base(e, NULL, expr_xform_bc_dist_cb);
}
typedef struct bc_dist_subst_cbd {
void (*callback) (unsigned int subst, yasm_bytecode *precbc,
yasm_bytecode *precbc2, void *cbd);
void *cbd;
unsigned int subst;
} bc_dist_subst_cbd;
static int
expr_bc_dist_subst_cb(yasm_expr__item *ei, yasm_bytecode *precbc,
yasm_bytecode *precbc2, /*@null@*/ void *d)
{
bc_dist_subst_cbd *my_cbd = d;
assert(my_cbd != NULL);
/* Call higher-level callback */
my_cbd->callback(my_cbd->subst, precbc, precbc2, my_cbd->cbd);
/* Change the term to an subst */
ei->type = YASM_EXPR_SUBST;
ei->data.subst = my_cbd->subst;
my_cbd->subst++;
return 1;
}
static yasm_expr *
expr_xform_bc_dist_subst(yasm_expr *e, void *d)
{
return expr_xform_bc_dist_base(e, d, expr_bc_dist_subst_cb);
}
int
yasm_expr__bc_dist_subst(yasm_expr **ep, void *cbd,
void (*callback) (unsigned int subst,
yasm_bytecode *precbc,
yasm_bytecode *precbc2,
void *cbd))
{
bc_dist_subst_cbd my_cbd; /* callback info for low-level callback */
my_cbd.callback = callback;
my_cbd.cbd = cbd;
my_cbd.subst = 0;
*ep = yasm_expr__level_tree(*ep, 1, 1, 1, 0, &expr_xform_bc_dist_subst,
&my_cbd);
return my_cbd.subst;
}
/* Negate just a single ExprItem by building a -1*ei subexpression */
static void
expr_xform_neg_item(yasm_expr *e, yasm_expr__item *ei)
{
yasm_expr *sube = yasm_xmalloc(sizeof(yasm_expr));
/* Build -1*ei subexpression */
sube->op = YASM_EXPR_MUL;
sube->line = e->line;
sube->numterms = 2;
sube->terms[0].type = YASM_EXPR_INT;
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
sube->terms[0].data.intn = yasm_intnum_create_int(-1);
sube->terms[1] = *ei; /* structure copy */
/* Replace original ExprItem with subexp */
ei->type = YASM_EXPR_EXPR;
ei->data.expn = sube;
}
/* Negates e by multiplying by -1, with distribution over lower-precedence
* operators (eg ADD) and special handling to simplify result w/ADD, NEG, and
* others.
*
* Returns a possibly reallocated e.
*/
static /*@only@*/ yasm_expr *
expr_xform_neg_helper(/*@returned@*/ /*@only@*/ yasm_expr *e)
{
yasm_expr *ne;
int i;
switch (e->op) {
case YASM_EXPR_ADD:
/* distribute (recursively if expr) over terms */
for (i=0; i<e->numterms; i++) {
if (e->terms[i].type == YASM_EXPR_EXPR)
e->terms[i].data.expn =
expr_xform_neg_helper(e->terms[i].data.expn);
else
expr_xform_neg_item(e, &e->terms[i]);
}
break;
case YASM_EXPR_SUB:
/* change op to ADD, and recursively negate left side (if expr) */
e->op = YASM_EXPR_ADD;
if (e->terms[0].type == YASM_EXPR_EXPR)
e->terms[0].data.expn =
expr_xform_neg_helper(e->terms[0].data.expn);
else
expr_xform_neg_item(e, &e->terms[0]);
break;
case YASM_EXPR_NEG:
/* Negating a negated value? Make it an IDENT. */
e->op = YASM_EXPR_IDENT;
break;
case YASM_EXPR_IDENT:
/* Negating an ident? Change it into a MUL w/ -1 if there's no
* floatnums present below; if there ARE floatnums, recurse.
*/
if (e->terms[0].type == YASM_EXPR_FLOAT)
Revamp error/warning handling, using a model similar to Python's internal exception handling. There are now two layers an error or warning goes through before it hits the user: first an error is logged via yasm_error_set() (or yasm_warn_set() for a warning). Only one error may be set, whereas multiple warnings can be set (yasm_warn_set maintains a linked list). Then, calling yasm_errwarn_propagate() propagates any error and/or warning(s) to an errwarns structure and associates the errors/warnings with a line number at that time; this call also clears the pending errors/warnings and allows new ones to be set. The propagate function can safely be called when there are no pending error/warnings. In addition, there are some helper errwarn functions that allow clearing of an error/warning without propagating, getting it separately, etc. Still yet to be done: changing most/all uses of yasm_internal_error() into yasm_error_set(YASM_ERROR_ASSERTION). The main advantage this change has is making libyasm functions feel much more library like, and separating the user code line numbers from the inner function error handling (e.g. intnum create functions only needed the line number to trigger errors; this is no longer required). The set/propagate/etc functions use global data structures to avoid passing around a pointer to every function. This would need to be made thread-local data in a threaded app. Errwarns containers (that keep associated line numbers) are no longer global, so multiple source streams can be processed separately with no conflict (at least if there's only a single thread of execution). svn path=/trunk/yasm/; revision=1521
19 years ago
yasm_floatnum_calc(e->terms[0].data.flt, YASM_EXPR_NEG, NULL);
else if (e->terms[0].type == YASM_EXPR_EXPR &&
yasm_expr__contains(e->terms[0].data.expn, YASM_EXPR_FLOAT))
expr_xform_neg_helper(e->terms[0].data.expn);
else {
e->op = YASM_EXPR_MUL;
e->numterms = 2;
e->terms[1].type = YASM_EXPR_INT;
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
e->terms[1].data.intn = yasm_intnum_create_int(-1);
}
break;
default:
/* Everything else. MUL will be combined when it's leveled.
* Make a new expr (to replace e) with -1*e.
*/
ne = yasm_xmalloc(sizeof(yasm_expr));
ne->op = YASM_EXPR_MUL;
ne->line = e->line;
ne->numterms = 2;
ne->terms[0].type = YASM_EXPR_INT;
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
ne->terms[0].data.intn = yasm_intnum_create_int(-1);
ne->terms[1].type = YASM_EXPR_EXPR;
ne->terms[1].data.expn = e;
return ne;
}
return e;
}
/* Transforms negatives into expressions that are easier to combine:
* -x -> -1*x
* a-b -> a+(-1*b)
*
* Call post-order on an expression tree to transform the entire tree.
*
* Returns a possibly reallocated e.
*/
static /*@only@*/ yasm_expr *
expr_xform_neg(/*@returned@*/ /*@only@*/ yasm_expr *e)
{
switch (e->op) {
case YASM_EXPR_NEG:
/* Turn -x into -1*x */
e->op = YASM_EXPR_IDENT;
return expr_xform_neg_helper(e);
case YASM_EXPR_SUB:
/* Turn a-b into a+(-1*b) */
/* change op to ADD, and recursively negate right side (if expr) */
e->op = YASM_EXPR_ADD;
if (e->terms[1].type == YASM_EXPR_EXPR)
e->terms[1].data.expn =
expr_xform_neg_helper(e->terms[1].data.expn);
else
expr_xform_neg_item(e, &e->terms[1]);
break;
default:
break;
}
return e;
}
/* Look for simple identities that make the entire result constant:
* 0*&x, -1|x, etc.
*/
static int
expr_is_constant(yasm_expr_op op, yasm_intnum *intn)
{
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
int iszero = yasm_intnum_is_zero(intn);
return ((iszero && op == YASM_EXPR_MUL) ||
(iszero && op == YASM_EXPR_AND) ||
(iszero && op == YASM_EXPR_LAND) ||
(yasm_intnum_is_neg1(intn) && op == YASM_EXPR_OR));
}
/* Look for simple "left" identities like 0+x, 1*x, etc. */
static int
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
expr_can_destroy_int_left(yasm_expr_op op, yasm_intnum *intn)
{
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
int iszero = yasm_intnum_is_zero(intn);
return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) ||
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
(iszero && op == YASM_EXPR_ADD) ||
(yasm_intnum_is_neg1(intn) && op == YASM_EXPR_AND) ||
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
(!iszero && op == YASM_EXPR_LAND) ||
(iszero && op == YASM_EXPR_OR) ||
(iszero && op == YASM_EXPR_LOR));
}
/* Look for simple "right" identities like x+|-0, x*&/1 */
static int
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
expr_can_destroy_int_right(yasm_expr_op op, yasm_intnum *intn)
{
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
int iszero = yasm_intnum_is_zero(intn);
int ispos1 = yasm_intnum_is_pos1(intn);
return ((ispos1 && op == YASM_EXPR_MUL) ||
(ispos1 && op == YASM_EXPR_DIV) ||
(iszero && op == YASM_EXPR_ADD) ||
(iszero && op == YASM_EXPR_SUB) ||
(yasm_intnum_is_neg1(intn) && op == YASM_EXPR_AND) ||
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
(!iszero && op == YASM_EXPR_LAND) ||
(iszero && op == YASM_EXPR_OR) ||
(iszero && op == YASM_EXPR_LOR) ||
(iszero && op == YASM_EXPR_SHL) ||
(iszero && op == YASM_EXPR_SHR));
}
/* Check for and simplify identities. Returns new number of expr terms.
* Sets e->op = EXPR_IDENT if numterms ends up being 1.
* Uses numterms parameter instead of e->numterms for basis of "new" number
* of terms.
* Assumes int_term is *only* integer term in e.
* NOTE: Really designed to only be used by expr_level_op().
*/
static int
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
expr_simplify_identity(yasm_expr *e, int numterms, int int_term,
int simplify_reg_mul)
{
int i;
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
int save_numterms;
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
/* Don't do this step if it's 1*REG. Save and restore numterms so
* yasm_expr__contains() works correctly.
*/
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
save_numterms = e->numterms;
e->numterms = numterms;
if (simplify_reg_mul || e->op != YASM_EXPR_MUL
|| !yasm_intnum_is_pos1(e->terms[int_term].data.intn)
|| !yasm_expr__contains(e, YASM_EXPR_REG)) {
/* Check for simple identities that delete the intnum.
* Don't delete if the intnum is the only thing in the expn.
*/
if ((int_term == 0 && numterms > 1 &&
expr_can_destroy_int_left(e->op, e->terms[0].data.intn)) ||
(int_term > 0 &&
expr_can_destroy_int_right(e->op, e->terms[int_term].data.intn))) {
/* Delete the intnum */
yasm_intnum_destroy(e->terms[int_term].data.intn);
/* Slide everything to its right over by 1 */
if (int_term != numterms-1) /* if it wasn't last.. */
memmove(&e->terms[int_term], &e->terms[int_term+1],
(numterms-1-int_term)*sizeof(yasm_expr__item));
/* Update numterms */
numterms--;
int_term = -1; /* no longer an int term */
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
}
}
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
e->numterms = save_numterms;
/* Check for simple identites that delete everything BUT the intnum.
* Don't bother if the intnum is the only thing in the expn.
*/
if (numterms > 1 && int_term != -1 &&
expr_is_constant(e->op, e->terms[int_term].data.intn)) {
/* Loop through, deleting everything but the integer term */
for (i=0; i<e->numterms; i++)
if (i != int_term)
expr_delete_term(&e->terms[i], 1);
/* Move integer term to the first term (if not already there) */
if (int_term != 0)
e->terms[0] = e->terms[int_term]; /* structure copy */
/* Set numterms to 1 */
numterms = 1;
}
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
/* Compute NOT, NEG, and LNOT on single intnum. */
if (numterms == 1 && int_term == 0 &&
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
(e->op == YASM_EXPR_NOT || e->op == YASM_EXPR_NEG ||
e->op == YASM_EXPR_LNOT))
Revamp error/warning handling, using a model similar to Python's internal exception handling. There are now two layers an error or warning goes through before it hits the user: first an error is logged via yasm_error_set() (or yasm_warn_set() for a warning). Only one error may be set, whereas multiple warnings can be set (yasm_warn_set maintains a linked list). Then, calling yasm_errwarn_propagate() propagates any error and/or warning(s) to an errwarns structure and associates the errors/warnings with a line number at that time; this call also clears the pending errors/warnings and allows new ones to be set. The propagate function can safely be called when there are no pending error/warnings. In addition, there are some helper errwarn functions that allow clearing of an error/warning without propagating, getting it separately, etc. Still yet to be done: changing most/all uses of yasm_internal_error() into yasm_error_set(YASM_ERROR_ASSERTION). The main advantage this change has is making libyasm functions feel much more library like, and separating the user code line numbers from the inner function error handling (e.g. intnum create functions only needed the line number to trigger errors; this is no longer required). The set/propagate/etc functions use global data structures to avoid passing around a pointer to every function. This would need to be made thread-local data in a threaded app. Errwarns containers (that keep associated line numbers) are no longer global, so multiple source streams can be processed separately with no conflict (at least if there's only a single thread of execution). svn path=/trunk/yasm/; revision=1521
19 years ago
yasm_intnum_calc(e->terms[0].data.intn, e->op, NULL);
/* Change expression to IDENT if possible. */
if (numterms == 1)
e->op = YASM_EXPR_IDENT;
/* Return the updated numterms */
return numterms;
}
/* Levels the expression tree starting at e. Eg:
* a+(b+c) -> a+b+c
* (a+b)+(c+d) -> a+b+c+d
* Naturally, only levels operators that allow more than two operand terms.
* NOTE: only does *one* level of leveling (no recursion). Should be called
* post-order on a tree to combine deeper levels.
* Also brings up any IDENT values into the current level (for ALL operators).
* Folds (combines by evaluation) *integer* constant values if fold_const != 0.
*
* Returns a possibly reallocated e.
*/
/*@-mustfree@*/
static /*@only@*/ yasm_expr *
expr_level_op(/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const,
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
int simplify_ident, int simplify_reg_mul)
{
int i, j, o, fold_numterms, level_numterms, level_fold_numterms;
int first_int_term = -1;
/* Determine how many operands will need to be brought up (for leveling).
* Go ahead and bring up any IDENT'ed values.
*/
while (e->op == YASM_EXPR_IDENT && e->terms[0].type == YASM_EXPR_EXPR) {
yasm_expr *sube = e->terms[0].data.expn;
yasm_xfree(e);
e = sube;
}
/* If non-numeric expression, don't fold constants. */
if (e->op > YASM_EXPR_NONNUM)
fold_const = 0;
level_numterms = e->numterms;
level_fold_numterms = 0;
for (i=0; i<e->numterms; i++) {
/* Search downward until we find something *other* than an
* IDENT, then bring it up to the current level.
*/
while (e->terms[i].type == YASM_EXPR_EXPR &&
e->terms[i].data.expn->op == YASM_EXPR_IDENT) {
yasm_expr *sube = e->terms[i].data.expn;
e->terms[i] = sube->terms[0];
yasm_xfree(sube);
}
if (e->terms[i].type == YASM_EXPR_EXPR &&
e->terms[i].data.expn->op == e->op) {
/* It's an expression w/the same operator, add in its numterms.
* But don't forget to subtract one for the expr itself!
*/
level_numterms += e->terms[i].data.expn->numterms - 1;
/* If we're folding constants, count up the number of constants
* that will be merged in.
*/
if (fold_const)
for (j=0; j<e->terms[i].data.expn->numterms; j++)
if (e->terms[i].data.expn->terms[j].type ==
YASM_EXPR_INT)
level_fold_numterms++;
}
/* Find the first integer term (if one is present) if we're folding
* constants.
*/
if (fold_const && first_int_term == -1 &&
e->terms[i].type == YASM_EXPR_INT)
first_int_term = i;
}
/* Look for other integer terms if there's one and combine.
* Also eliminate empty spaces when combining and adjust numterms
* variables.
*/
fold_numterms = e->numterms;
if (first_int_term != -1) {
for (i=first_int_term+1, o=first_int_term+1; i<e->numterms; i++) {
if (e->terms[i].type == YASM_EXPR_INT) {
yasm_intnum_calc(e->terms[first_int_term].data.intn, e->op,
Revamp error/warning handling, using a model similar to Python's internal exception handling. There are now two layers an error or warning goes through before it hits the user: first an error is logged via yasm_error_set() (or yasm_warn_set() for a warning). Only one error may be set, whereas multiple warnings can be set (yasm_warn_set maintains a linked list). Then, calling yasm_errwarn_propagate() propagates any error and/or warning(s) to an errwarns structure and associates the errors/warnings with a line number at that time; this call also clears the pending errors/warnings and allows new ones to be set. The propagate function can safely be called when there are no pending error/warnings. In addition, there are some helper errwarn functions that allow clearing of an error/warning without propagating, getting it separately, etc. Still yet to be done: changing most/all uses of yasm_internal_error() into yasm_error_set(YASM_ERROR_ASSERTION). The main advantage this change has is making libyasm functions feel much more library like, and separating the user code line numbers from the inner function error handling (e.g. intnum create functions only needed the line number to trigger errors; this is no longer required). The set/propagate/etc functions use global data structures to avoid passing around a pointer to every function. This would need to be made thread-local data in a threaded app. Errwarns containers (that keep associated line numbers) are no longer global, so multiple source streams can be processed separately with no conflict (at least if there's only a single thread of execution). svn path=/trunk/yasm/; revision=1521
19 years ago
e->terms[i].data.intn);
fold_numterms--;
level_numterms--;
/* make sure to delete folded intnum */
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
yasm_intnum_destroy(e->terms[i].data.intn);
} else if (o != i) {
/* copy term if it changed places */
e->terms[o++] = e->terms[i];
} else
o++;
}
if (simplify_ident) {
int new_fold_numterms;
/* Simplify identities and make IDENT if possible. */
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
new_fold_numterms =
expr_simplify_identity(e, fold_numterms, first_int_term,
simplify_reg_mul);
level_numterms -= fold_numterms-new_fold_numterms;
fold_numterms = new_fold_numterms;
}
if (fold_numterms == 1)
e->op = YASM_EXPR_IDENT;
}
/* Only level operators that allow more than two operand terms.
* Also don't bother leveling if it's not necessary to bring up any terms.
*/
if ((e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_MUL &&
e->op != YASM_EXPR_OR && e->op != YASM_EXPR_AND &&
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
e->op != YASM_EXPR_LOR && e->op != YASM_EXPR_LAND &&
e->op != YASM_EXPR_LXOR && e->op != YASM_EXPR_XOR) ||
level_numterms <= fold_numterms) {
/* Downsize e if necessary */
if (fold_numterms < e->numterms && e->numterms > 2)
e = yasm_xrealloc(e, sizeof(yasm_expr)+((fold_numterms<2) ? 0 :
sizeof(yasm_expr__item)*(fold_numterms-2)));
/* Update numterms */
e->numterms = fold_numterms;
return e;
}
/* Adjust numterms for constant folding from terms being "pulled up".
* Careful: if there's no integer term in e, then save space for it.
*/
if (fold_const) {
level_numterms -= level_fold_numterms;
if (first_int_term == -1 && level_fold_numterms != 0)
level_numterms++;
}
/* Alloc more (or conceivably less, but not usually) space for e */
e = yasm_xrealloc(e, sizeof(yasm_expr)+((level_numterms<2) ? 0 :
sizeof(yasm_expr__item)*(level_numterms-2)));
/* Copy up ExprItem's. Iterate from right to left to keep the same
* ordering as was present originally.
* Combine integer terms as necessary.
*/
for (i=e->numterms-1, o=level_numterms-1; i>=0; i--) {
if (e->terms[i].type == YASM_EXPR_EXPR &&
e->terms[i].data.expn->op == e->op) {
/* bring up subexpression */
yasm_expr *sube = e->terms[i].data.expn;
/* copy terms right to left */
for (j=sube->numterms-1; j>=0; j--) {
if (fold_const && sube->terms[j].type == YASM_EXPR_INT) {
/* Need to fold it in.. but if there's no int term already,
* just copy into a new one.
*/
if (first_int_term == -1) {
first_int_term = o--;
e->terms[first_int_term] = sube->terms[j]; /* struc */
} else {
yasm_intnum_calc(e->terms[first_int_term].data.intn,
Revamp error/warning handling, using a model similar to Python's internal exception handling. There are now two layers an error or warning goes through before it hits the user: first an error is logged via yasm_error_set() (or yasm_warn_set() for a warning). Only one error may be set, whereas multiple warnings can be set (yasm_warn_set maintains a linked list). Then, calling yasm_errwarn_propagate() propagates any error and/or warning(s) to an errwarns structure and associates the errors/warnings with a line number at that time; this call also clears the pending errors/warnings and allows new ones to be set. The propagate function can safely be called when there are no pending error/warnings. In addition, there are some helper errwarn functions that allow clearing of an error/warning without propagating, getting it separately, etc. Still yet to be done: changing most/all uses of yasm_internal_error() into yasm_error_set(YASM_ERROR_ASSERTION). The main advantage this change has is making libyasm functions feel much more library like, and separating the user code line numbers from the inner function error handling (e.g. intnum create functions only needed the line number to trigger errors; this is no longer required). The set/propagate/etc functions use global data structures to avoid passing around a pointer to every function. This would need to be made thread-local data in a threaded app. Errwarns containers (that keep associated line numbers) are no longer global, so multiple source streams can be processed separately with no conflict (at least if there's only a single thread of execution). svn path=/trunk/yasm/; revision=1521
19 years ago
e->op, sube->terms[j].data.intn);
/* make sure to delete folded intnum */
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
yasm_intnum_destroy(sube->terms[j].data.intn);
}
} else {
if (o == first_int_term)
o--;
e->terms[o--] = sube->terms[j]; /* structure copy */
}
}
/* delete subexpression, but *don't delete nodes* (as we've just
* copied them!)
*/
yasm_xfree(sube);
} else if (o != i) {
/* copy operand if it changed places */
if (o == first_int_term)
o--;
e->terms[o] = e->terms[i];
/* If we moved the first_int_term, change first_int_num too */
if (i == first_int_term)
first_int_term = o;
o--;
}
}
/* Simplify identities, make IDENT if possible, and save to e->numterms. */
if (simplify_ident && first_int_term != -1) {
e->numterms = expr_simplify_identity(e, level_numterms,
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
first_int_term, simplify_reg_mul);
} else {
e->numterms = level_numterms;
if (level_numterms == 1)
e->op = YASM_EXPR_IDENT;
}
return e;
}
/*@=mustfree@*/
typedef SLIST_HEAD(yasm__exprhead, yasm__exprentry) yasm__exprhead;
typedef struct yasm__exprentry {
/*@reldef@*/ SLIST_ENTRY(yasm__exprentry) next;
/*@null@*/ const yasm_expr *e;
} yasm__exprentry;
static yasm_expr *
expr_expand_equ(yasm_expr *e, yasm__exprhead *eh)
{
int i;
yasm__exprentry ee;
/* traverse terms */
for (i=0; i<e->numterms; i++) {
const yasm_expr *equ_expr;
/* Expand equ's. */
if (e->terms[i].type == YASM_EXPR_SYM &&
(equ_expr = yasm_symrec_get_equ(e->terms[i].data.sym))) {
yasm__exprentry *np;
/* Check for circular reference */
SLIST_FOREACH(np, eh, next) {
if (np->e == equ_expr) {
yasm_error_set(YASM_ERROR_TOO_COMPLEX,
N_("circular reference detected"));
return e;
}
}
e->terms[i].type = YASM_EXPR_EXPR;
e->terms[i].data.expn = yasm_expr_copy(equ_expr);
/* Remember we saw this equ and recurse */
ee.e = equ_expr;
SLIST_INSERT_HEAD(eh, &ee, next);
e->terms[i].data.expn = expr_expand_equ(e->terms[i].data.expn, eh);
SLIST_REMOVE_HEAD(eh, next);
} else if (e->terms[i].type == YASM_EXPR_EXPR)
/* Recurse */
e->terms[i].data.expn = expr_expand_equ(e->terms[i].data.expn, eh);
}
return e;
}
static yasm_expr *
expr_level_tree(yasm_expr *e, int fold_const, int simplify_ident,
int simplify_reg_mul, int calc_bc_dist,
yasm_expr_xform_func expr_xform_extra,
void *expr_xform_extra_data)
{
int i;
e = expr_xform_neg(e);
/* traverse terms */
for (i=0; i<e->numterms; i++) {
/* Recurse */
if (e->terms[i].type == YASM_EXPR_EXPR)
e->terms[i].data.expn =
expr_level_tree(e->terms[i].data.expn, fold_const,
simplify_ident, simplify_reg_mul, calc_bc_dist,
expr_xform_extra, expr_xform_extra_data);
}
/* Check for SEG of SEG:OFF, if we match, simplify to just the segment */
if (e->op == YASM_EXPR_SEG && e->terms[0].type == YASM_EXPR_EXPR &&
e->terms[0].data.expn->op == YASM_EXPR_SEGOFF) {
e->op = YASM_EXPR_IDENT;
e->terms[0].data.expn->op = YASM_EXPR_IDENT;
/* Destroy the second (offset) term */
expr_delete_term(&e->terms[1], 1);
}
/* do callback */
Massive cleanup of relocation and WRT handling. Closes #49 and lays the groundwork for further features and possible cleanups. Note: this commit changes the way in which relocations in the COFF/Win32/Win64 target can be forced to reference a different symbol than is being pointed to; instead of the ambiguous "trap+(trap.end-trap)" to get the reloc to point at trap.end but reference the trap symbol, after this commit "trap.end wrt trap" is the way to say this. This also reads a lot more clearly and is not ambiguous. This should really only affect people who write .pdata sections for Win64. See the objfmts/win64/tests/win64-dataref.asm testcase for an example of usage. This cleanup adds a new data structure, yasm_value, which is used for all expressions that can be potentially relocatable. This data structure splits the absolute portion of the expression away from the relative portion and any modifications to the relative portion (SEG, WRT, PC-relative, etc). A large amount of code in the new value module breaks a general expression into its absolute and relative parts (yasm_value_finalize_expr) and provides a common set of code for writing out non-relocated values (yasm_value_output_basic). All bytecode handling in both libyasm and the architecture modules was rewritten to use yasm_values when appropriate (e.g. data values, immediates, and effective addresses). The yasm_output_expr_func is now yasm_output_value_func and all users and implementors (mainly in object formats) have been updated to handle yasm_values. Simultaneously with this change, yasm_effaddr and yasm_immval full structure definitions have been moved from bc-int.h to bytecode.h. The data hiding provided by bc-int.h was relatively minimal and probably overkill. Also, great simplifications have been made to x86 effective address expression handling. svn path=/trunk/yasm/; revision=1419
19 years ago
e = expr_level_op(e, fold_const, simplify_ident, simplify_reg_mul);
if (calc_bc_dist || expr_xform_extra) {
if (calc_bc_dist)
e = expr_xform_bc_dist(e);
if (expr_xform_extra)
e = expr_xform_extra(e, expr_xform_extra_data);
e = expr_level_tree(e, fold_const, simplify_ident, simplify_reg_mul,
0, NULL, NULL);
}
return e;
}
/* Level an entire expn tree, expanding equ's as we go */
yasm_expr *
yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident,
int simplify_reg_mul, int calc_bc_dist,
yasm_expr_xform_func expr_xform_extra,
void *expr_xform_extra_data)
{
yasm__exprhead eh;
SLIST_INIT(&eh);
if (!e)
return 0;
e = expr_expand_equ(e, &eh);
e = expr_level_tree(e, fold_const, simplify_ident, simplify_reg_mul,
calc_bc_dist, expr_xform_extra, expr_xform_extra_data);
return e;
}
/* Comparison function for expr_order_terms().
* Assumes ExprType enum is in canonical order.
*/
static int
expr_order_terms_compare(const void *va, const void *vb)
{
const yasm_expr__item *a = va, *b = vb;
return (a->type - b->type);
}
/* Reorder terms of e into canonical order. Only reorders if reordering
* doesn't change meaning of expression. (eg, doesn't reorder SUB).
* Canonical order: REG, INT, FLOAT, SYM, EXPR.
* Multiple terms of a single type are kept in the same order as in
* the original expression.
* NOTE: Only performs reordering on *one* level (no recursion).
*/
void
yasm_expr__order_terms(yasm_expr *e)
{
/* don't bother reordering if only one element */
if (e->numterms == 1)
return;
/* only reorder some types of operations */
switch (e->op) {
case YASM_EXPR_ADD:
case YASM_EXPR_MUL:
case YASM_EXPR_OR:
case YASM_EXPR_AND:
case YASM_EXPR_XOR:
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
case YASM_EXPR_LOR:
case YASM_EXPR_LAND:
case YASM_EXPR_LXOR:
/* Use mergesort to sort. It's fast on already sorted values and a
* stable sort (multiple terms of same type are kept in the same
* order).
*/
yasm__mergesort(e->terms, (size_t)e->numterms,
sizeof(yasm_expr__item), expr_order_terms_compare);
break;
default:
break;
}
}
static void
expr_item_copy(yasm_expr__item *dest, const yasm_expr__item *src)
{
dest->type = src->type;
switch (src->type) {
case YASM_EXPR_SYM:
case YASM_EXPR_SYMEXP:
/* Symbols don't need to be copied */
dest->data.sym = src->data.sym;
break;
case YASM_EXPR_PRECBC:
/* Nor do direct bytecode references */
dest->data.precbc = src->data.precbc;
break;
case YASM_EXPR_EXPR:
dest->data.expn = yasm_expr__copy_except(src->data.expn, -1);
break;
case YASM_EXPR_INT:
dest->data.intn = yasm_intnum_copy(src->data.intn);
break;
case YASM_EXPR_FLOAT:
dest->data.flt = yasm_floatnum_copy(src->data.flt);
break;
case YASM_EXPR_REG:
dest->data.reg = src->data.reg;
break;
case YASM_EXPR_SUBST:
dest->data.subst = src->data.subst;
break;
default:
break;
}
}
/* Copy entire expression EXCEPT for index "except" at *top level only*. */
yasm_expr *
yasm_expr__copy_except(const yasm_expr *e, int except)
{
yasm_expr *n;
int i;
n = yasm_xmalloc(sizeof(yasm_expr) +
sizeof(yasm_expr__item)*(e->numterms<2?0:e->numterms-2));
n->op = e->op;
n->line = e->line;
n->numterms = e->numterms;
for (i=0; i<e->numterms; i++) {
if (i != except)
expr_item_copy(&n->terms[i], &e->terms[i]);
}
return n;
}
yasm_expr *
yasm_expr_copy(const yasm_expr *e)
{
return yasm_expr__copy_except(e, -1);
}
static void
expr_delete_term(yasm_expr__item *term, int recurse)
{
switch (term->type) {
case YASM_EXPR_INT:
yasm_intnum_destroy(term->data.intn);
break;
case YASM_EXPR_FLOAT:
yasm_floatnum_destroy(term->data.flt);
break;
case YASM_EXPR_EXPR:
if (recurse)
yasm_expr_destroy(term->data.expn);
break;
default:
break;
}
}
static int
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
expr_destroy_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d)
{
int i;
for (i=0; i<e->numterms; i++)
expr_delete_term(&e->terms[i], 0);
yasm_xfree(e); /* free ourselves */
return 0; /* don't stop recursion */
}
/*@-mustfree@*/
void
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
yasm_expr_destroy(yasm_expr *e)
{
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
expr_traverse_nodes_post(e, NULL, expr_destroy_each);
}
/*@=mustfree@*/
int
yasm_expr_is_op(const yasm_expr *e, yasm_expr_op op)
{
return (e->op == op);
}
static int
expr_contains_callback(const yasm_expr__item *ei, void *d)
{
yasm_expr__type *t = d;
return (ei->type & *t);
}
int
yasm_expr__contains(const yasm_expr *e, yasm_expr__type t)
{
return yasm_expr__traverse_leaves_in_const(e, &t, expr_contains_callback);
}
typedef struct subst_cbd {
unsigned int num_items;
const yasm_expr__item *items;
} subst_cbd;
static int
expr_subst_callback(yasm_expr__item *ei, void *d)
{
subst_cbd *cbd = d;
if (ei->type != YASM_EXPR_SUBST)
return 0;
if (ei->data.subst >= cbd->num_items)
return 1; /* error */
expr_item_copy(ei, &cbd->items[ei->data.subst]);
return 0;
}
int
yasm_expr__subst(yasm_expr *e, unsigned int num_items,
const yasm_expr__item *items)
{
subst_cbd cbd;
cbd.num_items = num_items;
cbd.items = items;
return yasm_expr__traverse_leaves_in(e, &cbd, expr_subst_callback);
}
/* Traverse over expression tree, calling func for each operation AFTER the
* branches (if expressions) have been traversed (eg, postorder
* traversal). The data pointer d is passed to each func call.
*
* Stops early (and returns 1) if func returns 1. Otherwise returns 0.
*/
static int
expr_traverse_nodes_post(yasm_expr *e, void *d,
int (*func) (/*@null@*/ yasm_expr *e,
/*@null@*/ void *d))
{
int i;
if (!e)
return 0;
/* traverse terms */
for (i=0; i<e->numterms; i++) {
if (e->terms[i].type == YASM_EXPR_EXPR &&
expr_traverse_nodes_post(e->terms[i].data.expn, d, func))
return 1;
}
/* do callback */
return func(e, d);
}
/* Traverse over expression tree in order, calling func for each leaf
* (non-operation). The data pointer d is passed to each func call.
*
* Stops early (and returns 1) if func returns 1. Otherwise returns 0.
*/
int
yasm_expr__traverse_leaves_in_const(const yasm_expr *e, void *d,
int (*func) (/*@null@*/ const yasm_expr__item *ei, /*@null@*/ void *d))
{
int i;
if (!e)
return 0;
for (i=0; i<e->numterms; i++) {
if (e->terms[i].type == YASM_EXPR_EXPR) {
if (yasm_expr__traverse_leaves_in_const(e->terms[i].data.expn, d,
func))
return 1;
} else {
if (func(&e->terms[i], d))
return 1;
}
}
return 0;
}
/* Traverse over expression tree in order, calling func for each leaf
* (non-operation). The data pointer d is passed to each func call.
*
* Stops early (and returns 1) if func returns 1. Otherwise returns 0.
*/
int
yasm_expr__traverse_leaves_in(yasm_expr *e, void *d,
int (*func) (/*@null@*/ yasm_expr__item *ei, /*@null@*/ void *d))
{
int i;
if (!e)
return 0;
for (i=0; i<e->numterms; i++) {
if (e->terms[i].type == YASM_EXPR_EXPR) {
if (yasm_expr__traverse_leaves_in(e->terms[i].data.expn, d, func))
return 1;
} else {
if (func(&e->terms[i], d))
return 1;
}
}
return 0;
}
yasm_expr *
yasm_expr_extract_deep_segoff(yasm_expr **ep)
{
yasm_expr *retval;
yasm_expr *e = *ep;
int i;
/* Try to extract at this level */
retval = yasm_expr_extract_segoff(ep);
if (retval)
return retval;
/* Not at this level? Search any expr children. */
for (i=0; i<e->numterms; i++) {
if (e->terms[i].type == YASM_EXPR_EXPR) {
retval = yasm_expr_extract_deep_segoff(&e->terms[i].data.expn);
if (retval)
return retval;
}
}
/* Didn't find one */
return NULL;
}
* expr.c (yasm_expr_extract_symrec): Add "relocate" parameter. Use it to control whether the symbol is replaced with the symbol's value (old behavior), or just replace it with 0 (new optional behavior). The old behavior is enabled by setting relocate=1. * expr.h (yasm_expr_extract_symrec): Likewise (and document new behavior). * elf-objfmt.c (elf_objfmt_output_expr): Use new function (with relocate=1). * coff-objfmt.c (coff_objfmt_output_expr): Likewise. * expr.c (yasm_expr_extract_segment): Renamed to yasm_expr_extract_segoff, a more approprate name given what operator it looks at. * expr.h (yasm_expr_extract_segment): Likewise. * x86bc.c (x86_bc_jmp_tobytes): Use new function name. * expr.c (yasm_expr_extract_seg): New function to remove SEG unary operator. * expr.h (yasm_expr_extract_seg): Likewise. * expr.c (yasm_expr_extract_shr): New function to split SHR operator into left and right halves. * expr.h (yasm_expr_extract_shr): Likewise. * xdf.h: New header file describing the newly added Extended Dynamic Object Format (XDF). Note: GCC-only code. * xdfdump.c: New utility that uses the format described in xdf.h to completely dump an XDF file. Note: non-portable code (runs correctly on little endian machines only). Neither of these files are currently included in the distribution. * xdf-objfmt.c: New YASM objfmt module to output XDF format object files. * modules/objfmts/xdf/Makefile.inc: Add to build. * modules/objfmts/Makefile.inc: Likewise. The XDF object format is a blend between COFF and OMF. It is a very simple object format intended for use by operating system loaders or similar types of targets. It allows shifted relocations (useful for static interrupt or page tables), both flat and segment-relative, and the use of the SEG, WRT, and x86 JMP FAR notations. Test cases will be committed soon. svn path=/trunk/yasm/; revision=1149
20 years ago
yasm_expr *
yasm_expr_extract_segoff(yasm_expr **ep)
{
yasm_expr *retval;
yasm_expr *e = *ep;
/* If not SEG:OFF, we can't do this transformation */
if (e->op != YASM_EXPR_SEGOFF)
return NULL;
/* Extract the SEG portion out to its own expression */
if (e->terms[0].type == YASM_EXPR_EXPR)
retval = e->terms[0].data.expn;
else {
/* Need to build IDENT expression to hold non-expression contents */
retval = yasm_xmalloc(sizeof(yasm_expr));
retval->op = YASM_EXPR_IDENT;
retval->numterms = 1;
retval->terms[0] = e->terms[0]; /* structure copy */
}
/* Delete the SEG: portion by changing the expression into an IDENT */
e->op = YASM_EXPR_IDENT;
e->numterms = 1;
e->terms[0] = e->terms[1]; /* structure copy */
return retval;
}
yasm_expr *
yasm_expr_extract_wrt(yasm_expr **ep)
{
yasm_expr *retval;
yasm_expr *e = *ep;
/* If not WRT, we can't do this transformation */
if (e->op != YASM_EXPR_WRT)
return NULL;
/* Extract the right side portion out to its own expression */
if (e->terms[1].type == YASM_EXPR_EXPR)
retval = e->terms[1].data.expn;
else {
/* Need to build IDENT expression to hold non-expression contents */
retval = yasm_xmalloc(sizeof(yasm_expr));
retval->op = YASM_EXPR_IDENT;
retval->numterms = 1;
retval->terms[0] = e->terms[1]; /* structure copy */
}
/* Delete the right side portion by changing the expr into an IDENT */
e->op = YASM_EXPR_IDENT;
e->numterms = 1;
* expr.c (yasm_expr_extract_symrec): Add "relocate" parameter. Use it to control whether the symbol is replaced with the symbol's value (old behavior), or just replace it with 0 (new optional behavior). The old behavior is enabled by setting relocate=1. * expr.h (yasm_expr_extract_symrec): Likewise (and document new behavior). * elf-objfmt.c (elf_objfmt_output_expr): Use new function (with relocate=1). * coff-objfmt.c (coff_objfmt_output_expr): Likewise. * expr.c (yasm_expr_extract_segment): Renamed to yasm_expr_extract_segoff, a more approprate name given what operator it looks at. * expr.h (yasm_expr_extract_segment): Likewise. * x86bc.c (x86_bc_jmp_tobytes): Use new function name. * expr.c (yasm_expr_extract_seg): New function to remove SEG unary operator. * expr.h (yasm_expr_extract_seg): Likewise. * expr.c (yasm_expr_extract_shr): New function to split SHR operator into left and right halves. * expr.h (yasm_expr_extract_shr): Likewise. * xdf.h: New header file describing the newly added Extended Dynamic Object Format (XDF). Note: GCC-only code. * xdfdump.c: New utility that uses the format described in xdf.h to completely dump an XDF file. Note: non-portable code (runs correctly on little endian machines only). Neither of these files are currently included in the distribution. * xdf-objfmt.c: New YASM objfmt module to output XDF format object files. * modules/objfmts/xdf/Makefile.inc: Add to build. * modules/objfmts/Makefile.inc: Likewise. The XDF object format is a blend between COFF and OMF. It is a very simple object format intended for use by operating system loaders or similar types of targets. It allows shifted relocations (useful for static interrupt or page tables), both flat and segment-relative, and the use of the SEG, WRT, and x86 JMP FAR notations. Test cases will be committed soon. svn path=/trunk/yasm/; revision=1149
20 years ago
return retval;
}
/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
yasm_intnum *
yasm_expr_get_intnum(yasm_expr **ep, int calc_bc_dist)
{
*ep = yasm_expr_simplify(*ep, calc_bc_dist);
if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_INT)
return (*ep)->terms[0].data.intn;
else
return (yasm_intnum *)NULL;
}
/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
const yasm_symrec *
yasm_expr_get_symrec(yasm_expr **ep, int simplify)
{
if (simplify)
*ep = yasm_expr_simplify(*ep, 0);
More gracefully handle absolute section refernce expansion, and allow for correct detection of absolute section reference loops (fixing a crash case). This is also needed for an ongoing rewrite of reloc/value handling. * expr.c (expr_xform_bc_dist): Remove transformation of absolute section references; move in changed form into... (yasm_expr__level_tree): Here. The new code doesn't immediately calculate the distance from the start of the absolute section to the referenced symbol; rather it generates an expression for this quantity. As this actually adds new absolute section refs to the tree, we can't expand with YASM_EXPR_SYMs, otherwise we would expand multiple times. Thus we need a new YASM_EXPR_SYMEXP type that thus does not get expanded. Unfortunately this ripples changes a bit because everywhere *else* we look for YASM_EXPR_SYM, we now need to look for YASM_EXPR_SYMEXP as well... (expr_xform_bc_dist): Here. (yasm_expr__copy_except): Here. (yasm_expr_extract_symrec): Here. (yasm_expr_get_symrec): Here. (yasm_expr_print): Here. * bin-objfmt.c (bin_objfmt_expr_xform): And here. * expr-int.h (yasm_expr__type): Define new YASM_EXPR_SYMEXP. * section.h (yasm_section_abs_get_sym): To implement above, we need to get a symbol referencing the first bytecode in the absolute section. To avoid creating redundant symrecs, one is generated for us now. This function lets us get it in yasm_expr__level_tree(). * section.c (yasm_section_abs_get_sym): Implement. (yasm_section): Add necessary SECTION_ABSOLUTE data. (yasm_section_create_absolute): Create the symrec here. * absloop-err.asm: New test for absolute section reference loops. svn path=/trunk/yasm/; revision=1417
19 years ago
if ((*ep)->op == YASM_EXPR_IDENT &&
((*ep)->terms[0].type == YASM_EXPR_SYM ||
(*ep)->terms[0].type == YASM_EXPR_SYMEXP))
return (*ep)->terms[0].data.sym;
else
return (yasm_symrec *)NULL;
}
/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
const unsigned long *
yasm_expr_get_reg(yasm_expr **ep, int simplify)
{
if (simplify)
*ep = yasm_expr_simplify(*ep, 0);
if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_REG)
return &((*ep)->terms[0].data.reg);
else
return NULL;
}
/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
void
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
yasm_expr_print(const yasm_expr *e, FILE *f)
{
char opstr[8];
int i;
if (!e) {
fprintf(f, "(nil)");
return;
}
switch (e->op) {
case YASM_EXPR_ADD:
strcpy(opstr, "+");
break;
case YASM_EXPR_SUB:
strcpy(opstr, "-");
break;
case YASM_EXPR_MUL:
strcpy(opstr, "*");
break;
case YASM_EXPR_DIV:
strcpy(opstr, "/");
break;
case YASM_EXPR_SIGNDIV:
strcpy(opstr, "//");
break;
case YASM_EXPR_MOD:
strcpy(opstr, "%");
break;
case YASM_EXPR_SIGNMOD:
strcpy(opstr, "%%");
break;
case YASM_EXPR_NEG:
fprintf(f, "-");
opstr[0] = 0;
break;
case YASM_EXPR_NOT:
fprintf(f, "~");
opstr[0] = 0;
break;
case YASM_EXPR_OR:
strcpy(opstr, "|");
break;
case YASM_EXPR_AND:
strcpy(opstr, "&");
break;
case YASM_EXPR_XOR:
strcpy(opstr, "^");
break;
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
case YASM_EXPR_XNOR:
strcpy(opstr, "XNOR");
break;
case YASM_EXPR_NOR:
strcpy(opstr, "NOR");
break;
case YASM_EXPR_SHL:
strcpy(opstr, "<<");
break;
case YASM_EXPR_SHR:
strcpy(opstr, ">>");
break;
case YASM_EXPR_LOR:
strcpy(opstr, "||");
break;
case YASM_EXPR_LAND:
strcpy(opstr, "&&");
break;
case YASM_EXPR_LNOT:
strcpy(opstr, "!");
break;
Change the NASM preprocessor to use yasm_intnum and yasm_expr. This decreases bloat and more importantly makes it possible to use >32-bit values in the preprocessor. This has NOT been heavily tested, so there may easily be bugs. I've not yet decided whether to merge this to 0.5.0 final for this reason. Inspired by: Jason Chen <jchen@centtech.com> patches to use "long long" rather than "long" in the preprocessor to enable >32-bit values. * coretype.h (yasm_op): Add XNOR, LXOR, LXNOR, LNOR. * intnum.c (yasm_intnum_calc): Calculate the above. * expr.c (expr_is_constant, expr_can_destroy_int_left) (expr_can_destroy_int_right, ...): Actually handle logical operations, including the new ones. * intnum.c (yasm_intnum_get_str): New; gets a signed decimal string representation of an intnum. * intnum.h (yasm_intnum_get_str): Prototype. * nasmlib.c (nasm_strcat): Change parameters to const. * nasmlib.h (nasm_strcat): Update prototype. * nasm-preproc.c (nasm_preproc_input): Close a memory leak. * nasm.h: Clean out a lot of cruft we don't use. (tokenval): Change t_integer and t_inttwo to yasm_intnums. (evalfunc): Remove fwref and hints parameters (cleanup), change return value to yasm_expr. * nasm-eval.c: Massively rewrite to just call appropriate yasm_expr creation functions rather than calculating the value here. Overall recursive descent parsing structure is unchanged. * nasmlib.c: Remove a lot of now-unused functions. (nasm_readnum): Use yasm_intnum functions and return that. (nasm_readstrnum): Likewise. * nasmlib.h: Update prototypes. * nasm-pp.c: Change to use intnum/expr as necessary. * nasm-preproc.c (nasm_preproc_destroy): Don't call nasm_eval_cleanup, it's been deleted. * nasmpp-bigint.asm: New test for >32-bit preproc values. * ifcritical-err.errwarn: The new code doesn't generate a duplicate warning. svn path=/trunk/yasm/; revision=1485
19 years ago
case YASM_EXPR_LXOR:
strcpy(opstr, "^^");
break;
case YASM_EXPR_LXNOR:
strcpy(opstr, "LXNOR");
break;
case YASM_EXPR_LNOR:
strcpy(opstr, "LNOR");
break;
case YASM_EXPR_LT:
strcpy(opstr, "<");
break;
case YASM_EXPR_GT:
strcpy(opstr, ">");
break;
case YASM_EXPR_LE:
strcpy(opstr, "<=");
break;
case YASM_EXPR_GE:
strcpy(opstr, ">=");
break;
case YASM_EXPR_NE:
strcpy(opstr, "!=");
break;
case YASM_EXPR_EQ:
strcpy(opstr, "==");
break;
case YASM_EXPR_SEG:
fprintf(f, "SEG ");
opstr[0] = 0;
break;
case YASM_EXPR_WRT:
strcpy(opstr, " WRT ");
break;
case YASM_EXPR_SEGOFF:
strcpy(opstr, ":");
break;
case YASM_EXPR_IDENT:
opstr[0] = 0;
break;
default:
strcpy(opstr, " !UNK! ");
break;
}
for (i=0; i<e->numterms; i++) {
switch (e->terms[i].type) {
case YASM_EXPR_PRECBC:
fprintf(f, "{%lx}",
yasm_bc_next_offset(e->terms[i].data.precbc));
break;
case YASM_EXPR_SYM:
More gracefully handle absolute section refernce expansion, and allow for correct detection of absolute section reference loops (fixing a crash case). This is also needed for an ongoing rewrite of reloc/value handling. * expr.c (expr_xform_bc_dist): Remove transformation of absolute section references; move in changed form into... (yasm_expr__level_tree): Here. The new code doesn't immediately calculate the distance from the start of the absolute section to the referenced symbol; rather it generates an expression for this quantity. As this actually adds new absolute section refs to the tree, we can't expand with YASM_EXPR_SYMs, otherwise we would expand multiple times. Thus we need a new YASM_EXPR_SYMEXP type that thus does not get expanded. Unfortunately this ripples changes a bit because everywhere *else* we look for YASM_EXPR_SYM, we now need to look for YASM_EXPR_SYMEXP as well... (expr_xform_bc_dist): Here. (yasm_expr__copy_except): Here. (yasm_expr_extract_symrec): Here. (yasm_expr_get_symrec): Here. (yasm_expr_print): Here. * bin-objfmt.c (bin_objfmt_expr_xform): And here. * expr-int.h (yasm_expr__type): Define new YASM_EXPR_SYMEXP. * section.h (yasm_section_abs_get_sym): To implement above, we need to get a symbol referencing the first bytecode in the absolute section. To avoid creating redundant symrecs, one is generated for us now. This function lets us get it in yasm_expr__level_tree(). * section.c (yasm_section_abs_get_sym): Implement. (yasm_section): Add necessary SECTION_ABSOLUTE data. (yasm_section_create_absolute): Create the symrec here. * absloop-err.asm: New test for absolute section reference loops. svn path=/trunk/yasm/; revision=1417
19 years ago
case YASM_EXPR_SYMEXP:
fprintf(f, "%s", yasm_symrec_get_name(e->terms[i].data.sym));
break;
case YASM_EXPR_EXPR:
fprintf(f, "(");
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
yasm_expr_print(e->terms[i].data.expn, f);
fprintf(f, ")");
break;
case YASM_EXPR_INT:
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
yasm_intnum_print(e->terms[i].data.intn, f);
break;
case YASM_EXPR_FLOAT:
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
yasm_floatnum_print(e->terms[i].data.flt, f);
break;
case YASM_EXPR_REG:
Massive libyasm / module interface update - Phase 1 As yasm has evolved, various minor additions have been made to libyasm to support the new features. These minor additions have accumulated, and some contain significant redundancies. In addition, the core focus of yasm has begun to move away from the front-end commandline program "yasm" to focusing on libyasm, a collection of reusable routines for use in all sorts of programs dealing with code at the assembly level, and the modules that provide specific features for parsing such code. This libyasm/module update focuses on cleaning up much of the cruft that has accumulated in libyasm, standardizing function names, eliminating redundancies, making many of the core objects more reusable for future extensions, and starting to make libyasm and the modules thread-safe by eliminating static variables. Specific changes include: - Making a symbol table data structure (no longer global). It follows a factory model for creating symrecs. - Label symbols now refer only to bytecodes; bytecodes have a pointer to their containing section. - Standardizing on *_create() and *_destroy() for allocation/deallocation. - Adding a standardized callback mechanism for all data structures that allow associated data. Allowed the removal of objfmt and dbgfmt-specific data callbacks in their interfaces. - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr is now renamed linemap). - Remove references to lindex; all virtual lines (from linemap) are now just "line"s. - Eliminating the bytecode "type" enum, instead adding a standardized callback mechanism for custom (and standard internal) bytecode types. This will make it much easier to add new bytecodes, and eliminate the possibility of type collisions. This also allowed the removal of the of_data and df_data bytecodes, as objfmts and dbgfmts can now easily implement their own bytecodes, and the cleanup of arch's bytecode usage. - Remove the bytecodehead and sectionhead pseudo-containers, instead making true containers: section now implements all the functions of bytecodehead, and the new object data structure implements all the functions of sectionhead. - Add object data structure: it's a container that contains sections, a symbol table, and a line mapping for a single object. Every former use of sectionhead now takes an object. - Make arch interface and all standard architectures thread-safe: yasm_arch_module is the module interface; it contains a create() function that returns a yasm_arch * to store local yasm_arch data; all yasm_arch_module functions take the yasm_arch *. - Make nasm parser thread-safe. To be done in phase 2: making other module interfaces thread-safe. Note that while the module interface may be thread-safe, not all modules may be written in such a fashion (hopefully all the "standard" ones will be, but this is yet to be determined). svn path=/trunk/yasm/; revision=1058
21 years ago
/* FIXME */
/*yasm_arch_reg_print(arch, e->terms[i].data.reg, f);*/
break;
case YASM_EXPR_SUBST:
fprintf(f, "[%u]", e->terms[i].data.subst);
break;
case YASM_EXPR_NONE:
break;
}
if (i < e->numterms-1)
fprintf(f, "%s", opstr);
}
}